-
Notifications
You must be signed in to change notification settings - Fork 5
/
linear_regression.go
157 lines (127 loc) · 5.1 KB
/
linear_regression.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
package mlpack
/*
#cgo CFLAGS: -I./capi -Wall
#cgo LDFLAGS: -L. -lmlpack_go_linear_regression
#include <capi/linear_regression.h>
#include <stdlib.h>
*/
import "C"
import "gonum.org/v1/gonum/mat"
type LinearRegressionOptionalParam struct {
InputModel *linearRegression
Lambda float64
Test *mat.Dense
Training *mat.Dense
TrainingResponses *mat.Dense
Verbose bool
}
func LinearRegressionOptions() *LinearRegressionOptionalParam {
return &LinearRegressionOptionalParam{
InputModel: nil,
Lambda: 0,
Test: nil,
Training: nil,
TrainingResponses: nil,
Verbose: false,
}
}
/*
An implementation of simple linear regression and simple ridge regression
using ordinary least squares. This solves the problem
y = X * b + e
where X (specified by "Training") and y (specified either as the last column
of the input matrix "Training" or via the "TrainingResponses" parameter) are
known and b is the desired variable. If the covariance matrix (X'X) is not
invertible, or if the solution is overdetermined, then specify a Tikhonov
regularization constant (with "Lambda") greater than 0, which will regularize
the covariance matrix to make it invertible. The calculated b may be saved
with the "OutputPredictions" output parameter.
Optionally, the calculated value of b is used to predict the responses for
another matrix X' (specified by the "Test" parameter):
y' = X' * b
and the predicted responses y' may be saved with the "OutputPredictions"
output parameter. This type of regression is related to least-angle
regression, which mlpack implements as the 'lars' program.
For example, to run a linear regression on the dataset X with responses y,
saving the trained model to lr_model, the following command could be used:
// Initialize optional parameters for LinearRegression().
param := mlpack.LinearRegressionOptions()
param.Training = X
param.TrainingResponses = y
lr_model, _ := mlpack.LinearRegression(param)
Then, to use lr_model to predict responses for a test set X_test, saving the
predictions to X_test_responses, the following command could be used:
// Initialize optional parameters for LinearRegression().
param := mlpack.LinearRegressionOptions()
param.InputModel = &lr_model
param.Test = X_test
_, X_test_responses := mlpack.LinearRegression(param)
Input parameters:
- InputModel (linearRegression): Existing LinearRegression model to
use.
- Lambda (float64): Tikhonov regularization for ridge regression. If
0, the method reduces to linear regression. Default value 0.
- Test (mat.Dense): Matrix containing X' (test regressors).
- Training (mat.Dense): Matrix containing training set X (regressors).
- TrainingResponses (mat.Dense): Optional vector containing y
(responses). If not given, the responses are assumed to be the last row
of the input file.
- Verbose (bool): Display informational messages and the full list of
parameters and timers at the end of execution.
Output parameters:
- outputModel (linearRegression): Output LinearRegression model.
- outputPredictions (mat.Dense): If --test_file is specified, this
matrix is where the predicted responses will be saved.
*/
func LinearRegression(param *LinearRegressionOptionalParam) (linearRegression, *mat.Dense) {
params := getParams("linear_regression")
timers := getTimers()
disableBacktrace()
disableVerbose()
// Detect if the parameter was passed; set if so.
if param.InputModel != nil {
setLinearRegression(params, "input_model", param.InputModel)
setPassed(params, "input_model")
}
// Detect if the parameter was passed; set if so.
if param.Lambda != 0 {
setParamDouble(params, "lambda", param.Lambda)
setPassed(params, "lambda")
}
// Detect if the parameter was passed; set if so.
if param.Test != nil {
gonumToArmaMat(params, "test", param.Test, false)
setPassed(params, "test")
}
// Detect if the parameter was passed; set if so.
if param.Training != nil {
gonumToArmaMat(params, "training", param.Training, false)
setPassed(params, "training")
}
// Detect if the parameter was passed; set if so.
if param.TrainingResponses != nil {
gonumToArmaRow(params, "training_responses", param.TrainingResponses)
setPassed(params, "training_responses")
}
// Detect if the parameter was passed; set if so.
if param.Verbose != false {
setParamBool(params, "verbose", param.Verbose)
setPassed(params, "verbose")
enableVerbose()
}
// Mark all output options as passed.
setPassed(params, "output_model")
setPassed(params, "output_predictions")
// Call the mlpack program.
C.mlpackLinearRegression(params.mem, timers.mem)
// Initialize result variable and get output.
var outputModel linearRegression
outputModel.getLinearRegression(params, "output_model")
var outputPredictionsPtr mlpackArma
outputPredictions := outputPredictionsPtr.armaToGonumRow(params, "output_predictions")
// Clean memory.
cleanParams(params)
cleanTimers(timers)
// Return output(s).
return outputModel, outputPredictions
}