Documentation
¶
Overview ¶
Package goml runs trained machine-learning models in pure Go, with output that matches the original scikit-learn estimator.
Caution: this library is fully AI-generated ¶
The implementation, tests, examples and documentation were all written by an AI agent.
Every shipped model is checked against scikit-learn's own outputs by the test suite in the repository, but the only real-world validation is against production workloads specific to Heru, Inc. Anything those workloads do not exercise — other estimator types, other hyper-parameters, other scikit-learn versions, other input regimes — is unproven, and exactness against a moving upstream is exactly where that gap is most likely to hurt. Use it with caution: read the code, validate your own exported model against your own scikit-learn outputs, and treat the fidelity claims below as claims to verify rather than as guarantees.
Goals ¶
The package is built around three ideas:
- Static, not dynamic. A model is exported once from Python (see tools/sklexport) into a portable go-ml/v1 JSON document. That document is either loaded at startup or, for maximum speed and zero runtime dependencies, compiled directly into your binary as Go source with the go-ml-gen tool (see cmd/go-ml-gen). There is no Python, no pickle, and no model file at runtime.
- Generic. Models are values behind small interfaces (Model, Classifier, Regressor). New estimator types register a decoder with Register and are then usable through the same Load entry point, mirroring how image.RegisterFormat or database/sql drivers work. The models that ship today are RandomForestClassifier and ExtraTreesClassifier, both in package github.com/heru-opensource/go-ml/ensemble.
- Faithful. Each model reproduces scikit-learn's prediction path exactly, down to its internal float32 cast and missing-value handling, so Go and Python agree to within floating-point rounding.
Loading a model ¶
Import the package that implements your model type for its side-effect registration, then load by type from the export envelope:
import (
goml "github.com/heru-opensource/go-ml"
_ "github.com/heru-opensource/go-ml/ensemble" // registers the forest models
)
clf, err := goml.LoadClassifierFile("model.json")
if err != nil { ... }
proba, err := clf.PredictProba([][]float64{{1, 2, 3, ...}})
The API mirrors scikit-learn: Classifier.PredictProba returns per-class probabilities in Classifier.Classes order, and Classifier.Predict returns the arg-max class label.
Missing features ¶
Tree models handle missing values natively. Pass math.NaN for an absent feature; it is routed exactly as scikit-learn would route it.
Index ¶
Constants ¶
const Format = "go-ml/v1"
Format is the export envelope version this package reads.
Variables ¶
var ( // ErrFormat is returned when the export envelope has an unsupported format. ErrFormat = errors.New("goml: unsupported export format") // ErrUnknownType is returned by Load when no decoder is registered for the // model's type. Importing the package that implements the model (for its // side-effect Register call) fixes this. ErrUnknownType = errors.New("goml: unknown model type") // ErrNotClassifier is returned by the classifier loaders when the loaded // model does not implement Classifier. ErrNotClassifier = errors.New("goml: model is not a Classifier") // ErrNumFeatures is returned by a model's predict methods when an input // sample has the wrong number of features. ErrNumFeatures = errors.New("goml: wrong number of features") )
Errors returned by the loading functions. Use errors.Is to test for them.
Functions ¶
func Register ¶
Register installs a decoder for a model type (the value of the envelope's "type" field, e.g. "RandomForestClassifier"). It is normally called from a model package's init function. Register panics if dec is nil or if typeName is already registered, mirroring image.RegisterFormat and sql.Register.
func RegisteredTypes ¶
func RegisteredTypes() []string
RegisteredTypes returns the sorted list of model types that have a decoder.
Types ¶
type Classifier ¶
type Classifier interface {
Model
// Classes returns the class labels, in the column order used by
// PredictProba. The returned slice is a copy and may be modified freely.
Classes() []float64
// PredictProba returns, for each input sample, a vector of class
// probabilities aligned with Classes.
PredictProba(X [][]float64) ([][]float64, error)
// Predict returns, for each input sample, the label of the most probable
// class (ties resolved toward the lowest column index, as in scikit-learn).
Predict(X [][]float64) ([]float64, error)
}
Classifier predicts class membership, mirroring scikit-learn's classifier API. In every method X is a batch of samples (one inner slice per sample, each of length Model.NFeatures); a missing feature is encoded as math.NaN.
func LoadClassifier ¶
func LoadClassifier(r io.Reader) (Classifier, error)
LoadClassifier is Load followed by an assertion that the model classifies.
func LoadClassifierBytes ¶
func LoadClassifierBytes(data []byte) (Classifier, error)
LoadClassifierBytes is LoadBytes followed by a Classifier assertion.
func LoadClassifierFile ¶
func LoadClassifierFile(path string) (Classifier, error)
LoadClassifierFile is LoadFile followed by a Classifier assertion.
type Decoder ¶
type Decoder func(model json.RawMessage) (Model, error)
A Decoder builds a Model from the type-specific "model" object of an export envelope. Model implementations register one with Register.
type Model ¶
type Model interface {
// Type returns the scikit-learn estimator class name, e.g.
// "RandomForestClassifier". It matches the "type" field of the export.
Type() string
// NFeatures returns the number of input features each sample must have.
NFeatures() int
}
Model is the behavior common to every model: it knows its scikit-learn estimator type name and how many input features it expects. Concrete models additionally implement a task interface such as Classifier or Regressor.
func Load ¶
Load reads a go-ml/v1 export from r and constructs the model, dispatching on the envelope's "type" to the decoder registered for it.
type Regressor ¶
type Regressor interface {
Model
// Predict returns one predicted target value per input sample.
Predict(X [][]float64) ([]float64, error)
}
Regressor predicts continuous targets. It is defined so the generic Load entry point and registry can serve regression models as they are added; no regressor ships in this package yet.
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
go-ml-bench
command
Command go-ml-bench measures prediction performance of a go-ml model, as a compiled binary, so the numbers are directly comparable to a scikit-learn timing of the same model (see tools/sklexport/bench_compare.py).
|
Command go-ml-bench measures prediction performance of a go-ml model, as a compiled binary, so the numbers are directly comparable to a scikit-learn timing of the same model (see tools/sklexport/bench_compare.py). |
|
go-ml-gen
command
Command go-ml-gen compiles a go-ml/v1 model export into Go source, so the model is linked statically into your binary with no runtime file or parsing.
|
Command go-ml-gen compiles a go-ml/v1 model export into Go source, so the model is linked statically into your binary with no runtime file or parsing. |
|
Package ensemble implements tree-ensemble models: static, parallel reimplementations of the prediction path of scikit-learn's forests.
|
Package ensemble implements tree-ensemble models: static, parallel reimplementations of the prediction path of scikit-learn's forests. |
|
examples
|
|
|
classify
command
Command classify is a runnable example of using go-ml models that have been compiled statically into the binary with go-ml-gen — there is no Python, no pickle, and no model file at runtime.
|
Command classify is a runnable example of using go-ml models that have been compiled statically into the binary with go-ml-gen — there is no Python, no pickle, and no model file at runtime. |
|
internal
|
|
|
jsonx
Package jsonx holds small JSON helpers shared across go-ml packages.
|
Package jsonx holds small JSON helpers shared across go-ml packages. |
|
Package tree implements binary decision trees whose evaluation is bit-for-bit compatible with scikit-learn's sklearn.tree._tree.Tree.
|
Package tree implements binary decision trees whose evaluation is bit-for-bit compatible with scikit-learn's sklearn.tree._tree.Tree. |