diff --git a/src/BaselineOfPolyMath/BaselineOfPolyMath.class.st b/src/BaselineOfPolyMath/BaselineOfPolyMath.class.st index 8f323990..2dfe9ce7 100644 --- a/src/BaselineOfPolyMath/BaselineOfPolyMath.class.st +++ b/src/BaselineOfPolyMath/BaselineOfPolyMath.class.st @@ -15,7 +15,7 @@ Class { #category : #BaselineOfPolyMath } -{ #category : #baseline } +{ #category : #baselines } BaselineOfPolyMath >> baseline: spec [ @@ -24,80 +24,14 @@ BaselineOfPolyMath >> baseline: spec [ sMark: spec; xmlWriter: spec; vectorMatrix: spec; - randomNumbers: spec. + randomNumbers: spec; + datasets: spec; + roassal: spec; + dataFrameInspector: spec. - spec - package: 'ExtendedNumberParser'; - package: 'Math-Accuracy-Core'; - package: 'Math-Accuracy-ODE' with: [ spec requires: #( 'Math-ODE' 'XMLWriter' ) ]; - package: 'Math-ArbitraryPrecisionFloat' with: [ spec requires: #( 'ExtendedNumberParser' ) ]; - package: 'Math-AutomaticDifferenciation' with: [ spec requires: #( 'Math-Numerical' 'MathVectorMatrix' ) ]; - package: 'Math-Benchmarks-KDTree' with: [ spec requires: #( 'Math-KDTree' 'SMark' ) ]; - package: 'Math-Benchmarks-ODE' with: [ spec requires: #( 'Math-ODE' 'SMark' 'XMLWriter' ) ]; - package: 'Math-Chromosome' with: [ spec requires: #( 'MathVectorMatrix' ) ]; - package: 'Math-Clustering' with: [ spec requires: #( 'Math-Numerical' 'Math-Core-Process' 'MathVectorMatrix' ) ]; - package: 'Math-Complex' with: [ spec requires: #( 'Math-Numerical' 'Math-Polynomials' ) ]; - package: 'Math-Helpers'; - package: 'Math-Distributions' with: [ spec requires: #( 'MathVectorMatrix' 'Math-Quantile' 'Math-Core-Process' ) ]; - package: 'Math-Core-Process'; - package: 'Math-Numerical' - with: [ spec requires: #( 'MathVectorMatrix' 'Math-Core-Process' 'Math-Distributions' 'Math-StatisticalMoments' - 'Math-Series' ) ]; - package: 'Math-Polynomials' - with: [ spec requires: #( 'MathVectorMatrix' 'Math-Core-Process' 'Math-Distributions' 'Math-StatisticalMoments' - 'Math-Series' ) ]; - package: 'Math-FastFourierTransform' with: [ spec requires: #( 'Math-Complex' ) ]; - package: 'Math-FunctionFit' - with: [ spec requires: #( 'Math-Numerical' 'Math-Chromosome' 'Math-Accuracy-Core' 'MathVectorMatrix' 'Math-Helpers' 'Math-Polynomials' ) ]; - package: 'Math-KDTree'; - package: 'Math-Number-Extensions'; - package: 'Math-ODE' with: [ spec requires: #( 'Math-Numerical' 'MathVectorMatrix' 'Math-Polynomials' ) ]; - package: 'Math-Permutation' with: [ spec requires: #( 'MathVectorMatrix' 'Math-Core-Process' ) ]; - package: 'Math-Physics-Constants'; - package: 'Math-PrincipalComponentAnalysis' with: [ spec requires: #( 'Math-Numerical' 'MathVectorMatrix' 'Math-Polynomials' ) ]; - package: 'Math-Quantile'; - package: 'Math-Quaternion' with: [ spec requires: #( 'Math-Complex' 'Math-Numerical' 'Math-Polynomials' ) ]; - package: 'Math-Series'; - package: 'Math-StatisticalMoments' with: [ spec requires: #( 'Math-Helpers' 'Math-Distributions' ) ]; - package: 'Math-TSNE'; - package: 'Math-Tests-Accuracy' with: [ spec requires: #( 'Math-Accuracy-Core' ) ]; - package: 'Math-Tests-ArbitraryPrecisionFloat' with: [ spec requires: #( 'Math-ArbitraryPrecisionFloat' ) ]; - package: 'Math-Tests-AutomaticDifferenciation' with: [ spec requires: #( 'Math-AutomaticDifferenciation' 'MathVectorMatrix' ) ]; - package: 'Math-Tests-Clustering' with: [ spec requires: #( 'Math-Clustering' 'Math-Distributions' 'Math-UtilsDataServer' ) ]; - package: 'Math-Tests-Complex' with: [ spec requires: #( 'Math-Complex' ) ]; - package: 'Math-Tests-Distributions' with: [ spec requires: #( 'Math-Distributions' ) ]; - package: 'Math-Tests-Core-Process' with: [ spec requires: #( 'Math-Core-Process' ) ]; - package: 'Math-Tests-Numerical' with: [ spec requires: #( 'Math-Numerical' 'Math-UtilsDataServer' ) ]; - package: 'Math-Tests-FastFourierTransform' with: [ spec requires: #( 'Math-FastFourierTransform' 'Math-Numerical' 'Math-Polynomials' ) ]; - package: 'Math-Tests-FunctionFit'; - package: 'Math-Tests-KDTree' with: [ spec requires: #( 'Math-KDTree' ) ]; - package: 'Math-Tests-Number-Extensions' with: [ spec requires: #( 'Math-Number-Extensions' ) ]; - package: 'Math-Tests-ODE' with: [ spec requires: #( 'Math-ODE' ) ]; - package: 'Math-Tests-Permutation' with: [ spec requires: #( 'Math-Permutation' ) ]; - package: 'Math-Tests-PrincipalComponentAnalysis' with: [ spec requires: #( 'Math-PrincipalComponentAnalysis' ) ]; - package: 'Math-Tests-Quantile' with: [ spec requires: #( 'Math-Quantile' ) ]; - package: 'Math-Tests-Polynomials' with: [ spec requires: #( 'Math-Polynomials' ) ]; - package: 'Math-Tests-Quaternion' with: [ spec requires: #( 'Math-Quaternion' ) ]; - package: 'Math-Tests-TSNE' with: [ spec requires: #( 'Math-TSNE' ) ]; - package: 'Math-UtilsDataServer'. - spec - group: 'Accuracy' with: #( 'Math-Accuracy-ODE' 'Math-Accuracy-Core' ); - group: 'Benchmarks' with: #( 'Math-Benchmarks-ODE' 'Math-Benchmarks-KDTree' ); - group: 'Core' - with: - #( 'Math-Complex' 'Math-Quaternion' 'Math-Numerical' 'MathRandomNumbers' 'Math-KDTree' 'Math-ODE' 'Math-ArbitraryPrecisionFloat' - 'Math-FastFourierTransform' 'ExtendedNumberParser' 'Math-Quantile' 'Math-Physics-Constants' 'Math-Polynomials' 'Math-TSNE' 'Math-Core-Process' - 'Math-Helpers' 'MathVectorMatrix' 'Math-Distributions' ); - group: 'Extensions' - with: #( 'Math-Clustering' 'Math-Number-Extensions' 'Math-Chromosome' 'Math-PrincipalComponentAnalysis' 'Math-FunctionFit' 'Math-AutomaticDifferenciation' - 'Math-Permutation' ); - group: 'Tests' - with: - #( 'Math-Tests-Clustering' 'Math-Tests-Numerical' 'Math-Tests-Complex' 'Math-Tests-Quaternion' 'Math-Tests-ODE' 'Math-Tests-KDTree' 'Math-Tests-FunctionFit' - 'Math-Tests-AutomaticDifferenciation' 'Math-Tests-FastFourierTransform' 'Math-Tests-Accuracy' 'Math-Tests-ArbitraryPrecisionFloat' - 'Math-Tests-Quantile' 'Math-Tests-Polynomials' 'Math-Tests-PrincipalComponentAnalysis' 'Math-Tests-Number-Extensions' 'Math-Tests-Permutation' - 'Math-Tests-TSNE' 'Math-Tests-Core-Process' 'Math-Tests-Distributions' ); - group: 'default' with: #( 'Core' 'Extensions' 'Tests' 'Benchmarks' 'Accuracy' ) ]. + self + packages: spec; + groups: spec ]. spec for: #( #'pharo6.x' #'pharo7.x' #'pharo8.x' #'pharo9.x' #'pharo10.x' ) do: [ spec @@ -107,6 +41,169 @@ BaselineOfPolyMath >> baseline: spec [ package: 'Math-CompatibilityUpToPharo11' ] ] +{ #category : #dependencies } +BaselineOfPolyMath >> dataFrameInspector: spec [ + + spec + baseline: 'AIDataFrameInspector' + with: [ spec repository: 'github://pharo-ai/data-inspector/src' ] +] + +{ #category : #dependencies } +BaselineOfPolyMath >> datasets: spec [ + + spec + baseline: 'AIDatasets' + with: [ spec repository: 'github://pharo-ai/datasets' ]. +] + +{ #category : #baselines } +BaselineOfPolyMath >> groups: spec [ + + spec + group: 'Accuracy' + with: #( 'Math-Accuracy-ODE' 'Math-Accuracy-Core' ); + group: 'Benchmarks' + with: #( 'Math-Benchmarks-ODE' 'Math-Benchmarks-KDTree' ); + group: 'Core' + with: + #( 'Math-Complex' 'Math-Quaternion' 'Math-Numerical' + 'MathRandomNumbers' 'Math-KDTree' 'Math-ODE' 'Math-ArbitraryPrecisionFloat' + 'Math-FastFourierTransform' 'ExtendedNumberParser' + 'Math-Quantile' 'Math-Physics-Constants' + 'Math-Polynomials' 'Math-TSNE' 'Math-Core-Process' + 'Math-Helpers' 'MathVectorMatrix' 'Math-Distributions' ); + group: 'Extensions' + with: + #( 'Math-Clustering' 'Math-Number-Extensions' + 'Math-Chromosome' 'Math-PrincipalComponentAnalysis' + 'Math-FunctionFit' 'Math-AutomaticDifferenciation' + 'Math-Permutation' ); + group: 'Tests' + with: #( 'Math-Tests-Clustering' 'Math-Tests-Numerical' + 'Math-Tests-Complex' 'Math-Tests-Quaternion' + 'Math-Tests-ODE' 'Math-Tests-KDTree' 'Math-Tests-FunctionFit' + 'Math-Tests-AutomaticDifferenciation' + 'Math-Tests-FastFourierTransform' + 'Math-Tests-Accuracy' 'Math-Tests-ArbitraryPrecisionFloat' + 'Math-Tests-Quantile' 'Math-Tests-Polynomials' + 'Math-Tests-PrincipalComponentAnalysis' + 'Math-Tests-Number-Extensions' 'Math-Tests-Permutation' + 'Math-Tests-TSNE' 'Math-Tests-Core-Process' + 'Math-Tests-Distributions' ); + group: 'visualizations' + with: + #( 'Core' 'Extensions' 'Tests' 'Benchmarks' 'Accuracy' 'Math-Visualizations' ); + group: 'default' + with: #( 'Core' 'Extensions' 'Tests' 'Benchmarks' 'Accuracy' ) +] + +{ #category : #baselines } +BaselineOfPolyMath >> packages: spec [ + + spec + package: 'ExtendedNumberParser'; + package: 'Math-Accuracy-Core'; + package: 'Math-Accuracy-ODE' + with: [ spec requires: #( 'Math-ODE' 'XMLWriter' ) ]; + package: 'Math-ArbitraryPrecisionFloat' + with: [ spec requires: #( 'ExtendedNumberParser' ) ]; + package: 'Math-AutomaticDifferenciation' + with: [ spec requires: #( 'Math-Numerical' 'MathVectorMatrix' ) ]; + package: 'Math-Benchmarks-KDTree' + with: [ spec requires: #( 'Math-KDTree' 'SMark' ) ]; + package: 'Math-Benchmarks-ODE' + with: [ spec requires: #( 'Math-ODE' 'SMark' 'XMLWriter' ) ]; + package: 'Math-Chromosome' + with: [ spec requires: #( 'MathVectorMatrix' ) ]; + package: 'Math-Clustering' with: [ + spec requires: + #( 'Math-Numerical' 'Math-Core-Process' 'MathVectorMatrix' ) ]; + package: 'Math-Complex' + with: [ spec requires: #( 'Math-Numerical' 'Math-Polynomials' ) ]; + package: 'Math-Helpers'; + package: 'Math-Distributions' with: [ + spec requires: + #( 'MathVectorMatrix' 'Math-Quantile' 'Math-Core-Process' ) ]; + package: 'Math-Core-Process'; + package: 'Math-Numerical' with: [ + spec requires: + #( 'MathVectorMatrix' 'Math-Core-Process' 'Math-Distributions' + 'Math-StatisticalMoments' 'Math-Series' ) ]; + package: 'Math-Polynomials' with: [ + spec requires: + #( 'MathVectorMatrix' 'Math-Core-Process' 'Math-Distributions' + 'Math-StatisticalMoments' 'Math-Series' ) ]; + package: 'Math-FastFourierTransform' + with: [ spec requires: #( 'Math-Complex' ) ]; + package: 'Math-FunctionFit' with: [ + spec requires: + #( 'Math-Numerical' 'Math-Chromosome' 'Math-Accuracy-Core' + 'MathVectorMatrix' 'Math-Helpers' 'Math-Polynomials' ) ]; + package: 'Math-KDTree'; + package: 'Math-Number-Extensions'; + package: 'Math-ODE' with: [ + spec requires: + #( 'Math-Numerical' 'MathVectorMatrix' 'Math-Polynomials' ) ]; + package: 'Math-Permutation' + with: [ spec requires: #( 'MathVectorMatrix' 'Math-Core-Process' ) ]; + package: 'Math-Physics-Constants'; + package: 'Math-PrincipalComponentAnalysis' with: [ + spec requires: + #( 'Math-Numerical' 'MathVectorMatrix' 'Math-Polynomials' ) ]; + package: 'Math-Quantile'; + package: 'Math-Quaternion' with: [ + spec requires: + #( 'Math-Complex' 'Math-Numerical' 'Math-Polynomials' ) ]; + package: 'Math-Series'; + package: 'Math-StatisticalMoments' + with: [ spec requires: #( 'Math-Helpers' 'Math-Distributions' ) ]; + package: 'Math-TSNE'; + package: 'Math-Tests-Accuracy' + with: [ spec requires: #( 'Math-Accuracy-Core' ) ]; + package: 'Math-Tests-ArbitraryPrecisionFloat' + with: [ spec requires: #( 'Math-ArbitraryPrecisionFloat' ) ]; + package: 'Math-Tests-AutomaticDifferenciation' with: [ + spec requires: + #( 'Math-AutomaticDifferenciation' + 'MathVectorMatrix' ) ]; + package: 'Math-Tests-Clustering' with: [ + spec requires: + #( 'Math-Clustering' 'Math-Distributions' 'Math-UtilsDataServer' ) ]; + package: 'Math-Tests-Complex' + with: [ spec requires: #( 'Math-Complex' ) ]; + package: 'Math-Tests-Distributions' + with: [ spec requires: #( 'Math-Distributions' ) ]; + package: 'Math-Tests-Core-Process' + with: [ spec requires: #( 'Math-Core-Process' ) ]; + package: 'Math-Tests-Numerical' + with: [ spec requires: #( 'Math-Numerical' 'Math-UtilsDataServer' ) ]; + package: 'Math-Tests-FastFourierTransform' with: [ + spec requires: + #( 'Math-FastFourierTransform' 'Math-Numerical' 'Math-Polynomials' ) ]; + package: 'Math-Tests-FunctionFit'; + package: 'Math-Tests-KDTree' + with: [ spec requires: #( 'Math-KDTree' ) ]; + package: 'Math-Tests-Number-Extensions' + with: [ spec requires: #( 'Math-Number-Extensions' ) ]; + package: 'Math-Tests-ODE' with: [ spec requires: #( 'Math-ODE' ) ]; + package: 'Math-Tests-Permutation' + with: [ spec requires: #( 'Math-Permutation' ) ]; + package: 'Math-Tests-PrincipalComponentAnalysis' + with: [ spec requires: #( 'Math-PrincipalComponentAnalysis' ) ]; + package: 'Math-Tests-Quantile' + with: [ spec requires: #( 'Math-Quantile' ) ]; + package: 'Math-Tests-Polynomials' + with: [ spec requires: #( 'Math-Polynomials' ) ]; + package: 'Math-Tests-Quaternion' + with: [ spec requires: #( 'Math-Quaternion' ) ]; + package: 'Math-Tests-TSNE' + with: [ spec requires: #( 'Math-TSNE' ) ]; + package: 'Math-UtilsDataServer'; + package: 'Math-Visualizations' + with: [ spec requires: #( 'AIDatasets' 'AIDataFrameInspector') ] +] + { #category : #accessing } BaselineOfPolyMath >> projectClass [ ^ [ self class environment at: #MetacelloCypressBaselineProject ] @@ -120,6 +217,14 @@ BaselineOfPolyMath >> randomNumbers: spec [ spec baseline: 'MathRandomNumbers' with: [ spec repository: 'github://PolyMathOrg/random-numbers:v1.x.x/src' ] ] +{ #category : #dependencies } +BaselineOfPolyMath >> roassal: spec [ + + spec + baseline: 'Roassal' + with: [ spec repository: 'github://pharo-graphics/Roassal' ]. +] + { #category : #dependencies } BaselineOfPolyMath >> sMark: spec [ diff --git a/src/Math-PrincipalComponentAnalysis/PMDataTransformer.class.st b/src/Math-PrincipalComponentAnalysis/PMDataTransformer.class.st index 90d715c7..56654531 100644 --- a/src/Math-PrincipalComponentAnalysis/PMDataTransformer.class.st +++ b/src/Math-PrincipalComponentAnalysis/PMDataTransformer.class.st @@ -3,22 +3,23 @@ PMDataTransformer is the abstract root class of transformers. All data transform " Class { - #name : #PMDataTransformer, - #superclass : #Object, - #category : #'Math-PrincipalComponentAnalysis' + #name : 'PMDataTransformer', + #superclass : 'Object', + #category : 'Math-PrincipalComponentAnalysis', + #package : 'Math-PrincipalComponentAnalysis' } -{ #category : #accessing } +{ #category : 'accessing' } PMDataTransformer >> fit: aPMMatrix [ ^ self subclassResponsibility ] -{ #category : #accessing } +{ #category : 'accessing' } PMDataTransformer >> fitAndTransform: aPMMatrix [ ^ (self fit: aPMMatrix) transform: aPMMatrix ] -{ #category : #transforming } +{ #category : 'transforming' } PMDataTransformer >> transform: aPMMatrix [ ^ self subclassResponsibility ] diff --git a/src/Math-PrincipalComponentAnalysis/PMPrincipalComponentAnalyser.class.st b/src/Math-PrincipalComponentAnalysis/PMPrincipalComponentAnalyser.class.st index 591c1771..12cb528b 100644 --- a/src/Math-PrincipalComponentAnalysis/PMPrincipalComponentAnalyser.class.st +++ b/src/Math-PrincipalComponentAnalysis/PMPrincipalComponentAnalyser.class.st @@ -1,33 +1,34 @@ Class { - #name : #PMPrincipalComponentAnalyser, - #superclass : #Object, + #name : 'PMPrincipalComponentAnalyser', + #superclass : 'Object', #instVars : [ 'componentsNumber' ], - #category : #'Math-PrincipalComponentAnalysis' + #category : 'Math-PrincipalComponentAnalysis', + #package : 'Math-PrincipalComponentAnalysis' } -{ #category : #accessing } +{ #category : 'accessing' } PMPrincipalComponentAnalyser >> componentsNumber [ ^ componentsNumber ] -{ #category : #accessing } +{ #category : 'accessing' } PMPrincipalComponentAnalyser >> componentsNumber: anInteger [ componentsNumber := anInteger ] -{ #category : #accessing } +{ #category : 'accessing' } PMPrincipalComponentAnalyser >> fit: aPMMatrix [ ^ self subclassResponsibility ] -{ #category : #accessing } +{ #category : 'accessing' } PMPrincipalComponentAnalyser >> fitAndTransform: aPMMatrix [ ^ (self fit: aPMMatrix) transform: aPMMatrix ] -{ #category : #accessing } +{ #category : 'accessing' } PMPrincipalComponentAnalyser >> transform: aPMMatrix [ ^ self subclassResponsibility ] diff --git a/src/Math-PrincipalComponentAnalysis/PMPrincipalComponentAnalyserJacobiTransformation.class.st b/src/Math-PrincipalComponentAnalysis/PMPrincipalComponentAnalyserJacobiTransformation.class.st index aa699459..54002e12 100644 --- a/src/Math-PrincipalComponentAnalysis/PMPrincipalComponentAnalyserJacobiTransformation.class.st +++ b/src/Math-PrincipalComponentAnalysis/PMPrincipalComponentAnalyserJacobiTransformation.class.st @@ -8,53 +8,54 @@ Clients should first " Class { - #name : #PMPrincipalComponentAnalyserJacobiTransformation, - #superclass : #PMPrincipalComponentAnalyser, + #name : 'PMPrincipalComponentAnalyserJacobiTransformation', + #superclass : 'PMPrincipalComponentAnalyser', #instVars : [ 'accumulatorForCovarianceMatrix', 'jacobiTransform' ], - #category : #'Math-PrincipalComponentAnalysis' + #category : 'Math-PrincipalComponentAnalysis', + #package : 'Math-PrincipalComponentAnalysis' } -{ #category : #'instance creation' } +{ #category : 'instance creation' } PMPrincipalComponentAnalyserJacobiTransformation class >> new: anInteger [ "anInteger is the size of the elements you will accumulate: the elements you want to compare using the component analysis." ^ self basicNew initialize: anInteger; yourself ] -{ #category : #transformation } +{ #category : 'transformation' } PMPrincipalComponentAnalyserJacobiTransformation >> accumulate: aPMVectorOrArray [ accumulatorForCovarianceMatrix accumulate: aPMVectorOrArray ] -{ #category : #accessing } +{ #category : 'accessing' } PMPrincipalComponentAnalyserJacobiTransformation >> components [ "Precondition: accumulate: should have been used." ^ self jacobiTransform evaluate copyFrom: 1 to: componentsNumber ] -{ #category : #accessing } +{ #category : 'accessing' } PMPrincipalComponentAnalyserJacobiTransformation >> fit: aPMMatrix [ accumulatorForCovarianceMatrix := PMCovarianceAccumulator new: aPMMatrix numberOfColumns. aPMMatrix rowsDo: [ :eachRow | self accumulate: eachRow ]. self components ] -{ #category : #accessing } +{ #category : 'accessing' } PMPrincipalComponentAnalyserJacobiTransformation >> jacobiTransform [ ^ jacobiTransform ifNil: [ jacobiTransform := PMJacobiTransformation matrix: accumulatorForCovarianceMatrix covarianceMatrix ] ] -{ #category : #accessing } +{ #category : 'accessing' } PMPrincipalComponentAnalyserJacobiTransformation >> transform: aPMMatrix [ "Apply dimensionality reduction to aPMMatrix" ^ aPMMatrix * self transformMatrix transpose ] -{ #category : #accessing } +{ #category : 'accessing' } PMPrincipalComponentAnalyserJacobiTransformation >> transformMatrix [ "Return a matrix that can be applied to any data vector to extract the relevant component of the data vector" diff --git a/src/Math-PrincipalComponentAnalysis/PMPrincipalComponentAnalyserSVD.class.st b/src/Math-PrincipalComponentAnalysis/PMPrincipalComponentAnalyserSVD.class.st index 1ec347da..f613984c 100644 --- a/src/Math-PrincipalComponentAnalysis/PMPrincipalComponentAnalyserSVD.class.st +++ b/src/Math-PrincipalComponentAnalysis/PMPrincipalComponentAnalyserSVD.class.st @@ -1,41 +1,16 @@ Class { - #name : #PMPrincipalComponentAnalyserSVD, - #superclass : #PMPrincipalComponentAnalyser, + #name : 'PMPrincipalComponentAnalyserSVD', + #superclass : 'PMPrincipalComponentAnalyser', #instVars : [ 'svd', 'u', 'v' ], - #category : #'Math-PrincipalComponentAnalysis' + #category : 'Math-PrincipalComponentAnalysis', + #package : 'Math-PrincipalComponentAnalysis' } -{ #category : #examples } -PMPrincipalComponentAnalyserSVD class >> example1 [ - -"Extract 4 columns from original data" -| d m pca m1 d1 | -d := (DataFrame loadIris) columnsFrom: 1 to: 4. - -"Transform DF as matrix" -m := PMMatrix rows: (d asArrayOfRows). - -"Data standardization (mean = 0 and variance = 1)" -m := (PMStandardizationScaler new) fitAndTransform: m. - -"Compute PCA components" -pca := PMPrincipalComponentAnalyserSVD new. -pca componentsNumber: 2. -pca fit: m. -pca transformMatrix. - -m1 := pca transform: m. - -d1 := DataFrame fromRows: m1 rows. -d1 addColumn: ((DataFrame loadIris) columnsFrom:5 to:5) asArrayOfColumns first named:''. -d1 scatterplotMatrix -] - -{ #category : #accessing } +{ #category : 'accessing' } PMPrincipalComponentAnalyserSVD >> fit: aPMMatrix [ svd := aPMMatrix decomposeSV. @@ -44,7 +19,7 @@ PMPrincipalComponentAnalyserSVD >> fit: aPMMatrix [ self flipEigenvectorsSign ] -{ #category : #accessing } +{ #category : 'accessing' } PMPrincipalComponentAnalyserSVD >> flipEigenvectorsSign [ "flip eigenvectors sign to enforce deterministic output" "U-based decision like : https://github.com/scikit-learn/scikit-learn/blob/4c65d8e615c9331d37cbb6225c5b67c445a5c959/sklearn/utils/extmath.py#L609" @@ -56,14 +31,14 @@ PMPrincipalComponentAnalyserSVD >> flipEigenvectorsSign [ v := algo vFlipped . ] -{ #category : #accessing } +{ #category : 'accessing' } PMPrincipalComponentAnalyserSVD >> transform: aPMMatrix [ "Apply dimensionality reduction to aPMMatrix" ^ aPMMatrix * self transformMatrix transpose ] -{ #category : #accessing } +{ #category : 'accessing' } PMPrincipalComponentAnalyserSVD >> transformMatrix [ "Return a matrix that can be applied to any data vector to extract the relevant component of the data vector" diff --git a/src/Math-PrincipalComponentAnalysis/PMSciKitLearnSVDFlipAlgorithm.class.st b/src/Math-PrincipalComponentAnalysis/PMSciKitLearnSVDFlipAlgorithm.class.st index b442cd5e..c1436bd2 100644 --- a/src/Math-PrincipalComponentAnalysis/PMSciKitLearnSVDFlipAlgorithm.class.st +++ b/src/Math-PrincipalComponentAnalysis/PMSciKitLearnSVDFlipAlgorithm.class.st @@ -6,24 +6,25 @@ This class uses the SciKit-Learn SVD flip algorithm to ensure the signs of the e " Class { - #name : #PMSciKitLearnSVDFlipAlgorithm, - #superclass : #Object, + #name : 'PMSciKitLearnSVDFlipAlgorithm', + #superclass : 'Object', #instVars : [ 'u', 'v', 'signs' ], - #category : #'Math-PrincipalComponentAnalysis' + #category : 'Math-PrincipalComponentAnalysis', + #package : 'Math-PrincipalComponentAnalysis' } -{ #category : #'instance creation' } +{ #category : 'instance creation' } PMSciKitLearnSVDFlipAlgorithm class >> flipU: u andV: v [ ^ self new initializeWithU: u andV: v; yourself ] -{ #category : #accessing } +{ #category : 'accessing' } PMSciKitLearnSVDFlipAlgorithm >> computeSignsFromU [ | maxAbsCols i maxElements | maxAbsCols := u abs argMaxOnColumns. @@ -35,7 +36,7 @@ PMSciKitLearnSVDFlipAlgorithm >> computeSignsFromU [ ^ maxElements sign asPMVector ] -{ #category : #initialization } +{ #category : 'initialization' } PMSciKitLearnSVDFlipAlgorithm >> initializeWithU: uMatrix andV: vMatrix [ "instantiate the algorithm" u := uMatrix . @@ -43,7 +44,7 @@ PMSciKitLearnSVDFlipAlgorithm >> initializeWithU: uMatrix andV: vMatrix [ signs := self computeSignsFromU ] -{ #category : #accessing } +{ #category : 'accessing' } PMSciKitLearnSVDFlipAlgorithm >> signMatrixForU [ ^ PMMatrix rows: @@ -55,7 +56,7 @@ PMSciKitLearnSVDFlipAlgorithm >> signMatrixForU [ yourself ]) ] -{ #category : #accessing } +{ #category : 'accessing' } PMSciKitLearnSVDFlipAlgorithm >> signMatrixForV [ | signsForV | signsForV := self signs copyFrom: 1 to: v numberOfColumns. @@ -69,17 +70,17 @@ PMSciKitLearnSVDFlipAlgorithm >> signMatrixForV [ yourself ])) transpose ] -{ #category : #accessing } +{ #category : 'accessing' } PMSciKitLearnSVDFlipAlgorithm >> signs [ ^ signs ] -{ #category : #accessing } +{ #category : 'accessing' } PMSciKitLearnSVDFlipAlgorithm >> uFlipped [ ^ u hadamardProduct: (self signMatrixForU) ] -{ #category : #accessing } +{ #category : 'accessing' } PMSciKitLearnSVDFlipAlgorithm >> vFlipped [ ^ v hadamardProduct: (self signMatrixForV) ] diff --git a/src/Math-PrincipalComponentAnalysis/PMStandardizationScaler.class.st b/src/Math-PrincipalComponentAnalysis/PMStandardizationScaler.class.st index e4619c71..9f9ea96f 100644 --- a/src/Math-PrincipalComponentAnalysis/PMStandardizationScaler.class.st +++ b/src/Math-PrincipalComponentAnalysis/PMStandardizationScaler.class.st @@ -1,13 +1,14 @@ Class { - #name : #PMStandardizationScaler, - #superclass : #PMDataTransformer, + #name : 'PMStandardizationScaler', + #superclass : 'PMDataTransformer', #instVars : [ 'accumulator' ], - #category : #'Math-PrincipalComponentAnalysis' + #category : 'Math-PrincipalComponentAnalysis', + #package : 'Math-PrincipalComponentAnalysis' } -{ #category : #accessing } +{ #category : 'accessing' } PMStandardizationScaler >> fit: aPMMatrix [ "Compute the mean and the scale of a PMMatrix (in order to have a std of 1)" @@ -15,12 +16,12 @@ PMStandardizationScaler >> fit: aPMMatrix [ aPMMatrix rowsDo: [ :each | accumulator accumulate: each ] ] -{ #category : #accessing } +{ #category : 'accessing' } PMStandardizationScaler >> mean [ ^ accumulator average ] -{ #category : #accessing } +{ #category : 'accessing' } PMStandardizationScaler >> scale [ ^ self variance collect: [ :element | | root | @@ -29,7 +30,7 @@ PMStandardizationScaler >> scale [ ] ] -{ #category : #transforming } +{ #category : 'transforming' } PMStandardizationScaler >> transform: aPMMatrix [ "Perform standardization by centering and scaling" @@ -39,7 +40,7 @@ PMStandardizationScaler >> transform: aPMMatrix [ ^ PMMatrix rows: ((PMMatrix rows: (aPMMatrix rowsCollect: [ :each | each - mean ])) rowsCollect: [ :each| each / scale]) ] -{ #category : #information } +{ #category : 'information' } PMStandardizationScaler >> variance [ "Return the diagonal of the covarianceMatrix" diff --git a/src/Math-PrincipalComponentAnalysis/package.st b/src/Math-PrincipalComponentAnalysis/package.st index d6d1052e..84a57df6 100644 --- a/src/Math-PrincipalComponentAnalysis/package.st +++ b/src/Math-PrincipalComponentAnalysis/package.st @@ -1 +1 @@ -Package { #name : #'Math-PrincipalComponentAnalysis' } +Package { #name : 'Math-PrincipalComponentAnalysis' } diff --git a/src/Math-Visualizations/PMPrincipalComponentAnalyserSVD.extension.st b/src/Math-Visualizations/PMPrincipalComponentAnalyserSVD.extension.st new file mode 100644 index 00000000..ac79699f --- /dev/null +++ b/src/Math-Visualizations/PMPrincipalComponentAnalyserSVD.extension.st @@ -0,0 +1,92 @@ +Extension { #name : #PMPrincipalComponentAnalyserSVD } + +{ #category : #'*Math-Visualizations' } +PMPrincipalComponentAnalyserSVD class >> example1 [ + "Extract 4 columns from original data" + + | d m pca m1 d1 irisDataFrame roassalChart scatterPlotShapes | + + irisDataFrame := AIDatasets loadIris. + d := irisDataFrame columnsFrom: 1 to: 4. + + "Transform DF as matrix" + m := PMMatrix rows: d asArrayOfRows. + + "Data standardization (mean = 0 and variance = 1)" + m := PMStandardizationScaler new fitAndTransform: m. + + "Compute PCA components" + pca := PMPrincipalComponentAnalyserSVD new. + pca componentsNumber: 2. + pca fit: m. + pca transformMatrix. + + m1 := pca transform: m. + + d1 := DataFrame withRows: m1 rows. + d1 + addColumn: (irisDataFrame columnsFrom: 5 to: 5) asArrayOfColumns first + named: 'type'. + + roassalChart := self roassalChartClass new + title: 'PCA of Iris Data Frame'; + addDecoration: (RSHorizontalTick new doNotUseNiceLabel asFloat: 3); + addDecoration: RSVerticalTick new; + yourself. + + scatterPlotShapes := (d1 column: 'type') asSet collect: [ : type | + (d1 select: [ : e | e values includes: type ]) + addScatterPlotShapeToChart: roassalChart ]. + + roassalChart padding: 10. + scatterPlotShapes asOrderedCollection + with: { Color red . Color green . Color blue } + do: [ : scatterPlotShape : scatterPlotDotColor | + scatterPlotShape color: scatterPlotDotColor ]. + + roassalChart open. + + +] + +{ #category : #'*Math-Visualizations' } +PMPrincipalComponentAnalyserSVD class >> example2 [ + "Extract 4 columns from original data. This example uses Random colors for each flower type" + + | d m pca m1 d1 irisDataFrame | + + irisDataFrame := AIDatasets loadIris. + d := irisDataFrame columnsFrom: 1 to: 4. + + "Transform DF as matrix" + m := PMMatrix rows: d asArrayOfRows. + + "Data standardization (mean = 0 and variance = 1)" + m := PMStandardizationScaler new fitAndTransform: m. + + "Compute PCA components" + pca := PMPrincipalComponentAnalyserSVD new. + pca componentsNumber: 2. + pca fit: m. + pca transformMatrix. + + m1 := pca transform: m. + + d1 := DataFrame withRows: m1 rows. + d1 + addColumn: (irisDataFrame columnsFrom: 5 to: 5) asArrayOfColumns first + named: 'type'. + + d1 + openScatterPlotWithTitle: 'PCA of Iris data set' + forColumn: 'type'. +] + +{ #category : #'*Math-Visualizations' } +PMPrincipalComponentAnalyserSVD class >> roassalChartClass [ + + ^ SystemVersion current major < 12 + ifTrue: [ Smalltalk at: #RSChart ] + ifFalse: [ Smalltalk at: #RSCompositeChart ] + +] diff --git a/src/Math-Visualizations/package.st b/src/Math-Visualizations/package.st new file mode 100644 index 00000000..2b4afcd5 --- /dev/null +++ b/src/Math-Visualizations/package.st @@ -0,0 +1 @@ +Package { #name : #'Math-Visualizations' }