diff --git a/src/methods/perceptron/perceptron.pl b/src/methods/perceptron/perceptron.pl index 8b3c4a5f00049abd64c2dd68c1b25a2fcb254c10..b71547e9bad1b18e216e4404cdfd4ff0d2f1b9b3 100644 --- a/src/methods/perceptron/perceptron.pl +++ b/src/methods/perceptron/perceptron.pl @@ -32,6 +32,9 @@ %% Initilizes the perceptron model and its weight matrix but doesnt train it. %% initModelNoTrain(NumClasses, Dimensionality, MaxIterations) :- + NumClasses >= 0, + Dimensionality > 0, + MaxIterations >= 0, initModelNoTrainI(NumClasses, Dimensionality, MaxIterations). foreign(initModelNoTrain, c, initModelNoTrainI(+integer, +integer, +integer)). @@ -48,6 +51,8 @@ foreign(initModelNoTrain, c, initModelNoTrainI(+integer, +integer, +integer)). %% Initilizes the perceptron model and its weight matrix and trains it with the given data. %% initModelWithTrain(DataList, DataRows, LabelsList, NumClasses, MaxIterations) :- + NumClasses >= 0, + MaxIterations >= 0, convert_list_to_float_array(DataList, DataRows, array(Xsize, Xrownum, X)), convert_list_to_float_array(LabelsList, array(Ysize, Y)), initModelWithTrainI(X, Xsize, Xrownum, Y, Ysize, NumClasses, MaxIterations). @@ -100,6 +105,7 @@ foreign(classify, c, classifyI( +pointer(float_array), +integer, +integer, %% Train the perceptron on the given data for up to the maximum number of iterations. This training does not reset the model weights, so you can call train/8 on multiple datasets sequentially. %% train(DataList, DataRows, LabelsList, NumClasses, WeightsList) :- + NumClasses >= 0, convert_list_to_float_array(DataList, DataRows, array(Xsize, Xrownum, X)), convert_list_to_float_array(LabelsList, array(Ysize, Y)), convert_list_to_float_array(WeightsList, array(Zsize, Z)), diff --git a/src/methods/perceptron/perceptron_test.pl b/src/methods/perceptron/perceptron_test.pl index e151fa1c2a221522beed62316e28beafb4aa6693..782c1ad1d9931d075ac5bc3a8131499a179ec224 100644 --- a/src/methods/perceptron/perceptron_test.pl +++ b/src/methods/perceptron/perceptron_test.pl @@ -6,38 +6,212 @@ :- use_module(perceptron). :- use_module('../../helper_files/helper.pl'). -reset_Model :- - initModel(1,0,50,0.0001). +reset_Model_NoTrain :- + initModelNoTrain(2, 3, 1000). + +reset_Model_WithTrain :- + initModelWithTrain([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, [0,1,0,1], 2, 1000). + + + +%% +%% TESTING predicate initModelNoTrain/3 +%% +:- begin_tests(initModelNoTrain). + +%% Failure Tests + +test(perceptron_InitModelNoTrain_Negative_NumClasses, fail) :- + initModelNoTrain(-2, 3, 1000). + +test(perceptron_InitModelNoTrain_Negative_Dimensionality, fail) :- + initModelNoTrain(2, -3, 1000). + +test(perceptron_InitModelNoTrain_Negative_MaxIterations, fail) :- + initModelNoTrain(2, 3, -1000). + + +%% Successful Tests + +test(perceptron_InitModelNoTrain_Normal_Use) :- + initModelNoTrain(2, 3, 1000). + +test(perceptron_InitModelNoTrain_Alternative_Input) :- + initModelNoTrain(0, 0, 1000). + +:- end_tests(initModelNoTrain). + + %% -%% TESTING predicate predicate/10 +%% TESTING predicate initModelWithTrain/5 %% -:- begin_tests(predicate). +:- begin_tests(initModelWithTrain). %% Failure Tests + +test(perceptron_InitModelWithTrain_Negative_NumClasses, fail) :- + initModelWithTrain([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, [0,1,0,1], -2, 1000). + + +test(perceptron_InitModelWithTrain_Negative_MaxIterations, fail) :- + initModelWithTrain([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, [0,1,0,1], 2, -1000). -test(testDescription, [error(domain_error('expectation' , culprit), _)]) :- - reset_Model_No_Train(perceptron), - train([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, [0,0,0,0], 2, culprit, 50, 0.0001, _). -test(testDescription2, [error(_,system_error('The values of the Label have to start at 0 and be >= 0 and < the given numClass!'))]) :- - reset_Model_No_Train(perceptron), - train([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, [0,1,0,2], 2, perceptron, 50, 0.0001, _). +test(random_forest_InitModelWithTrainNoWeights_Too_Short_Label, [error(_,system_error('Error'))]) :- + initModelWithTrain([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, [0,1], 2, 1000). + +test(random_forest_InitModelWithTrainNoWeights_Too_Long_Label, [error(_,system_error('Error'))]) :- + initModelWithTrain([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, [0,1,0,1,0,1], 2, 1000). + +test(random_forest_InitModelWithTrainNoWeights_Too_Many_Label_Classes, [error(_,system_error('Error'))]) :- + initModelWithTrain([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, [0,1,2,3], 2, 1000). %% Successful Tests -test(testDescription3, [true(Error =:= 1)]) :- - reset_Model_No_Train(perceptron), - train([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, [0,0,0,0], 2, perceptron, 50, 0.0001, Error). +test(perceptron_InitModelWithTrain_Normal_Use) :- + initModelWithTrain([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, [0,1,0,1], 2, 1000). -test(testDescription4, [true(Error =:= 0.9797958971132711)]) :- - reset_Model_No_Train(perceptron), +test(perceptron_InitModelWithTrain_CSV_Input) :- open('src/data_csv/iris2.csv', read, File), take_csv_row(File, skipFirstRow,10, Data), - train(Data, 4, [0,1,0,1,1,0,1,1,1,0], 2, perceptron, 50, 0.0001, Error). + initModelWithTrain(Data, 4, [0,1,0,1,1,0,1,1,1,0], 2, 1000). + +:- end_tests(initModelWithTrain). + + + +%% +%% TESTING predicate biases/1 +%% +:- begin_tests(biases). + +%% Failure Tests + +test(perceptron_Biases_Before_Train, [error(_,system_error('Error'))]) :- + reset_Model_NoTrain, + biases(_). + + +%% Successful Tests + +test(perceptron_Biases_AfterTrain) :- + reset_Model_WithTrain, + biases(Biases), + print('\nBiases: '), + print(Biases). + +:- end_tests(biases). + + + +%% +%% TESTING predicate classify/3 +%% +:- begin_tests(classify). + +%% Failure Tests + +test(perceptron_Classify_Before_Train, [error(_,system_error('Error'))]) :- + reset_Model_NoTrain, + classify([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, _). + +test(perceptron_Classify_Before_Train_Wrong_Dims, [error(_,system_error('Error'))]) :- + reset_Model_NoTrain, + classify([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 4, _). + +test(perceptron_Classify_Different_Dims_Than_Train) :- + reset_Model_WithTrain, + classify([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 4, _). + + +%% Successful Tests + +test(perceptron_Classify_Normal_Use) :- + reset_Model_WithTrain, + classify([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, PredictList), + print('\nPredicted Labels: '), + print(PredictList). + +:- end_tests(classify). + + + +%% +%% TESTING predicate train/5 +%% +:- begin_tests(train). + +%% Failure Tests + +test(perceptron_Train_Negaitve_NumClasses, fail) :- + reset_Model_NoTrain, + train([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, [0,1,0,1], -2, [0.1,0.2,0.3,0.4]). + +test(perceptron_Train_Too_Small_Data_Dims, [error(_,system_error('Error'))]) :- + reset_Model_NoTrain, + train([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 4, [0,1,0], 2, [0.1,0.2,0.3]). + + +test(perceptron_Train_Too_Short_Label, [error(_,system_error('Error'))]) :- + reset_Model_NoTrain, + train([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, [0,1], 2, [0.1,0.2,0.3,0.4]). + +test(perceptron_Train_Too_Long_Label, [error(_,system_error('Error'))]) :- + reset_Model_NoTrain, + train([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, [0,1,0,1,0,1], 2, [0.1,0.2,0.3,0.4]). + +test(perceptron_Train_Too_Many_Label_Classes, [error(_,system_error('Error'))]) :- + reset_Model_NoTrain, + train([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, [0,1,2,3], 2, [0.1,0.2,0.3,0.4]). + + +test(perceptron_Train_Too_Short_Label, [error(_,system_error('Error'))]) :- + reset_Model_NoTrain, + train([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, [0,1,0,1], 2, [0.1,0.2]). + +test(perceptron_Train_Too_Long_Label, [error(_,system_error('Error'))]) :- + reset_Model_NoTrain, + train([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, [0,1,0,1], 2, [0.1,0.2,0.3,0.4,0.6,0.7]). + +test(perceptron_Train_Too_Many_Label_Classes, [error(_,system_error('Error'))]) :- + reset_Model_NoTrain, + train([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, [0,1,0,1], 2, [-0.1,0.2,1.3,2.4]). + + +%% Successful Tests + +test(perceptron_Train_Normal_Use) :- + reset_Model_NoTrain, + train([5.1,3.5,1.4,4.9,3.0,1.4,4.7,3.2,1.3,4.6,3.1,1.5], 3, [0,1,0,1], 2, [0.1,0.2,0.3,0.4]). + + +:- end_tests(train). + + + +%% +%% TESTING predicate weights/2 +%% +:- begin_tests(weights). + +%% Failure Tests + +test(perceptron_Weights_Before_Train, [error(_,system_error('Error'))]) :- + reset_Model_NoTrain, + weights(_, _). + + +%% Successful Tests + +test(perceptron_Weights_AfterTrain) :- + reset_Model_WithTrain, + weights(Weights, _), + print('\nWeights: '), + print(Weights). -:- end_tests(predicate). +:- end_tests(weights). run_perceptron_tests :- run_tests.