Skip to content
Snippets Groups Projects
Commit 86423c87 authored by Jakhes's avatar Jakhes
Browse files

Finishing Linear regression implementation

parent 95889c17
No related branches found
No related tags found
No related merge requests found
...@@ -3,6 +3,8 @@ SPLFR_PATH=/usr/local/sicstus4.7.1/bin/splfr ...@@ -3,6 +3,8 @@ SPLFR_PATH=/usr/local/sicstus4.7.1/bin/splfr
all: all:
make -C src/methods/bayesian_linear_regression splfr=$(SPLFR_PATH) make -C src/methods/bayesian_linear_regression splfr=$(SPLFR_PATH)
make -C src/methods/linear_regression splfr=$(SPLFR_PATH)
clean: clean:
make -C src/methods/bayesian_linear_regression clean make -C src/methods/bayesian_linear_regression clean
make -C src/methods/linear_regression clean
...@@ -17,61 +17,116 @@ using namespace mlpack::regression; ...@@ -17,61 +17,116 @@ using namespace mlpack::regression;
// Global Variable of the LinearRegression object so it can be accessed from all functions // Global Variable of the LinearRegression object so it can be accessed from all functions
LinearRegression regressor; LinearRegression regressor;
// input: const bool , const bool , const size_t , const double // input: const arma::mat &data, const arma::rowvec &responses, const double lambda, const bool intercept
// output: double // output:
void initModel(SP_integer centerData, SP_integer scaleData, SP_integer nIterMax, double tol) void initModel(float *matrix, SP_integer matSize, SP_integer matRowNum, float *responses_arr, SP_integer vecSize, SP_integer lambda, SP_integer bool_intercept)
{
if(matSize / matRowNum != vecSize)
{
cout << "Target dim doesnt fit to the Data dim" << endl;
return;
}
// convert the Prolog arrays to arma::rowvec and arma::mat
mat data = convertArrayToMat(matrix, matSize, matRowNum);
rowvec responses = convertArrayToRowvec(responses_arr, vecSize);
regressor = LinearRegression(data, responses, lambda, bool_intercept);
}
// input: const arma::mat &data, const arma::rowvec &responses, const arma::rowvec &weights, const double lambda, const bool intercept
// output:
void initModelWithWeights(float *matrix, SP_integer matSize, SP_integer matRowNum, float *responses_arr, SP_integer vecSize, float *weights_arr, SP_integer weightsSize, SP_integer lambda, SP_integer bool_intercept)
{ {
regressor = new LinearRegression((centerData == 1), (scaleData == 1), nIterMax, tol); if(matSize / matRowNum != vecSize)
{
cout << "Target dim doesnt fit to the Data dim" << endl;
return;
}
// convert the Prolog arrays to arma::rowvec and arma::mat
mat data = convertArrayToMat(matrix, matSize, matRowNum);
rowvec responses = convertArrayToRowvec(responses_arr, vecSize);
rowvec weights = convertArrayToRowvec(weights_arr, weightsSize);
regressor = LinearRegression(data, responses, weights, lambda, bool_intercept);
} }
// input: // input:
// output: double // output:
SP_integer alpha() void initModelEmpty(SP_integer)
{ {
return regressor.Alpha(); regressor = LinearRegression();
}
// input: const arma::mat &points, const arma::rowvec &responses
// output: double L2SquardError
SP_integer computeError(float *points_mat_arr, SP_integer matSize, SP_integer matRowNum, float *responses_arr, SP_integer vecSize)
{
if(matSize / matRowNum != vecSize)
{
cout << "Target dim doesnt fit to the Data dim" << endl;
return 0;
}
// convert the Prolog arrays to arma::rowvec and arma::mat
mat data = convertArrayToMat(points_mat_arr, matSize, matRowNum);
rowvec responses = convertArrayToRowvec(responses_arr, vecSize);
// run the model function
return regressor.ComputeError(data, responses);
} }
// input: // input:
// output: double // output: double
SP_integer beta() SP_integer intercept()
{ {
return regressor.Beta(); if(regressor.Intercept()) {return 1;}
else {return 0;}
} }
// input: // input:
// output: const arma::colvec & // output: double Tikhonov regularization parameter
float * dataOffset(SP_integer *arraySize) SP_integer lambda()
{ {
// save the DataOffset output in colvec return regressor.Lambda();;
colvec armaDataOffset = regressor.DataOffset(); }
*arraySize = armaDataOffset.n_elem;
return convertArmaToArray(armaDataOffset); // input: double new Tikhonov regularization parameter
// output:
void modifyLambda(SP_integer new_lambda)
{
double& lambda_ref = regressor.Lambda();
lambda_ref = new_lambda;
} }
// input: // input:
// output: const arma::colvec & // output: const arma::vec & parameters b vector
float * dataScale(SP_integer *arraySize) float * parameters(SP_integer *arraySize)
{ {
// save the DataScale output in colvec // get b vector
colvec armaDataScale = regressor.DataScale(); colvec armaDataOffset = regressor.Parameters();
*arraySize = armaDataScale.n_elem; cout << regressor.Parameters() << endl;
cout << armaDataOffset << endl;
// set the b vector length
*arraySize = armaDataOffset.n_elem;
return convertArmaToArray(armaDataScale); // convert b vector to array and return
return convertArmaToArray(armaDataOffset);
} }
// input: // input: arma::vec & new b vector
// output: const arma::colvec & // output:
float * omega(SP_integer *arraySize) void modifyParameters(float *paramArr, SP_integer paramSize)
{ {
// save the Omega output in colvec // convert array to arma:: vec
colvec armaOmega = regressor.Omega(); rowvec new_B_Vector = convertArrayToRowvec(paramArr, paramSize);
*arraySize = armaOmega.n_elem; // get parameter b vector ref
vec& bVector = regressor.Parameters();
return convertArmaToArray(armaOmega); // set new b vector
bVector = new_B_Vector;
} }
// input: const arma::mat &points, arma::rowvec &predictions // input: const arma::mat &points, arma::rowvec &predictions
...@@ -92,104 +147,37 @@ void predict(float *pointsArr, SP_integer pointsSize, SP_integer pointsRowNum, f ...@@ -92,104 +147,37 @@ void predict(float *pointsArr, SP_integer pointsSize, SP_integer pointsRowNum, f
*predicArr = convertArmaToArray(predictions); *predicArr = convertArmaToArray(predictions);
} }
// input: const arma::mat &points, arma::rowvec &predictions, arma::rowvec &std // input: const arma::mat &data, const arma::rowvec &responses, const bool intercept
// output: // output:
void predictWithStd(float *pointsArr, SP_integer pointsSize, SP_integer pointsRowNum, float **predicArr, SP_integer *predicSize, float **stdArr, SP_integer *stdSize) SP_integer train(float *matrix, SP_integer matSize, SP_integer matRowNum, float *responses_arr, SP_integer vecSize, SP_integer bool_intercept)
{ {
// convert the Prolog arrays to std::vec for easy conversion to arma::mat if(matSize / matRowNum != vecSize)
mat data = convertArrayToMat(pointsArr, pointsSize, pointsRowNum);
// run the prediction and save the results in arma::rowvecs
rowvec predictions;
rowvec std;
regressor.Predict(data, predictions, std);
// give back the sizes and the converted results as arrays
*predicSize = predictions.n_elem;
*stdSize = std.n_elem;
*predicArr = convertArmaToArray(predictions);
*stdArr = convertArmaToArray(std);
}
// input:
// output: double
SP_integer responsesOffset()
{ {
return regressor.ResponsesOffset(); cout << "Target dim doesnt fit to the Data dim" << endl;
return 0;
} }
// input: const arma::mat &data, const arma::rowvec &responses
// output: double
SP_integer rmse(float *matrix, SP_integer matSize, SP_integer matRowNum, float *arr, SP_integer vecSize)
{
// convert the Prolog arrays to arma::rowvec and arma::mat // convert the Prolog arrays to arma::rowvec and arma::mat
rowvec responses = convertArrayToRowvec(arr, vecSize); rowvec responses = convertArrayToRowvec(responses_arr, vecSize);
mat data = convertArrayToMat(matrix, matSize, matRowNum); mat data = convertArrayToMat(matrix, matSize, matRowNum);
// run the model function and return the error // run the model train function
return regressor.RMSE(data, responses); return regressor.Train(data, responses, (bool_intercept == 1));
} }
// input: const arma::mat &data, const arma::rowvec &responses // input: const arma::mat &data, const arma::rowvec &responses, const arma::rowvec &weights, const bool intercept
// output: // output:
void train(float *matrix, SP_integer matSize, SP_integer matRowNum, float *arr, SP_integer vecSize) SP_integer trainWithWeights(float *matrix, SP_integer matSize, SP_integer matRowNum, float *responses_arr, SP_integer vecSize, float *weights_arr, SP_integer weightsSize, SP_integer bool_intercept)
{ {
if(matSize / matRowNum != vecSize) if(matSize / matRowNum != vecSize)
{ {
cout << "Target dim doesnt fit to the Data dim" << endl; cout << "Target dim doesnt fit to the Data dim" << endl;
return; return 0;
} }
// convert the Prolog arrays to arma::rowvec and arma::mat // convert the Prolog arrays to arma::rowvec and arma::mat
rowvec responses = convertArrayToRowvec(arr, vecSize);
mat data = convertArrayToMat(matrix, matSize, matRowNum); mat data = convertArrayToMat(matrix, matSize, matRowNum);
rowvec responses = convertArrayToRowvec(responses_arr, vecSize);
rowvec weights = convertArrayToRowvec(weights_arr, weightsSize);
// run the model function // run the model train function
regressor.Train(data, responses); return regressor.Train(data, responses, weights, (bool_intercept == 1));
} }
// input:
// output: double
SP_integer variance()
{
return regressor.Variance();
}
/*
void testing()
{
// load the iris data
mat dataset;
bool loaded = mlpack::data::Load("iris.csv", dataset);
// split the data into train and test
mat trainData = dataset.cols(1, 4);
trainData.shed_row(trainData.n_rows - 1);
rowvec trainTarget = trainData.row(trainData.n_rows - 1);
trainData.shed_row(trainData.n_rows - 1);
mat testData = dataset.col(dataset.n_cols - 1);
testData.shed_row(testData.n_rows - 1);
rowvec testTarget = testData.row(testData.n_rows - 1);
testData.shed_row(testData.n_rows - 1);
// init the bayesian linear regressor model
// train the model
regressor.Train(trainData, trainTarget);
// predict with the test data
rowvec prediction;
regressor.Predict(testData, prediction);
// compare test target and prediction
cout << "Train Data: " << trainData << endl;
cout << "Train Target: " << trainTarget << endl;
cout << "Alpha" << alpha() << endl;
cout << "Beta" << beta() << endl;
}
*/
:- module(linear_regression, [initModel/4, alpha/1, beta/1, dataOffset/2, dataScale/2, omega/2, predict/5, predictWithStd/7, rmse/6, train/5, variance/1]). :- module(linear_regression, [initModel/7, initModelWithWeights/9, initModelEmpty/1, computeError/6, intercept/1, lambda/1, modifyLambda/1, parameters/2, modifyParameters/2, predict/5, train/7, trainWithWeights/9]).
:- load_files(library(str_decl), :- load_files(library(str_decl),
[when(compile_time), if(changed)]). [when(compile_time), if(changed)]).
...@@ -13,37 +13,21 @@ ...@@ -13,37 +13,21 @@
float_array = array(float32). float_array = array(float32).
%% definitions for the connected function and what there inputs and output arguments are %% definitions for the connected function and what there inputs and output arguments are
foreign(initModel, c, initModel(+integer, +integer, +integer, +float32)). foreign(initModel, c, initModel(+pointer(float_array), +integer, +integer, +pointer(float_array), +integer, +integer, +integer)).
foreign(alpha, c, alpha([-integer])). foreign(initModelWithWeights, c, initModelWithWeights(+pointer(float_array), +integer, +integer, +pointer(float_array), +integer, +pointer(float_array), +integer, +integer, +integer)).
foreign(beta, c, beta([-integer])). foreign(initModelEmpty, c, initModelEmpty(+integer)).
foreign(dataOffset, c, dataOffset(-integer, [-pointer(float_array)])). foreign(computeError, c, computeError(+pointer(float_array), +integer, +integer, +pointer(float_array), +integer, [-integer])).
foreign(dataScale, c, dataScale(-integer, [-pointer(float_array)])). foreign(intercept, c, intercept([-integer])).
foreign(omega, c, omega(-integer, [-pointer(float_array)])). foreign(lambda, c, lambda([-integer])).
foreign(modifyLambda, c, modifyLambda(+integer)).
foreign(parameters, c, parameters([-pointer(float_array)], -integer)).
foreign(modifyParameters, c, modifyParameters(+pointer(float_array), +integer)).
foreign(predict, c, predict(+pointer(float_array), +integer, +integer, -pointer(float_array), -integer)). foreign(predict, c, predict(+pointer(float_array), +integer, +integer, -pointer(float_array), -integer)).
foreign(predictWithStd, c, predictWithStd(+pointer(float_array), +integer, +integer, -pointer(float_array), -integer, -pointer(float_array), -integer)). foreign(train, c, train(+pointer(float_array), +integer, +integer, +pointer(float_array), +integer, +integer, [-integer])).
foreign(rmse, c, rmse(+pointer(float_array), +integer, +integer, +pointer(float_array), +integer, [-integer])). foreign(trainWithWeights, c, trainWithWeights(+pointer(float_array), +integer, +integer, +pointer(float_array), +integer, +pointer(float_array), +integer, +integer, [-integer])).
foreign(train, c, train(+pointer(float_array), +integer, +integer, +pointer(float_array), +integer)).
foreign(variance, c, variance([-integer])).
%% Defines what functions should be connected from main.cpp %% Defines what functions should be connected from main.cpp
foreign_resource(linear_regression, [initModel, alpha, beta, dataOffset, dataScale, omega, predict, predictWithStd, rmse, train, variance]). foreign_resource(linear_regression, [initModel, initModelWithWeights, initModelEmpty, computeError, intercept, lambda, modifyLambda, parameters, modifyParameters, predict, train, trainWithWeights]).
:- load_foreign_resource(linear_regression). :- load_foreign_resource(linear_regression).
\ No newline at end of file
%% Some funktions that use the new Method
%% First trains the model and then tries to predict the targets and the std for the given data
predict(PredictList, StdList) :-
train,
convert_list_to_float_array([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, array(Xsize, Xrownum, X)),
predictWithStd(X, Xsize,Xrownum, Predic, PredicSize, Std, StdSize),
convert_float_array_to_list(Predic, PredicSize, PredictList),
convert_float_array_to_list(Std, StdSize, StdList).
%% Trains the model with the given data and targets
train :-
convert_list_to_float_array([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, array(Xsize, Xrownum, X)),
convert_list_to_float_array([0.2,0.2,0.2,0.2], array(Ysize, Y)),
train(X,Xsize, Xrownum,Y, Ysize).
...@@ -4,53 +4,49 @@ ...@@ -4,53 +4,49 @@
:- use_module('../../helper_files/helper.pl'). :- use_module('../../helper_files/helper.pl').
reset_Model :- reset_Model :-
initModel(1,0,50,0.0001). initModelEmpty(1).
:- begin_tests(lists). :- begin_tests(lists).
%% alpha tests
test(alpha_std_init) :-
reset_Model,
alpha(0).
test(alpha_wrong_input, fail) :-
reset_Model,
alpha(1).
test(alpha_after_train, A =:= 9223372036854775808) :-
reset_Model,
convert_list_to_float_array([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, array(Xsize, Xrownum, X)),
convert_list_to_float_array([0.2,0.2,0.2,0.2], array(Ysize, Y)),
train(X,Xsize, Xrownum,Y, Ysize),
alpha(A).
%% train tests %% train tests
test(correct_train) :- test(correct_train) :-
reset_Model, reset_Model,
convert_list_to_float_array([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, array(Xsize, Xrownum, X)), convert_list_to_float_array([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, array(Xsize, Xrownum, X)),
convert_list_to_float_array([0.2,0.2,0.2,0.2], array(Ysize, Y)), convert_list_to_float_array([0.2,0.2,0.2,0.2], array(Ysize, Y)),
train(X,Xsize, Xrownum,Y, Ysize). train(X,Xsize, Xrownum,Y, Ysize,1 ,0).
test(false_train, fail) :- test(false_train, fail) :-
reset_Model, reset_Model,
convert_list_to_float_array([],3, array(Xsize, Xrownum, X)), convert_list_to_float_array([],3, array(Xsize, Xrownum, X)),
convert_list_to_float_array([0.2,0.2,0.2,0.2], array(Ysize, Y)), convert_list_to_float_array([0.2,0.2,0.2,0.2], array(Ysize, Y)),
train(X,Xsize, Xrownum,Y, Ysize). train(X,Xsize, Xrownum,Y, Ysize, 1, 0).
test(false_train2, fail) :- test(false_train2, fail) :-
reset_Model, reset_Model,
convert_list_to_float_array([],0, array(Xsize, Xrownum, X)), convert_list_to_float_array([],0, array(Xsize, Xrownum, X)),
convert_list_to_float_array([0.2,0.2,0.2,0.2], array(Ysize, Y)), convert_list_to_float_array([0.2,0.2,0.2,0.2], array(Ysize, Y)),
train(X,Xsize, Xrownum,Y, Ysize). train(X,Xsize, Xrownum,Y, Ysize, 1, 0).
test(false_train3, fail) :- test(false_train3, fail) :-
reset_Model, reset_Model,
convert_list_to_float_array([1,2],0, array(Xsize, Xrownum, X)), convert_list_to_float_array([1,2],0, array(Xsize, Xrownum, X)),
convert_list_to_float_array([0.2,0.2,0.2,0.2], array(Ysize, Y)), convert_list_to_float_array([0.2,0.2,0.2,0.2], array(Ysize, Y)),
train(X,Xsize, Xrownum,Y, Ysize). train(X,Xsize, Xrownum,Y, Ysize, 1, 0).
test(false_train3, fail) :- test(false_train3, fail) :-
reset_Model, reset_Model,
convert_list_to_float_array([1,2,44,3],3, array(Xsize, Xrownum, X)), convert_list_to_float_array([1,2,44,3],3, array(Xsize, Xrownum, X)),
convert_list_to_float_array([0.2,0.2,0.2,0.2], array(Ysize, Y)), convert_list_to_float_array([0.2,0.2,0.2,0.2], array(Ysize, Y)),
train(X,Xsize, Xrownum,Y, Ysize). train(X,Xsize, Xrownum,Y, Ysize, 1, 0).
test(false_train4) :- test(false_train4) :-
reset_Model, reset_Model,
convert_list_to_float_array([1,2,44,3],2, array(Xsize, Xrownum, X)), convert_list_to_float_array([1,2,44,3],2, array(Xsize, Xrownum, X)),
convert_list_to_float_array([0.2,0.2,0.2,0.2], array(Ysize, Y)), convert_list_to_float_array([0.2,0.2,0.2,0.2], array(Ysize, Y)),
train(X,Xsize, Xrownum,Y, Ysize). train(X,Xsize, Xrownum,Y, Ysize, 1, 0).
test(train) :-
reset_Model,
convert_list_to_float_array([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, array(Xsize, Xrownum, X)),
convert_list_to_float_array([0.2,0.2,0.2,0.2], array(Ysize, Y)),
train(X,Xsize, Xrownum,Y, Ysize, 1, 0),
predict(X, Xsize,Xrownum, Predic, PredicSize),
convert_float_array_to_list(Predic, PredicSize, [0.20000000298023224,0.20000000298023224,0.20000000298023224,0.20000000298023224]).
:- end_tests(lists). :- end_tests(lists).
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment