diff --git a/src/AI-LinearModels-Tests/AIAbstractLinearModelTest.class.st b/src/AI-LinearModels-Tests/AIAbstractLinearModelTest.class.st index 35c553e..01d2a1a 100644 --- a/src/AI-LinearModels-Tests/AIAbstractLinearModelTest.class.st +++ b/src/AI-LinearModels-Tests/AIAbstractLinearModelTest.class.st @@ -1,41 +1,42 @@ Class { - #name : #AIAbstractLinearModelTest, - #superclass : #TestCase, + #name : 'AIAbstractLinearModelTest', + #superclass : 'TestCase', #instVars : [ 'model' ], - #category : #'AI-LinearModels-Tests' + #category : 'AI-LinearModels-Tests', + #package : 'AI-LinearModels-Tests' } -{ #category : #testing } +{ #category : 'testing' } AIAbstractLinearModelTest class >> isAbstract [ ^self == AIAbstractLinearModelTest ] -{ #category : #running } +{ #category : 'running' } AIAbstractLinearModelTest >> regression [ ^ self subclassResponsibility ] -{ #category : #running } +{ #category : 'running' } AIAbstractLinearModelTest >> setUp [ super setUp. model := self regression ] -{ #category : #tests } +{ #category : 'tests' } AIAbstractLinearModelTest >> testDivergingException [ ^ self subclassResponsibility ] -{ #category : #tests } +{ #category : 'tests' } AIAbstractLinearModelTest >> testExactFitSingleVariable [ ^ self subclassResponsibility ] -{ #category : #tests } +{ #category : 'tests' } AIAbstractLinearModelTest >> testInconsistentFitOnDimension [ | input output | @@ -45,7 +46,7 @@ AIAbstractLinearModelTest >> testInconsistentFitOnDimension [ self should: [ model fitX: input y: output ] raise: Error ] -{ #category : #tests } +{ #category : 'tests' } AIAbstractLinearModelTest >> testInitializeWeightsToZeroOfSize [ | expectedInitWeigths | @@ -55,13 +56,13 @@ AIAbstractLinearModelTest >> testInitializeWeightsToZeroOfSize [ self assert: model weights equals: expectedInitWeigths ] -{ #category : #tests } +{ #category : 'tests' } AIAbstractLinearModelTest >> testPerformedIterationsIsInitialized [ self assert: model performedIterations equals: nil ] -{ #category : #tests } +{ #category : 'tests' } AIAbstractLinearModelTest >> testPredictionWithNonFittedModel [ | input output | @@ -70,7 +71,7 @@ AIAbstractLinearModelTest >> testPredictionWithNonFittedModel [ self should: [ output := model predict: input ] raise: Error ] -{ #category : #tests } +{ #category : 'tests' } AIAbstractLinearModelTest >> testWeightedSumOf [ model bias: 2. diff --git a/src/AI-LinearModels-Tests/AILinearRegressionFixture.class.st b/src/AI-LinearModels-Tests/AILinearRegressionFixture.class.st index 0ff7906..02d78c5 100644 --- a/src/AI-LinearModels-Tests/AILinearRegressionFixture.class.st +++ b/src/AI-LinearModels-Tests/AILinearRegressionFixture.class.st @@ -3,24 +3,25 @@ I am a fixture with a small and simple example for linear regression. I provide input matrix X and expected output vector y. " Class { - #name : #AILinearRegressionFixture, - #superclass : #Object, + #name : 'AILinearRegressionFixture', + #superclass : 'Object', #instVars : [ 'bias', 'inputMatrix', 'outputVector', 'weights' ], - #category : #'AI-LinearModels-Tests' + #category : 'AI-LinearModels-Tests', + #package : 'AI-LinearModels-Tests' } -{ #category : #accessing } +{ #category : 'accessing' } AILinearRegressionFixture >> bias [ ^ bias ] -{ #category : #initialization } +{ #category : 'initialization' } AILinearRegressionFixture >> initialize [ | function | @@ -36,19 +37,19 @@ AILinearRegressionFixture >> initialize [ ] -{ #category : #accessing } +{ #category : 'accessing' } AILinearRegressionFixture >> inputMatrix [ ^ inputMatrix ] -{ #category : #accessing } +{ #category : 'accessing' } AILinearRegressionFixture >> outputVector [ ^ outputVector ] -{ #category : #accessing } +{ #category : 'accessing' } AILinearRegressionFixture >> weights [ ^ weights diff --git a/src/AI-LinearModels-Tests/AILinearRegressionLeastSquaresTest.class.st b/src/AI-LinearModels-Tests/AILinearRegressionLeastSquaresTest.class.st index 3920608..b041521 100644 --- a/src/AI-LinearModels-Tests/AILinearRegressionLeastSquaresTest.class.st +++ b/src/AI-LinearModels-Tests/AILinearRegressionLeastSquaresTest.class.st @@ -1,40 +1,41 @@ Class { - #name : #AILinearRegressionLeastSquaresTest, - #superclass : #AILinearRegressionTest, - #category : #'AI-LinearModels-Tests' + #name : 'AILinearRegressionLeastSquaresTest', + #superclass : 'AILinearRegressionTest', + #category : 'AI-LinearModels-Tests', + #package : 'AI-LinearModels-Tests' } -{ #category : #running } +{ #category : 'running' } AILinearRegressionLeastSquaresTest >> regression [ ^ AILinearRegressionLeastSquares new ] -{ #category : #tests } +{ #category : 'tests' } AILinearRegressionLeastSquaresTest >> testInitializeWeightsToZeroOfSize [ self skip ] -{ #category : #tests } +{ #category : 'tests' } AILinearRegressionLeastSquaresTest >> testLearningRateIsInitialized [ self skip ] -{ #category : #tests } +{ #category : 'tests' } AILinearRegressionLeastSquaresTest >> testMaxIterationsIsInitialized [ self skip ] -{ #category : #tests } +{ #category : 'tests' } AILinearRegressionLeastSquaresTest >> testPerformedIterationsIsInitialized [ self skip ] -{ #category : #tests } +{ #category : 'tests' } AILinearRegressionLeastSquaresTest >> testWeightDerivativeforXCostDerivative [ self skip diff --git a/src/AI-LinearModels-Tests/AILinearRegressionLeastSquaresVanillaTest.class.st b/src/AI-LinearModels-Tests/AILinearRegressionLeastSquaresVanillaTest.class.st index 866defd..e959d11 100644 --- a/src/AI-LinearModels-Tests/AILinearRegressionLeastSquaresVanillaTest.class.st +++ b/src/AI-LinearModels-Tests/AILinearRegressionLeastSquaresVanillaTest.class.st @@ -1,28 +1,29 @@ Class { - #name : #AILinearRegressionLeastSquaresVanillaTest, - #superclass : #AILinearRegressionLeastSquaresTest, - #category : #'AI-LinearModels-Tests' + #name : 'AILinearRegressionLeastSquaresVanillaTest', + #superclass : 'AILinearRegressionLeastSquaresTest', + #category : 'AI-LinearModels-Tests', + #package : 'AI-LinearModels-Tests' } -{ #category : #running } +{ #category : 'running' } AILinearRegressionLeastSquaresVanillaTest >> regression [ ^ AILinearRegressionLeastSquaresVanilla new ] -{ #category : #tests } +{ #category : 'tests' } AILinearRegressionLeastSquaresVanillaTest >> testBiasDerivative [ self skip ] -{ #category : #tests } +{ #category : 'tests' } AILinearRegressionLeastSquaresVanillaTest >> testCostDerivativeActual [ self skip ] -{ #category : #tests } +{ #category : 'tests' } AILinearRegressionLeastSquaresVanillaTest >> testWeightedSumOf [ self skip diff --git a/src/AI-LinearModels-Tests/AILinearRegressionTest.class.st b/src/AI-LinearModels-Tests/AILinearRegressionTest.class.st index 3771188..928941c 100644 --- a/src/AI-LinearModels-Tests/AILinearRegressionTest.class.st +++ b/src/AI-LinearModels-Tests/AILinearRegressionTest.class.st @@ -1,13 +1,14 @@ Class { - #name : #AILinearRegressionTest, - #superclass : #AIAbstractLinearModelTest, + #name : 'AILinearRegressionTest', + #superclass : 'AIAbstractLinearModelTest', #instVars : [ 'fixture' ], - #category : #'AI-LinearModels-Tests' + #category : 'AI-LinearModels-Tests', + #package : 'AI-LinearModels-Tests' } -{ #category : #running } +{ #category : 'running' } AILinearRegressionTest >> regression [ ^ AILinearRegression new @@ -16,7 +17,7 @@ AILinearRegressionTest >> regression [ yourself ] -{ #category : #running } +{ #category : 'running' } AILinearRegressionTest >> setUp [ super setUp. @@ -25,7 +26,7 @@ AILinearRegressionTest >> setUp [ ] -{ #category : #tests } +{ #category : 'tests' } AILinearRegressionTest >> testBiasAlmostEqual [ model @@ -35,7 +36,7 @@ AILinearRegressionTest >> testBiasAlmostEqual [ self assert: model bias closeTo: fixture bias precision: 0.001 ] -{ #category : #tests } +{ #category : 'tests' } AILinearRegressionTest >> testBiasDerivative [ self @@ -43,7 +44,7 @@ AILinearRegressionTest >> testBiasDerivative [ equals: 4.5 ] -{ #category : #tests } +{ #category : 'tests' } AILinearRegressionTest >> testCostDerivativeActual [ self @@ -55,7 +56,7 @@ AILinearRegressionTest >> testCostDerivativeActual [ equals: #(1 2 3) ] -{ #category : #tests } +{ #category : 'tests' } AILinearRegressionTest >> testDivergingException [ "Training the model with non-sense, completely unproportioned data and with a very high learning rate to raise the diverging exception." @@ -71,7 +72,7 @@ AILinearRegressionTest >> testDivergingException [ self should: [model fitX: input y: output] raise: ModelStartingToDivergeException ] -{ #category : #tests } +{ #category : 'tests' } AILinearRegressionTest >> testExactFitSingleVariable [ | newInput expectedOutput actualOutput | @@ -83,7 +84,7 @@ AILinearRegressionTest >> testExactFitSingleVariable [ actualOutput with: expectedOutput do: [ :actual :expected | self assert: actual closeTo: expected precision: 0.001 ] ] -{ #category : #tests } +{ #category : 'tests' } AILinearRegressionTest >> testWeightDerivativeforXCostDerivative [ self @@ -91,7 +92,7 @@ AILinearRegressionTest >> testWeightDerivativeforXCostDerivative [ equals: #( 37.5 45 52.5 ) ] -{ #category : #tests } +{ #category : 'tests' } AILinearRegressionTest >> testWeightsAlmostEqual [ model diff --git a/src/AI-LinearModels-Tests/AILinearRegressionTrivialFixture.class.st b/src/AI-LinearModels-Tests/AILinearRegressionTrivialFixture.class.st index c2d476c..433dd3d 100644 --- a/src/AI-LinearModels-Tests/AILinearRegressionTrivialFixture.class.st +++ b/src/AI-LinearModels-Tests/AILinearRegressionTrivialFixture.class.st @@ -2,8 +2,8 @@ This is a simple and trivial fixture that we did to compute things manually " Class { - #name : #AILinearRegressionTrivialFixture, - #superclass : #Object, + #name : 'AILinearRegressionTrivialFixture', + #superclass : 'Object', #instVars : [ 'initialBias', 'initialWeights', @@ -17,58 +17,59 @@ Class { 'expectedBiasAtFirstIteration', 'expectedPredictionBeforeLearning' ], - #category : #'AI-LinearModels-Tests' + #category : 'AI-LinearModels-Tests', + #package : 'AI-LinearModels-Tests' } -{ #category : #accessing } +{ #category : 'accessing' } AILinearRegressionTrivialFixture >> expectedBiasAtFirstIteration [ ^ expectedBiasAtFirstIteration ] -{ #category : #accessing } +{ #category : 'accessing' } AILinearRegressionTrivialFixture >> expectedBiasDerivativeAtFirstIteration [ ^ expectedBiasDerivativeAtFirstIteration ] -{ #category : #accessing } +{ #category : 'accessing' } AILinearRegressionTrivialFixture >> expectedCostBeforeLearning [ ^ expectedCostBeforeLearning ] -{ #category : #accessing } +{ #category : 'accessing' } AILinearRegressionTrivialFixture >> expectedPredictionBeforeLearning [ ^ expectedPredictionBeforeLearning ] -{ #category : #accessing } +{ #category : 'accessing' } AILinearRegressionTrivialFixture >> expectedWeightDerivativeAtFirstIterarion [ ^ expectedWeightDerivativeAtFirstIterarion ] -{ #category : #accessing } +{ #category : 'accessing' } AILinearRegressionTrivialFixture >> expectedWeightsAtFirstIteration [ ^ expectedWeightsAtFirstIteration ] -{ #category : #accessing } +{ #category : 'accessing' } AILinearRegressionTrivialFixture >> initialBias [ ^ initialBias ] -{ #category : #accessing } +{ #category : 'accessing' } AILinearRegressionTrivialFixture >> initialWeights [ ^ initialWeights ] -{ #category : #initialization } +{ #category : 'initialization' } AILinearRegressionTrivialFixture >> initialize [ super initialize. @@ -80,26 +81,26 @@ AILinearRegressionTrivialFixture >> initialize [ learningRate := 0.1. expectedPredictionBeforeLearning := #(0 0 0). - expectedCostBeforeLearning := 1 / 3. + expectedCostBeforeLearning := 2 / 3. expectedWeightDerivativeAtFirstIterarion := { -2. (-8 / 3) }. expectedBiasDerivativeAtFirstIteration := -2 / 3. expectedWeightsAtFirstIteration := { 0.2. (4 / 15) }. expectedBiasAtFirstIteration := 1/15 ] -{ #category : #accessing } +{ #category : 'accessing' } AILinearRegressionTrivialFixture >> inputMatrix [ ^ inputMatrix ] -{ #category : #accessing } +{ #category : 'accessing' } AILinearRegressionTrivialFixture >> learningRate [ ^ learningRate ] -{ #category : #accessing } +{ #category : 'accessing' } AILinearRegressionTrivialFixture >> outputVector [ ^ outputVector diff --git a/src/AI-LinearModels-Tests/AILinearRegressionTrivialTest.class.st b/src/AI-LinearModels-Tests/AILinearRegressionTrivialTest.class.st index 459c095..4215c37 100644 --- a/src/AI-LinearModels-Tests/AILinearRegressionTrivialTest.class.st +++ b/src/AI-LinearModels-Tests/AILinearRegressionTrivialTest.class.st @@ -1,14 +1,15 @@ Class { - #name : #AILinearRegressionTrivialTest, - #superclass : #TestCase, + #name : 'AILinearRegressionTrivialTest', + #superclass : 'TestCase', #instVars : [ 'model', 'fixture' ], - #category : #'AI-LinearModels-Tests' + #category : 'AI-LinearModels-Tests', + #package : 'AI-LinearModels-Tests' } -{ #category : #running } +{ #category : 'running' } AILinearRegressionTrivialTest >> setUp [ super setUp. @@ -21,7 +22,7 @@ AILinearRegressionTrivialTest >> setUp [ learningRate: fixture learningRate ] -{ #category : #tests } +{ #category : 'tests' } AILinearRegressionTrivialTest >> testCostBeforeLearning [ | cost | @@ -29,7 +30,7 @@ AILinearRegressionTrivialTest >> testCostBeforeLearning [ self assert: cost equals: fixture expectedCostBeforeLearning ] -{ #category : #tests } +{ #category : 'tests' } AILinearRegressionTrivialTest >> testExpectedBiasAtFirstIteration [ model updateWeightsForX: fixture inputMatrix y: fixture outputVector. @@ -37,7 +38,7 @@ AILinearRegressionTrivialTest >> testExpectedBiasAtFirstIteration [ self assert: model bias closeTo: fixture expectedBiasAtFirstIteration ] -{ #category : #tests } +{ #category : 'tests' } AILinearRegressionTrivialTest >> testExpectedBiasDerivativeAtFirstIteration [ | predictedOutputVector costDerivative biasDerivative | @@ -49,7 +50,7 @@ AILinearRegressionTrivialTest >> testExpectedBiasDerivativeAtFirstIteration [ self assert: biasDerivative equals: fixture expectedBiasDerivativeAtFirstIteration ] -{ #category : #tests } +{ #category : 'tests' } AILinearRegressionTrivialTest >> testExpectedWeightDerivateAtFirstIteration [ | predictedOutputVector costDerivative weightDerivative | @@ -60,7 +61,7 @@ AILinearRegressionTrivialTest >> testExpectedWeightDerivateAtFirstIteration [ self assert: weightDerivative equals: fixture expectedWeightDerivativeAtFirstIterarion ] -{ #category : #tests } +{ #category : 'tests' } AILinearRegressionTrivialTest >> testExpectedWeightsAtFirstIteration [ model updateWeightsForX: fixture inputMatrix y: fixture outputVector. @@ -70,7 +71,7 @@ AILinearRegressionTrivialTest >> testExpectedWeightsAtFirstIteration [ do: [ :real : expected | self assert: real closeTo: expected ] ] -{ #category : #tests } +{ #category : 'tests' } AILinearRegressionTrivialTest >> testPredictionBeforeLearning [ | prediction | diff --git a/src/AI-LinearModels-Tests/AILogisticRegressionTest.class.st b/src/AI-LinearModels-Tests/AILogisticRegressionTest.class.st index adc37ec..18c5356 100644 --- a/src/AI-LinearModels-Tests/AILogisticRegressionTest.class.st +++ b/src/AI-LinearModels-Tests/AILogisticRegressionTest.class.st @@ -2,24 +2,25 @@ An AILogisticRegressionTest is a test class for testing the behavior of AILogisticRegression " Class { - #name : #AILogisticRegressionTest, - #superclass : #AIAbstractLinearModelTest, - #category : #'AI-LinearModels-Tests' + #name : 'AILogisticRegressionTest', + #superclass : 'AIAbstractLinearModelTest', + #category : 'AI-LinearModels-Tests', + #package : 'AI-LinearModels-Tests' } -{ #category : #defaults } +{ #category : 'defaults' } AILogisticRegressionTest >> generateRandomNumber: random between: lowerBound and: higherBound [ ^ lowerBound + (random next * (higherBound - lowerBound)) ] -{ #category : #running } +{ #category : 'running' } AILogisticRegressionTest >> regression [ ^AILogisticRegression new ] -{ #category : #tests } +{ #category : 'tests' } AILogisticRegressionTest >> testDivergingException [ "Training the model with non-sense, completely unproportioned data and with a very high learning rate to raise the diverging exception." @@ -38,7 +39,7 @@ AILogisticRegressionTest >> testDivergingException [ self should: [model fitX: input y: output] raise: ModelStartingToDivergeException ] -{ #category : #tests } +{ #category : 'tests' } AILogisticRegressionTest >> testExactFitSingleVariable [ | output newInput expectedOutput actualOutput inputPositive inputNegative input | @@ -72,7 +73,7 @@ AILogisticRegressionTest >> testExactFitSingleVariable [ do: [ :actual :expected | self assert: actual equals: expected ] ] -{ #category : #tests } +{ #category : 'tests' } AILogisticRegressionTest >> testPredictProbabilities [ | output newInput expectedOutput actualOutput inputPositive inputNegative input actualOutputPositive actualOutputNegative | diff --git a/src/AI-LinearModels-Tests/package.st b/src/AI-LinearModels-Tests/package.st index bc1b2bb..f5b9397 100644 --- a/src/AI-LinearModels-Tests/package.st +++ b/src/AI-LinearModels-Tests/package.st @@ -1 +1 @@ -Package { #name : #'AI-LinearModels-Tests' } +Package { #name : 'AI-LinearModels-Tests' } diff --git a/src/AI-LinearModels/AIAbstractLinearModel.class.st b/src/AI-LinearModels/AIAbstractLinearModel.class.st index 97e028a..8f34730 100644 --- a/src/AI-LinearModels/AIAbstractLinearModel.class.st +++ b/src/AI-LinearModels/AIAbstractLinearModel.class.st @@ -6,8 +6,8 @@ y = W*X + b where both W and X are vectors that can have any size (multidimensional lines). " Class { - #name : #AIAbstractLinearModel, - #superclass : #Object, + #name : 'AIAbstractLinearModel', + #superclass : 'Object', #instVars : [ 'bias', 'maxIterations', @@ -16,28 +16,30 @@ Class { 'costHistory', 'performedIterations' ], - #category : #'AI-LinearModels-Core' + #category : 'AI-LinearModels-Core', + #package : 'AI-LinearModels', + #tag : 'Core' } -{ #category : #accessing } +{ #category : 'accessing' } AIAbstractLinearModel class >> defaultLearningRate [ ^ 0.01 ] -{ #category : #accessing } +{ #category : 'accessing' } AIAbstractLinearModel class >> defaultMaxIterations [ ^ 5000 ] -{ #category : #'instance creation' } +{ #category : 'instance creation' } AIAbstractLinearModel class >> learningRate: aNumber [ ^ self new learningRate: aNumber ] -{ #category : #'instance creation' } +{ #category : 'instance creation' } AIAbstractLinearModel class >> learningRate: aNumber maxIterations: maxIterations [ ^ self new @@ -45,41 +47,41 @@ AIAbstractLinearModel class >> learningRate: aNumber maxIterations: maxIteration maxIterations: maxIterations ] -{ #category : #accessing } +{ #category : 'accessing' } AIAbstractLinearModel >> bias [ ^ bias ] -{ #category : #accessing } +{ #category : 'accessing' } AIAbstractLinearModel >> bias: anInteger [ bias := anInteger ] -{ #category : #running } +{ #category : 'running' } AIAbstractLinearModel >> biasDerivative: arg1 [ ^ self subclassResponsibility ] -{ #category : #running } +{ #category : 'running' } AIAbstractLinearModel >> costDerivative: inputMatrix actual: actualValues [ ^ self subclassResponsibility ] -{ #category : #running } +{ #category : 'running' } AIAbstractLinearModel >> costFunctionX: inputMatrix y: actualValues [ ^ self subclassResponsibility ] -{ #category : #accessing } +{ #category : 'accessing' } AIAbstractLinearModel >> costHistory [ ^ costHistory ] -{ #category : #api } +{ #category : 'api' } AIAbstractLinearModel >> fitX: inputMatrix y: actualValues [ @@ -97,7 +99,7 @@ AIAbstractLinearModel >> fitX: inputMatrix y: actualValues [ ] -{ #category : #testing } +{ #category : 'testing' } AIAbstractLinearModel >> hasConverged [ | precision difference | @@ -115,12 +117,12 @@ AIAbstractLinearModel >> hasConverged [ difference closeTo: 0 precision: precision ] ] -{ #category : #running } +{ #category : 'running' } AIAbstractLinearModel >> hypothesisFunction: inputMatrix [ ^ self subclassResponsibility ] -{ #category : #initialization } +{ #category : 'initialization' } AIAbstractLinearModel >> initialize [ super initialize. @@ -128,7 +130,7 @@ AIAbstractLinearModel >> initialize [ maxIterations := self class defaultMaxIterations ] -{ #category : #initialization } +{ #category : 'initialization' } AIAbstractLinearModel >> initializeRandomWeightsOfSize: aNumber [ | rand | @@ -138,56 +140,56 @@ AIAbstractLinearModel >> initializeRandomWeightsOfSize: aNumber [ weights := (1 to: aNumber) collect: [ :i | rand next ]. ] -{ #category : #initialization } +{ #category : 'initialization' } AIAbstractLinearModel >> initializeWeightsOfSize: aNumber [ self initializeRandomWeightsOfSize: aNumber ] -{ #category : #initialization } +{ #category : 'initialization' } AIAbstractLinearModel >> initializeWeightsToZeroOfSize: aNumber [ bias := 0. weights := (1 to: aNumber) collect: [ :each | 0 ] ] -{ #category : #accessing } +{ #category : 'accessing' } AIAbstractLinearModel >> learningRate [ ^ learningRate ] -{ #category : #accessing } +{ #category : 'accessing' } AIAbstractLinearModel >> learningRate: anObject [ learningRate := anObject ] -{ #category : #accessing } +{ #category : 'accessing' } AIAbstractLinearModel >> maxIterations [ ^ maxIterations ] -{ #category : #accessing } +{ #category : 'accessing' } AIAbstractLinearModel >> maxIterations: anObject [ maxIterations := anObject ] -{ #category : #accessing } +{ #category : 'accessing' } AIAbstractLinearModel >> performedIterations [ ^ performedIterations ] -{ #category : #api } +{ #category : 'api' } AIAbstractLinearModel >> predict: inputMatrix [ ^ self subclassResponsibility ] -{ #category : #running } +{ #category : 'running' } AIAbstractLinearModel >> updateWeightsForX: inputMatrix y: actualValues [ | weightDerivative biasDerivative predictedOutputVector costDerivative | @@ -203,12 +205,12 @@ AIAbstractLinearModel >> updateWeightsForX: inputMatrix y: actualValues [ bias := bias - (learningRate * biasDerivative) ] -{ #category : #running } +{ #category : 'running' } AIAbstractLinearModel >> weightDerivativeforX: arg1 costDerivative: arg2 [ ^ self subclassResponsibility ] -{ #category : #running } +{ #category : 'running' } AIAbstractLinearModel >> weightedSumOf: inputMatrix [ "z = Xw + b" @@ -221,13 +223,13 @@ AIAbstractLinearModel >> weightedSumOf: inputMatrix [ (row * weights) sum + bias ] ] -{ #category : #accessing } +{ #category : 'accessing' } AIAbstractLinearModel >> weights [ ^ weights ] -{ #category : #accessing } +{ #category : 'accessing' } AIAbstractLinearModel >> weights: aCollection [ weights := aCollection ] diff --git a/src/AI-LinearModels/AILinearRegression.class.st b/src/AI-LinearModels/AILinearRegression.class.st index df2a891..0b8c512 100644 --- a/src/AI-LinearModels/AILinearRegression.class.st +++ b/src/AI-LinearModels/AILinearRegression.class.st @@ -39,12 +39,14 @@ output := #(-10.6 10.5 -13.6 27.7 -24.1 12.3 -2.6 -0.2 12.2 -22.1 -10.5 -24.3 2. ``` " Class { - #name : #AILinearRegression, - #superclass : #AIAbstractLinearModel, - #category : #'AI-LinearModels-Linear regression' + #name : 'AILinearRegression', + #superclass : 'AIAbstractLinearModel', + #category : 'AI-LinearModels-Linear regression', + #package : 'AI-LinearModels', + #tag : 'Linear regression' } -{ #category : #running } +{ #category : 'running' } AILinearRegression >> biasDerivative: costDerivative [ @@ -60,7 +62,7 @@ AILinearRegression >> biasDerivative: costDerivative [ ^ costDerivative average ] -{ #category : #running } +{ #category : 'running' } AILinearRegression >> costDerivative: predictedOutputVector actual: targetOutputVector [ "We are using the mean squared error function to minimize the errors." @@ -82,7 +84,7 @@ AILinearRegression >> costDerivative: predictedOutputVector actual: targetOutput ^ (predictedOutputVector - targetOutputVector) ] -{ #category : #running } +{ #category : 'running' } AILinearRegression >> costFunctionX: inputMatrix y: actualValues [ "The cost function for the linear regression is the mean squared error function" @@ -93,10 +95,10 @@ AILinearRegression >> costFunctionX: inputMatrix y: actualValues [ predictedValues := self hypothesisFunction: inputMatrix. squaredSum := (actualValues - predictedValues) collect: [ :each | each ** 2 ]. - ^ squaredSum average / 2 + ^ squaredSum average ] -{ #category : #running } +{ #category : 'running' } AILinearRegression >> hypothesisFunction: inputMatrix [ "The hypothesis function for the linear regression is the line equation. It can be a multidimensional line." @@ -106,13 +108,13 @@ AILinearRegression >> hypothesisFunction: inputMatrix [ ^ self weightedSumOf: inputMatrix ] -{ #category : #api } +{ #category : 'api' } AILinearRegression >> predict: inputMatrix [ ^ self hypothesisFunction: inputMatrix ] -{ #category : #running } +{ #category : 'running' } AILinearRegression >> weightDerivativeforX: inputMatrix costDerivative: costDerivativeVector [ "J(w) = (1/n) * Σ (yi - h(z))^2" diff --git a/src/AI-LinearModels/AILinearRegressionLeastSquares.class.st b/src/AI-LinearModels/AILinearRegressionLeastSquares.class.st index 08f08e8..6a6d6f8 100644 --- a/src/AI-LinearModels/AILinearRegressionLeastSquares.class.st +++ b/src/AI-LinearModels/AILinearRegressionLeastSquares.class.st @@ -2,22 +2,24 @@ Linear regression implementation solving the least squares problem using Pharo-LAPACK " Class { - #name : #AILinearRegressionLeastSquares, - #superclass : #Object, + #name : 'AILinearRegressionLeastSquares', + #superclass : 'Object', #instVars : [ 'weights', 'bias' ], - #category : #'AI-LinearModels-Linear regression' + #category : 'AI-LinearModels-Linear regression', + #package : 'AI-LinearModels', + #tag : 'Linear regression' } -{ #category : #accessing } +{ #category : 'accessing' } AILinearRegressionLeastSquares >> bias [ ^ bias ] -{ #category : #api } +{ #category : 'api' } AILinearRegressionLeastSquares >> fitX: inputColumnMajorMatrix y: outputVector [ | xOffset yOffset centeredOutputVector | @@ -34,7 +36,7 @@ AILinearRegressionLeastSquares >> fitX: inputColumnMajorMatrix y: outputVector [ bias := yOffset - (xOffset * weights) sum ] -{ #category : #running } +{ #category : 'running' } AILinearRegressionLeastSquares >> hypothesisFunction: inputMatrix [ "The hypothesis function for the linear regression is the line equation. It can be a multidimensional line." @@ -44,13 +46,13 @@ AILinearRegressionLeastSquares >> hypothesisFunction: inputMatrix [ ^ self weightedSumOf: inputMatrix ] -{ #category : #api } +{ #category : 'api' } AILinearRegressionLeastSquares >> predict: inputMatrix [ ^ self hypothesisFunction: inputMatrix ] -{ #category : #training } +{ #category : 'training' } AILinearRegressionLeastSquares >> solveLeastSquaresInputMatrix: aMatrix outputVector: aVector [ | leastSquares rowSize | @@ -65,7 +67,7 @@ AILinearRegressionLeastSquares >> solveLeastSquaresInputMatrix: aMatrix outputVe ^ (1 to: rowSize) collect: [ :i | leastSquares solution contents at: i ] ] -{ #category : #running } +{ #category : 'running' } AILinearRegressionLeastSquares >> weightedSumOf: inputMatrix [ "z = Xw + b" @@ -76,17 +78,17 @@ AILinearRegressionLeastSquares >> weightedSumOf: inputMatrix [ Then we return a vector of the same size of the original inputMatrix." | weightedSum | - weightedSum := Array new: inputMatrix size. + weightedSum := OrderedCollection new: inputMatrix size. 1 to: inputMatrix size do: [ :index | | sum row | row := (inputMatrix at: index). sum := (row * weights) sum + bias. - weightedSum at: index add: sum ]. + weightedSum add: sum ]. ^ weightedSum ] -{ #category : #accessing } +{ #category : 'accessing' } AILinearRegressionLeastSquares >> weights [ ^ weights diff --git a/src/AI-LinearModels/AILinearRegressionLeastSquaresVanilla.class.st b/src/AI-LinearModels/AILinearRegressionLeastSquaresVanilla.class.st index 328b649..90bcd18 100644 --- a/src/AI-LinearModels/AILinearRegressionLeastSquaresVanilla.class.st +++ b/src/AI-LinearModels/AILinearRegressionLeastSquaresVanilla.class.st @@ -2,12 +2,31 @@ Linear Regression using least squares algorithm from PolyMath, that is Pure written in pure Pharo " Class { - #name : #AILinearRegressionLeastSquaresVanilla, - #superclass : #AILinearRegressionLeastSquares, - #category : #'AI-LinearModels-Linear regression' + #name : 'AILinearRegressionLeastSquaresVanilla', + #superclass : 'AILinearRegressionLeastSquares', + #category : 'AI-LinearModels-Linear regression', + #package : 'AI-LinearModels', + #tag : 'Linear regression' } -{ #category : #training } +{ #category : 'api' } +AILinearRegressionLeastSquaresVanilla >> fitX: inputMatrix y: outputVector [ + + | xOffset yOffset centeredInputMatrix centeredOutputVector | + "yOffset := outputVector columnAverage first." + yOffset := outputVector average. + xOffset := inputMatrix average. + centeredInputMatrix := inputMatrix collect: [ :col | col - xOffset]. + centeredOutputVector := outputVector - yOffset. + + weights := self + solveLeastSquaresInputMatrix: centeredInputMatrix + outputVector: centeredOutputVector. + + bias := yOffset - (xOffset * weights) sum +] + +{ #category : 'training' } AILinearRegressionLeastSquaresVanilla >> solveLeastSquaresInputMatrix: aMatrix outputVector: aVector [ | leastSquares | diff --git a/src/AI-LinearModels/AILogisticRegression.class.st b/src/AI-LinearModels/AILogisticRegression.class.st index 0b49113..9b5d5a3 100644 --- a/src/AI-LinearModels/AILogisticRegression.class.st +++ b/src/AI-LinearModels/AILogisticRegression.class.st @@ -15,12 +15,14 @@ So, we need to minimize the error of the cost function. To do that, we derive th See more information in the comments of the methods. " Class { - #name : #AILogisticRegression, - #superclass : #AIAbstractLinearModel, - #category : #'AI-LinearModels-Logistic regression' + #name : 'AILogisticRegression', + #superclass : 'AIAbstractLinearModel', + #category : 'AI-LinearModels-Logistic regression', + #package : 'AI-LinearModels', + #tag : 'Logistic regression' } -{ #category : #running } +{ #category : 'running' } AILogisticRegression >> biasDerivative: costDerivativeVector [ "J(w) = cost function" @@ -33,7 +35,7 @@ AILogisticRegression >> biasDerivative: costDerivativeVector [ ^ costDerivativeVector average ] -{ #category : #running } +{ #category : 'running' } AILogisticRegression >> costDerivative: predictedOutputVector actual: targetOutputVector [ "h(z) = sigmoid function (see method comment)" @@ -50,7 +52,7 @@ AILogisticRegression >> costDerivative: predictedOutputVector actual: targetOutp ^ predictedOutputVector - targetOutputVector ] -{ #category : #running } +{ #category : 'running' } AILogisticRegression >> costFunctionX: inputMatrix y: actualValues [ "The cost function for the logistic regression is defined as: @@ -77,7 +79,7 @@ AILogisticRegression >> costFunctionX: inputMatrix y: actualValues [ ^ sum average ] -{ #category : #running } +{ #category : 'running' } AILogisticRegression >> hypothesisFunction: inputMatrix [ "The hypothesis function for logistic regression is the logistic function @@ -95,7 +97,7 @@ AILogisticRegression >> hypothesisFunction: inputMatrix [ ^ weightedSumVector collect: [ :z | sigmoidFunction value: z ] ] -{ #category : #api } +{ #category : 'api' } AILogisticRegression >> predict: inputMatrix [ | predictions | @@ -107,13 +109,13 @@ AILogisticRegression >> predict: inputMatrix [ ifFalse: [ 0 ] ] ] -{ #category : #api } +{ #category : 'api' } AILogisticRegression >> predictProbabilities: inputMatrix [ ^ self hypothesisFunction: inputMatrix ] -{ #category : #running } +{ #category : 'running' } AILogisticRegression >> weightDerivativeforX: inputMatrix costDerivative: costDerivativeVector [ "J(w) = cost function" diff --git a/src/AI-LinearModels/ManifestAILinearModels.class.st b/src/AI-LinearModels/ManifestAILinearModels.class.st index 02a4916..64756b3 100644 --- a/src/AI-LinearModels/ManifestAILinearModels.class.st +++ b/src/AI-LinearModels/ManifestAILinearModels.class.st @@ -2,17 +2,19 @@ Please describe the package using the class comment of the included manifest class. The manifest class also includes other additional metadata for the package. These meta data are used by other tools such as the SmalllintManifestChecker and the critics Browser " Class { - #name : #ManifestAILinearModels, - #superclass : #PackageManifest, - #category : #'AI-LinearModels-Manifest' + #name : 'ManifestAILinearModels', + #superclass : 'PackageManifest', + #category : 'AI-LinearModels-Manifest', + #package : 'AI-LinearModels', + #tag : 'Manifest' } -{ #category : #'code-critics' } +{ #category : 'code-critics' } ManifestAILinearModels class >> ruleToDoCollectRuleV1FalsePositive [ ^ #(#(#(#RGPackageDefinition #(#'AI-LinearModels')) #'2022-04-28T22:32:17.818221+02:00') ) ] -{ #category : #'code-critics' } +{ #category : 'code-critics' } ManifestAILinearModels class >> ruleToDoRuleV1FalsePositive [ ^ #(#(#(#RGPackageDefinition #(#'AI-LinearModels')) #'2022-04-28T22:22:47.162403+02:00') ) ] diff --git a/src/AI-LinearModels/ModelStartingToDivergeException.class.st b/src/AI-LinearModels/ModelStartingToDivergeException.class.st index 7de9485..e3b0219 100644 --- a/src/AI-LinearModels/ModelStartingToDivergeException.class.st +++ b/src/AI-LinearModels/ModelStartingToDivergeException.class.st @@ -2,12 +2,14 @@ I am a custom exception that is signaled when the model is starting to diverge (the weights start to grow up to infinity) " Class { - #name : #ModelStartingToDivergeException, - #superclass : #Exception, - #category : #'AI-LinearModels-Exception' + #name : 'ModelStartingToDivergeException', + #superclass : 'Exception', + #category : 'AI-LinearModels-Exception', + #package : 'AI-LinearModels', + #tag : 'Exception' } -{ #category : #signaling } +{ #category : 'signaling' } ModelStartingToDivergeException >> signal [ self messageText: diff --git a/src/AI-LinearModels/package.st b/src/AI-LinearModels/package.st index 7e9610b..763b106 100644 --- a/src/AI-LinearModels/package.st +++ b/src/AI-LinearModels/package.st @@ -1 +1 @@ -Package { #name : #'AI-LinearModels' } +Package { #name : 'AI-LinearModels' }