1
0
mirror of https://github.com/sjwhitworth/golearn.git synced 2025-04-26 13:49:14 +08:00
golearn/linear_models/logistic.go

71 lines
1.8 KiB
Go
Raw Normal View History

2014-05-05 21:47:56 +08:00
package linear_models
2014-07-02 15:48:35 +01:00
import (
"errors"
2014-07-02 15:48:35 +01:00
"fmt"
2014-08-22 07:21:24 +00:00
"github.com/sjwhitworth/golearn/base"
2014-07-02 15:48:35 +01:00
)
2014-05-05 21:47:56 +08:00
type LogisticRegression struct {
param *Parameter
model *Model
}
func NewLogisticRegression(penalty string, C float64, eps float64) (*LogisticRegression, error) {
2014-05-05 21:47:56 +08:00
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))
2014-05-05 21:47:56 +08:00
}
lr := LogisticRegression{}
lr.param = NewParameter(solver_type, C, eps)
lr.model = nil
return &lr, nil
2014-05-05 21:47:56 +08:00
}
func (lr *LogisticRegression) Fit(X base.FixedDataGrid) error {
2014-07-02 15:48:35 +01:00
problemVec := convertInstancesToProblemVec(X)
labelVec := convertInstancesToLabelVec(X)
prob := NewProblem(problemVec, labelVec, 0)
2014-05-05 21:47:56 +08:00
lr.model = Train(prob, lr.param)
return nil
2014-05-05 21:47:56 +08:00
}
func (lr *LogisticRegression) Predict(X base.FixedDataGrid) (base.FixedDataGrid, error) {
2014-08-02 16:22:15 +01:00
// Only support 1 class Attribute
classAttrs := X.AllClassAttributes()
if len(classAttrs) != 1 {
panic(fmt.Sprintf("%d Wrong number of classes", len(classAttrs)))
2014-05-05 21:47:56 +08:00
}
2014-08-02 16:22:15 +01:00
// Generate return structure
ret := base.GeneratePredictionVector(X)
classAttrSpecs := base.ResolveAttributes(ret, classAttrs)
2014-08-02 16:22:15 +01:00
// Retrieve numeric non-class Attributes
numericAttrs := base.NonClassFloatAttributes(X)
numericAttrSpecs := base.ResolveAttributes(X, numericAttrs)
2014-08-02 16:22:15 +01:00
// 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"
2014-05-05 21:47:56 +08:00
}