1
0
mirror of https://github.com/sjwhitworth/golearn.git synced 2025-04-26 13:49:14 +08:00
golearn/linear_models/logistic.go
Richard Townsend 5ceb4e7111 linear_models: fix cgo issues, upgrade to liblinear 2.14
Requires an additional step to install:
 - cd /tmp &&
 - wget https://github.com/cjlin1/liblinear/archive/v241.tar.gz
 - tar xvf v241.tar.gz
 - cd liblinear-241
 - make lib
 - sudo install -vm644 linear.h /usr/include
 - sudo install -vm755 liblinear.so.4 /usr/lib
 - sudo ln -sfv liblinear.so.4 /usr/lib/liblinear.so
2020-09-06 10:01:24 +01:00

71 lines
1.8 KiB
Go

package linear_models
import (
"errors"
"fmt"
"github.com/sjwhitworth/golearn/base"
)
type LogisticRegression struct {
param *Parameter
model *Model
}
func NewLogisticRegression(penalty string, C float64, eps float64) (*LogisticRegression, error) {
solver_type := 0
if penalty == "l2" {
solver_type = L2R_LR
} else if penalty == "l1" {
solver_type = L1R_LR
} else {
return nil, errors.New(fmt.Sprintf("Invalid penalty '%s'", penalty))
}
lr := LogisticRegression{}
lr.param = NewParameter(solver_type, C, eps)
lr.model = nil
return &lr, nil
}
func (lr *LogisticRegression) Fit(X base.FixedDataGrid) error {
problemVec := convertInstancesToProblemVec(X)
labelVec := convertInstancesToLabelVec(X)
prob := NewProblem(problemVec, labelVec, 0)
lr.model = Train(prob, lr.param)
return nil
}
func (lr *LogisticRegression) Predict(X base.FixedDataGrid) (base.FixedDataGrid, error) {
// Only support 1 class Attribute
classAttrs := X.AllClassAttributes()
if len(classAttrs) != 1 {
panic(fmt.Sprintf("%d Wrong number of classes", len(classAttrs)))
}
// Generate return structure
ret := base.GeneratePredictionVector(X)
classAttrSpecs := base.ResolveAttributes(ret, classAttrs)
// Retrieve numeric non-class Attributes
numericAttrs := base.NonClassFloatAttributes(X)
numericAttrSpecs := base.ResolveAttributes(X, numericAttrs)
// Allocate row storage
row := make([]float64, len(numericAttrSpecs))
X.MapOverRows(numericAttrSpecs, func(rowBytes [][]byte, rowNo int) (bool, error) {
for i, r := range rowBytes {
row[i] = base.UnpackBytesToFloat(r)
}
val := Predict(lr.model, row)
vals := base.PackFloatToBytes(val)
ret.Set(classAttrSpecs[0], rowNo, vals)
return true, nil
})
return ret, nil
}
func (lr *LogisticRegression) String() string {
return "LogisticRegression"
}