dtgo

command module
v0.0.0-...-0a10915 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 12, 2026 License: MIT Imports: 22 Imported by: 0

README

dtgo

Decision tree in Go based on the @random-forests example.

Command line

Train a model from a labeled CSV file. By default, the final column is the target label and 20% of rows are reserved for evaluation:

go run . train -input testdata/Iris.csv -output iris-model.json

Use -target-name to select the target by its exact, case-sensitive header, or -target-index to select it by its zero-based CSV column index:

go run . train -input testdata/Iris.csv -output iris-model.json -target-name Species
go run . train -input testdata/Iris.csv -output iris-model.json -target-index 4

The target flags are mutually exclusive. Remaining columns become model features in their original relative order.

Use -no-header when the training CSV contains data records only:

go run . train -input headerless-training.csv -output model.json -no-header

Headerless training names the model features feature_0, feature_1, and so on, and names the target label. The final CSV column remains the default target. Use -target-index to select another column; -target-name cannot be used without a header. Generated feature numbers follow feature order after the target column is removed.

The command prints the trained tree, any failed holdout predictions, and a summary containing the training size, test size, correct and failed counts, and accuracy. Change the holdout with -test-split; use -test-split 0 to train on every row without evaluation.

Every successful training run also prints wall-clock time, percentage of total time, and throughput for typed CSV loading, splitting, column finalization, training, rendering, evaluation, and model saving. Loading reports source bytes, records, values, and retained typed storage; finalization reports the selected rows, immutable storage, and feature strategies. The performance block also reports the process's current GOMAXPROCS. Use -perf-details to include tree shape, split-scoring work, the five slowest features, allocations, and garbage collection activity:

go run . train -input testdata/Iris.csv -output iris-model.json -perf-details

CLI training uses up to GOMAXPROCS workers for loading large regular CSV files, merging typed source columns, global numeric presorting, feature scoring at large nodes, and sufficiently large sibling subtrees. The phases reuse the same bound and do not oversubscribe the process. Files smaller than 8 MiB and inputs without regular-file size metadata retain the streaming serial loader. Use -parallelism 1 for fully serial loading and training or -parallelism N to set a smaller bound. Values above GOMAXPROCS are capped.

CLI training parses CSV records directly into typed immutable source columns; it does not retain a [][]string or [][]any copy. Train/test selections are indexed views over those columns, so holdout size, membership, and source order remain unchanged. Constant source columns retain one value, binary source columns retain two values plus a bitset, and integer source columns with 3–64 values retain byte ordinals. Selected views reuse this source inference metadata and compatible masks or ordinals during finalization. Globally binary integer, finite-float, and string features then use bitsets, including popcount scoring at sufficiently dense nodes. Higher-cardinality integers and non-binary numeric features are globally presorted once and retain their order through child partitions. These representations are discarded after training and do not change the saved model format.

For large files, the loader first finds quote-aware record boundaries and then parses bounded ReaderAt sections concurrently. Typed shards are concatenated in source order, including numeric promotion and dictionary reconciliation. Quoted multiline fields, escaped quotes, TrimLeadingSpace, missing-value locations, and deterministic error precedence remain identical to serial CSV loading. Detailed performance output reports loader workers, chunks, boundary scan time, and shard-merge time.

Use -cpuprofile FILE, -memprofile FILE, or -trace FILE to capture standard Go diagnostic artifacts. Profile output paths must differ from the command's input and output paths and from one another. Reported operational time excludes the final profile flush.

Empty fields and the case-sensitive value NA are treated as missing. Training rejects missing feature values by default and reports their CSV location. Use -missing drop to discard rows with missing features before the train/test split:

go run . train -input testdata/penguins.csv -output penguins-model.json -missing drop

The training summary always reports how many rows were dropped. Missing labels are rejected under both missing-value policies.

Run inference with a feature-only CSV whose header exactly matches the model's feature names and order:

go run . infer -input iris-features.csv -model iris-model.json > predictions.csv

The output CSV preserves the input columns and appends the label column from the training data. Inference performance is reported on standard error so the prediction CSV on standard output remains unchanged. Its phases are model loading, CSV reading, record processing, and CSV writing; -perf-details and the profiling flags are also available for inference.

For a feature-only CSV without a header, pass -no-header. Every input record is processed, and the output remains headerless with the prediction appended:

go run . infer -input headerless-features.csv -model model.json -no-header > predictions.csv

Model API

decisiontree.TrainModel returns a model containing both the trained tree and its input schema. Models can be persisted and restored with decisiontree.SaveModel and decisiontree.LoadModel:

model, err := decisiontree.TrainModel(rows, header)
if err != nil {
	return err
}
if err := decisiontree.SaveModel(writer, model); err != nil {
	return err
}

loaded, err := decisiontree.LoadModel[any](reader)
if err != nil {
	return err
}
label, err := loaded.Predict(features)

Use decisiontree.TrainModelWithMetrics when training diagnostics are needed. It additionally returns ordered per-feature scoring calls, row visits, candidate counts and elapsed time, along with columnar storage, global presorting, histogram, binary/bitset, parallel-task, node, leaf, and depth totals. TrainModel does not collect or time these details. The existing Train, TrainModel, and TrainModelWithMetrics APIs remain serial. Use the options-based APIs to enable bounded parallel training:

model, metrics, err := decisiontree.TrainModelWithOptionsAndMetrics(
	rows,
	header,
	decisiontree.TrainingOptions{Parallelism: 0}, // use GOMAXPROCS
)

Streaming CSV integrations can build the same typed representation directly with decisiontree.NewTrainingDataBuilder and AppendCSVRecord. Build returns immutable TrainingData; Select makes checked indexed views without copying column values, and RowInto reconstructs a row only when needed. Prepare a non-empty selection once and train it repeatedly:

builder, err := decisiontree.NewTrainingDataBuilder(header, estimatedRows)
if err != nil {
	return err
}
for readNextCSVRecord() {
	if err := builder.AppendCSVRecord(record); err != nil {
		return err
	}
}
data, err := builder.Build()
if err != nil {
	return err
}
prepared, preparation, err := decisiontree.PrepareTrainingData(data)
if err != nil {
	return err
}
model, metrics, err := decisiontree.TrainPreparedModelWithOptionsAndMetrics(
	prepared,
	decisiontree.TrainingOptions{Parallelism: 0},
)

Parallel ingestion integrations can create category-compatible shard builders with NewTrainingDataBuilderLike, then join immutable shards in source order with ConcatTrainingData or ConcatTrainingDataWithOptions. Concatenation reconciles numeric promotion, compact integer dictionaries, binary bitsets, categorical string pools, and selected views without materializing Rows[any].

For batches, provide the destination slice so prediction does not allocate:

labels := make([]string, len(featureRows))
predicted, err := loaded.PredictInto(featureRows, labels)
if err != nil {
	// labels[:predicted] contains the successful predictions.
	return err
}

The JSON artifact is versioned and stores ordered feature names, explicit int, float64, or string types, the label name, and the complete decision tree. Load rejects unsupported versions and malformed trees before inference. Models are immutable after training or loading; their prediction methods are safe for concurrent callers using disjoint input and output slices.

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL