├── .gitignore ├── .travis.yml ├── LICENSE ├── Makefile ├── README.md ├── activation ├── common.go ├── logistic.go ├── raw.go └── softmax.go ├── doc.go ├── go.mod ├── go.sum ├── inference └── inference.go ├── mat ├── mat.go └── mat_test.go ├── protobuf ├── activation.pb.go ├── activation.proto └── gen_pb.sh ├── test ├── data │ ├── breast_cancer_fmap.txt │ ├── breast_cancer_test.libsvm │ ├── breast_cancer_xgboost_dump.json │ ├── breast_cancer_xgboost_dump_fmap.json │ ├── breast_cancer_xgboost_dump_regression.json │ ├── breast_cancer_xgboost_true_prediction.txt │ ├── breast_cancer_xgboost_true_prediction_regression.txt │ ├── diamonds.csv │ ├── diamonds_test.libsvm │ ├── diamonds_xgboost_dump.json │ ├── diamonds_xgboost_true_prediction_proba.txt │ ├── iris_test.libsvm │ ├── iris_xgboost_dump.json │ ├── iris_xgboost_true_prediction.txt │ └── iris_xgboost_true_prediction_proba.txt ├── scripts │ ├── breast_cancer_xgboost.py │ ├── diamonds_xgboost.py │ └── iris_xgboost.py └── xgbensemble_test.go ├── xgbensemble.go ├── xgbensembleio.go └── xgbtree.go /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | test/.idea 3 | vendor 4 | .DS_Store -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | go: 3 | - "1.14" 4 | 5 | script: 6 | - go get golang.org/x/lint/golint 7 | - make ci -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 BB 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for TStream 2 | 3 | # Definition 4 | SHELL := /bin/bash # use bash all the time! 5 | FILES = $(shell find . -type f -name "*.go" | grep -v "vendor" | grep -v "^\./\.") 6 | 7 | # `make help` for more 8 | help: ## This is help dialog. 9 | help h: 10 | @IFS=$$'\n' ; \ 11 | help_lines=(`fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/\\$$//' | sed -e 's/##/:/'`); \ 12 | printf "%-20s %s\n" "target" "help" ; \ 13 | printf "%-20s %s\n" "------" "----" ; \ 14 | for help_line in $${help_lines[@]}; do \ 15 | IFS=$$':' ; \ 16 | help_split=($$help_line) ; \ 17 | help_command=`echo $${help_split[0]} | sed -e 's/^ *//' -e 's/ *$$//'` ; \ 18 | help_info=`echo $${help_split[2]} | sed -e 's/^ *//' -e 's/ *$$//'` ; \ 19 | printf '\033[36m'; \ 20 | printf "%-20s %s" $$help_command ; \ 21 | printf '\033[0m'; \ 22 | printf "%s\n" $$help_info; \ 23 | done 24 | 25 | vet: ## Vet the codebase. 26 | @go vet ./... 27 | 28 | lint: ## Go lint files 29 | STATUS=0; \ 30 | for FILE in $(FILES); do \ 31 | golint -set_exit_status $$FILE || STATUS=1; \ 32 | done ;\ 33 | exit $$STATUS 34 | 35 | gotest: ## Go test codebase. 36 | go test ./... 37 | 38 | fmt: ## Go fmt package 39 | for FILE in $(FILES); do \ 40 | go fmt $$FILE; \ 41 | done 42 | 43 | ci: lint vet gotest ## Simulate gitlab-CI 44 | @echo "CI passed!" 45 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # xgboost-go 2 | 3 | [![Build Status](https://travis-ci.com/Elvenson/xgboost-go.svg?token=rzHXU1xSU77dfjTLof6x&branch=main)](https://travis-ci.com/github/Elvenson/xgboost-go) 4 | [![GoDoc](https://godoc.org/github.com/Elvenson/xgboost-go?status.png)](https://godoc.org/github.com/Elvenson/xgboost-go) 5 | 6 | XGBoost inference with Golang by means of exporting xgboost model into json format and load model from that json file. 7 | This repo only supports [DMLC XGBoost](https://github.com/dmlc/xgboost) model at the moment. For more information regarding 8 | how XGBoost inference works, you can refer to this [medium article](https://medium.com/@bobi_29852/how-boosted-trees-inference-works-f161b03d5f5b). 9 | 10 | ## Features 11 | Currently, this repo only supports a few core features such as: 12 | 13 | * Read models from json format file (via `dump_model` API call) 14 | * Support sigmoid and softmax transformation activation. 15 | * Support binary and multiclass predictions. 16 | * Support regressions predictions. 17 | * Support missing values. 18 | * Support libsvm data format. 19 | 20 | **NOTE**: The result from DMLC XGBoost model may slightly differ from this model due to float number precision. 21 | 22 | ## How to use: 23 | To use this repo, first you need to get it: 24 | ```shell script 25 | go get github.com/Elvenson/xgboost-go 26 | ``` 27 | 28 | Basic example: 29 | 30 | ```go 31 | package main 32 | 33 | import ( 34 | "fmt" 35 | 36 | xgb "github.com/Elvenson/xgboost-go" 37 | "github.com/Elvenson/xgboost-go/activation" 38 | "github.com/Elvenson/xgboost-go/mat" 39 | ) 40 | 41 | func main() { 42 | ensemble, err := xgb.LoadXGBoostFromJSON("your model path", 43 | "", 1, 4, &activation.Logistic{}) 44 | if err != nil { 45 | panic(err) 46 | } 47 | 48 | input, err := mat.ReadLibsvmFileToSparseMatrix("your libsvm input path") 49 | if err != nil { 50 | panic(err) 51 | } 52 | predictions, err := ensemble.PredictProba(input) 53 | if err != nil { 54 | panic(err) 55 | } 56 | fmt.Printf("%+v\n", predictions) 57 | } 58 | ``` 59 | 60 | Here `LoadXGBoostFromJSON` requires 5 parameters: 61 | * The json model path. 62 | * DMLC feature map format, if no feature map leave this blank. 63 | * The number of classes (if this is a binary classification, the number of classes should be 1) 64 | * The depth of the tree, if unable to get the tree depth can specify 0 (slightly slower model built time) 65 | * Activation function, for now binary is `Logistic` multiclass is `Softmax` and regression is `Raw`. 66 | 67 | For more example, can take a look at `xgbensemble_test.go` or read this package 68 | [documentation](https://godoc.org/github.com/Elvenson/xgboost-go). 69 | 70 | **NOTE**: This repo only got tested on Python `xgboost` package version `1.2.0`. 71 | 72 | ## Contribution: 73 | All contributions are welcome. Before submitting a pull request, we first need to format the code using the 74 | following command: 75 | ```shell 76 | make fmt 77 | ``` 78 | 79 | Then run the following command to check if everything is good: 80 | ```shell 81 | make ci 82 | ``` 83 | 84 | -------------------------------------------------------------------------------- /activation/common.go: -------------------------------------------------------------------------------- 1 | package activation 2 | 3 | import ( 4 | "github.com/Elvenson/xgboost-go/mat" 5 | "github.com/Elvenson/xgboost-go/protobuf" 6 | ) 7 | 8 | // Activation is an interface that an activation needs to implement. 9 | type Activation interface { 10 | Transform(rawPrediction mat.Vector) (mat.Vector, error) 11 | Type() protobuf.ActivateType 12 | Name() string 13 | } 14 | -------------------------------------------------------------------------------- /activation/logistic.go: -------------------------------------------------------------------------------- 1 | package activation 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/Elvenson/xgboost-go/mat" 7 | "github.com/Elvenson/xgboost-go/protobuf" 8 | "github.com/chewxy/math32" 9 | ) 10 | 11 | // Logistic is struct contains necessary data for doing logistic calculation 12 | // for now is empty. 13 | type Logistic struct{} 14 | 15 | // sigmoid applies sigmoid transformation to value 16 | func sigmoid(x float32) float32 { 17 | return 1.0 / (1.0 + math32.Exp(-x)) 18 | } 19 | 20 | // Transform passes prediction through logistic function. 21 | func (a *Logistic) Transform(rawPredictions mat.Vector) (mat.Vector, error) { 22 | if len(rawPredictions) != 1 { 23 | return mat.Vector{}, fmt.Errorf("prediction should have only 1 dimension got %d", len(rawPredictions)) 24 | } 25 | rawPredictions[0] = sigmoid(rawPredictions[0]) 26 | return rawPredictions, nil 27 | } 28 | 29 | // Type returns activation type. 30 | func (a *Logistic) Type() protobuf.ActivateType { 31 | return protobuf.ActivateType_LOGISTIC 32 | } 33 | 34 | // Name returns activation name. 35 | func (a *Logistic) Name() string { 36 | return protobuf.ActivateType_name[int32(protobuf.ActivateType_LOGISTIC)] 37 | } 38 | -------------------------------------------------------------------------------- /activation/raw.go: -------------------------------------------------------------------------------- 1 | package activation 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/Elvenson/xgboost-go/mat" 7 | "github.com/Elvenson/xgboost-go/protobuf" 8 | ) 9 | 10 | // Raw is struct contains necessary data for doing logistic calculation 11 | // for now is empty. 12 | type Raw struct{} 13 | 14 | // Transform does nothing just returns the raw prediction. 15 | func (a *Raw) Transform(rawPredictions mat.Vector) (mat.Vector, error) { 16 | if len(rawPredictions) == 0 { 17 | return mat.Vector{}, fmt.Errorf("prediction should have at least 1 dimension") 18 | } 19 | return rawPredictions, nil 20 | } 21 | 22 | // Type returns activate type. 23 | func (a *Raw) Type() protobuf.ActivateType { 24 | return protobuf.ActivateType_RAW 25 | } 26 | 27 | // Name returns activation name. 28 | func (a *Raw) Name() string { 29 | return protobuf.ActivateType_name[int32(protobuf.ActivateType_RAW)] 30 | } 31 | -------------------------------------------------------------------------------- /activation/softmax.go: -------------------------------------------------------------------------------- 1 | package activation 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/Elvenson/xgboost-go/mat" 7 | "github.com/Elvenson/xgboost-go/protobuf" 8 | "github.com/chewxy/math32" 9 | ) 10 | 11 | // Softmax is struct contains necessary data for doing logistic calculation 12 | // for now is empty. 13 | type Softmax struct{} 14 | 15 | // softmax function. 16 | func softmax(vector mat.Vector) mat.Vector { 17 | var sum float32 = 0.0 18 | r := make([]float32, len(vector)) 19 | for i, v := range vector { 20 | exp := math32.Exp(v) 21 | r[i] = exp 22 | sum += exp 23 | } 24 | if sum != 0.0 { 25 | inverseSum := 1.0 / sum 26 | for i := range r { 27 | r[i] *= inverseSum 28 | } 29 | } 30 | return r 31 | } 32 | 33 | // Transform passes prediction through softmax function. 34 | func (a *Softmax) Transform(rawPredictions mat.Vector) (mat.Vector, error) { 35 | if len(rawPredictions) == 0 { 36 | return mat.Vector{}, fmt.Errorf("prediction should have at least 1 dimension") 37 | } 38 | 39 | p := softmax(rawPredictions) 40 | return p, nil 41 | } 42 | 43 | // Type returns activation type. 44 | func (a *Softmax) Type() protobuf.ActivateType { 45 | return protobuf.ActivateType_SOFTMAX 46 | } 47 | 48 | // Name returns activation name. 49 | func (a *Softmax) Name() string { 50 | return protobuf.ActivateType_name[int32(protobuf.ActivateType_SOFTMAX)] 51 | } 52 | -------------------------------------------------------------------------------- /doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Package xgboost is a pure Golang implementation of loading DMLC XGBoost json model generated from dump_model python 3 | API. This package supports binary, multiclass and regression inference. Note that this package is just for inference 4 | purpose only, for training part please reference to https://github.com/dmlc/xgboost. 5 | 6 | # Training model 7 | 8 | In order to have a json encoded model file, we need to train the model via Python first: 9 | 10 | iris_xgboost.py: 11 | 12 | import xgboost as xgb 13 | from sklearn import datasets 14 | from sklearn.model_selection import train_test_split 15 | from sklearn.datasets import dump_svmlight_file 16 | import numpy as np 17 | 18 | X, y = datasets.load_iris(return_X_y=True) 19 | X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0) 20 | 21 | dtrain = xgb.DMatrix(X_train, label=y_train) 22 | param = {'max_depth': 4, 'eta': 1, 'objective': 'multi:softmax', 'nthread': 4, 23 | 'eval_metric': 'auc', 'num_class': 3} 24 | 25 | num_round = 10 26 | bst = xgb.train(param, dtrain, num_round) 27 | y_pred = bst.predict(xgb.DMatrix(X_test)) 28 | 29 | clf = xgb.XGBClassifier(max_depth=4, objective='multi:softprob', n_estimators=10, 30 | num_classes=3) 31 | 32 | clf.fit(X_train, y_train) 33 | y_pred_proba = clf.predict_proba(X_test) 34 | 35 | np.savetxt('../data/iris_xgboost_true_prediction.txt', y_pred, delimiter='\t') 36 | np.savetxt('../data/iris_xgboost_true_prediction_proba.txt', y_pred_proba, delimiter='\t') 37 | dump_svmlight_file(X_test, y_test, '../data/iris_test.libsvm') 38 | bst.dump_model('../data/iris_xgboost_dump.json', dump_format='json') 39 | 40 | Here is how to load the model exported from the above script: 41 | 42 | package main 43 | 44 | import ( 45 | "fmt" 46 | 47 | "github.com/Elvenson/xgboost-go/activation" 48 | "github.com/Elvenson/xgboost-go/mat" 49 | "github.com/Elvenson/xgboost-go/models" 50 | ) 51 | 52 | func main() { 53 | ensemble, err := models.LoadXGBoostFromJSON("your model path", 54 | "", 1, 4, &activation.Logistic{}) 55 | if err != nil { 56 | panic(err) 57 | } 58 | 59 | input, err := mat.ReadLibsvmFileToSparseMatrix("your libsvm input path") 60 | if err != nil { 61 | panic(err) 62 | } 63 | predictions, err := ensemble.PredictProba(input) 64 | if err != nil { 65 | panic(err) 66 | } 67 | fmt.Printf("%+v\n", predictions) 68 | } 69 | 70 | For more information, please take a look at xgbensemble_test.go 71 | */ 72 | package xgboost 73 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/Elvenson/xgboost-go 2 | 3 | go 1.14 4 | 5 | require ( 6 | github.com/chewxy/math32 v1.10.1 7 | github.com/golang/protobuf v1.4.3 8 | github.com/google/go-cmp v0.5.2 // indirect 9 | github.com/pkg/errors v0.9.1 10 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect 11 | gotest.tools v2.2.0+incompatible 12 | ) 13 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/chewxy/math32 v1.10.1 h1:LFpeY0SLJXeaiej/eIp2L40VYfscTvKh/FSEZ68uMkU= 2 | github.com/chewxy/math32 v1.10.1/go.mod h1:dOB2rcuFrCn6UHrze36WSLVPKtzPMRAQvBvUwkSsLqs= 3 | github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= 4 | github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= 5 | github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= 6 | github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= 7 | github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= 8 | github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= 9 | github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= 10 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 11 | github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 12 | github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 13 | github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= 14 | github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 15 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 16 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 17 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 18 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= 19 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 20 | google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= 21 | google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= 22 | google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= 23 | google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= 24 | google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= 25 | google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= 26 | google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 27 | gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= 28 | gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= 29 | -------------------------------------------------------------------------------- /inference/inference.go: -------------------------------------------------------------------------------- 1 | package inference 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/Elvenson/xgboost-go/activation" 7 | "github.com/Elvenson/xgboost-go/mat" 8 | "github.com/Elvenson/xgboost-go/protobuf" 9 | ) 10 | 11 | // EnsembleBase contains interface of a base model. 12 | type EnsembleBase interface { 13 | PredictInner(features mat.SparseVector) (mat.Vector, error) 14 | Name() string 15 | NumClasses() int 16 | } 17 | 18 | // Ensemble struct contains ensemble model interface that a model needs to implement. 19 | type Ensemble struct { 20 | EnsembleBase 21 | activation.Activation 22 | } 23 | 24 | // PredictRegression predicts float number for regression task using ensemble model interface. 25 | func (e *Ensemble) PredictRegression(features mat.SparseMatrix, baseVal float32) (mat.Matrix, error) { 26 | if e.NumClasses() == 0 { 27 | return mat.Matrix{}, fmt.Errorf("0 class please check your model") 28 | } 29 | if e.NumClasses() != 1 { 30 | return mat.Matrix{}, fmt.Errorf("regression prediction only support binary classes for now") 31 | } 32 | 33 | results := mat.Matrix{Vectors: make([]*mat.Vector, len(features.Vectors))} 34 | for i, row := range features.Vectors { 35 | pred, err := e.PredictInner(row) 36 | if err != nil { 37 | return mat.Matrix{}, err 38 | } 39 | if len(pred) != e.NumClasses() { 40 | return mat.Matrix{}, fmt.Errorf("number of predicted value (%d) must match number of classes (%d)", 41 | len(pred), e.NumClasses()) 42 | } 43 | if e.Type() != protobuf.ActivateType_RAW { 44 | return mat.Matrix{}, fmt.Errorf("regression model must have raw activation") 45 | } 46 | pred, err = e.Transform(pred) 47 | pred[0] += baseVal 48 | if err != nil { 49 | return mat.Matrix{}, err 50 | } 51 | results.Vectors[i] = &pred 52 | } 53 | return results, nil 54 | } 55 | 56 | // PredictProba predicts probabilities using ensemble model interface. 57 | func (e *Ensemble) PredictProba(features mat.SparseMatrix) (mat.Matrix, error) { 58 | if e.NumClasses() == 0 { 59 | return mat.Matrix{}, fmt.Errorf("0 class please check your model") 60 | } 61 | 62 | results := mat.Matrix{Vectors: make([]*mat.Vector, len(features.Vectors))} 63 | for i, row := range features.Vectors { 64 | pred, err := e.PredictInner(row) 65 | if err != nil { 66 | return mat.Matrix{}, err 67 | } 68 | if len(pred) != e.NumClasses() { 69 | return mat.Matrix{}, fmt.Errorf("number of predicted value (%d) must match number of classes (%d)", 70 | len(pred), e.NumClasses()) 71 | } 72 | pred, err = e.Transform(pred) 73 | if err != nil { 74 | return mat.Matrix{}, err 75 | } 76 | results.Vectors[i] = &pred 77 | } 78 | return results, nil 79 | } 80 | 81 | // Predict predicts class using ensemble model interface. 82 | // If model is a binary classification model, the prediction results will be probabilities instead of classes. 83 | func (e *Ensemble) Predict(features mat.SparseMatrix) (mat.Matrix, error) { 84 | if e.NumClasses() == 0 { 85 | return mat.Matrix{}, fmt.Errorf("0 class please check your model") 86 | } 87 | results := mat.Matrix{Vectors: make([]*mat.Vector, len(features.Vectors))} 88 | for i, row := range features.Vectors { 89 | pred, err := e.PredictInner(row) 90 | if err != nil { 91 | return mat.Matrix{}, err 92 | } 93 | if len(pred) != e.NumClasses() { 94 | return mat.Matrix{}, fmt.Errorf("number of predicted value (%d) must match number of classes (%d)", 95 | len(pred), e.NumClasses()) 96 | } 97 | if len(pred) == 0 { 98 | return mat.Matrix{}, fmt.Errorf("empty inner prediction") 99 | } 100 | pred, err = e.Transform(pred) 101 | if err != nil { 102 | return mat.Matrix{}, err 103 | } 104 | if e.NumClasses() == 1 { 105 | // for binary classification prediction results is probabilities. 106 | results.Vectors[i] = &pred 107 | } else { 108 | idx, err := mat.GetVectorMaxIdx(&pred) 109 | if err != nil { 110 | return mat.Matrix{}, err 111 | } 112 | results.Vectors[i] = &mat.Vector{float32(idx)} 113 | } 114 | } 115 | 116 | return results, nil 117 | } 118 | 119 | // Name returns ensemble model name. 120 | func (e *Ensemble) Name() string { 121 | return e.EnsembleBase.Name() 122 | } 123 | -------------------------------------------------------------------------------- /mat/mat.go: -------------------------------------------------------------------------------- 1 | package mat 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "io" 7 | "os" 8 | "strconv" 9 | "strings" 10 | 11 | "github.com/chewxy/math32" 12 | "github.com/pkg/errors" 13 | ) 14 | 15 | // Vector is a list of float numbers. 16 | type Vector []float32 17 | 18 | // SparseVector is a map with index is a key and value is a value at that index. 19 | type SparseVector map[int]float32 20 | 21 | // SparseMatrix is a list of sparse vectors. 22 | type SparseMatrix struct { 23 | Vectors []SparseVector 24 | } 25 | 26 | // Matrix is a list of vector. 27 | type Matrix struct { 28 | Vectors []*Vector 29 | } 30 | 31 | // ReadLibsvmFileToSparseMatrix reads libsvm file into sparse matrix. 32 | func ReadLibsvmFileToSparseMatrix(fileName string) (SparseMatrix, error) { 33 | file, err := os.Open(fileName) 34 | if err != nil { 35 | return SparseMatrix{}, fmt.Errorf("unable to open %s: %s", fileName, err) 36 | } 37 | defer file.Close() 38 | 39 | reader := bufio.NewReader(file) 40 | 41 | sparseMatrix := SparseMatrix{Vectors: make([]SparseVector, 0)} 42 | for { 43 | line, err := reader.ReadString('\n') 44 | if err != nil { 45 | if err != io.EOF { 46 | return SparseMatrix{}, err 47 | } 48 | break 49 | 50 | } 51 | line = strings.TrimSpace(line) 52 | if line == "" { 53 | break 54 | } 55 | tokens := strings.Split(line, " ") 56 | if len(tokens) < 2 { 57 | return SparseMatrix{}, fmt.Errorf("too few columns") 58 | } 59 | // first column is label so skip it. 60 | vec := SparseVector{} 61 | for c := 1; c < len(tokens); c++ { 62 | if len(tokens[c]) == 0 { 63 | return SparseMatrix{}, fmt.Errorf("corrupted data format please check for empty spaces") 64 | } 65 | pair := strings.Split(tokens[c], ":") 66 | if len(pair) != 2 { 67 | return SparseMatrix{}, fmt.Errorf("wrong data format %s", tokens[c]) 68 | } 69 | colIdx, err := strconv.ParseUint(pair[0], 10, 32) 70 | if err != nil { 71 | return SparseMatrix{}, fmt.Errorf("cannot parse to int %s: %s", pair[0], err) 72 | } 73 | val, err := strconv.ParseFloat(pair[1], 32) 74 | if err != nil { 75 | return SparseMatrix{}, fmt.Errorf("cannot parse to float %s: %s", pair[1], err) 76 | } 77 | vec[int(colIdx)] = float32(val) 78 | } 79 | sparseMatrix.Vectors = append(sparseMatrix.Vectors, vec) 80 | } 81 | return sparseMatrix, nil 82 | } 83 | 84 | // ReadCSVFileToDenseMatrix reads CSV file to dense matrix. 85 | func ReadCSVFileToDenseMatrix(fileName string, delimiter string, defaultVal float32) (Matrix, error) { 86 | file, err := os.Open(fileName) 87 | if err != nil { 88 | return Matrix{}, fmt.Errorf("unable to open %s: %s", fileName, err) 89 | } 90 | defer file.Close() 91 | 92 | reader := bufio.NewReader(file) 93 | 94 | matrix := Matrix{Vectors: make([]*Vector, 0)} 95 | colDim := -1 96 | row := 0 97 | for { 98 | line, err := reader.ReadString('\n') 99 | if err != nil && err != io.EOF { 100 | return Matrix{}, err 101 | } 102 | line = strings.TrimSpace(line) 103 | if line == "" { 104 | break 105 | } 106 | tokens := strings.Split(line, delimiter) 107 | vec := Vector{} 108 | for i := 0; i < len(tokens); i++ { 109 | var val float32 110 | if len(tokens[i]) == 0 { 111 | val = defaultVal 112 | } else { 113 | v, err := strconv.ParseFloat(tokens[i], 32) 114 | if err != nil { 115 | return Matrix{}, fmt.Errorf("cannot convert to float %s: %s", tokens[i], err) 116 | } 117 | val = float32(v) 118 | } 119 | vec = append(vec, val) 120 | } 121 | if colDim == -1 { 122 | colDim = len(vec) 123 | } else if colDim != len(vec) { 124 | return Matrix{}, fmt.Errorf("row %d has different dimension: %d, please check your file", 125 | row, len(vec)) 126 | } 127 | matrix.Vectors = append(matrix.Vectors, &vec) 128 | row++ 129 | } 130 | return matrix, nil 131 | } 132 | 133 | // IsEqualVectors compares 2 vectors with a threshold. 134 | func IsEqualVectors(v1, v2 *Vector, threshold float32) error { 135 | if len(*v1) != len(*v2) { 136 | return fmt.Errorf("different vector length v1=%d, v2=%d", len(*v1), len(*v2)) 137 | } 138 | for i := range *v1 { 139 | if math32.Abs((*v1)[i]-(*v2)[i]) > threshold { 140 | return fmt.Errorf("%d element mismatch: v1[%d]=%f, v2[%d]=%f", i, i, (*v1)[i], i, (*v2)[i]) 141 | } 142 | } 143 | return nil 144 | } 145 | 146 | // GetVectorMaxIdx gets the index of the maximum value within a vector. 147 | func GetVectorMaxIdx(v *Vector) (int, error) { 148 | if len(*v) == 0 { 149 | return -1, fmt.Errorf("empty vector") 150 | } 151 | maxVal := math32.Inf(-1) 152 | r := 0 153 | for idx, i := range *v { 154 | if i > maxVal { 155 | maxVal = i 156 | r = idx 157 | } 158 | } 159 | return r, nil 160 | } 161 | 162 | // IsEqualMatrices compares 2 matrices with a threshold. 163 | func IsEqualMatrices(m1, m2 *Matrix, threshold float32) error { 164 | if len(m1.Vectors) != len(m2.Vectors) { 165 | return fmt.Errorf("row matrix mismatch: m1 got %d rows, m2 got %d rows", len(m1.Vectors), len(m2.Vectors)) 166 | } 167 | for i := range m1.Vectors { 168 | err := IsEqualVectors(m1.Vectors[i], m2.Vectors[i], threshold) 169 | if err != nil { 170 | return errors.Wrap(err, fmt.Sprintf("matrix comparison at index %d", i)) 171 | } 172 | } 173 | return nil 174 | } 175 | -------------------------------------------------------------------------------- /mat/mat_test.go: -------------------------------------------------------------------------------- 1 | package mat 2 | 3 | import ( 4 | "testing" 5 | 6 | "gotest.tools/assert" 7 | ) 8 | 9 | func TestReadLibsvmFile(t *testing.T) { 10 | m, err := ReadLibsvmFileToSparseMatrix("../test/data/iris_test.libsvm") 11 | assert.NilError(t, err) 12 | assert.Check(t, len(m.Vectors) != 0) 13 | assert.Equal(t, len(m.Vectors[0]), 4) 14 | } 15 | 16 | func TestReadCSVFileToDenseMatrix(t *testing.T) { 17 | m, err := ReadCSVFileToDenseMatrix( 18 | "../test/data/iris_xgboost_true_prediction_proba.txt", "\t", 0) 19 | assert.NilError(t, err) 20 | assert.Check(t, len(m.Vectors) != 0) 21 | assert.Equal(t, len(*m.Vectors[0]), 3) 22 | } 23 | -------------------------------------------------------------------------------- /protobuf/activation.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-gogo. DO NOT EDIT. 2 | // source: activation.proto 3 | 4 | package protobuf 5 | 6 | import ( 7 | fmt "fmt" 8 | proto "github.com/golang/protobuf/proto" 9 | math "math" 10 | ) 11 | 12 | // Reference imports to suppress errors if they are not otherwise used. 13 | var _ = proto.Marshal 14 | var _ = fmt.Errorf 15 | var _ = math.Inf 16 | 17 | // This is a compile-time assertion to ensure that this generated file 18 | // is compatible with the proto package it is being compiled against. 19 | // A compilation error at this line likely means your copy of the 20 | // proto package needs to be updated. 21 | const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package 22 | 23 | type ActivateType int32 24 | 25 | const ( 26 | ActivateType_UNKNOWN ActivateType = 0 27 | ActivateType_RAW ActivateType = 1 28 | ActivateType_LOGISTIC ActivateType = 2 29 | ActivateType_SOFTMAX ActivateType = 3 30 | ) 31 | 32 | var ActivateType_name = map[int32]string{ 33 | 0: "UNKNOWN", 34 | 1: "RAW", 35 | 2: "LOGISTIC", 36 | 3: "SOFTMAX", 37 | } 38 | 39 | var ActivateType_value = map[string]int32{ 40 | "UNKNOWN": 0, 41 | "RAW": 1, 42 | "LOGISTIC": 2, 43 | "SOFTMAX": 3, 44 | } 45 | 46 | func (x ActivateType) String() string { 47 | return proto.EnumName(ActivateType_name, int32(x)) 48 | } 49 | 50 | func (ActivateType) EnumDescriptor() ([]byte, []int) { 51 | return fileDescriptor_baec3c6aeacf77ef, []int{0} 52 | } 53 | 54 | func init() { 55 | proto.RegisterEnum("protobuf.ActivateType", ActivateType_name, ActivateType_value) 56 | } 57 | 58 | func init() { proto.RegisterFile("activation.proto", fileDescriptor_baec3c6aeacf77ef) } 59 | 60 | var fileDescriptor_baec3c6aeacf77ef = []byte{ 61 | // 132 bytes of a gzipped FileDescriptorProto 62 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x48, 0x4c, 0x2e, 0xc9, 63 | 0x2c, 0x4b, 0x2c, 0xc9, 0xcc, 0xcf, 0xd3, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x00, 0x53, 64 | 0x49, 0xa5, 0x69, 0x5a, 0xf6, 0x5c, 0x3c, 0x8e, 0x10, 0xd9, 0xd4, 0x90, 0xca, 0x82, 0x54, 0x21, 65 | 0x6e, 0x2e, 0xf6, 0x50, 0x3f, 0x6f, 0x3f, 0xff, 0x70, 0x3f, 0x01, 0x06, 0x21, 0x76, 0x2e, 0xe6, 66 | 0x20, 0xc7, 0x70, 0x01, 0x46, 0x21, 0x1e, 0x2e, 0x0e, 0x1f, 0x7f, 0x77, 0xcf, 0xe0, 0x10, 0x4f, 67 | 0x67, 0x01, 0x26, 0x90, 0x9a, 0x60, 0x7f, 0xb7, 0x10, 0x5f, 0xc7, 0x08, 0x01, 0x66, 0x27, 0x81, 68 | 0x13, 0x8f, 0xe4, 0x18, 0x2f, 0x3c, 0x92, 0x63, 0x7c, 0xf0, 0x48, 0x8e, 0x71, 0xc6, 0x63, 0x39, 69 | 0x86, 0x24, 0x36, 0xb0, 0xe1, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf4, 0xa2, 0x98, 0xe6, 70 | 0x77, 0x00, 0x00, 0x00, 71 | } 72 | -------------------------------------------------------------------------------- /protobuf/activation.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package protobuf; 3 | 4 | enum ActivateType { 5 | UNKNOWN = 0; 6 | RAW = 1; 7 | LOGISTIC = 2; 8 | SOFTMAX = 3; 9 | } -------------------------------------------------------------------------------- /protobuf/gen_pb.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "${GOPATH}:." 4 | 5 | protoc \ 6 | --proto_path=${GOPATH}/src/:${GOPATH}/src/github.com/gogo/protobuf/protobuf/:. \ 7 | --gofast_out=. *.proto -------------------------------------------------------------------------------- /test/data/breast_cancer_fmap.txt: -------------------------------------------------------------------------------- 1 | 0 mean_radius q 2 | 1 mean_texture q 3 | 2 mean_perimeter q 4 | 3 mean_area q 5 | 4 mean_smoothness q 6 | 5 mean_compactness q 7 | 6 mean_concavity q 8 | 7 mean_concave_points q 9 | 8 mean_symmetry q 10 | 9 mean_fractal_dimension q 11 | 10 radius_error q 12 | 11 texture_error q 13 | 12 perimeter_error q 14 | 13 area_error q 15 | 14 smoothness_error q 16 | 15 compactness_error q 17 | 16 concavity_error q 18 | 17 concave_points_error q 19 | 18 symmetry_error q 20 | 19 fractal_dimension_error q 21 | 20 worst_radius q 22 | 21 worst_texture q 23 | 22 worst_perimeter q 24 | 23 worst_area q 25 | 24 worst_smoothness q 26 | 25 worst_compactness q 27 | 26 worst_concavity q 28 | 27 worst_concave_points q 29 | 28 worst_symmetry q 30 | 29 worst_fractal_dimension q 31 | 30 target i 32 | -------------------------------------------------------------------------------- /test/data/breast_cancer_test.libsvm: -------------------------------------------------------------------------------- 1 | 0 0:13.4 1:20.52 2:88.64 3:556.7 4:0.1106 5:0.1469 6:0.1445 7:0.08172 8:0.2116 9:0.07325 10:0.3906 11:0.9306 12:3.093 13:33.67 14:0.005414 15:0.02265 16:0.03452 17:0.01334 18:0.01705 19:0.004005 20:16.41 21:29.66 22:113.3 23:844.4 24:0.1574 25:0.3856 26:0.5106000000000001 27:0.2051 28:0.3585 29:0.1109 2 | 1 0:13.21 1:25.25 2:84.09999999999999 3:537.9 4:0.08791 5:0.05205 6:0.02772 7:0.02068 8:0.1619 9:0.05584 10:0.2084 11:1.35 12:1.314 13:17.58 14:0.005768 15:0.008082000000000001 16:0.0151 17:0.006451 18:0.01347 19:0.001828 20:14.35 21:34.23 22:91.29000000000001 23:632.9 24:0.1289 25:0.1063 26:0.139 27:0.06005 28:0.2444 29:0.06788 3 | 1 0:14.02 1:15.66 2:89.59 3:606.5 4:0.07965999999999999 5:0.05581 6:0.02087 7:0.02652 8:0.1589 9:0.05586 10:0.2142 11:0.6549 12:1.606 13:19.25 14:0.004837 15:0.009238 16:0.009213000000000001 17:0.01076 18:0.01171 19:0.002104 20:14.91 21:19.31 22:96.53 23:688.9 24:0.1034 25:0.1017 26:0.0626 27:0.08216 28:0.2136 29:0.06710000000000001 4 | 1 0:14.26 1:18.17 2:91.22 3:633.1 4:0.06576 5:0.0522 6:0.02475 7:0.01374 8:0.1635 9:0.05586 10:0.23 11:0.669 12:1.661 13:20.56 14:0.003169 15:0.01377 16:0.01079 17:0.005243 18:0.01103 19:0.001957 20:16.22 21:25.26 22:105.8 23:819.7 24:0.09445000000000001 25:0.2167 26:0.1565 27:0.07530000000000001 28:0.2636 29:0.07675999999999999 5 | 1 0:13.03 1:18.42 2:82.61 3:523.8 4:0.08982999999999999 5:0.03766 6:0.02562 7:0.02923 8:0.1467 9:0.05863 10:0.1839 11:2.342 12:1.17 13:14.16 14:0.004352 15:0.004899 16:0.01343 17:0.01164 18:0.02671 19:0.001777 20:13.3 21:22.81 22:84.45999999999999 23:545.9 24:0.09701 25:0.04619 26:0.04833 27:0.05013 28:0.1987 29:0.06169 6 | 1 0:11.34 1:18.61 2:72.76000000000001 3:391.2 4:0.1049 5:0.08499 6:0.04302 7:0.02594 8:0.1927 9:0.06211 10:0.243 11:1.01 12:1.491 13:18.19 14:0.008577 15:0.01641 16:0.02099 17:0.01107 18:0.02434 19:0.001217 20:12.47 21:23.03 22:79.15000000000001 23:478.6 24:0.1483 25:0.1574 26:0.1624 27:0.08542 28:0.306 29:0.06783 7 | 1 0:12.05 1:22.72 2:78.75 3:447.8 4:0.06934999999999999 5:0.1073 6:0.07943 7:0.02978 8:0.1203 9:0.06659 10:0.1194 11:1.434 12:1.778 13:9.548999999999999 14:0.005042 15:0.0456 16:0.04305 17:0.01667 18:0.0247 19:0.007358 20:12.57 21:28.71 22:87.36 23:488.4 24:0.08799 25:0.3214 26:0.2912 27:0.1092 28:0.2191 29:0.09349 8 | 1 0:11.7 1:19.11 2:74.33 3:418.7 4:0.08814 5:0.05253 6:0.01583 7:0.01148 8:0.1936 9:0.06128 10:0.1601 11:1.43 12:1.109 13:11.28 14:0.006064 15:0.00911 16:0.01042 17:0.007638 18:0.02349 19:0.001661 20:12.61 21:26.55 22:80.92 23:483.1 24:0.1223 25:0.1087 26:0.07915 27:0.05741 28:0.3487 29:0.06958 9 | 1 0:7.729 1:25.49 2:47.98 3:178.8 4:0.08098 5:0.04878 8:0.187 9:0.07285 10:0.3777 11:1.462 12:2.492 13:19.14 14:0.01266 15:0.009691999999999999 18:0.02882 19:0.006872 20:9.077 21:30.92 22:57.17 23:248 24:0.1256 25:0.0834 28:0.3058 29:0.09938 10 | 1 0:10.26 1:14.71 2:66.2 3:321.6 4:0.09882000000000001 5:0.09159 6:0.03581 7:0.02037 8:0.1633 9:0.07005 10:0.338 11:2.509 12:2.394 13:19.33 14:0.01736 15:0.04671 16:0.02611 17:0.01296 18:0.03675 19:0.006758 20:10.88 21:19.48 22:70.89 23:357.1 24:0.136 25:0.1636 26:0.07162 27:0.04074 28:0.2434 29:0.08488 11 | 1 0:14.69 1:13.98 2:98.22 3:656.1 4:0.1031 5:0.1836 6:0.145 7:0.063 8:0.2086 9:0.07406 10:0.5462 11:1.511 12:4.795 13:49.45 14:0.009976 15:0.05244 16:0.05278 17:0.0158 18:0.02653 19:0.005444 20:16.46 21:18.34 22:114.1 23:809.2 24:0.1312 25:0.3635 26:0.3219 27:0.1108 28:0.2827 29:0.09208 12 | 1 0:14.62 1:24.02 2:94.56999999999999 3:662.7 4:0.08974 5:0.08606 6:0.03102 7:0.02957 8:0.1685 9:0.05866 10:0.3721 11:1.111 12:2.279 13:33.76 14:0.004868 15:0.01818 16:0.01121 17:0.008606000000000001 18:0.02085 19:0.002893 20:16.11 21:29.11 22:102.9 23:803.7 24:0.1115 25:0.1766 26:0.09189 27:0.06945999999999999 28:0.2522 29:0.07246 13 | 1 0:9.397 1:21.68 2:59.75 3:268.8 4:0.07969 5:0.06053 6:0.03735 7:0.005128 8:0.1274 9:0.06723999999999999 10:0.1186 11:1.182 12:1.174 13:6.802 14:0.005515 15:0.02674 16:0.03735 17:0.005128 18:0.01951 19:0.004583 20:9.965 21:27.99 22:66.61 23:301 24:0.1086 25:0.1887 26:0.1868 27:0.02564 28:0.2376 29:0.09206 14 | 1 0:16.84 1:19.46 2:108.4 3:880.2 4:0.07445 5:0.07223 6:0.0515 7:0.02771 8:0.1844 9:0.05268 10:0.4789 11:2.06 12:3.479 13:46.61 14:0.003443 15:0.02661 16:0.03056 17:0.0111 18:0.0152 19:0.001519 20:18.22 21:28.07 22:120.3 23:1032 24:0.08774 25:0.171 26:0.1882 27:0.08436 28:0.2527 29:0.05972 15 | 1 0:14.64 1:15.24 2:95.77 3:651.9 4:0.1132 5:0.1339 6:0.09966 7:0.07063999999999999 8:0.2116 9:0.06346 10:0.5115 11:0.7372 12:3.814 13:42.76 14:0.005508 15:0.04412 16:0.04436 17:0.01623 18:0.02427 19:0.004841 20:16.34 21:18.24 22:109.4 23:803.6 24:0.1277 25:0.3089 26:0.2604 27:0.1397 28:0.3151 29:0.08473 16 | 0 0:15.46 1:11.89 2:102.5 3:736.9 4:0.1257 5:0.1555 6:0.2032 7:0.1097 8:0.1966 9:0.07069 10:0.4209 11:0.6583 12:2.805 13:44.64 14:0.005393 15:0.02321 16:0.04303 17:0.0132 18:0.01792 19:0.004168 20:18.79 21:17.04 22:125 23:1102 24:0.1531 25:0.3583 26:0.583 27:0.1827 28:0.3216 29:0.101 17 | 1 0:9.042 1:18.9 2:60.07 3:244.5 4:0.09968 5:0.1972 6:0.1975 7:0.04908 8:0.233 9:0.08742999999999999 10:0.4653 11:1.911 12:3.769 13:24.2 14:0.009845 15:0.0659 16:0.1027 17:0.02527 18:0.03491 19:0.007877 20:10.06 21:23.4 22:68.62 23:297.1 24:0.1221 25:0.3748 26:0.4609 27:0.1145 28:0.3135 29:0.1055 18 | 0 0:20.51 1:27.81 2:134.4 3:1319 4:0.09159 5:0.1074 6:0.1554 7:0.0834 8:0.1448 9:0.05592 10:0.524 11:1.189 12:3.767 13:70.01000000000001 14:0.00502 15:0.02062 16:0.03457 17:0.01091 18:0.01298 19:0.002887 20:24.47 21:37.38 22:162.7 23:1872 24:0.1223 25:0.2761 26:0.4146 27:0.1563 28:0.2437 29:0.08328000000000001 19 | 0 0:19.55 1:23.21 2:128.9 3:1174 4:0.101 5:0.1318 6:0.1856 7:0.1021 8:0.1989 9:0.05884 10:0.6107 11:2.836 12:5.383 13:70.09999999999999 14:0.01124 15:0.04097 16:0.07469000000000001 17:0.03441 18:0.02768 19:0.00624 20:20.82 21:30.44 22:142 23:1313 24:0.1251 25:0.2414 26:0.3829 27:0.1825 28:0.2576 29:0.07602 20 | 0 0:20.94 1:23.56 2:138.9 3:1364 4:0.1007 5:0.1606 6:0.2712 7:0.131 8:0.2205 9:0.05898 10:1.004 11:0.8208 12:6.372 13:137.9 14:0.005283 15:0.03908 16:0.09518 17:0.01864 18:0.02401 19:0.005002 20:25.58 21:27 22:165.3 23:2010 24:0.1211 25:0.3172 26:0.6991000000000001 27:0.2105 28:0.3126 29:0.07849 21 | 0 0:11.84 1:18.7 2:77.93000000000001 3:440.6 4:0.1109 5:0.1516 6:0.1218 7:0.05182 8:0.2301 9:0.07799 10:0.4825 11:1.03 12:3.475 13:41 14:0.005551 15:0.03414 16:0.04205 17:0.01044 18:0.02273 19:0.005667 20:16.82 21:28.12 22:119.4 23:888.7 24:0.1637 25:0.5775 26:0.6956 27:0.1546 28:0.4761 29:0.1402 22 | 0 0:16.24 1:18.77 2:108.8 3:805.1 4:0.1066 5:0.1802 6:0.1948 7:0.09052 8:0.1876 9:0.06684 10:0.2873 11:0.9173 12:2.464 13:28.09 14:0.004563 15:0.03481 16:0.03872 17:0.01209 18:0.01388 19:0.004081 20:18.55 21:25.09 22:126.9 23:1031 24:0.1365 25:0.4706 26:0.5026 27:0.1732 28:0.277 29:0.1063 23 | 1 0:13.47 1:14.06 2:87.31999999999999 3:546.3 4:0.1071 5:0.1155 6:0.05786 7:0.05266 8:0.1779 9:0.06639 10:0.1588 11:0.5733 12:1.102 13:12.84 14:0.00445 15:0.01452 16:0.01334 17:0.008791 18:0.01698 19:0.002787 20:14.83 21:18.32 22:94.94 23:660.2 24:0.1393 25:0.2499 26:0.1848 27:0.1335 28:0.3227 29:0.09326 24 | 1 0:11.84 1:18.94 2:75.51000000000001 3:428 4:0.08871 5:0.06900000000000001 6:0.02669 7:0.01393 8:0.1533 9:0.06057 10:0.2222 11:0.8652 12:1.444 13:17.12 14:0.005517 15:0.01727 16:0.02045 17:0.006747 18:0.01616 19:0.002922 20:13.3 21:24.99 22:85.22 23:546.3 24:0.128 25:0.188 26:0.1471 27:0.06913 28:0.2535 29:0.07993 25 | 0 0:21.37 1:15.1 2:141.3 3:1386 4:0.1001 5:0.1515 6:0.1932 7:0.1255 8:0.1973 9:0.06183 10:0.3414 11:1.309 12:2.407 13:39.06 14:0.004426 15:0.02675 16:0.03437 17:0.01343 18:0.01675 19:0.004367 20:22.69 21:21.84 22:152.1 23:1535 24:0.1192 25:0.284 26:0.4024 27:0.1966 28:0.273 29:0.08666 26 | 1 0:11.93 1:10.91 2:76.14 3:442.7 4:0.08871999999999999 5:0.05242 6:0.02606 7:0.01796 8:0.1601 9:0.05541 10:0.2522 11:1.045 12:1.649 13:18.95 14:0.006175 15:0.01204 16:0.01376 17:0.005832 18:0.01096 19:0.001857 20:13.8 21:20.14 22:87.64 23:589.5 24:0.1374 25:0.1575 26:0.1514 27:0.06876 28:0.246 29:0.07262 27 | 1 0:10.9 1:12.96 2:68.69 3:366.8 4:0.07514999999999999 5:0.03718 6:0.00309 7:0.006588 8:0.1442 9:0.05743 10:0.2818 11:0.7614 12:1.808 13:18.54 14:0.006142 15:0.006134 16:0.001835 17:0.003576 18:0.01637 19:0.002665 20:12.36 21:18.2 22:78.06999999999999 23:470 24:0.1171 25:0.08294 26:0.01854 27:0.03953 28:0.2738 29:0.07685 28 | 0 0:13.73 1:22.61 2:93.59999999999999 3:578.3 4:0.1131 5:0.2293 6:0.2128 7:0.08025 8:0.2069 9:0.07682 10:0.2121 11:1.169 12:2.061 13:19.21 14:0.006429 15:0.05936 16:0.05501 17:0.01628 18:0.01961 19:0.008092999999999999 20:15.03 21:32.01 22:108.8 23:697.7 24:0.1651 25:0.7725 26:0.6943 27:0.2208 28:0.3596 29:0.1431 29 | 1 0:13.4 1:16.95 2:85.48 3:552.4 4:0.07937 5:0.05696 6:0.02181 7:0.01473 8:0.165 9:0.05701 10:0.1584 11:0.6124000000000001 12:1.036 13:13.22 14:0.004394 15:0.0125 16:0.01451 17:0.005484 18:0.01291 19:0.002074 20:14.73 21:21.7 22:93.76000000000001 23:663.5 24:0.1213 25:0.1676 26:0.1364 27:0.06987 28:0.2741 29:0.07582 30 | 0 0:18.77 1:21.43 2:122.9 3:1092 4:0.09116 5:0.1402 6:0.106 7:0.0609 8:0.1953 9:0.06083 10:0.6422 11:1.53 12:4.369 13:88.25 14:0.007548 15:0.03897 16:0.03914 17:0.01816 18:0.02168 19:0.004445 20:24.54 21:34.37 22:161.1 23:1873 24:0.1498 25:0.4827 26:0.4634 27:0.2048 28:0.3679 29:0.0987 31 | 1 0:12.81 1:13.06 2:81.29000000000001 3:508.8 4:0.08739 5:0.03774 6:0.009193 7:0.0133 8:0.1466 9:0.06133 10:0.2889 11:0.9899 12:1.778 13:21.79 14:0.008534 15:0.006364 16:0.00618 17:0.007408 18:0.01065 19:0.003351 20:13.63 21:16.15 22:86.7 23:570.7 24:0.1162 25:0.05445 26:0.02758 27:0.0399 28:0.1783 29:0.07319000000000001 32 | 0 0:20.57 1:17.77 2:132.9 3:1326 4:0.08474 5:0.07864 6:0.08690000000000001 7:0.07017 8:0.1812 9:0.05667 10:0.5435 11:0.7339 12:3.398 13:74.08 14:0.005225 15:0.01308 16:0.0186 17:0.0134 18:0.01389 19:0.003532 20:24.99 21:23.41 22:158.8 23:1956 24:0.1238 25:0.1866 26:0.2416 27:0.186 28:0.275 29:0.08902 33 | 1 0:13.14 1:20.74 2:85.98 3:536.9 4:0.08674999999999999 5:0.1089 6:0.1085 7:0.0351 8:0.1562 9:0.0602 10:0.3152 11:0.7884 12:2.312 13:27.4 14:0.007295 15:0.03179 16:0.04615 17:0.01254 18:0.01561 19:0.00323 20:14.8 21:25.46 22:100.9 23:689.1 24:0.1351 25:0.3549 26:0.4504 27:0.1181 28:0.2563 29:0.08173999999999999 34 | 0 0:16.16 1:21.54 2:106.2 3:809.8 4:0.1008 5:0.1284 6:0.1043 7:0.05613 8:0.216 9:0.05891 10:0.4332 11:1.265 12:2.844 13:43.68 14:0.004877 15:0.01952 16:0.02219 17:0.009231 18:0.01535 19:0.002373 20:19.47 21:31.68 22:129.7 23:1175 24:0.1395 25:0.3055 26:0.2992 27:0.1312 28:0.348 29:0.07618999999999999 35 | 1 0:9.738 1:11.97 2:61.24 3:288.5 4:0.0925 5:0.04102 8:0.1903 9:0.06422 10:0.1988 11:0.496 12:1.218 13:12.26 14:0.00604 15:0.005656 18:0.02277 19:0.00322 20:10.62 21:14.1 22:66.53 23:342.9 24:0.1234 25:0.07204000000000001 28:0.3105 29:0.08151 36 | 0 0:12.68 1:23.84 2:82.69 3:499 4:0.1122 5:0.1262 6:0.1128 7:0.06873 8:0.1905 9:0.0659 10:0.4255 11:1.178 12:2.927 13:36.46 14:0.007781 15:0.02648 16:0.02973 17:0.0129 18:0.01635 19:0.003601 20:17.09 21:33.47 22:111.8 23:888.3 24:0.1851 25:0.4061 26:0.4024 27:0.1716 28:0.3383 29:0.1031 37 | 1 0:13.27 1:17.02 2:84.55 3:546.4 4:0.08445 5:0.04994 6:0.03554 7:0.02456 8:0.1496 9:0.05674 10:0.2927 11:0.8907 12:2.044 13:24.68 14:0.006032 15:0.01104 16:0.02259 17:0.009057000000000001 18:0.01482 19:0.002496 20:15.14 21:23.6 22:98.84 23:708.8 24:0.1276 25:0.1311 26:0.1786 27:0.09678 28:0.2506 29:0.07623000000000001 38 | 0 0:19 1:18.91 2:123.4 3:1138 4:0.08217000000000001 5:0.08028 6:0.09271 7:0.05627 8:0.1946 9:0.05044 10:0.6896 11:1.342 12:5.216 13:81.23 14:0.004428 15:0.02731 16:0.0404 17:0.01361 18:0.0203 19:0.002686 20:22.32 21:25.73 22:148.2 23:1538 24:0.1021 25:0.2264 26:0.3207 27:0.1218 28:0.2841 29:0.06541 39 | 1 0:14.86 1:16.94 2:94.89 3:673.7 4:0.08924 5:0.07074 6:0.03346 7:0.02877 8:0.1573 9:0.05703 10:0.3028 11:0.6683 12:1.612 13:23.92 14:0.005756 15:0.01665 16:0.01461 17:0.008281 18:0.01551 19:0.002168 20:16.31 21:20.54 22:102.3 23:777.5 24:0.1218 25:0.155 26:0.122 27:0.07971 28:0.2525 29:0.06827 40 | 0 0:15.08 1:25.74 2:98 3:716.6 4:0.1024 5:0.09769 6:0.1235 7:0.06553 8:0.1647 9:0.06464 10:0.6534 11:1.506 12:4.174 13:63.37 14:0.01052 15:0.02431 16:0.04912 17:0.01746 18:0.0212 19:0.004867 20:18.51 21:33.22 22:121.2 23:1050 24:0.166 25:0.2356 26:0.4029 27:0.1526 28:0.2654 29:0.09438000000000001 41 | 0 0:15.13 1:29.81 2:96.70999999999999 3:719.5 4:0.0832 5:0.04605 6:0.04686 7:0.02739 8:0.1852 9:0.05294 10:0.4681 11:1.627 12:3.043 13:45.38 14:0.006831 15:0.01427 16:0.02489 17:0.009087 18:0.03151 19:0.00175 20:17.26 21:36.91 22:110.1 23:931.4 24:0.1148 25:0.09866 26:0.1547 27:0.06575 28:0.3233 29:0.06165 42 | 1 0:8.878 1:15.49 2:56.74 3:241 4:0.08293 5:0.07698000000000001 6:0.04721 7:0.02381 8:0.193 9:0.06621 10:0.5381 11:1.2 12:4.277 13:30.18 14:0.01093 15:0.02899 16:0.03214 17:0.01506 18:0.02837 19:0.004174 20:9.981 21:17.7 22:65.27 23:302 24:0.1015 25:0.1248 26:0.09440999999999999 27:0.04762 28:0.2434 29:0.07431 43 | 0 0:16.02 1:23.24 2:102.7 3:797.8 4:0.08205999999999999 5:0.06669 6:0.03299 7:0.03323 8:0.1528 9:0.05697 10:0.3795 11:1.187 12:2.466 13:40.51 14:0.004029 15:0.009268999999999999 16:0.01101 17:0.007591 18:0.0146 19:0.003042 20:19.19 21:33.88 22:123.8 23:1150 24:0.1181 25:0.1551 26:0.1459 27:0.09975000000000001 28:0.2948 29:0.08452 44 | 1 0:10.32 1:16.35 2:65.31 3:324.9 4:0.09433999999999999 5:0.04994 6:0.01012 7:0.005495 8:0.1885 9:0.06201 10:0.2104 11:0.967 12:1.356 13:12.97 14:0.007086 15:0.007247 16:0.01012 17:0.005495 18:0.0156 19:0.002606 20:11.25 21:21.77 22:71.12 23:384.9 24:0.1285 25:0.08842 26:0.04384 27:0.02381 28:0.2681 29:0.07399 45 | 1 0:13.24 1:20.13 2:86.87 3:542.9 4:0.08284 5:0.1223 6:0.101 7:0.02833 8:0.1601 9:0.06432 10:0.281 11:0.8135 12:3.369 13:23.81 14:0.004929 15:0.06657 16:0.07683 17:0.01368 18:0.01526 19:0.008133 20:15.44 21:25.5 22:115 23:733.5 24:0.1201 25:0.5646 26:0.6556 27:0.1357 28:0.2845 29:0.1249 46 | 0 0:21.56 1:22.39 2:142 3:1479 4:0.111 5:0.1159 6:0.2439 7:0.1389 8:0.1726 9:0.05623 10:1.176 11:1.256 12:7.673 13:158.7 14:0.0103 15:0.02891 16:0.05198 17:0.02454 18:0.01114 19:0.004239 20:25.45 21:26.4 22:166.1 23:2027 24:0.141 25:0.2113 26:0.4107 27:0.2216 28:0.206 29:0.07115 47 | 1 0:8.670999999999999 1:14.45 2:54.42 3:227.2 4:0.09138 5:0.04276 8:0.1722 9:0.06723999999999999 10:0.2204 11:0.7873 12:1.435 13:11.36 14:0.009172 15:0.008007 18:0.02711 19:0.003399 20:9.262 21:17.04 22:58.36 23:259.2 24:0.1162 25:0.07056999999999999 28:0.2592 29:0.07847999999999999 48 | 1 0:14.03 1:21.25 2:89.79000000000001 3:603.4 4:0.0907 5:0.06945 6:0.01462 7:0.01896 8:0.1517 9:0.05835 10:0.2589 11:1.503 12:1.667 13:22.07 14:0.007389 15:0.01383 16:0.007302 17:0.01004 18:0.01263 19:0.002925 20:15.33 21:30.28 22:98.27 23:715.5 24:0.1287 25:0.1513 26:0.06231 27:0.07963000000000001 28:0.2226 29:0.07617 49 | 1 0:11.81 1:17.39 2:75.27 3:428.9 4:0.1007 5:0.05562 6:0.02353 7:0.01553 8:0.1718 9:0.0578 10:0.1859 11:1.926 12:1.011 13:14.47 14:0.007830999999999999 15:0.008776000000000001 16:0.01556 17:0.00624 18:0.03139 19:0.001988 20:12.57 21:26.48 22:79.56999999999999 23:489.5 24:0.1356 25:0.1 26:0.08803 27:0.04306 28:0.32 29:0.06576 50 | 0 0:14.54 1:27.54 2:96.73 3:658.8 4:0.1139 5:0.1595 6:0.1639 7:0.07364 8:0.2303 9:0.07077 10:0.37 11:1.033 12:2.879 13:32.55 14:0.005607 15:0.0424 16:0.04741 17:0.0109 18:0.01857 19:0.005466 20:17.46 21:37.13 22:124.1 23:943.2 24:0.1678 25:0.6577 26:0.7026 27:0.1712 28:0.4218 29:0.1341 51 | 0 0:19.17 1:24.8 2:132.4 3:1123 4:0.0974 5:0.2458 6:0.2065 7:0.1118 8:0.2397 9:0.078 10:0.9555 11:3.568 12:11.07 13:116.2 14:0.003139 15:0.08297 16:0.08890000000000001 17:0.0409 18:0.04484 19:0.01284 20:20.96 21:29.94 22:151.7 23:1332 24:0.1037 25:0.3903 26:0.3639 27:0.1767 28:0.3176 29:0.1023 52 | 0 0:14.86 1:23.21 2:100.4 3:671.4 4:0.1044 5:0.198 6:0.1697 7:0.08878 8:0.1737 9:0.06672 10:0.2796 11:0.9622000000000001 12:3.591 13:25.2 14:0.008081 15:0.05122 16:0.05551 17:0.01883 18:0.02545 19:0.004312 20:16.08 21:27.78 22:118.6 23:784.7 24:0.1316 25:0.4648 26:0.4589 27:0.1727 28:0.3 29:0.08701 53 | 0 0:18.45 1:21.91 2:120.2 3:1075 4:0.09429999999999999 5:0.09709 6:0.1153 7:0.06847 8:0.1692 9:0.05727 10:0.5959 11:1.202 12:3.766 13:68.34999999999999 14:0.006001 15:0.01422 16:0.02855 17:0.009148 18:0.01492 19:0.002205 20:22.52 21:31.39 22:145.6 23:1590 24:0.1465 25:0.2275 26:0.3965 27:0.1379 28:0.3109 29:0.0761 54 | 1 0:11.6 1:18.36 2:73.88 3:412.7 4:0.08508 5:0.05855 6:0.03367 7:0.01777 8:0.1516 9:0.05859 10:0.1816 11:0.7655999999999999 12:1.303 13:12.89 14:0.006709 15:0.01701 16:0.0208 17:0.007497 18:0.02124 19:0.002768 20:12.77 21:24.02 22:82.68000000000001 23:495.1 24:0.1342 25:0.1808 26:0.186 27:0.08288 28:0.321 29:0.07863000000000001 55 | 1 0:12.46 1:19.89 2:80.43000000000001 3:471.3 4:0.08451 5:0.1014 6:0.0683 7:0.03099 8:0.1781 9:0.06249 10:0.3642 11:1.04 12:2.579 13:28.32 14:0.00653 15:0.03369 16:0.04712 17:0.01403 18:0.0274 19:0.004651 20:13.46 21:23.07 22:88.13 23:551.3 24:0.105 25:0.2158 26:0.1904 27:0.07625 28:0.2685 29:0.07764 56 | 1 0:11.47 1:16.03 2:73.02 3:402.7 4:0.09075999999999999 5:0.05886 6:0.02587 7:0.02322 8:0.1634 9:0.06372 10:0.1707 11:0.7615 12:1.09 13:12.25 14:0.009191 15:0.008548 16:0.0094 17:0.006315 18:0.01755 19:0.003009 20:12.51 21:20.79 22:79.67 23:475.8 24:0.1531 25:0.112 26:0.09823 27:0.06548 28:0.2851 29:0.08763 57 | 1 0:11.32 1:27.08 2:71.76000000000001 3:395.7 4:0.06883 5:0.03813 6:0.01633 7:0.003125 8:0.1869 9:0.05628 10:0.121 11:0.8927 12:1.059 13:8.605 14:0.003653 15:0.01647 16:0.01633 17:0.003125 18:0.01537 19:0.002052 20:12.08 21:33.75 22:79.81999999999999 23:452.3 24:0.09203 25:0.1432 26:0.1089 27:0.02083 28:0.2849 29:0.07087 58 | 1 0:12.27 1:29.97 2:77.42 3:465.4 4:0.07699 5:0.03398 8:0.1701 9:0.0596 10:0.4455 11:3.647 12:2.884 13:35.13 14:0.007339 15:0.008243 18:0.03141 19:0.003136 20:13.45 21:38.05 22:85.08 23:558.9 24:0.09422 25:0.05213 28:0.2409 29:0.06743 59 | 1 0:12.18 1:20.52 2:77.22 3:458.7 4:0.08013000000000001 5:0.04038 6:0.02383 7:0.0177 8:0.1739 9:0.05677 10:0.1924 11:1.571 12:1.183 13:14.68 14:0.00508 15:0.006098 16:0.01069 17:0.006797 18:0.01447 19:0.001532 20:13.34 21:32.84 22:84.58 23:547.8 24:0.1123 25:0.08862 26:0.1145 27:0.07431 28:0.2694 29:0.06877999999999999 60 | 0 0:21.75 1:20.99 2:147.3 3:1491 4:0.09401 5:0.1961 6:0.2195 7:0.1088 8:0.1721 9:0.06194 10:1.167 11:1.352 12:8.867000000000001 13:156.8 14:0.005687 15:0.0496 16:0.06329 17:0.01561 18:0.01924 19:0.004614 20:28.19 21:28.18 22:195.9 23:2384 24:0.1272 25:0.4725 26:0.5807 27:0.1841 28:0.2833 29:0.08858000000000001 61 | 0 0:13.77 1:22.29 2:90.63 3:588.9 4:0.12 5:0.1267 6:0.1385 7:0.06526 8:0.1834 9:0.06877 10:0.6191 11:2.112 12:4.906 13:49.7 14:0.0138 15:0.03348 16:0.04665 17:0.0206 18:0.02689 19:0.004306 20:16.39 21:34.01 22:111.6 23:806.9 24:0.1737 25:0.3122 26:0.3809 27:0.1673 28:0.308 29:0.09333 62 | 0 0:16.07 1:19.65 2:104.1 3:817.7 4:0.09168 5:0.08424 6:0.09769 7:0.06637999999999999 8:0.1798 9:0.05391 10:0.7474 11:1.016 12:5.029 13:79.25 14:0.01082 15:0.02203 16:0.035 17:0.01809 18:0.0155 19:0.001948 20:19.77 21:24.56 22:128.8 23:1223 24:0.15 25:0.2045 26:0.2829 27:0.152 28:0.265 29:0.06387 63 | 1 0:11.14 1:14.07 2:71.23999999999999 3:384.6 4:0.07274 5:0.06064 6:0.04505 7:0.01471 8:0.169 9:0.06083 10:0.4222 11:0.8092 12:3.33 13:28.84 14:0.005541 15:0.03387 16:0.04505 17:0.01471 18:0.03102 19:0.004831 20:12.12 21:15.82 22:79.62 23:453.5 24:0.08864 25:0.1256 26:0.1201 27:0.03922 28:0.2576 29:0.07018000000000001 64 | 1 0:12.87 1:16.21 2:82.38 3:512.2 4:0.09425 5:0.06219 6:0.039 7:0.01615 8:0.201 9:0.05769 10:0.2345 11:1.219 12:1.546 13:18.24 14:0.005518 15:0.02178 16:0.02589 17:0.00633 18:0.02593 19:0.002157 20:13.9 21:23.64 22:89.27 23:597.5 24:0.1256 25:0.1808 26:0.1992 27:0.0578 28:0.3604 29:0.07062 65 | 0 0:17.6 1:23.33 2:119 3:980.5 4:0.09289 5:0.2004 6:0.2136 7:0.1002 8:0.1696 9:0.07369000000000001 10:0.9288999999999999 11:1.465 12:5.801 13:104.9 14:0.006766 15:0.07025000000000001 16:0.06591 17:0.02311 18:0.01673 19:0.0113 20:21.57 21:28.87 22:143.6 23:1437 24:0.1207 25:0.4785 26:0.5165 27:0.1996 28:0.2301 29:0.1224 66 | 1 0:12.04 1:28.14 2:76.84999999999999 3:449.9 4:0.08752 5:0.06 6:0.02367 7:0.02377 8:0.1854 9:0.05698 10:0.6061 11:2.643 12:4.099 13:44.96 14:0.007517 15:0.01555 16:0.01465 17:0.01183 18:0.02047 19:0.003883 20:13.6 21:33.33 22:87.23999999999999 23:567.6 24:0.1041 25:0.09726 26:0.05524 27:0.05547 28:0.2404 29:0.06639 67 | 0 0:22.27 1:19.67 2:152.8 3:1509 4:0.1326 5:0.2768 6:0.4264 7:0.1823 8:0.2556 9:0.07038999999999999 10:1.215 11:1.545 12:10.05 13:170 14:0.006515 15:0.08667999999999999 16:0.104 17:0.0248 18:0.03112 19:0.005037 20:28.4 21:28.01 22:206.8 23:2360 24:0.1701 25:0.6997 26:0.9608 27:0.291 28:0.4055 29:0.09789 68 | 0 0:17.46 1:39.28 2:113.4 3:920.6 4:0.09812 5:0.1298 6:0.1417 7:0.08810999999999999 8:0.1809 9:0.05966 10:0.5366 11:0.8561 12:3.002 13:49 14:0.00486 15:0.02785 16:0.02602 17:0.01374 18:0.01226 19:0.002759 20:22.51 21:44.87 22:141.2 23:1408 24:0.1365 25:0.3735 26:0.3241 27:0.2066 28:0.2853 29:0.08495999999999999 69 | 0 0:20.58 1:22.14 2:134.7 3:1290 4:0.09089999999999999 5:0.1348 6:0.164 7:0.09561 8:0.1765 9:0.05024 10:0.8601 11:1.48 12:7.029 13:111.7 14:0.008123999999999999 15:0.03611 16:0.05489 17:0.02765 18:0.03176 19:0.002365 20:23.24 21:27.84 22:158.3 23:1656 24:0.1178 25:0.292 26:0.3861 27:0.192 28:0.2909 29:0.05865 70 | 1 0:9.465 1:21.01 2:60.11 3:269.4 4:0.1044 5:0.07772999999999999 6:0.02172 7:0.01504 8:0.1717 9:0.06899 10:0.2351 11:2.011 12:1.66 13:14.2 14:0.01052 15:0.01755 16:0.01714 17:0.009332999999999999 18:0.02279 19:0.004237 20:10.41 21:31.56 22:67.03 23:330.7 24:0.1548 25:0.1664 26:0.09412 27:0.06517000000000001 28:0.2878 29:0.09211 71 | 1 0:14.42 1:16.54 2:94.15000000000001 3:641.2 4:0.09751 5:0.1139 6:0.08007 7:0.04223 8:0.1912 9:0.06412 10:0.3491 11:0.7706 12:2.677 13:32.14 14:0.004577 15:0.03053 16:0.0384 17:0.01243 18:0.01873 19:0.003373 20:16.67 21:21.51 22:111.4 23:862.1 24:0.1294 25:0.3371 26:0.3755 27:0.1414 28:0.3053 29:0.08764 72 | 0 0:16.13 1:20.68 2:108.1 3:798.8 4:0.117 5:0.2022 6:0.1722 7:0.1028 8:0.2164 9:0.07356 10:0.5692 11:1.073 12:3.854 13:54.18 14:0.007026 15:0.02501 16:0.03188 17:0.01297 18:0.01689 19:0.004142 20:20.96 21:31.48 22:136.8 23:1315 24:0.1789 25:0.4233 26:0.4784 27:0.2073 28:0.3706 29:0.1142 73 | 1 0:11.52 1:14.93 2:73.87 3:406.3 4:0.1013 5:0.07808 6:0.04328 7:0.02929 8:0.1883 9:0.06168 10:0.2562 11:1.038 12:1.686 13:18.62 14:0.006662 15:0.01228 16:0.02105 17:0.01006 18:0.01677 19:0.002784 20:12.65 21:21.19 22:80.88 23:491.8 24:0.1389 25:0.1582 26:0.1804 27:0.09608 28:0.2664 29:0.07809000000000001 74 | 0 0:14.6 1:23.29 2:93.97 3:664.7 4:0.08681999999999999 5:0.06636 6:0.0839 7:0.05271 8:0.1627 9:0.05416 10:0.4157 11:1.627 12:2.914 13:33.01 14:0.008312 15:0.01742 16:0.03389 17:0.01576 18:0.0174 19:0.002871 20:15.79 21:31.71 22:102.2 23:758.2 24:0.1312 25:0.1581 26:0.2675 27:0.1359 28:0.2477 29:0.06836 75 | 0 0:18.65 1:17.6 2:123.7 3:1076 4:0.1099 5:0.1686 6:0.1974 7:0.1009 8:0.1907 9:0.06049 10:0.6289 11:0.6633 12:4.293 13:71.56 14:0.006294 15:0.03994 16:0.05554 17:0.01695 18:0.02428 19:0.003535 20:22.82 21:21.32 22:150.6 23:1567 24:0.1679 25:0.509 26:0.7345 27:0.2378 28:0.3799 29:0.09185 76 | 1 0:13 1:25.13 2:82.61 3:520.2 4:0.08369 5:0.05073 6:0.01206 7:0.01762 8:0.1667 9:0.05449 10:0.2621 11:1.232 12:1.657 13:21.19 14:0.006054 15:0.008973999999999999 16:0.005681 17:0.006336 18:0.01215 19:0.001514 20:14.34 21:31.88 22:91.06 23:628.5 24:0.1218 25:0.1093 26:0.04462 27:0.05921 28:0.2306 29:0.06290999999999999 77 | 1 0:8.571 1:13.1 2:54.53 3:221.3 4:0.1036 5:0.07632 6:0.02565 7:0.0151 8:0.1678 9:0.07126 10:0.1267 11:0.6793 12:1.069 13:7.254 14:0.007897 15:0.01762 16:0.01801 17:0.00732 18:0.01592 19:0.003925 20:9.473000000000001 21:18.45 22:63.3 23:275.6 24:0.1641 25:0.2235 26:0.1754 27:0.08512 28:0.2983 29:0.1049 78 | 1 0:13.05 1:18.59 2:85.09 3:512 4:0.1082 5:0.1304 6:0.09603 7:0.05603 8:0.2035 9:0.06501 10:0.3106 11:1.51 12:2.59 13:21.57 14:0.007807 15:0.03932 16:0.05112 17:0.01876 18:0.0286 19:0.005715 20:14.19 21:24.85 22:94.22 23:591.2 24:0.1343 25:0.2658 26:0.2573 27:0.1258 28:0.3113 29:0.08316999999999999 79 | 1 0:11.66 1:17.07 2:73.7 3:421 4:0.07561 5:0.0363 6:0.008305999999999999 7:0.01162 8:0.1671 9:0.05731 10:0.3534 11:0.6724 12:2.225 13:26.03 14:0.006583 15:0.006991 16:0.005949 17:0.006296 18:0.02216 19:0.002668 20:13.28 21:19.74 22:83.61 23:542.5 24:0.09958 25:0.06476 26:0.03046 27:0.04262 28:0.2731 29:0.06825000000000001 80 | 1 0:8.734 1:16.84 2:55.27 3:234.3 4:0.1039 5:0.07428 8:0.1985 9:0.07098 10:0.5169 11:2.079 12:3.167 13:28.85 14:0.01582 15:0.01966 18:0.01865 19:0.006736 20:10.17 21:22.8 22:64.01000000000001 23:317 24:0.146 25:0.131 28:0.2445 29:0.08865000000000001 81 | 0 0:16.6 1:28.08 2:108.3 3:858.1 4:0.08455 5:0.1023 6:0.09251 7:0.05302 8:0.159 9:0.05648 10:0.4564 11:1.075 12:3.425 13:48.55 14:0.005903 15:0.03731 16:0.0473 17:0.01557 18:0.01318 19:0.003892 20:18.98 21:34.12 22:126.7 23:1124 24:0.1139 25:0.3094 26:0.3403 27:0.1418 28:0.2218 29:0.07820000000000001 82 | 0 0:20.18 1:23.97 2:143.7 3:1245 4:0.1286 5:0.3454 6:0.3754 7:0.1604 8:0.2906 9:0.08142000000000001 10:0.9317 11:1.885 12:8.648999999999999 13:116.4 14:0.01038 15:0.06834999999999999 16:0.1091 17:0.02593 18:0.07895000000000001 19:0.005987 20:23.37 21:31.72 22:170.3 23:1623 24:0.1639 25:0.6163999999999999 26:0.7681 27:0.2508 28:0.544 29:0.09964000000000001 83 | 0 0:15.78 1:22.91 2:105.7 3:782.6 4:0.1155 5:0.1752 6:0.2133 7:0.09479 8:0.2096 9:0.07331 10:0.552 11:1.072 12:3.598 13:58.63 14:0.008699 15:0.03976 16:0.0595 17:0.0139 18:0.01495 19:0.005984 20:20.19 21:30.5 22:130.3 23:1272 24:0.1855 25:0.4925 26:0.7356 27:0.2034 28:0.3274 29:0.1252 84 | 1 0:12.43 1:17 2:78.59999999999999 3:477.3 4:0.07557 5:0.03454 6:0.01342 7:0.01699 8:0.1472 9:0.05561 10:0.3778 11:2.2 12:2.487 13:31.16 14:0.007357 15:0.01079 16:0.009959000000000001 17:0.0112 18:0.03433 19:0.002961 20:12.9 21:20.21 22:81.76000000000001 23:515.9 24:0.08409 25:0.04712 26:0.02237 27:0.02832 28:0.1901 29:0.05932 85 | 0 0:16.03 1:15.51 2:105.8 3:793.2 4:0.09490999999999999 5:0.1371 6:0.1204 7:0.07041 8:0.1782 9:0.05976 10:0.3371 11:0.7476 12:2.629 13:33.27 14:0.005839 15:0.03245 16:0.03715 17:0.01459 18:0.01467 19:0.003121 20:18.76 21:21.98 22:124.3 23:1070 24:0.1435 25:0.4478 26:0.4956 27:0.1981 28:0.3019 29:0.09124 86 | 1 0:12.32 1:12.39 2:78.84999999999999 3:464.1 4:0.1028 5:0.06981 6:0.03987 7:0.037 8:0.1959 9:0.05955 10:0.236 11:0.6656 12:1.67 13:17.43 14:0.008045 15:0.0118 16:0.01683 17:0.01241 18:0.01924 19:0.002248 20:13.5 21:15.64 22:86.97 23:549.1 24:0.1385 25:0.1266 26:0.1242 27:0.09390999999999999 28:0.2827 29:0.06771000000000001 87 | 1 0:13.5 1:12.71 2:85.69 3:566.2 4:0.07376000000000001 5:0.03614 6:0.002758 7:0.004419 8:0.1365 9:0.05335 10:0.2244 11:0.6864 12:1.509 13:20.39 14:0.003338 15:0.003746 16:0.00203 17:0.003242 18:0.0148 19:0.001566 20:14.97 21:16.94 22:95.48 23:698.7 24:0.09023 25:0.05836 26:0.01379 27:0.0221 28:0.2267 29:0.06192 88 | 1 0:8.196 1:16.84 2:51.71 3:201.9 4:0.08599999999999999 5:0.05943 6:0.01588 7:0.005917 8:0.1769 9:0.06503 10:0.1563 11:0.9567 12:1.094 13:8.205 14:0.008968 15:0.01646 16:0.01588 17:0.005917 18:0.02574 19:0.002582 20:8.964 21:21.96 22:57.26 23:242.2 24:0.1297 25:0.1357 26:0.0688 27:0.02564 28:0.3105 29:0.07409 89 | 0 0:17.19 1:22.07 2:111.6 3:928.3 4:0.09726 5:0.08995 6:0.09061 7:0.06526999999999999 8:0.1867 9:0.0558 10:0.4203 11:0.7383 12:2.819 13:45.42 14:0.004493 15:0.01206 16:0.02048 17:0.009875 18:0.01144 19:0.001575 20:21.58 21:29.33 22:140.5 23:1436 24:0.1558 25:0.2567 26:0.3889 27:0.1984 28:0.3216 29:0.0757 90 | 0 0:20.6 1:29.33 2:140.1 3:1265 4:0.1178 5:0.277 6:0.3514 7:0.152 8:0.2397 9:0.07016 10:0.726 11:1.595 12:5.772 13:86.22 14:0.006522 15:0.06158 16:0.07117 17:0.01664 18:0.02324 19:0.006185 20:25.74 21:39.42 22:184.6 23:1821 24:0.165 25:0.8681 26:0.9387 27:0.265 28:0.4087 29:0.124 91 | 1 0:9.504 1:12.44 2:60.34 3:273.9 4:0.1024 5:0.06492000000000001 6:0.02956 7:0.02076 8:0.1815 9:0.06905 10:0.2773 11:0.9768 12:1.909 13:15.7 14:0.009606 15:0.01432 16:0.01985 17:0.01421 18:0.02027 19:0.002968 20:10.23 21:15.66 22:65.13 23:314.9 24:0.1324 25:0.1148 26:0.08867 27:0.06227 28:0.245 29:0.07772999999999999 92 | 0 0:15.12 1:16.68 2:98.78 3:716.6 4:0.08876000000000001 5:0.09588000000000001 6:0.0755 7:0.04079 8:0.1594 9:0.05986 10:0.2711 11:0.3621 12:1.974 13:26.44 14:0.005472 15:0.01919 16:0.02039 17:0.00826 18:0.01523 19:0.002881 20:17.77 21:20.24 22:117.7 23:989.5 24:0.1491 25:0.3331 26:0.3327 27:0.1252 28:0.3415 29:0.0974 93 | 1 0:14.99 1:22.11 2:97.53 3:693.7 4:0.08515 5:0.1025 6:0.06859 7:0.03876 8:0.1944 9:0.05913 10:0.3186 11:1.336 12:2.31 13:28.51 14:0.004449 15:0.02808 16:0.03312 17:0.01196 18:0.01906 19:0.004015 20:16.76 21:31.55 22:110.2 23:867.1 24:0.1077 25:0.3345 26:0.3114 27:0.1308 28:0.3163 29:0.09251 94 | 0 0:15.22 1:30.62 2:103.4 3:716.9 4:0.1048 5:0.2087 6:0.255 7:0.09429 8:0.2128 9:0.07152 10:0.2602 11:1.205 12:2.362 13:22.65 14:0.004625 15:0.04844 16:0.07359 17:0.01608 18:0.02137 19:0.006142 20:17.52 21:42.79 22:128.7 23:915 24:0.1417 25:0.7917 26:1.17 27:0.2356 28:0.4089 29:0.1409 95 | 1 0:9.404999999999999 1:21.7 2:59.6 3:271.2 4:0.1044 5:0.06159 6:0.02047 7:0.01257 8:0.2025 9:0.06601 10:0.4302 11:2.878 12:2.759 13:25.17 14:0.01474 15:0.01674 16:0.01367 17:0.008673999999999999 18:0.03044 19:0.00459 20:10.85 21:31.24 22:68.73 23:359.4 24:0.1526 25:0.1193 26:0.06141 27:0.0377 28:0.2872 29:0.08304 96 | 1 0:9.875999999999999 1:19.4 2:63.95 3:298.3 4:0.1005 5:0.09697 6:0.06154 7:0.03029 8:0.1945 9:0.06322 10:0.1803 11:1.222 12:1.528 13:11.77 14:0.009058 15:0.02196 16:0.03029 17:0.01112 18:0.01609 19:0.00357 20:10.76 21:26.83 22:72.22 23:361.2 24:0.1559 25:0.2302 26:0.2644 27:0.09748999999999999 28:0.2622 29:0.0849 97 | 0 0:15.5 1:21.08 2:102.9 3:803.1 4:0.112 5:0.1571 6:0.1522 7:0.08481 8:0.2085 9:0.06864000000000001 10:1.37 11:1.213 12:9.423999999999999 13:176.5 14:0.008198 15:0.03889 16:0.04493 17:0.02139 18:0.02018 19:0.005815 20:23.17 21:27.65 22:157.1 23:1748 24:0.1517 25:0.4002 26:0.4211 27:0.2134 28:0.3003 29:0.1048 98 | 1 0:12.89 1:14.11 2:84.95 3:512.2 4:0.0876 5:0.1346 6:0.1374 7:0.0398 8:0.1596 9:0.06408999999999999 10:0.2025 11:0.4402 12:2.393 13:16.35 14:0.005501 15:0.05592 16:0.08158 17:0.0137 18:0.01266 19:0.007555 20:14.39 21:17.7 22:105 23:639.1 24:0.1254 25:0.5849 26:0.7727000000000001 27:0.1561 28:0.2639 29:0.1178 99 | 1 0:11.57 1:19.04 2:74.2 3:409.7 4:0.08545999999999999 5:0.07722 6:0.05485 7:0.01428 8:0.2031 9:0.06267 10:0.2864 11:1.44 12:2.206 13:20.3 14:0.007278 15:0.02047 16:0.04447 17:0.008799 18:0.01868 19:0.003339 20:13.07 21:26.98 22:86.43000000000001 23:520.5 24:0.1249 25:0.1937 26:0.256 27:0.06664 28:0.3035 29:0.08284 100 | 1 0:11.43 1:17.31 2:73.66 3:398 4:0.1092 5:0.09486 6:0.02031 7:0.01861 8:0.1645 9:0.06562 10:0.2843 11:1.908 12:1.937 13:21.38 14:0.006664 15:0.01735 16:0.01158 17:0.009520000000000001 18:0.02282 19:0.003526 20:12.78 21:26.76 22:82.66 23:503 24:0.1413 25:0.1792 26:0.07708 27:0.06401999999999999 28:0.2584 29:0.08096 101 | 1 0:8.888 1:14.64 2:58.79 3:244 4:0.09783 5:0.1531 6:0.08606 7:0.02872 8:0.1902 9:0.0898 10:0.5262 11:0.8522 12:3.168 13:25.44 14:0.01721 15:0.09368 16:0.05671 17:0.01766 18:0.02541 19:0.02193 20:9.733000000000001 21:15.67 22:62.56 23:284.4 24:0.1207 25:0.2436 26:0.1434 27:0.04786 28:0.2254 29:0.1084 102 | 1 0:12.36 1:18.54 2:79.01000000000001 3:466.7 4:0.08477 5:0.06815 6:0.02643 7:0.01921 8:0.1602 9:0.06066 10:0.1199 11:0.8944 12:0.8484 13:9.227 14:0.003457 15:0.01047 16:0.01167 17:0.005558 18:0.01251 19:0.001356 20:13.29 21:27.49 22:85.56 23:544.1 24:0.1184 25:0.1963 26:0.1937 27:0.08442 28:0.2983 29:0.07185 103 | 1 0:14.97 1:19.76 2:95.5 3:690.2 4:0.08420999999999999 5:0.05352 6:0.01947 7:0.01939 8:0.1515 9:0.05266 10:0.184 11:1.065 12:1.286 13:16.64 14:0.003634 15:0.007983000000000001 16:0.008267999999999999 17:0.006432 18:0.01924 19:0.00152 20:15.98 21:25.82 22:102.3 23:782.1 24:0.1045 25:0.09995 26:0.0775 27:0.05754 28:0.2646 29:0.06085 104 | 1 0:14.05 1:27.15 2:91.38 3:600.4 4:0.09929 5:0.1126 6:0.04462 7:0.04304 8:0.1537 9:0.06171 10:0.3645 11:1.492 12:2.888 13:29.84 14:0.007256 15:0.02678 16:0.02071 17:0.01626 18:0.0208 19:0.005304 20:15.3 21:33.17 22:100.2 23:706.7 24:0.1241 25:0.2264 26:0.1326 27:0.1048 28:0.225 29:0.08321000000000001 105 | 0 0:18.46 1:18.52 2:121.1 3:1075 4:0.09873999999999999 5:0.1053 6:0.1335 7:0.08795 8:0.2132 9:0.06022 10:0.6997 11:1.475 12:4.782 13:80.59999999999999 14:0.006471 15:0.01649 16:0.02806 17:0.0142 18:0.0237 19:0.003755 20:22.93 21:27.68 22:152.2 23:1603 24:0.1398 25:0.2089 26:0.3157 27:0.1642 28:0.3695 29:0.08579000000000001 106 | 1 0:9.268000000000001 1:12.87 2:61.49 3:248.7 4:0.1634 5:0.2239 6:0.0973 7:0.05252 8:0.2378 9:0.09501999999999999 10:0.4076 11:1.093 12:3.014 13:20.04 14:0.009783 15:0.04542 16:0.03483 17:0.02188 18:0.02542 19:0.01045 20:10.28 21:16.38 22:69.05 23:300.2 24:0.1902 25:0.3441 26:0.2099 27:0.1025 28:0.3038 29:0.1252 107 | 0 0:17.91 1:21.02 2:124.4 3:994 4:0.123 5:0.2576 6:0.3189 7:0.1198 8:0.2113 9:0.07115 10:0.403 11:0.7747000000000001 12:3.123 13:41.51 14:0.007159 15:0.03718 16:0.06165 17:0.01051 18:0.01591 19:0.005099 20:20.8 21:27.78 22:149.6 23:1304 24:0.1873 25:0.5917 26:0.9034 27:0.1964 28:0.3245 29:0.1198 108 | 1 0:12.88 1:18.22 2:84.45 3:493.1 4:0.1218 5:0.1661 6:0.04825 7:0.05303 8:0.1709 9:0.07253 10:0.4426 11:1.169 12:3.176 13:34.37 14:0.005273 15:0.02329 16:0.01405 17:0.01244 18:0.01816 19:0.003299 20:15.05 21:24.37 22:99.31 23:674.7 24:0.1456 25:0.2961 26:0.1246 27:0.1096 28:0.2582 29:0.08893 109 | 0 0:15.61 1:19.38 2:100 3:758.6 4:0.0784 5:0.05616 6:0.04209 7:0.02847 8:0.1547 9:0.05443 10:0.2298 11:0.9988 12:1.534 13:22.18 14:0.002826 15:0.009105 16:0.01311 17:0.005174 18:0.01013 19:0.001345 20:17.91 21:31.67 22:115.9 23:988.6 24:0.1084 25:0.1807 26:0.226 27:0.08568000000000001 28:0.2683 29:0.06829 110 | 0 0:17.42 1:25.56 2:114.5 3:948 4:0.1006 5:0.1146 6:0.1682 7:0.06597 8:0.1308 9:0.05866 10:0.5296 11:1.667 12:3.767 13:58.53 14:0.03113 15:0.08555 16:0.1438 17:0.03927 18:0.02175 19:0.01256 20:18.07 21:28.07 22:120.4 23:1021 24:0.1243 25:0.1793 26:0.2803 27:0.1099 28:0.1603 29:0.06818 111 | 1 0:12.75 1:16.7 2:82.51000000000001 3:493.8 4:0.1125 5:0.1117 6:0.0388 7:0.02995 8:0.212 9:0.06623 10:0.3834 11:1.003 12:2.495 13:28.62 14:0.007509 15:0.01561 16:0.01977 17:0.009199000000000001 18:0.01805 19:0.003629 20:14.45 21:21.74 22:93.63 23:624.1 24:0.1475 25:0.1979 26:0.1423 27:0.08044999999999999 28:0.3071 29:0.08556999999999999 112 | 0 0:20.18 1:19.54 2:133.8 3:1250 4:0.1133 5:0.1489 6:0.2133 7:0.1259 8:0.1724 9:0.06053 10:0.4331 11:1.001 12:3.008 13:52.49 14:0.009087 15:0.02715 16:0.05546 17:0.0191 18:0.02451 19:0.004005 20:22.03 21:25.07 22:146 23:1479 24:0.1665 25:0.2942 26:0.5308 27:0.2173 28:0.3032 29:0.08075 113 | 0 0:18.31 1:20.58 2:120.8 3:1052 4:0.1068 5:0.1248 6:0.1569 7:0.09451 8:0.186 9:0.05941 10:0.5449000000000001 11:0.9225 12:3.218 13:67.36 14:0.006176 15:0.01877 16:0.02913 17:0.01046 18:0.01559 19:0.002725 20:21.86 21:26.2 22:142.2 23:1493 24:0.1492 25:0.2536 26:0.3759 27:0.151 28:0.3074 29:0.07863000000000001 114 | 1 0:15.04 1:16.74 2:98.73 3:689.4 4:0.09883 5:0.1364 6:0.07721 7:0.06142 8:0.1668 9:0.06869 10:0.372 11:0.8423 12:2.304 13:34.84 14:0.004123 15:0.01819 16:0.01996 17:0.01004 18:0.01055 19:0.003237 20:16.76 21:20.43 22:109.7 23:856.9 24:0.1135 25:0.2176 26:0.1856 27:0.1018 28:0.2177 29:0.08549 115 | -------------------------------------------------------------------------------- /test/data/breast_cancer_xgboost_dump.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "nodeid": 0, "depth": 0, "split": "f27", "split_condition": 0.142349988, "yes": 1, "no": 2, "missing": 1 , "children": [ 3 | { "nodeid": 1, "depth": 1, "split": "f23", "split_condition": 957.450012, "yes": 3, "no": 4, "missing": 3 , "children": [ 4 | { "nodeid": 3, "depth": 2, "split": "f22", "split_condition": 107.75, "yes": 7, "no": 8, "missing": 7 , "children": [ 5 | { "nodeid": 7, "depth": 3, "split": "f13", "split_condition": 48.9749985, "yes": 15, "no": 16, "missing": 15 , "children": [ 6 | { "nodeid": 15, "leaf": 1.9256506 }, 7 | { "nodeid": 16, "leaf": -0 } 8 | ]}, 9 | { "nodeid": 8, "depth": 3, "split": "f0", "split_condition": 14.0799999, "yes": 17, "no": 18, "missing": 17 , "children": [ 10 | { "nodeid": 17, "leaf": -1 }, 11 | { "nodeid": 18, "leaf": 1.15789473 } 12 | ]} 13 | ]}, 14 | { "nodeid": 4, "depth": 2, "split": "f1", "split_condition": 18.8850002, "yes": 9, "no": 10, "missing": 9 , "children": [ 15 | { "nodeid": 9, "leaf": -0 }, 16 | { "nodeid": 10, "leaf": -1.4666667 } 17 | ]} 18 | ]}, 19 | { "nodeid": 2, "depth": 1, "split": "f23", "split_condition": 729.549988, "yes": 5, "no": 6, "missing": 5 , "children": [ 20 | { "nodeid": 5, "depth": 2, "split": "f4", "split_condition": 0.1083, "yes": 11, "no": 12, "missing": 11 , "children": [ 21 | { "nodeid": 11, "leaf": 1.33333337 }, 22 | { "nodeid": 12, "leaf": -1.20000005 } 23 | ]}, 24 | { "nodeid": 6, "depth": 2, "split": "f1", "split_condition": 15.3700008, "yes": 13, "no": 14, "missing": 13 , "children": [ 25 | { "nodeid": 13, "leaf": -0.400000006 }, 26 | { "nodeid": 14, "depth": 3, "split": "f6", "split_condition": 0.077820003, "yes": 19, "no": 20, "missing": 19 , "children": [ 27 | { "nodeid": 19, "leaf": -0.5 }, 28 | { "nodeid": 20, "leaf": -1.939394 } 29 | ]} 30 | ]} 31 | ]} 32 | ]}, 33 | { "nodeid": 0, "depth": 0, "split": "f7", "split_condition": 0.0489199981, "yes": 1, "no": 2, "missing": 1 , "children": [ 34 | { "nodeid": 1, "depth": 1, "split": "f1", "split_condition": 21.5750008, "yes": 3, "no": 4, "missing": 3 , "children": [ 35 | { "nodeid": 3, "depth": 2, "split": "f13", "split_condition": 38.4150009, "yes": 7, "no": 8, "missing": 7 , "children": [ 36 | { "nodeid": 7, "leaf": 1.1230942 }, 37 | { "nodeid": 8, "leaf": 0.290251553 } 38 | ]}, 39 | { "nodeid": 4, "depth": 2, "split": "f20", "split_condition": 14.4300003, "yes": 9, "no": 10, "missing": 9 , "children": [ 40 | { "nodeid": 9, "leaf": 0.866951168 }, 41 | { "nodeid": 10, "depth": 3, "split": "f15", "split_condition": 0.0120250005, "yes": 15, "no": 16, "missing": 15 , "children": [ 42 | { "nodeid": 15, "leaf": -1.35367692 }, 43 | { "nodeid": 16, "leaf": 0.303786576 } 44 | ]} 45 | ]} 46 | ]}, 47 | { "nodeid": 2, "depth": 1, "split": "f22", "split_condition": 104.100006, "yes": 5, "no": 6, "missing": 5 , "children": [ 48 | { "nodeid": 5, "depth": 2, "split": "f24", "split_condition": 0.178299993, "yes": 11, "no": 12, "missing": 11 , "children": [ 49 | { "nodeid": 11, "leaf": 0.768755019 }, 50 | { "nodeid": 12, "leaf": -0.514137685 } 51 | ]}, 52 | { "nodeid": 6, "depth": 2, "split": "f21", "split_condition": 20.3549995, "yes": 13, "no": 14, "missing": 13 , "children": [ 53 | { "nodeid": 13, "depth": 3, "split": "f0", "split_condition": 16.8699989, "yes": 17, "no": 18, "missing": 17 , "children": [ 54 | { "nodeid": 17, "leaf": 0.638263881 }, 55 | { "nodeid": 18, "leaf": -0.771065712 } 56 | ]}, 57 | { "nodeid": 14, "leaf": -1.20938683 } 58 | ]} 59 | ]} 60 | ]}, 61 | { "nodeid": 0, "depth": 0, "split": "f27", "split_condition": 0.110849999, "yes": 1, "no": 2, "missing": 1 , "children": [ 62 | { "nodeid": 1, "depth": 1, "split": "f10", "split_condition": 0.566249967, "yes": 3, "no": 4, "missing": 3 , "children": [ 63 | { "nodeid": 3, "depth": 2, "split": "f21", "split_condition": 32.8300018, "yes": 7, "no": 8, "missing": 7 , "children": [ 64 | { "nodeid": 7, "depth": 3, "split": "f28", "split_condition": 0.329450011, "yes": 11, "no": 12, "missing": 11 , "children": [ 65 | { "nodeid": 11, "leaf": 0.988147557 }, 66 | { "nodeid": 12, "leaf": 0.197919026 } 67 | ]}, 68 | { "nodeid": 8, "leaf": 0.178187609 } 69 | ]}, 70 | { "nodeid": 4, "leaf": -0.0292120669 } 71 | ]}, 72 | { "nodeid": 2, "depth": 1, "split": "f13", "split_condition": 31.1700001, "yes": 5, "no": 6, "missing": 5 , "children": [ 73 | { "nodeid": 5, "depth": 2, "split": "f21", "split_condition": 26.2750015, "yes": 9, "no": 10, "missing": 9 , "children": [ 74 | { "nodeid": 9, "leaf": 0.829586327 }, 75 | { "nodeid": 10, "depth": 3, "split": "f7", "split_condition": 0.0548949987, "yes": 13, "no": 14, "missing": 13 , "children": [ 76 | { "nodeid": 13, "leaf": -0.0383893661 }, 77 | { "nodeid": 14, "leaf": -0.894984603 } 78 | ]} 79 | ]}, 80 | { "nodeid": 6, "leaf": -1.02690852 } 81 | ]} 82 | ]}, 83 | { "nodeid": 0, "depth": 0, "split": "f23", "split_condition": 874.849976, "yes": 1, "no": 2, "missing": 1 , "children": [ 84 | { "nodeid": 1, "depth": 1, "split": "f21", "split_condition": 29.2250004, "yes": 3, "no": 4, "missing": 3 , "children": [ 85 | { "nodeid": 3, "depth": 2, "split": "f25", "split_condition": 0.0866750032, "yes": 7, "no": 8, "missing": 7 , "children": [ 86 | { "nodeid": 7, "leaf": -0.0709136873 }, 87 | { "nodeid": 8, "depth": 3, "split": "f25", "split_condition": 0.348550022, "yes": 11, "no": 12, "missing": 11 , "children": [ 88 | { "nodeid": 11, "leaf": 0.917927325 }, 89 | { "nodeid": 12, "leaf": 0.000908494403 } 90 | ]} 91 | ]}, 92 | { "nodeid": 4, "depth": 2, "split": "f1", "split_condition": 23.8699989, "yes": 9, "no": 10, "missing": 9 , "children": [ 93 | { "nodeid": 9, "leaf": -0.752491057 }, 94 | { "nodeid": 10, "leaf": 0.491739243 } 95 | ]} 96 | ]}, 97 | { "nodeid": 2, "depth": 1, "split": "f1", "split_condition": 18.3800011, "yes": 5, "no": 6, "missing": 5 , "children": [ 98 | { "nodeid": 5, "leaf": -0.161077604 }, 99 | { "nodeid": 6, "leaf": -0.867159784 } 100 | ]} 101 | ]}, 102 | { "nodeid": 0, "depth": 0, "split": "f23", "split_condition": 711.300049, "yes": 1, "no": 2, "missing": 1 , "children": [ 103 | { "nodeid": 1, "depth": 1, "split": "f15", "split_condition": 0.0120250005, "yes": 3, "no": 4, "missing": 3 , "children": [ 104 | { "nodeid": 3, "leaf": -0.119858712 }, 105 | { "nodeid": 4, "depth": 2, "split": "f4", "split_condition": 0.107099995, "yes": 7, "no": 8, "missing": 7 , "children": [ 106 | { "nodeid": 7, "leaf": 0.798094213 }, 107 | { "nodeid": 8, "leaf": 0.196188718 } 108 | ]} 109 | ]}, 110 | { "nodeid": 2, "depth": 1, "split": "f26", "split_condition": 0.231400013, "yes": 5, "no": 6, "missing": 5 , "children": [ 111 | { "nodeid": 5, "leaf": 0.279408604 }, 112 | { "nodeid": 6, "depth": 2, "split": "f10", "split_condition": 0.254350007, "yes": 9, "no": 10, "missing": 9 , "children": [ 113 | { "nodeid": 9, "leaf": -0.169663087 }, 114 | { "nodeid": 10, "leaf": -0.752452731 } 115 | ]} 116 | ]} 117 | ]}, 118 | { "nodeid": 0, "depth": 0, "split": "f21", "split_condition": 23.3499985, "yes": 1, "no": 2, "missing": 1 , "children": [ 119 | { "nodeid": 1, "depth": 1, "split": "f27", "split_condition": 0.136550009, "yes": 3, "no": 4, "missing": 3 , "children": [ 120 | { "nodeid": 3, "leaf": 0.676270008 }, 121 | { "nodeid": 4, "leaf": 0.0649775714 } 122 | ]}, 123 | { "nodeid": 2, "depth": 1, "split": "f4", "split_condition": 0.0903899968, "yes": 5, "no": 6, "missing": 5 , "children": [ 124 | { "nodeid": 5, "depth": 2, "split": "f9", "split_condition": 0.0573199987, "yes": 7, "no": 8, "missing": 7 , "children": [ 125 | { "nodeid": 7, "leaf": -0.326284021 }, 126 | { "nodeid": 8, "leaf": 0.606267214 } 127 | ]}, 128 | { "nodeid": 6, "depth": 2, "split": "f9", "split_condition": 0.0632700026, "yes": 9, "no": 10, "missing": 9 , "children": [ 129 | { "nodeid": 9, "leaf": -0.675102949 }, 130 | { "nodeid": 10, "leaf": -0.200931102 } 131 | ]} 132 | ]} 133 | ]}, 134 | { "nodeid": 0, "depth": 0, "split": "f26", "split_condition": 0.207949996, "yes": 1, "no": 2, "missing": 1 , "children": [ 135 | { "nodeid": 1, "depth": 1, "split": "f10", "split_condition": 0.339850008, "yes": 3, "no": 4, "missing": 3 , "children": [ 136 | { "nodeid": 3, "leaf": 0.615091383 }, 137 | { "nodeid": 4, "leaf": 0.0652931333 } 138 | ]}, 139 | { "nodeid": 2, "depth": 1, "split": "f28", "split_condition": 0.269450009, "yes": 5, "no": 6, "missing": 5 , "children": [ 140 | { "nodeid": 5, "leaf": 0.210927114 }, 141 | { "nodeid": 6, "depth": 2, "split": "f23", "split_condition": 724.049988, "yes": 7, "no": 8, "missing": 7 , "children": [ 142 | { "nodeid": 7, "leaf": 0.0217199586 }, 143 | { "nodeid": 8, "leaf": -0.587608159 } 144 | ]} 145 | ]} 146 | ]}, 147 | { "nodeid": 0, "depth": 0, "split": "f23", "split_condition": 553.299988, "yes": 1, "no": 2, "missing": 1 , "children": [ 148 | { "nodeid": 1, "leaf": 0.475401312 }, 149 | { "nodeid": 2, "depth": 1, "split": "f4", "split_condition": 0.0899550021, "yes": 3, "no": 4, "missing": 3 , "children": [ 150 | { "nodeid": 3, "leaf": 0.235072598 }, 151 | { "nodeid": 4, "depth": 2, "split": "f11", "split_condition": 1.37400007, "yes": 5, "no": 6, "missing": 5 , "children": [ 152 | { "nodeid": 5, "leaf": -0.0521557853 }, 153 | { "nodeid": 6, "leaf": -0.51898706 } 154 | ]} 155 | ]} 156 | ]}, 157 | { "nodeid": 0, "depth": 0, "split": "f26", "split_condition": 0.207949996, "yes": 1, "no": 2, "missing": 1 , "children": [ 158 | { "nodeid": 1, "leaf": 0.316972673 }, 159 | { "nodeid": 2, "depth": 1, "split": "f21", "split_condition": 25.5149994, "yes": 3, "no": 4, "missing": 3 , "children": [ 160 | { "nodeid": 3, "leaf": 0.151291728 }, 161 | { "nodeid": 4, "leaf": -0.336530745 } 162 | ]} 163 | ]}, 164 | { "nodeid": 0, "depth": 0, "split": "f13", "split_condition": 40.0100021, "yes": 1, "no": 2, "missing": 1 , "children": [ 165 | { "nodeid": 1, "depth": 1, "split": "f28", "split_condition": 0.299250007, "yes": 3, "no": 4, "missing": 3 , "children": [ 166 | { "nodeid": 3, "depth": 2, "split": "f29", "split_condition": 0.0779999942, "yes": 5, "no": 6, "missing": 5 , "children": [ 167 | { "nodeid": 5, "leaf": 0.459454387 }, 168 | { "nodeid": 6, "leaf": 0.105021186 } 169 | ]}, 170 | { "nodeid": 4, "leaf": -0.099408403 } 171 | ]}, 172 | { "nodeid": 2, "leaf": -0.380893648 } 173 | ]} 174 | ] -------------------------------------------------------------------------------- /test/data/breast_cancer_xgboost_dump_fmap.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "nodeid": 0, "depth": 0, "split": "worst_concave_points", "split_condition": 0.142349988, "yes": 1, "no": 2, "missing": 1 , "children": [ 3 | { "nodeid": 1, "depth": 1, "split": "worst_area", "split_condition": 957.450012, "yes": 3, "no": 4, "missing": 3 , "children": [ 4 | { "nodeid": 3, "depth": 2, "split": "worst_perimeter", "split_condition": 107.75, "yes": 7, "no": 8, "missing": 7 , "children": [ 5 | { "nodeid": 7, "depth": 3, "split": "area_error", "split_condition": 48.9749985, "yes": 15, "no": 16, "missing": 15 , "children": [ 6 | { "nodeid": 15, "leaf": 1.9256506 }, 7 | { "nodeid": 16, "leaf": -0 } 8 | ]}, 9 | { "nodeid": 8, "depth": 3, "split": "mean_radius", "split_condition": 14.0799999, "yes": 17, "no": 18, "missing": 17 , "children": [ 10 | { "nodeid": 17, "leaf": -1 }, 11 | { "nodeid": 18, "leaf": 1.15789473 } 12 | ]} 13 | ]}, 14 | { "nodeid": 4, "depth": 2, "split": "mean_texture", "split_condition": 18.8850002, "yes": 9, "no": 10, "missing": 9 , "children": [ 15 | { "nodeid": 9, "leaf": -0 }, 16 | { "nodeid": 10, "leaf": -1.4666667 } 17 | ]} 18 | ]}, 19 | { "nodeid": 2, "depth": 1, "split": "worst_area", "split_condition": 729.549988, "yes": 5, "no": 6, "missing": 5 , "children": [ 20 | { "nodeid": 5, "depth": 2, "split": "mean_smoothness", "split_condition": 0.1083, "yes": 11, "no": 12, "missing": 11 , "children": [ 21 | { "nodeid": 11, "leaf": 1.33333337 }, 22 | { "nodeid": 12, "leaf": -1.20000005 } 23 | ]}, 24 | { "nodeid": 6, "depth": 2, "split": "mean_texture", "split_condition": 15.3700008, "yes": 13, "no": 14, "missing": 13 , "children": [ 25 | { "nodeid": 13, "leaf": -0.400000006 }, 26 | { "nodeid": 14, "depth": 3, "split": "mean_concavity", "split_condition": 0.077820003, "yes": 19, "no": 20, "missing": 19 , "children": [ 27 | { "nodeid": 19, "leaf": -0.5 }, 28 | { "nodeid": 20, "leaf": -1.939394 } 29 | ]} 30 | ]} 31 | ]} 32 | ]}, 33 | { "nodeid": 0, "depth": 0, "split": "mean_concave_points", "split_condition": 0.0489199981, "yes": 1, "no": 2, "missing": 1 , "children": [ 34 | { "nodeid": 1, "depth": 1, "split": "mean_texture", "split_condition": 21.5750008, "yes": 3, "no": 4, "missing": 3 , "children": [ 35 | { "nodeid": 3, "depth": 2, "split": "area_error", "split_condition": 38.4150009, "yes": 7, "no": 8, "missing": 7 , "children": [ 36 | { "nodeid": 7, "leaf": 1.1230942 }, 37 | { "nodeid": 8, "leaf": 0.290251553 } 38 | ]}, 39 | { "nodeid": 4, "depth": 2, "split": "worst_radius", "split_condition": 14.4300003, "yes": 9, "no": 10, "missing": 9 , "children": [ 40 | { "nodeid": 9, "leaf": 0.866951168 }, 41 | { "nodeid": 10, "depth": 3, "split": "compactness_error", "split_condition": 0.0120250005, "yes": 15, "no": 16, "missing": 15 , "children": [ 42 | { "nodeid": 15, "leaf": -1.35367692 }, 43 | { "nodeid": 16, "leaf": 0.303786576 } 44 | ]} 45 | ]} 46 | ]}, 47 | { "nodeid": 2, "depth": 1, "split": "worst_perimeter", "split_condition": 104.100006, "yes": 5, "no": 6, "missing": 5 , "children": [ 48 | { "nodeid": 5, "depth": 2, "split": "worst_smoothness", "split_condition": 0.178299993, "yes": 11, "no": 12, "missing": 11 , "children": [ 49 | { "nodeid": 11, "leaf": 0.768755019 }, 50 | { "nodeid": 12, "leaf": -0.514137685 } 51 | ]}, 52 | { "nodeid": 6, "depth": 2, "split": "worst_texture", "split_condition": 20.3549995, "yes": 13, "no": 14, "missing": 13 , "children": [ 53 | { "nodeid": 13, "depth": 3, "split": "mean_radius", "split_condition": 16.8699989, "yes": 17, "no": 18, "missing": 17 , "children": [ 54 | { "nodeid": 17, "leaf": 0.638263881 }, 55 | { "nodeid": 18, "leaf": -0.771065712 } 56 | ]}, 57 | { "nodeid": 14, "leaf": -1.20938683 } 58 | ]} 59 | ]} 60 | ]}, 61 | { "nodeid": 0, "depth": 0, "split": "worst_concave_points", "split_condition": 0.110849999, "yes": 1, "no": 2, "missing": 1 , "children": [ 62 | { "nodeid": 1, "depth": 1, "split": "radius_error", "split_condition": 0.566249967, "yes": 3, "no": 4, "missing": 3 , "children": [ 63 | { "nodeid": 3, "depth": 2, "split": "worst_texture", "split_condition": 32.8300018, "yes": 7, "no": 8, "missing": 7 , "children": [ 64 | { "nodeid": 7, "depth": 3, "split": "worst_symmetry", "split_condition": 0.329450011, "yes": 11, "no": 12, "missing": 11 , "children": [ 65 | { "nodeid": 11, "leaf": 0.988147557 }, 66 | { "nodeid": 12, "leaf": 0.197919026 } 67 | ]}, 68 | { "nodeid": 8, "leaf": 0.178187609 } 69 | ]}, 70 | { "nodeid": 4, "leaf": -0.0292120669 } 71 | ]}, 72 | { "nodeid": 2, "depth": 1, "split": "area_error", "split_condition": 31.1700001, "yes": 5, "no": 6, "missing": 5 , "children": [ 73 | { "nodeid": 5, "depth": 2, "split": "worst_texture", "split_condition": 26.2750015, "yes": 9, "no": 10, "missing": 9 , "children": [ 74 | { "nodeid": 9, "leaf": 0.829586327 }, 75 | { "nodeid": 10, "depth": 3, "split": "mean_concave_points", "split_condition": 0.0548949987, "yes": 13, "no": 14, "missing": 13 , "children": [ 76 | { "nodeid": 13, "leaf": -0.0383893661 }, 77 | { "nodeid": 14, "leaf": -0.894984603 } 78 | ]} 79 | ]}, 80 | { "nodeid": 6, "leaf": -1.02690852 } 81 | ]} 82 | ]}, 83 | { "nodeid": 0, "depth": 0, "split": "worst_area", "split_condition": 874.849976, "yes": 1, "no": 2, "missing": 1 , "children": [ 84 | { "nodeid": 1, "depth": 1, "split": "worst_texture", "split_condition": 29.2250004, "yes": 3, "no": 4, "missing": 3 , "children": [ 85 | { "nodeid": 3, "depth": 2, "split": "worst_compactness", "split_condition": 0.0866750032, "yes": 7, "no": 8, "missing": 7 , "children": [ 86 | { "nodeid": 7, "leaf": -0.0709136873 }, 87 | { "nodeid": 8, "depth": 3, "split": "worst_compactness", "split_condition": 0.348550022, "yes": 11, "no": 12, "missing": 11 , "children": [ 88 | { "nodeid": 11, "leaf": 0.917927325 }, 89 | { "nodeid": 12, "leaf": 0.000908494403 } 90 | ]} 91 | ]}, 92 | { "nodeid": 4, "depth": 2, "split": "mean_texture", "split_condition": 23.8699989, "yes": 9, "no": 10, "missing": 9 , "children": [ 93 | { "nodeid": 9, "leaf": -0.752491057 }, 94 | { "nodeid": 10, "leaf": 0.491739243 } 95 | ]} 96 | ]}, 97 | { "nodeid": 2, "depth": 1, "split": "mean_texture", "split_condition": 18.3800011, "yes": 5, "no": 6, "missing": 5 , "children": [ 98 | { "nodeid": 5, "leaf": -0.161077604 }, 99 | { "nodeid": 6, "leaf": -0.867159784 } 100 | ]} 101 | ]}, 102 | { "nodeid": 0, "depth": 0, "split": "worst_area", "split_condition": 711.300049, "yes": 1, "no": 2, "missing": 1 , "children": [ 103 | { "nodeid": 1, "depth": 1, "split": "compactness_error", "split_condition": 0.0120250005, "yes": 3, "no": 4, "missing": 3 , "children": [ 104 | { "nodeid": 3, "leaf": -0.119858712 }, 105 | { "nodeid": 4, "depth": 2, "split": "mean_smoothness", "split_condition": 0.107099995, "yes": 7, "no": 8, "missing": 7 , "children": [ 106 | { "nodeid": 7, "leaf": 0.798094213 }, 107 | { "nodeid": 8, "leaf": 0.196188718 } 108 | ]} 109 | ]}, 110 | { "nodeid": 2, "depth": 1, "split": "worst_concavity", "split_condition": 0.231400013, "yes": 5, "no": 6, "missing": 5 , "children": [ 111 | { "nodeid": 5, "leaf": 0.279408604 }, 112 | { "nodeid": 6, "depth": 2, "split": "radius_error", "split_condition": 0.254350007, "yes": 9, "no": 10, "missing": 9 , "children": [ 113 | { "nodeid": 9, "leaf": -0.169663087 }, 114 | { "nodeid": 10, "leaf": -0.752452731 } 115 | ]} 116 | ]} 117 | ]}, 118 | { "nodeid": 0, "depth": 0, "split": "worst_texture", "split_condition": 23.3499985, "yes": 1, "no": 2, "missing": 1 , "children": [ 119 | { "nodeid": 1, "depth": 1, "split": "worst_concave_points", "split_condition": 0.136550009, "yes": 3, "no": 4, "missing": 3 , "children": [ 120 | { "nodeid": 3, "leaf": 0.676270008 }, 121 | { "nodeid": 4, "leaf": 0.0649775714 } 122 | ]}, 123 | { "nodeid": 2, "depth": 1, "split": "mean_smoothness", "split_condition": 0.0903899968, "yes": 5, "no": 6, "missing": 5 , "children": [ 124 | { "nodeid": 5, "depth": 2, "split": "mean_fractal_dimension", "split_condition": 0.0573199987, "yes": 7, "no": 8, "missing": 7 , "children": [ 125 | { "nodeid": 7, "leaf": -0.326284021 }, 126 | { "nodeid": 8, "leaf": 0.606267214 } 127 | ]}, 128 | { "nodeid": 6, "depth": 2, "split": "mean_fractal_dimension", "split_condition": 0.0632700026, "yes": 9, "no": 10, "missing": 9 , "children": [ 129 | { "nodeid": 9, "leaf": -0.675102949 }, 130 | { "nodeid": 10, "leaf": -0.200931102 } 131 | ]} 132 | ]} 133 | ]}, 134 | { "nodeid": 0, "depth": 0, "split": "worst_concavity", "split_condition": 0.207949996, "yes": 1, "no": 2, "missing": 1 , "children": [ 135 | { "nodeid": 1, "depth": 1, "split": "radius_error", "split_condition": 0.339850008, "yes": 3, "no": 4, "missing": 3 , "children": [ 136 | { "nodeid": 3, "leaf": 0.615091383 }, 137 | { "nodeid": 4, "leaf": 0.0652931333 } 138 | ]}, 139 | { "nodeid": 2, "depth": 1, "split": "worst_symmetry", "split_condition": 0.269450009, "yes": 5, "no": 6, "missing": 5 , "children": [ 140 | { "nodeid": 5, "leaf": 0.210927114 }, 141 | { "nodeid": 6, "depth": 2, "split": "worst_area", "split_condition": 724.049988, "yes": 7, "no": 8, "missing": 7 , "children": [ 142 | { "nodeid": 7, "leaf": 0.0217199586 }, 143 | { "nodeid": 8, "leaf": -0.587608159 } 144 | ]} 145 | ]} 146 | ]}, 147 | { "nodeid": 0, "depth": 0, "split": "worst_area", "split_condition": 553.299988, "yes": 1, "no": 2, "missing": 1 , "children": [ 148 | { "nodeid": 1, "leaf": 0.475401312 }, 149 | { "nodeid": 2, "depth": 1, "split": "mean_smoothness", "split_condition": 0.0899550021, "yes": 3, "no": 4, "missing": 3 , "children": [ 150 | { "nodeid": 3, "leaf": 0.235072598 }, 151 | { "nodeid": 4, "depth": 2, "split": "texture_error", "split_condition": 1.37400007, "yes": 5, "no": 6, "missing": 5 , "children": [ 152 | { "nodeid": 5, "leaf": -0.0521557853 }, 153 | { "nodeid": 6, "leaf": -0.51898706 } 154 | ]} 155 | ]} 156 | ]}, 157 | { "nodeid": 0, "depth": 0, "split": "worst_concavity", "split_condition": 0.207949996, "yes": 1, "no": 2, "missing": 1 , "children": [ 158 | { "nodeid": 1, "leaf": 0.316972673 }, 159 | { "nodeid": 2, "depth": 1, "split": "worst_texture", "split_condition": 25.5149994, "yes": 3, "no": 4, "missing": 3 , "children": [ 160 | { "nodeid": 3, "leaf": 0.151291728 }, 161 | { "nodeid": 4, "leaf": -0.336530745 } 162 | ]} 163 | ]}, 164 | { "nodeid": 0, "depth": 0, "split": "area_error", "split_condition": 40.0100021, "yes": 1, "no": 2, "missing": 1 , "children": [ 165 | { "nodeid": 1, "depth": 1, "split": "worst_symmetry", "split_condition": 0.299250007, "yes": 3, "no": 4, "missing": 3 , "children": [ 166 | { "nodeid": 3, "depth": 2, "split": "worst_fractal_dimension", "split_condition": 0.0779999942, "yes": 5, "no": 6, "missing": 5 , "children": [ 167 | { "nodeid": 5, "leaf": 0.459454387 }, 168 | { "nodeid": 6, "leaf": 0.105021186 } 169 | ]}, 170 | { "nodeid": 4, "leaf": -0.099408403 } 171 | ]}, 172 | { "nodeid": 2, "leaf": -0.380893648 } 173 | ]} 174 | ] -------------------------------------------------------------------------------- /test/data/breast_cancer_xgboost_dump_regression.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "nodeid": 0, "depth": 0, "split": "f27", "split_condition": 0.142349988, "yes": 1, "no": 2, "missing": 1 , "children": [ 3 | { "nodeid": 1, "depth": 1, "split": "f23", "split_condition": 957.450012, "yes": 3, "no": 4, "missing": 3 , "children": [ 4 | { "nodeid": 3, "depth": 2, "split": "f22", "split_condition": 107.75, "yes": 7, "no": 8, "missing": 7 , "children": [ 5 | { "nodeid": 7, "depth": 3, "split": "f13", "split_condition": 48.9749985, "yes": 15, "no": 16, "missing": 15 , "children": [ 6 | { "nodeid": 15, "leaf": 0.349995852 }, 7 | { "nodeid": 16, "leaf": -0.109890126 } 8 | ]}, 9 | { "nodeid": 8, "depth": 3, "split": "f0", "split_condition": 14.0799999, "yes": 17, "no": 18, "missing": 17 , "children": [ 10 | { "nodeid": 17, "leaf": -0.509890139 }, 11 | { "nodeid": 18, "leaf": 0.214972511 } 12 | ]} 13 | ]}, 14 | { "nodeid": 4, "depth": 2, "split": "f8", "split_condition": 0.151649997, "yes": 9, "no": 10, "missing": 9 , "children": [ 15 | { "nodeid": 9, "leaf": 0.241758227 }, 16 | { "nodeid": 10, "leaf": -0.591836751 } 17 | ]} 18 | ]}, 19 | { "nodeid": 2, "depth": 1, "split": "f23", "split_condition": 729.549988, "yes": 5, "no": 6, "missing": 5 , "children": [ 20 | { "nodeid": 5, "depth": 2, "split": "f4", "split_condition": 0.1083, "yes": 11, "no": 12, "missing": 11 , "children": [ 21 | { "nodeid": 11, "leaf": 0.322344303 }, 22 | { "nodeid": 12, "leaf": -0.546310842 } 23 | ]}, 24 | { "nodeid": 6, "depth": 2, "split": "f10", "split_condition": 0.17840001, "yes": 13, "no": 14, "missing": 13 , "children": [ 25 | { "nodeid": 13, "leaf": 0.181318671 }, 26 | { "nodeid": 14, "depth": 3, "split": "f26", "split_condition": 0.203400001, "yes": 19, "no": 20, "missing": 19 , "children": [ 27 | { "nodeid": 19, "leaf": 0.181318671 }, 28 | { "nodeid": 20, "leaf": -0.625411093 } 29 | ]} 30 | ]} 31 | ]} 32 | ]}, 33 | { "nodeid": 0, "depth": 0, "split": "f1", "split_condition": 21.4349995, "yes": 1, "no": 2, "missing": 1 , "children": [ 34 | { "nodeid": 1, "depth": 1, "split": "f15", "split_condition": 0.102229998, "yes": 3, "no": 4, "missing": 3 , "children": [ 35 | { "nodeid": 3, "depth": 2, "split": "f21", "split_condition": 19.875, "yes": 7, "no": 8, "missing": 7 , "children": [ 36 | { "nodeid": 7, "depth": 3, "split": "f21", "split_condition": 19.8250008, "yes": 11, "no": 12, "missing": 11 , "children": [ 37 | { "nodeid": 11, "leaf": 0.0291584227 }, 38 | { "nodeid": 12, "leaf": 0.494024217 } 39 | ]}, 40 | { "nodeid": 8, "depth": 3, "split": "f1", "split_condition": 21.3950005, "yes": 13, "no": 14, "missing": 13 , "children": [ 41 | { "nodeid": 13, "leaf": 0.00219235546 }, 42 | { "nodeid": 14, "leaf": 0.161722973 } 43 | ]} 44 | ]}, 45 | { "nodeid": 4, "leaf": 0.236263722 } 46 | ]}, 47 | { "nodeid": 2, "depth": 1, "split": "f14", "split_condition": 0.0032850001, "yes": 5, "no": 6, "missing": 5 , "children": [ 48 | { "nodeid": 5, "leaf": -0.493679255 }, 49 | { "nodeid": 6, "depth": 2, "split": "f29", "split_condition": 0.0630400032, "yes": 9, "no": 10, "missing": 9 , "children": [ 50 | { "nodeid": 9, "depth": 3, "split": "f17", "split_condition": 0.0170799997, "yes": 15, "no": 16, "missing": 15 , "children": [ 51 | { "nodeid": 15, "leaf": 0.00333285332 }, 52 | { "nodeid": 16, "leaf": -0.459935904 } 53 | ]}, 54 | { "nodeid": 10, "depth": 3, "split": "f1", "split_condition": 21.4699993, "yes": 17, "no": 18, "missing": 17 , "children": [ 55 | { "nodeid": 17, "leaf": -0.288095564 }, 56 | { "nodeid": 18, "leaf": -0.0232061818 } 57 | ]} 58 | ]} 59 | ]} 60 | ]}, 61 | { "nodeid": 0, "depth": 0, "split": "f28", "split_condition": 0.269600004, "yes": 1, "no": 2, "missing": 1 , "children": [ 62 | { "nodeid": 1, "depth": 1, "split": "f28", "split_condition": 0.268999994, "yes": 3, "no": 4, "missing": 3 , "children": [ 63 | { "nodeid": 3, "depth": 2, "split": "f28", "split_condition": 0.198300004, "yes": 7, "no": 8, "missing": 7 , "children": [ 64 | { "nodeid": 7, "depth": 3, "split": "f28", "split_condition": 0.195600003, "yes": 13, "no": 14, "missing": 13 , "children": [ 65 | { "nodeid": 13, "leaf": -0.00164335163 }, 66 | { "nodeid": 14, "leaf": -0.264832467 } 67 | ]}, 68 | { "nodeid": 8, "depth": 3, "split": "f18", "split_condition": 0.0332700014, "yes": 15, "no": 16, "missing": 15 , "children": [ 69 | { "nodeid": 15, "leaf": 0.0117311552 }, 70 | { "nodeid": 16, "leaf": 0.104868777 } 71 | ]} 72 | ]}, 73 | { "nodeid": 4, "depth": 2, "split": "f0", "split_condition": 13.9499998, "yes": 9, "no": 10, "missing": 9 , "children": [ 74 | { "nodeid": 9, "leaf": 0.0154322581 }, 75 | { "nodeid": 10, "leaf": 0.247012109 } 76 | ]} 77 | ]}, 78 | { "nodeid": 2, "depth": 1, "split": "f28", "split_condition": 0.269850016, "yes": 5, "no": 6, "missing": 5 , "children": [ 79 | { "nodeid": 5, "leaf": -0.482076168 }, 80 | { "nodeid": 6, "depth": 2, "split": "f9", "split_condition": 0.0564149991, "yes": 11, "no": 12, "missing": 11 , "children": [ 81 | { "nodeid": 11, "depth": 3, "split": "f14", "split_condition": 0.00822900049, "yes": 17, "no": 18, "missing": 17 , "children": [ 82 | { "nodeid": 17, "leaf": -0.0202233139 }, 83 | { "nodeid": 18, "leaf": -0.318879634 } 84 | ]}, 85 | { "nodeid": 12, "depth": 3, "split": "f8", "split_condition": 0.161750004, "yes": 19, "no": 20, "missing": 19 , "children": [ 86 | { "nodeid": 19, "leaf": -0.0556677505 }, 87 | { "nodeid": 20, "leaf": 0.00242803758 } 88 | ]} 89 | ]} 90 | ]} 91 | ]}, 92 | { "nodeid": 0, "depth": 0, "split": "f4", "split_condition": 0.0903850049, "yes": 1, "no": 2, "missing": 1 , "children": [ 93 | { "nodeid": 1, "depth": 1, "split": "f19", "split_condition": 0.00129749998, "yes": 3, "no": 4, "missing": 3 , "children": [ 94 | { "nodeid": 3, "depth": 2, "split": "f17", "split_condition": 0.00680000009, "yes": 7, "no": 8, "missing": 7 , "children": [ 95 | { "nodeid": 7, "depth": 3, "split": "f0", "split_condition": 12.3600006, "yes": 15, "no": 16, "missing": 15 , "children": [ 96 | { "nodeid": 15, "leaf": -0.0157310162 }, 97 | { "nodeid": 16, "leaf": -0.000344207278 } 98 | ]}, 99 | { "nodeid": 8, "leaf": -0.236727968 } 100 | ]}, 101 | { "nodeid": 4, "depth": 2, "split": "f27", "split_condition": 0.114150003, "yes": 9, "no": 10, "missing": 9 , "children": [ 102 | { "nodeid": 9, "depth": 3, "split": "f10", "split_condition": 0.683650017, "yes": 17, "no": 18, "missing": 17 , "children": [ 103 | { "nodeid": 17, "leaf": 0.00840061903 }, 104 | { "nodeid": 18, "leaf": 0.112443566 } 105 | ]}, 106 | { "nodeid": 10, "depth": 3, "split": "f29", "split_condition": 0.0675299987, "yes": 19, "no": 20, "missing": 19 , "children": [ 107 | { "nodeid": 19, "leaf": -0.0265968665 }, 108 | { "nodeid": 20, "leaf": 0.0653319433 } 109 | ]} 110 | ]} 111 | ]}, 112 | { "nodeid": 2, "depth": 1, "split": "f4", "split_condition": 0.0905549973, "yes": 5, "no": 6, "missing": 5 , "children": [ 113 | { "nodeid": 5, "depth": 2, "split": "f0", "split_condition": 12.8000002, "yes": 11, "no": 12, "missing": 11 , "children": [ 114 | { "nodeid": 11, "leaf": -0.454242289 }, 115 | { "nodeid": 12, "depth": 3, "split": "f0", "split_condition": 13.1300001, "yes": 21, "no": 22, "missing": 21 , "children": [ 116 | { "nodeid": 21, "leaf": -0.00947248936 }, 117 | { "nodeid": 22, "leaf": 0.00397474319 } 118 | ]} 119 | ]}, 120 | { "nodeid": 6, "depth": 2, "split": "f25", "split_condition": 0.0866699964, "yes": 13, "no": 14, "missing": 13 , "children": [ 121 | { "nodeid": 13, "depth": 3, "split": "f21", "split_condition": 22.9150009, "yes": 23, "no": 24, "missing": 23 , "children": [ 122 | { "nodeid": 23, "leaf": -0.0137156146 }, 123 | { "nodeid": 24, "leaf": -0.0937535986 } 124 | ]}, 125 | { "nodeid": 14, "depth": 3, "split": "f16", "split_condition": 0.0449949987, "yes": 25, "no": 26, "missing": 25 , "children": [ 126 | { "nodeid": 25, "leaf": 0.000649829279 }, 127 | { "nodeid": 26, "leaf": -0.0225983579 } 128 | ]} 129 | ]} 130 | ]} 131 | ]}, 132 | { "nodeid": 0, "depth": 0, "split": "f11", "split_condition": 0.402249992, "yes": 1, "no": 2, "missing": 1 , "children": [ 133 | { "nodeid": 1, "depth": 1, "split": "f0", "split_condition": 13.1499996, "yes": 3, "no": 4, "missing": 3 , "children": [ 134 | { "nodeid": 3, "leaf": -0.0136728287 }, 135 | { "nodeid": 4, "leaf": 0.086749047 } 136 | ]}, 137 | { "nodeid": 2, "depth": 1, "split": "f1", "split_condition": 22.6149998, "yes": 5, "no": 6, "missing": 5 , "children": [ 138 | { "nodeid": 5, "depth": 2, "split": "f21", "split_condition": 33.2900009, "yes": 7, "no": 8, "missing": 7 , "children": [ 139 | { "nodeid": 7, "depth": 3, "split": "f6", "split_condition": 0.093294993, "yes": 11, "no": 12, "missing": 11 , "children": [ 140 | { "nodeid": 11, "leaf": 0.00183420046 }, 141 | { "nodeid": 12, "leaf": -0.012388912 } 142 | ]}, 143 | { "nodeid": 8, "depth": 3, "split": "f1", "split_condition": 22.0750008, "yes": 13, "no": 14, "missing": 13 , "children": [ 144 | { "nodeid": 13, "leaf": -0.00760726165 }, 145 | { "nodeid": 14, "leaf": -0.304573357 } 146 | ]} 147 | ]}, 148 | { "nodeid": 6, "depth": 2, "split": "f9", "split_condition": 0.05418, "yes": 9, "no": 10, "missing": 9 , "children": [ 149 | { "nodeid": 9, "depth": 3, "split": "f0", "split_condition": 19.5600014, "yes": 15, "no": 16, "missing": 15 , "children": [ 150 | { "nodeid": 15, "leaf": -0.0448068455 }, 151 | { "nodeid": 16, "leaf": 0.00880362745 } 152 | ]}, 153 | { "nodeid": 10, "depth": 3, "split": "f14", "split_condition": 0.00416500028, "yes": 17, "no": 18, "missing": 17 , "children": [ 154 | { "nodeid": 17, "leaf": -0.0470660739 }, 155 | { "nodeid": 18, "leaf": 0.0172191653 } 156 | ]} 157 | ]} 158 | ]} 159 | ]}, 160 | { "nodeid": 0, "depth": 0, "split": "f3", "split_condition": 632.799988, "yes": 1, "no": 2, "missing": 1 , "children": [ 161 | { "nodeid": 1, "depth": 1, "split": "f23", "split_condition": 780.650024, "yes": 3, "no": 4, "missing": 3 , "children": [ 162 | { "nodeid": 3, "depth": 2, "split": "f21", "split_condition": 19.8499985, "yes": 7, "no": 8, "missing": 7 , "children": [ 163 | { "nodeid": 7, "depth": 3, "split": "f5", "split_condition": 0.144749999, "yes": 15, "no": 16, "missing": 15 , "children": [ 164 | { "nodeid": 15, "leaf": -0.0201933905 }, 165 | { "nodeid": 16, "leaf": 0.0199120436 } 166 | ]}, 167 | { "nodeid": 8, "depth": 3, "split": "f24", "split_condition": 0.1822, "yes": 17, "no": 18, "missing": 17 , "children": [ 168 | { "nodeid": 17, "leaf": 0.00205801101 }, 169 | { "nodeid": 18, "leaf": -0.0549958311 } 170 | ]} 171 | ]}, 172 | { "nodeid": 4, "depth": 2, "split": "f11", "split_condition": 0.875149965, "yes": 9, "no": 10, "missing": 9 , "children": [ 173 | { "nodeid": 9, "depth": 3, "split": "f0", "split_condition": 13.3599997, "yes": 19, "no": 20, "missing": 19 , "children": [ 174 | { "nodeid": 19, "leaf": -0.00241643796 }, 175 | { "nodeid": 20, "leaf": -0.125699013 } 176 | ]}, 177 | { "nodeid": 10, "depth": 3, "split": "f1", "split_condition": 24.5900002, "yes": 21, "no": 22, "missing": 21 , "children": [ 178 | { "nodeid": 21, "leaf": 0.0024822182 }, 179 | { "nodeid": 22, "leaf": -0.0647148788 } 180 | ]} 181 | ]} 182 | ]}, 183 | { "nodeid": 2, "depth": 1, "split": "f1", "split_condition": 16.1100006, "yes": 5, "no": 6, "missing": 5 , "children": [ 184 | { "nodeid": 5, "depth": 2, "split": "f22", "split_condition": 106.5, "yes": 11, "no": 12, "missing": 11 , "children": [ 185 | { "nodeid": 11, "depth": 3, "split": "f1", "split_condition": 15.1949997, "yes": 23, "no": 24, "missing": 23 , "children": [ 186 | { "nodeid": 23, "leaf": -0.0258253571 }, 187 | { "nodeid": 24, "leaf": -0.00138604641 } 188 | ]}, 189 | { "nodeid": 12, "depth": 3, "split": "f7", "split_condition": 0.0708200037, "yes": 25, "no": 26, "missing": 25 , "children": [ 190 | { "nodeid": 25, "leaf": 0.0848956481 }, 191 | { "nodeid": 26, "leaf": -0.0134349465 } 192 | ]} 193 | ]}, 194 | { "nodeid": 6, "depth": 2, "split": "f8", "split_condition": 0.150000006, "yes": 13, "no": 14, "missing": 13 , "children": [ 195 | { "nodeid": 13, "depth": 3, "split": "f21", "split_condition": 28.4349995, "yes": 27, "no": 28, "missing": 27 , "children": [ 196 | { "nodeid": 27, "leaf": 0.0701582432 }, 197 | { "nodeid": 28, "leaf": -0.00345371664 } 198 | ]}, 199 | { "nodeid": 14, "depth": 3, "split": "f25", "split_condition": 0.293249995, "yes": 29, "no": 30, "missing": 29 , "children": [ 200 | { "nodeid": 29, "leaf": -0.0120941699 }, 201 | { "nodeid": 30, "leaf": 0.00756479334 } 202 | ]} 203 | ]} 204 | ]} 205 | ]}, 206 | { "nodeid": 0, "depth": 0, "split": "f17", "split_condition": 0.0267949998, "yes": 1, "no": 2, "missing": 1 , "children": [ 207 | { "nodeid": 1, "depth": 1, "split": "f12", "split_condition": 4.88599968, "yes": 3, "no": 4, "missing": 3 , "children": [ 208 | { "nodeid": 3, "depth": 2, "split": "f28", "split_condition": 0.270399988, "yes": 7, "no": 8, "missing": 7 , "children": [ 209 | { "nodeid": 7, "depth": 3, "split": "f10", "split_condition": 0.643100023, "yes": 15, "no": 16, "missing": 15 , "children": [ 210 | { "nodeid": 15, "leaf": -0.00645657768 }, 211 | { "nodeid": 16, "leaf": -0.0545931607 } 212 | ]}, 213 | { "nodeid": 8, "depth": 3, "split": "f13", "split_condition": 18.5149994, "yes": 17, "no": 18, "missing": 17 , "children": [ 214 | { "nodeid": 17, "leaf": 0.0106216753 }, 215 | { "nodeid": 18, "leaf": -0.00270999153 } 216 | ]} 217 | ]}, 218 | { "nodeid": 4, "depth": 2, "split": "f4", "split_condition": 0.0887399986, "yes": 9, "no": 10, "missing": 9 , "children": [ 219 | { "nodeid": 9, "leaf": 0.0722294599 }, 220 | { "nodeid": 10, "depth": 3, "split": "f7", "split_condition": 0.102899998, "yes": 19, "no": 20, "missing": 19 , "children": [ 221 | { "nodeid": 19, "leaf": 0.0123830521 }, 222 | { "nodeid": 20, "leaf": 0.000419991353 } 223 | ]} 224 | ]} 225 | ]}, 226 | { "nodeid": 2, "depth": 1, "split": "f4", "split_condition": 0.0872550011, "yes": 5, "no": 6, "missing": 5 , "children": [ 227 | { "nodeid": 5, "depth": 2, "split": "f0", "split_condition": 15.2250004, "yes": 11, "no": 12, "missing": 11 , "children": [ 228 | { "nodeid": 11, "leaf": -0.00213587284 }, 229 | { "nodeid": 12, "leaf": -0.000210208353 } 230 | ]}, 231 | { "nodeid": 6, "depth": 2, "split": "f0", "split_condition": 15.3050003, "yes": 13, "no": 14, "missing": 13 , "children": [ 232 | { "nodeid": 13, "leaf": 0.0366886556 }, 233 | { "nodeid": 14, "leaf": 0.00332048861 } 234 | ]} 235 | ]} 236 | ]}, 237 | { "nodeid": 0, "depth": 0, "split": "f10", "split_condition": 0.238600001, "yes": 1, "no": 2, "missing": 1 , "children": [ 238 | { "nodeid": 1, "depth": 1, "split": "f13", "split_condition": 18.5300007, "yes": 3, "no": 4, "missing": 3 , "children": [ 239 | { "nodeid": 3, "depth": 2, "split": "f8", "split_condition": 0.160750002, "yes": 7, "no": 8, "missing": 7 , "children": [ 240 | { "nodeid": 7, "depth": 3, "split": "f28", "split_condition": 0.272549987, "yes": 15, "no": 16, "missing": 15 , "children": [ 241 | { "nodeid": 15, "leaf": -0.00356240827 }, 242 | { "nodeid": 16, "leaf": 0.0381823666 } 243 | ]}, 244 | { "nodeid": 8, "depth": 3, "split": "f5", "split_condition": 0.130199999, "yes": 17, "no": 18, "missing": 17 , "children": [ 245 | { "nodeid": 17, "leaf": -0.00798517559 }, 246 | { "nodeid": 18, "leaf": 0.0112123443 } 247 | ]} 248 | ]}, 249 | { "nodeid": 4, "depth": 2, "split": "f26", "split_condition": 0.207249999, "yes": 9, "no": 10, "missing": 9 , "children": [ 250 | { "nodeid": 9, "depth": 3, "split": "f12", "split_condition": 1.53900003, "yes": 19, "no": 20, "missing": 19 , "children": [ 251 | { "nodeid": 19, "leaf": 0.0174627751 }, 252 | { "nodeid": 20, "leaf": 0.00308580394 } 253 | ]}, 254 | { "nodeid": 10, "depth": 3, "split": "f9", "split_condition": 0.0607199967, "yes": 21, "no": 22, "missing": 21 , "children": [ 255 | { "nodeid": 21, "leaf": -0.0761663839 }, 256 | { "nodeid": 22, "leaf": -0.00696767494 } 257 | ]} 258 | ]} 259 | ]}, 260 | { "nodeid": 2, "depth": 1, "split": "f10", "split_condition": 0.24075, "yes": 5, "no": 6, "missing": 5 , "children": [ 261 | { "nodeid": 5, "depth": 2, "split": "f4", "split_condition": 0.0973249972, "yes": 11, "no": 12, "missing": 11 , "children": [ 262 | { "nodeid": 11, "leaf": 0.0217676368 }, 263 | { "nodeid": 12, "leaf": 0.0830444992 } 264 | ]}, 265 | { "nodeid": 6, "depth": 2, "split": "f11", "split_condition": 2.09749985, "yes": 13, "no": 14, "missing": 13 , "children": [ 266 | { "nodeid": 13, "depth": 3, "split": "f16", "split_condition": 0.0470049977, "yes": 23, "no": 24, "missing": 23 , "children": [ 267 | { "nodeid": 23, "leaf": 0.000812674058 }, 268 | { "nodeid": 24, "leaf": 0.0103985416 } 269 | ]}, 270 | { "nodeid": 14, "depth": 3, "split": "f11", "split_condition": 2.26300001, "yes": 25, "no": 26, "missing": 25 , "children": [ 271 | { "nodeid": 25, "leaf": -0.0413447469 }, 272 | { "nodeid": 26, "leaf": 0.00202009291 } 273 | ]} 274 | ]} 275 | ]} 276 | ]}, 277 | { "nodeid": 0, "depth": 0, "split": "f13", "split_condition": 34.6699982, "yes": 1, "no": 2, "missing": 1 , "children": [ 278 | { "nodeid": 1, "depth": 1, "split": "f22", "split_condition": 105.949997, "yes": 3, "no": 4, "missing": 3 , "children": [ 279 | { "nodeid": 3, "depth": 2, "split": "f5", "split_condition": 0.167999998, "yes": 7, "no": 8, "missing": 7 , "children": [ 280 | { "nodeid": 7, "depth": 3, "split": "f4", "split_condition": 0.0905600041, "yes": 15, "no": 16, "missing": 15 , "children": [ 281 | { "nodeid": 15, "leaf": -0.00220231875 }, 282 | { "nodeid": 16, "leaf": 0.00390908495 } 283 | ]}, 284 | { "nodeid": 8, "depth": 3, "split": "f7", "split_condition": 0.077519998, "yes": 17, "no": 18, "missing": 17 , "children": [ 285 | { "nodeid": 17, "leaf": -0.0297411643 }, 286 | { "nodeid": 18, "leaf": -0.00898960885 } 287 | ]} 288 | ]}, 289 | { "nodeid": 4, "depth": 2, "split": "f20", "split_condition": 16.4549999, "yes": 9, "no": 10, "missing": 9 , "children": [ 290 | { "nodeid": 9, "depth": 3, "split": "f9", "split_condition": 0.0636550039, "yes": 19, "no": 20, "missing": 19 , "children": [ 291 | { "nodeid": 19, "leaf": 0.0544396304 }, 292 | { "nodeid": 20, "leaf": 0.0092678722 } 293 | ]}, 294 | { "nodeid": 10, "depth": 3, "split": "f29", "split_condition": 0.0814699978, "yes": 21, "no": 22, "missing": 21 , "children": [ 295 | { "nodeid": 21, "leaf": 0.0142280906 }, 296 | { "nodeid": 22, "leaf": -0.0097112488 } 297 | ]} 298 | ]} 299 | ]}, 300 | { "nodeid": 2, "depth": 1, "split": "f19", "split_condition": 0.00228999997, "yes": 5, "no": 6, "missing": 5 , "children": [ 301 | { "nodeid": 5, "depth": 2, "split": "f12", "split_condition": 3.1875, "yes": 11, "no": 12, "missing": 11 , "children": [ 302 | { "nodeid": 11, "depth": 3, "split": "f10", "split_condition": 0.391849995, "yes": 23, "no": 24, "missing": 23 , "children": [ 303 | { "nodeid": 23, "leaf": -0.0203813519 }, 304 | { "nodeid": 24, "leaf": 0.00446531037 } 305 | ]}, 306 | { "nodeid": 12, "depth": 3, "split": "f1", "split_condition": 18.5050011, "yes": 25, "no": 26, "missing": 25 , "children": [ 307 | { "nodeid": 25, "leaf": 0.00297276443 }, 308 | { "nodeid": 26, "leaf": 0.0293554477 } 309 | ]} 310 | ]}, 311 | { "nodeid": 6, "depth": 2, "split": "f10", "split_condition": 0.421599984, "yes": 13, "no": 14, "missing": 13 , "children": [ 312 | { "nodeid": 13, "depth": 3, "split": "f4", "split_condition": 0.0952049941, "yes": 27, "no": 28, "missing": 27 , "children": [ 313 | { "nodeid": 27, "leaf": -0.0561531335 }, 314 | { "nodeid": 28, "leaf": -0.0054722731 } 315 | ]}, 316 | { "nodeid": 14, "depth": 3, "split": "f16", "split_condition": 0.0308800004, "yes": 29, "no": 30, "missing": 29 , "children": [ 317 | { "nodeid": 29, "leaf": -0.015630642 }, 318 | { "nodeid": 30, "leaf": -0.00235219649 } 319 | ]} 320 | ]} 321 | ]} 322 | ]}, 323 | { "nodeid": 0, "depth": 0, "split": "f4", "split_condition": 0.0575699992, "yes": 1, "no": 2, "missing": 1 , "children": [ 324 | { "nodeid": 1, "leaf": 0.0339686275 }, 325 | { "nodeid": 2, "depth": 1, "split": "f29", "split_condition": 0.0648549944, "yes": 3, "no": 4, "missing": 3 , "children": [ 326 | { "nodeid": 3, "depth": 2, "split": "f17", "split_condition": 0.0120000001, "yes": 5, "no": 6, "missing": 5 , "children": [ 327 | { "nodeid": 5, "depth": 3, "split": "f10", "split_condition": 0.367200017, "yes": 9, "no": 10, "missing": 9 , "children": [ 328 | { "nodeid": 9, "leaf": 0.00622582156 }, 329 | { "nodeid": 10, "leaf": -0.00560423546 } 330 | ]}, 331 | { "nodeid": 6, "depth": 3, "split": "f8", "split_condition": 0.179399997, "yes": 11, "no": 12, "missing": 11 , "children": [ 332 | { "nodeid": 11, "leaf": 0.00278634299 }, 333 | { "nodeid": 12, "leaf": 0.0243973657 } 334 | ]} 335 | ]}, 336 | { "nodeid": 4, "depth": 2, "split": "f1", "split_condition": 18.1749992, "yes": 7, "no": 8, "missing": 7 , "children": [ 337 | { "nodeid": 7, "depth": 3, "split": "f1", "split_condition": 18.1199989, "yes": 13, "no": 14, "missing": 13 , "children": [ 338 | { "nodeid": 13, "leaf": -0.002514716 }, 339 | { "nodeid": 14, "leaf": -0.0199086815 } 340 | ]}, 341 | { "nodeid": 8, "depth": 3, "split": "f9", "split_condition": 0.0565249994, "yes": 15, "no": 16, "missing": 15 , "children": [ 342 | { "nodeid": 15, "leaf": -0.00707105827 }, 343 | { "nodeid": 16, "leaf": 0.00212062523 } 344 | ]} 345 | ]} 346 | ]} 347 | ]} 348 | ] -------------------------------------------------------------------------------- /test/data/breast_cancer_xgboost_true_prediction.txt: -------------------------------------------------------------------------------- 1 | 9.507884387858211994e-04 2 | 9.904628396034240723e-01 3 | 9.992061257362365723e-01 4 | 9.985496401786804199e-01 5 | 9.983233809471130371e-01 6 | 9.995638728141784668e-01 7 | 9.985830783843994141e-01 8 | 9.974243640899658203e-01 9 | 9.959988594055175781e-01 10 | 9.996445178985595703e-01 11 | 7.978377938270568848e-01 12 | 9.977576136589050293e-01 13 | 9.995075464248657227e-01 14 | 2.961168885231018066e-01 15 | 5.325380563735961914e-01 16 | 7.539935410022735596e-02 17 | 9.907246232032775879e-01 18 | 8.849819423630833626e-04 19 | 5.550544010475277901e-04 20 | 3.984247741755098104e-04 21 | 6.399875273928046227e-04 22 | 1.073779538273811340e-02 23 | 9.977506995201110840e-01 24 | 9.996187686920166016e-01 25 | 2.046625502407550812e-02 26 | 9.996829032897949219e-01 27 | 9.983233809471130371e-01 28 | 1.068702526390552521e-02 29 | 9.996829032897949219e-01 30 | 2.498439571354538202e-04 31 | 9.978688955307006836e-01 32 | 2.478448208421468735e-03 33 | 9.974924325942993164e-01 34 | 6.390641210600733757e-04 35 | 9.970718622207641602e-01 36 | 8.478686213493347168e-04 37 | 9.978394508361816406e-01 38 | 1.206506974995136261e-03 39 | 9.994673132896423340e-01 40 | 8.914961363188922405e-04 41 | 7.235777974128723145e-01 42 | 9.995678067207336426e-01 43 | 3.489995375275611877e-02 44 | 9.993756413459777832e-01 45 | 6.706620454788208008e-01 46 | 8.849819423630833626e-04 47 | 9.976118803024291992e-01 48 | 9.772736430168151855e-01 49 | 9.957977533340454102e-01 50 | 8.478686213493347168e-04 51 | 4.013589641544967890e-04 52 | 2.301374450325965881e-03 53 | 6.390641210600733757e-04 54 | 9.995323419570922852e-01 55 | 9.995678067207336426e-01 56 | 9.991102814674377441e-01 57 | 9.969853758811950684e-01 58 | 9.934760928153991699e-01 59 | 9.800665378570556641e-01 60 | 3.984247741755098104e-04 61 | 4.501029034145176411e-04 62 | 1.440626569092273712e-03 63 | 9.995678067207336426e-01 64 | 9.937449097633361816e-01 65 | 8.914961363188922405e-04 66 | 9.813554883003234863e-01 67 | 4.013589641544967890e-04 68 | 3.984247741755098104e-04 69 | 2.498439571354538202e-04 70 | 9.954770207405090332e-01 71 | 7.102609872817993164e-01 72 | 6.399875273928046227e-04 73 | 9.996445178985595703e-01 74 | 5.999345779418945312e-01 75 | 2.749431179836392403e-03 76 | 9.957346320152282715e-01 77 | 9.996445178985595703e-01 78 | 9.818682670593261719e-01 79 | 9.970982074737548828e-01 80 | 9.993841648101806641e-01 81 | 2.677252516150474548e-03 82 | 4.013589641544967890e-04 83 | 6.399875273928046227e-04 84 | 9.970982074737548828e-01 85 | 3.640007227659225464e-03 86 | 9.993756413459777832e-01 87 | 9.978688955307006836e-01 88 | 9.995638728141784668e-01 89 | 3.984247741755098104e-04 90 | 4.013589641544967890e-04 91 | 9.997505545616149902e-01 92 | 8.045169115066528320e-01 93 | 4.344152510166168213e-01 94 | 9.673204622231423855e-04 95 | 9.899302721023559570e-01 96 | 9.960599541664123535e-01 97 | 6.399875273928046227e-04 98 | 9.922502040863037109e-01 99 | 9.983745813369750977e-01 100 | 9.984416365623474121e-01 101 | 9.993841648101806641e-01 102 | 9.993304014205932617e-01 103 | 9.985496401786804199e-01 104 | 9.521502256393432617e-01 105 | 2.498439571354538202e-04 106 | 9.913288354873657227e-01 107 | 6.399875273928046227e-04 108 | 9.935092329978942871e-01 109 | 5.743113160133361816e-01 110 | 6.639178376644849777e-03 111 | 9.976663589477539062e-01 112 | 6.487781065516173840e-04 113 | 3.984247741755098104e-04 114 | 9.625071883201599121e-01 115 | -------------------------------------------------------------------------------- /test/data/breast_cancer_xgboost_true_prediction_regression.txt: -------------------------------------------------------------------------------- 1 | 1.680630445480346680e-02 2 | 9.798461198806762695e-01 3 | 1.010201692581176758e+00 4 | 9.739408493041992188e-01 5 | 1.007579326629638672e+00 6 | 1.013984918594360352e+00 7 | 9.934605360031127930e-01 8 | 1.006826519966125488e+00 9 | 9.922791123390197754e-01 10 | 1.100634217262268066e+00 11 | 9.366516470909118652e-01 12 | 9.836834669113159180e-01 13 | 9.780756235122680664e-01 14 | 7.569742202758789062e-02 15 | 9.503139257431030273e-01 16 | 8.479654788970947266e-03 17 | 9.391176104545593262e-01 18 | -1.753568649291992188e-04 19 | -1.188772916793823242e-02 20 | 3.946006298065185547e-03 21 | 5.186259746551513672e-03 22 | 2.909719944000244141e-03 23 | 1.005266427993774414e+00 24 | 1.003474116325378418e+00 25 | -1.848638057708740234e-02 26 | 1.003213882446289062e+00 27 | 9.442762136459350586e-01 28 | 3.905528783798217773e-02 29 | 1.002191185951232910e+00 30 | 1.745810210704803467e-01 31 | 9.945540428161621094e-01 32 | 5.160129070281982422e-02 33 | 1.050557374954223633e+00 34 | 5.166113376617431641e-03 35 | 9.909009933471679688e-01 36 | -3.882706165313720703e-03 37 | 1.003213882446289062e+00 38 | 5.425703525543212891e-02 39 | 9.890617132186889648e-01 40 | -6.142294406890869141e-02 41 | 7.839080691337585449e-01 42 | 1.007928609848022461e+00 43 | -1.400375366210937500e-01 44 | 9.927766323089599609e-01 45 | 1.480752825736999512e-01 46 | -4.520964622497558594e-02 47 | 9.831258654594421387e-01 48 | 1.006209850311279297e+00 49 | 1.000551819801330566e+00 50 | -6.543040275573730469e-03 51 | -5.362903475761413574e-01 52 | 1.243609189987182617e-02 53 | 3.049325942993164062e-02 54 | 9.948982596397399902e-01 55 | 1.017435073852539062e+00 56 | 1.000551819801330566e+00 57 | 9.006847143173217773e-01 58 | 9.856147766113281250e-01 59 | 1.002752542495727539e+00 60 | -2.635121345520019531e-04 61 | -3.627093434333801270e-01 62 | 6.899040937423706055e-02 63 | 1.007928609848022461e+00 64 | 1.000551819801330566e+00 65 | 2.521216869354248047e-02 66 | 9.856147766113281250e-01 67 | -2.635121345520019531e-04 68 | 1.199841499328613281e-03 69 | -5.011358857154846191e-01 70 | 1.005187153816223145e+00 71 | 8.528810739517211914e-01 72 | 1.026880741119384766e-02 73 | 1.001574516296386719e+00 74 | 9.693971276283264160e-01 75 | -8.028805255889892578e-03 76 | 1.028479814529418945e+00 77 | 1.005266427993774414e+00 78 | 9.727678298950195312e-01 79 | 1.002372026443481445e+00 80 | 1.001574516296386719e+00 81 | 1.186855435371398926e-01 82 | 3.946006298065185547e-03 83 | 8.160471916198730469e-04 84 | 9.445924758911132812e-01 85 | 7.560527324676513672e-02 86 | 1.005266427993774414e+00 87 | 1.033319234848022461e+00 88 | 1.002191185951232910e+00 89 | -4.559117555618286133e-02 90 | 3.946006298065185547e-03 91 | 1.006289243698120117e+00 92 | 1.375730335712432861e-01 93 | 8.968000411987304688e-01 94 | -6.543040275573730469e-03 95 | 9.764622449874877930e-01 96 | 9.974119663238525391e-01 97 | 2.536183595657348633e-02 98 | 1.018610119819641113e+00 99 | 1.002292633056640625e+00 100 | 1.001574516296386719e+00 101 | 1.032732248306274414e+00 102 | 9.948982596397399902e-01 103 | 9.934271574020385742e-01 104 | 9.961962699890136719e-01 105 | -2.266860008239746094e-02 106 | 9.929647445678710938e-01 107 | -6.513595581054687500e-03 108 | 1.006209850311279297e+00 109 | -1.787585020065307617e-02 110 | 9.325378537178039551e-01 111 | 9.960179924964904785e-01 112 | -3.393471240997314453e-03 113 | -2.266860008239746094e-02 114 | 8.430176377296447754e-01 115 | -------------------------------------------------------------------------------- /test/data/iris_test.libsvm: -------------------------------------------------------------------------------- 1 | 2 0:5.8 1:2.8 2:5.1 3:2.4 2 | 1 0:6 1:2.2 2:4 3:1 3 | 0 0:5.5 1:4.2 2:1.4 3:0.2 4 | 2 0:7.3 1:2.9 2:6.3 3:1.8 5 | 0 0:5 1:3.4 2:1.5 3:0.2 6 | 2 0:6.3 1:3.3 2:6 3:2.5 7 | 0 0:5 1:3.5 2:1.3 3:0.3 8 | 1 0:6.7 1:3.1 2:4.7 3:1.5 9 | 1 0:6.8 1:2.8 2:4.8 3:1.4 10 | 1 0:6.1 1:2.8 2:4 3:1.3 11 | 2 0:6.1 1:2.6 2:5.6 3:1.4 12 | 1 0:6.4 1:3.2 2:4.5 3:1.5 13 | 1 0:6.1 1:2.8 2:4.7 3:1.2 14 | 1 0:6.5 1:2.8 2:4.6 3:1.5 15 | 1 0:6.1 1:2.9 2:4.7 3:1.4 16 | 0 0:4.9 1:3.6 2:1.4 3:0.1 17 | 1 0:6 1:2.9 2:4.5 3:1.5 18 | 1 0:5.5 1:2.6 2:4.4 3:1.2 19 | 0 0:4.8 1:3 2:1.4 3:0.3 20 | 0 0:5.4 1:3.9 2:1.3 3:0.4 21 | 2 0:5.6 1:2.8 2:4.9 3:2 22 | 1 0:5.6 1:3 2:4.5 3:1.5 23 | 0 0:4.8 1:3.4 2:1.9 3:0.2 24 | 0 0:4.4 1:2.9 2:1.4 3:0.2 25 | 2 0:6.2 1:2.8 2:4.8 3:1.8 26 | 0 0:4.6 1:3.6 2:1 3:0.2 27 | 0 0:5.1 1:3.8 2:1.9 3:0.4 28 | 1 0:6.2 1:2.9 2:4.3 3:1.3 29 | 1 0:5 1:2.3 2:3.3 3:1 30 | 0 0:5 1:3.4 2:1.6 3:0.4 31 | -------------------------------------------------------------------------------- /test/data/iris_xgboost_dump.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "nodeid": 0, "depth": 0, "split": "f2", "split_condition": 2.3499999, "yes": 1, "no": 2, "missing": 1 , "children": [ 3 | { "nodeid": 1, "leaf": 1.41818178 }, 4 | { "nodeid": 2, "leaf": -0.729729772 } 5 | ]}, 6 | { "nodeid": 0, "depth": 0, "split": "f2", "split_condition": 2.3499999, "yes": 1, "no": 2, "missing": 1 , "children": [ 7 | { "nodeid": 1, "leaf": -0.709090948 }, 8 | { "nodeid": 2, "depth": 1, "split": "f3", "split_condition": 1.75, "yes": 3, "no": 4, "missing": 3 , "children": [ 9 | { "nodeid": 3, "depth": 2, "split": "f2", "split_condition": 4.94999981, "yes": 5, "no": 6, "missing": 5 , "children": [ 10 | { "nodeid": 5, "depth": 3, "split": "f0", "split_condition": 5.05000019, "yes": 9, "no": 10, "missing": 9 , "children": [ 11 | { "nodeid": 9, "leaf": 0.428571403 }, 12 | { "nodeid": 10, "leaf": 1.40145981 } 13 | ]}, 14 | { "nodeid": 6, "leaf": 0.103448249 } 15 | ]}, 16 | { "nodeid": 4, "depth": 2, "split": "f2", "split_condition": 4.94999981, "yes": 7, "no": 8, "missing": 7 , "children": [ 17 | { "nodeid": 7, "leaf": -0.120000027 }, 18 | { "nodeid": 8, "leaf": -0.707006454 } 19 | ]} 20 | ]} 21 | ]}, 22 | { "nodeid": 0, "depth": 0, "split": "f3", "split_condition": 1.6500001, "yes": 1, "no": 2, "missing": 1 , "children": [ 23 | { "nodeid": 1, "depth": 1, "split": "f2", "split_condition": 4.94999981, "yes": 3, "no": 4, "missing": 3 , "children": [ 24 | { "nodeid": 3, "leaf": -0.727574825 }, 25 | { "nodeid": 4, "leaf": 0.599999964 } 26 | ]}, 27 | { "nodeid": 2, "depth": 1, "split": "f2", "split_condition": 4.85000038, "yes": 5, "no": 6, "missing": 5 , "children": [ 28 | { "nodeid": 5, "leaf": 0.428571403 }, 29 | { "nodeid": 6, "leaf": 1.36686385 } 30 | ]} 31 | ]}, 32 | { "nodeid": 0, "depth": 0, "split": "f2", "split_condition": 2.3499999, "yes": 1, "no": 2, "missing": 1 , "children": [ 33 | { "nodeid": 1, "leaf": 0.570723355 }, 34 | { "nodeid": 2, "leaf": -0.525305271 } 35 | ]}, 36 | { "nodeid": 0, "depth": 0, "split": "f2", "split_condition": 2.3499999, "yes": 1, "no": 2, "missing": 1 , "children": [ 37 | { "nodeid": 1, "leaf": -0.482347488 }, 38 | { "nodeid": 2, "depth": 1, "split": "f3", "split_condition": 1.75, "yes": 3, "no": 4, "missing": 3 , "children": [ 39 | { "nodeid": 3, "depth": 2, "split": "f2", "split_condition": 5.05000019, "yes": 5, "no": 6, "missing": 5 , "children": [ 40 | { "nodeid": 5, "depth": 3, "split": "f1", "split_condition": 2.25, "yes": 9, "no": 10, "missing": 9 , "children": [ 41 | { "nodeid": 9, "leaf": 0.113863461 }, 42 | { "nodeid": 10, "leaf": 0.563220203 } 43 | ]}, 44 | { "nodeid": 6, "leaf": 0.0109019689 } 45 | ]}, 46 | { "nodeid": 4, "depth": 2, "split": "f0", "split_condition": 5.94999981, "yes": 7, "no": 8, "missing": 7 , "children": [ 47 | { "nodeid": 7, "leaf": 0.135854721 }, 48 | { "nodeid": 8, "leaf": -0.497978657 } 49 | ]} 50 | ]} 51 | ]}, 52 | { "nodeid": 0, "depth": 0, "split": "f3", "split_condition": 1.75, "yes": 1, "no": 2, "missing": 1 , "children": [ 53 | { "nodeid": 1, "depth": 1, "split": "f3", "split_condition": 1.45000005, "yes": 3, "no": 4, "missing": 3 , "children": [ 54 | { "nodeid": 3, "leaf": -0.51224184 }, 55 | { "nodeid": 4, "depth": 2, "split": "f1", "split_condition": 2.5999999, "yes": 7, "no": 8, "missing": 7 , "children": [ 56 | { "nodeid": 7, "leaf": 0.360349715 }, 57 | { "nodeid": 8, "depth": 3, "split": "f2", "split_condition": 5.05000019, "yes": 9, "no": 10, "missing": 9 , "children": [ 58 | { "nodeid": 9, "leaf": -0.522972643 }, 59 | { "nodeid": 10, "leaf": 0.159815907 } 60 | ]} 61 | ]} 62 | ]}, 63 | { "nodeid": 2, "depth": 1, "split": "f0", "split_condition": 5.94999981, "yes": 5, "no": 6, "missing": 5 , "children": [ 64 | { "nodeid": 5, "leaf": 0.0965198055 }, 65 | { "nodeid": 6, "leaf": 0.591015399 } 66 | ]} 67 | ]}, 68 | { "nodeid": 0, "depth": 0, "split": "f2", "split_condition": 2.3499999, "yes": 1, "no": 2, "missing": 1 , "children": [ 69 | { "nodeid": 1, "leaf": 0.456344187 }, 70 | { "nodeid": 2, "leaf": -0.457812548 } 71 | ]}, 72 | { "nodeid": 0, "depth": 0, "split": "f2", "split_condition": 5.14999962, "yes": 1, "no": 2, "missing": 1 , "children": [ 73 | { "nodeid": 1, "depth": 1, "split": "f2", "split_condition": 2.3499999, "yes": 3, "no": 4, "missing": 3 , "children": [ 74 | { "nodeid": 3, "leaf": -0.386105388 }, 75 | { "nodeid": 4, "depth": 2, "split": "f3", "split_condition": 1.6500001, "yes": 5, "no": 6, "missing": 5 , "children": [ 76 | { "nodeid": 5, "depth": 3, "split": "f2", "split_condition": 4.94999981, "yes": 7, "no": 8, "missing": 7 , "children": [ 77 | { "nodeid": 7, "leaf": 0.469188809 }, 78 | { "nodeid": 8, "leaf": 0.0293931793 } 79 | ]}, 80 | { "nodeid": 6, "depth": 3, "split": "f1", "split_condition": 2.8499999, "yes": 9, "no": 10, "missing": 9 , "children": [ 81 | { "nodeid": 9, "leaf": -0.418015361 }, 82 | { "nodeid": 10, "leaf": 0.31059292 } 83 | ]} 84 | ]} 85 | ]}, 86 | { "nodeid": 2, "leaf": -0.403920561 } 87 | ]}, 88 | { "nodeid": 0, "depth": 0, "split": "f3", "split_condition": 1.45000005, "yes": 1, "no": 2, "missing": 1 , "children": [ 89 | { "nodeid": 1, "leaf": -0.434588552 }, 90 | { "nodeid": 2, "depth": 1, "split": "f2", "split_condition": 5.14999962, "yes": 3, "no": 4, "missing": 3 , "children": [ 91 | { "nodeid": 3, "depth": 2, "split": "f0", "split_condition": 5.85000038, "yes": 5, "no": 6, "missing": 5 , "children": [ 92 | { "nodeid": 5, "leaf": 0.432496309 }, 93 | { "nodeid": 6, "depth": 3, "split": "f3", "split_condition": 1.54999995, "yes": 7, "no": 8, "missing": 7 , "children": [ 94 | { "nodeid": 7, "leaf": 0.195194468 }, 95 | { "nodeid": 8, "leaf": -0.228408083 } 96 | ]} 97 | ]}, 98 | { "nodeid": 4, "leaf": 0.470525205 } 99 | ]} 100 | ]}, 101 | { "nodeid": 0, "depth": 0, "split": "f2", "split_condition": 2.3499999, "yes": 1, "no": 2, "missing": 1 , "children": [ 102 | { "nodeid": 1, "leaf": 0.368954629 }, 103 | { "nodeid": 2, "leaf": -0.394197434 } 104 | ]}, 105 | { "nodeid": 0, "depth": 0, "split": "f3", "split_condition": 1.8499999, "yes": 1, "no": 2, "missing": 1 , "children": [ 106 | { "nodeid": 1, "depth": 1, "split": "f2", "split_condition": 2.3499999, "yes": 3, "no": 4, "missing": 3 , "children": [ 107 | { "nodeid": 3, "leaf": -0.290147722 }, 108 | { "nodeid": 4, "depth": 2, "split": "f3", "split_condition": 1.45000005, "yes": 5, "no": 6, "missing": 5 , "children": [ 109 | { "nodeid": 5, "leaf": 0.341089159 }, 110 | { "nodeid": 6, "depth": 3, "split": "f1", "split_condition": 2.5999999, "yes": 7, "no": 8, "missing": 7 , "children": [ 111 | { "nodeid": 7, "leaf": -0.186997622 }, 112 | { "nodeid": 8, "leaf": 0.144342914 } 113 | ]} 114 | ]} 115 | ]}, 116 | { "nodeid": 2, "leaf": -0.305422276 } 117 | ]}, 118 | { "nodeid": 0, "depth": 0, "split": "f3", "split_condition": 1.75, "yes": 1, "no": 2, "missing": 1 , "children": [ 119 | { "nodeid": 1, "depth": 1, "split": "f1", "split_condition": 2.54999995, "yes": 3, "no": 4, "missing": 3 , "children": [ 120 | { "nodeid": 3, "leaf": 0.107419312 }, 121 | { "nodeid": 4, "depth": 2, "split": "f0", "split_condition": 6.19999981, "yes": 7, "no": 8, "missing": 7 , "children": [ 122 | { "nodeid": 7, "leaf": -0.447303772 }, 123 | { "nodeid": 8, "leaf": 0.0119502079 } 124 | ]} 125 | ]}, 126 | { "nodeid": 2, "depth": 1, "split": "f1", "split_condition": 3.1500001, "yes": 5, "no": 6, "missing": 5 , "children": [ 127 | { "nodeid": 5, "leaf": 0.428696811 }, 128 | { "nodeid": 6, "leaf": -0.004399647 } 129 | ]} 130 | ]}, 131 | { "nodeid": 0, "depth": 0, "split": "f2", "split_condition": 2.3499999, "yes": 1, "no": 2, "missing": 1 , "children": [ 132 | { "nodeid": 1, "leaf": 0.282539934 }, 133 | { "nodeid": 2, "leaf": -0.328204125 } 134 | ]}, 135 | { "nodeid": 0, "depth": 0, "split": "f2", "split_condition": 5.05000019, "yes": 1, "no": 2, "missing": 1 , "children": [ 136 | { "nodeid": 1, "depth": 1, "split": "f0", "split_condition": 5.44999981, "yes": 3, "no": 4, "missing": 3 , "children": [ 137 | { "nodeid": 3, "leaf": -0.165845931 }, 138 | { "nodeid": 4, "depth": 2, "split": "f0", "split_condition": 6.14999962, "yes": 7, "no": 8, "missing": 7 , "children": [ 139 | { "nodeid": 7, "depth": 3, "split": "f3", "split_condition": 1.54999995, "yes": 9, "no": 10, "missing": 9 , "children": [ 140 | { "nodeid": 9, "leaf": 0.0212558489 }, 141 | { "nodeid": 10, "leaf": 0.0911257192 } 142 | ]}, 143 | { "nodeid": 8, "leaf": 0.319729418 } 144 | ]} 145 | ]}, 146 | { "nodeid": 2, "depth": 1, "split": "f1", "split_condition": 2.8499999, "yes": 5, "no": 6, "missing": 5 , "children": [ 147 | { "nodeid": 5, "leaf": 0.0176138561 }, 148 | { "nodeid": 6, "leaf": -0.304889649 } 149 | ]} 150 | ]}, 151 | { "nodeid": 0, "depth": 0, "split": "f2", "split_condition": 5.05000019, "yes": 1, "no": 2, "missing": 1 , "children": [ 152 | { "nodeid": 1, "depth": 1, "split": "f1", "split_condition": 2.75, "yes": 3, "no": 4, "missing": 3 , "children": [ 153 | { "nodeid": 3, "leaf": 0.077804476 }, 154 | { "nodeid": 4, "depth": 2, "split": "f3", "split_condition": 1.75, "yes": 7, "no": 8, "missing": 7 , "children": [ 155 | { "nodeid": 7, "leaf": -0.350292534 }, 156 | { "nodeid": 8, "leaf": -0.0562754013 } 157 | ]} 158 | ]}, 159 | { "nodeid": 2, "depth": 1, "split": "f1", "split_condition": 2.8499999, "yes": 5, "no": 6, "missing": 5 , "children": [ 160 | { "nodeid": 5, "leaf": 0.0480240881 }, 161 | { "nodeid": 6, "leaf": 0.350658625 } 162 | ]} 163 | ]}, 164 | { "nodeid": 0, "leaf": -0.0702709854 }, 165 | { "nodeid": 0, "depth": 0, "split": "f2", "split_condition": 4.85000038, "yes": 1, "no": 2, "missing": 1 , "children": [ 166 | { "nodeid": 1, "depth": 1, "split": "f0", "split_condition": 5.44999981, "yes": 3, "no": 4, "missing": 3 , "children": [ 167 | { "nodeid": 3, "leaf": -0.105541542 }, 168 | { "nodeid": 4, "leaf": 0.232524648 } 169 | ]}, 170 | { "nodeid": 2, "depth": 1, "split": "f3", "split_condition": 1.75, "yes": 5, "no": 6, "missing": 5 , "children": [ 171 | { "nodeid": 5, "leaf": 0.0554334447 }, 172 | { "nodeid": 6, "leaf": -0.273440927 } 173 | ]} 174 | ]}, 175 | { "nodeid": 0, "depth": 0, "split": "f2", "split_condition": 4.85000038, "yes": 1, "no": 2, "missing": 1 , "children": [ 176 | { "nodeid": 1, "depth": 1, "split": "f3", "split_condition": 1.6500001, "yes": 3, "no": 4, "missing": 3 , "children": [ 177 | { "nodeid": 3, "leaf": -0.281562328 }, 178 | { "nodeid": 4, "leaf": 0.036158219 } 179 | ]}, 180 | { "nodeid": 2, "depth": 1, "split": "f3", "split_condition": 1.75, "yes": 5, "no": 6, "missing": 5 , "children": [ 181 | { "nodeid": 5, "leaf": -0.0176518075 }, 182 | { "nodeid": 6, "leaf": 0.314271659 } 183 | ]} 184 | ]}, 185 | { "nodeid": 0, "leaf": -0.042983193 }, 186 | { "nodeid": 0, "depth": 0, "split": "f1", "split_condition": 2.75, "yes": 1, "no": 2, "missing": 1 , "children": [ 187 | { "nodeid": 1, "leaf": 0.105582148 }, 188 | { "nodeid": 2, "depth": 1, "split": "f0", "split_condition": 5.94999981, "yes": 3, "no": 4, "missing": 3 , "children": [ 189 | { "nodeid": 3, "leaf": 0.0856811777 }, 190 | { "nodeid": 4, "leaf": -0.202215835 } 191 | ]} 192 | ]}, 193 | { "nodeid": 0, "depth": 0, "split": "f0", "split_condition": 5.94999981, "yes": 1, "no": 2, "missing": 1 , "children": [ 194 | { "nodeid": 1, "leaf": -0.136622816 }, 195 | { "nodeid": 2, "depth": 1, "split": "f1", "split_condition": 2.75, "yes": 3, "no": 4, "missing": 3 , "children": [ 196 | { "nodeid": 3, "leaf": -0.104906783 }, 197 | { "nodeid": 4, "depth": 2, "split": "f0", "split_condition": 6.35000038, "yes": 5, "no": 6, "missing": 5 , "children": [ 198 | { "nodeid": 5, "leaf": 0.345432401 }, 199 | { "nodeid": 6, "leaf": 0.0375811718 } 200 | ]} 201 | ]} 202 | ]}, 203 | { "nodeid": 0, "leaf": -0.0233375337 }, 204 | { "nodeid": 0, "depth": 0, "split": "f0", "split_condition": 5.44999981, "yes": 1, "no": 2, "missing": 1 , "children": [ 205 | { "nodeid": 1, "leaf": -0.151180819 }, 206 | { "nodeid": 2, "depth": 1, "split": "f3", "split_condition": 1.54999995, "yes": 3, "no": 4, "missing": 3 , "children": [ 207 | { "nodeid": 3, "leaf": -0.0866853967 }, 208 | { "nodeid": 4, "depth": 2, "split": "f3", "split_condition": 1.75, "yes": 5, "no": 6, "missing": 5 , "children": [ 209 | { "nodeid": 5, "leaf": 0.290820271 }, 210 | { "nodeid": 6, "leaf": -0.060414616 } 211 | ]} 212 | ]} 213 | ]}, 214 | { "nodeid": 0, "depth": 0, "split": "f1", "split_condition": 2.6500001, "yes": 1, "no": 2, "missing": 1 , "children": [ 215 | { "nodeid": 1, "leaf": 0.155195192 }, 216 | { "nodeid": 2, "depth": 1, "split": "f0", "split_condition": 6.05000019, "yes": 3, "no": 4, "missing": 3 , "children": [ 217 | { "nodeid": 3, "leaf": -0.204592392 }, 218 | { "nodeid": 4, "leaf": 0.119657941 } 219 | ]} 220 | ]}, 221 | { "nodeid": 0, "leaf": -0.03755242 }, 222 | { "nodeid": 0, "depth": 0, "split": "f0", "split_condition": 5.44999981, "yes": 1, "no": 2, "missing": 1 , "children": [ 223 | { "nodeid": 1, "leaf": -0.100530624 }, 224 | { "nodeid": 2, "depth": 1, "split": "f2", "split_condition": 4.94999981, "yes": 3, "no": 4, "missing": 3 , "children": [ 225 | { "nodeid": 3, "leaf": 0.154029667 }, 226 | { "nodeid": 4, "leaf": -0.070170112 } 227 | ]} 228 | ]}, 229 | { "nodeid": 0, "depth": 0, "split": "f2", "split_condition": 4.94999981, "yes": 1, "no": 2, "missing": 1 , "children": [ 230 | { "nodeid": 1, "leaf": -0.0967265368 }, 231 | { "nodeid": 2, "leaf": 0.123283878 } 232 | ]}, 233 | { "nodeid": 0, "leaf": -0.0266483147 }, 234 | { "nodeid": 0, "depth": 0, "split": "f3", "split_condition": 1.75, "yes": 1, "no": 2, "missing": 1 , "children": [ 235 | { "nodeid": 1, "depth": 1, "split": "f0", "split_condition": 5.44999981, "yes": 3, "no": 4, "missing": 3 , "children": [ 236 | { "nodeid": 3, "leaf": -0.0930355117 }, 237 | { "nodeid": 4, "depth": 2, "split": "f3", "split_condition": 1.54999995, "yes": 5, "no": 6, "missing": 5 , "children": [ 238 | { "nodeid": 5, "leaf": -0.0467111468 }, 239 | { "nodeid": 6, "leaf": 0.261408627 } 240 | ]} 241 | ]}, 242 | { "nodeid": 2, "leaf": -0.105106108 } 243 | ]}, 244 | { "nodeid": 0, "depth": 0, "split": "f3", "split_condition": 1.75, "yes": 1, "no": 2, "missing": 1 , "children": [ 245 | { "nodeid": 1, "depth": 1, "split": "f1", "split_condition": 2.54999995, "yes": 3, "no": 4, "missing": 3 , "children": [ 246 | { "nodeid": 3, "leaf": 0.0710720643 }, 247 | { "nodeid": 4, "leaf": -0.17827712 } 248 | ]}, 249 | { "nodeid": 2, "leaf": 0.155670643 } 250 | ]} 251 | ] -------------------------------------------------------------------------------- /test/data/iris_xgboost_true_prediction.txt: -------------------------------------------------------------------------------- 1 | 2.000000000000000000e+00 2 | 1.000000000000000000e+00 3 | 0.000000000000000000e+00 4 | 2.000000000000000000e+00 5 | 0.000000000000000000e+00 6 | 2.000000000000000000e+00 7 | 0.000000000000000000e+00 8 | 1.000000000000000000e+00 9 | 1.000000000000000000e+00 10 | 1.000000000000000000e+00 11 | 1.000000000000000000e+00 12 | 1.000000000000000000e+00 13 | 1.000000000000000000e+00 14 | 1.000000000000000000e+00 15 | 1.000000000000000000e+00 16 | 0.000000000000000000e+00 17 | 1.000000000000000000e+00 18 | 1.000000000000000000e+00 19 | 0.000000000000000000e+00 20 | 0.000000000000000000e+00 21 | 2.000000000000000000e+00 22 | 1.000000000000000000e+00 23 | 0.000000000000000000e+00 24 | 0.000000000000000000e+00 25 | 2.000000000000000000e+00 26 | 0.000000000000000000e+00 27 | 0.000000000000000000e+00 28 | 1.000000000000000000e+00 29 | 1.000000000000000000e+00 30 | 0.000000000000000000e+00 31 | -------------------------------------------------------------------------------- /test/data/iris_xgboost_true_prediction_proba.txt: -------------------------------------------------------------------------------- 1 | 5.097981076687574387e-03 1.299364026635885239e-02 9.819083809852600098e-01 2 | 4.710546229034662247e-03 9.838193655014038086e-01 1.147000957280397415e-02 3 | 9.860628247261047363e-01 1.206334959715604782e-02 1.873833476565778255e-03 4 | 1.364143332466483116e-03 1.593237393535673618e-03 9.970425963401794434e-01 5 | 9.931260943412780762e-01 4.986637271940708160e-03 1.887255930341780186e-03 6 | 1.546557177789509296e-03 1.152009470388293266e-03 9.973014593124389648e-01 7 | 9.931260943412780762e-01 4.986637271940708160e-03 1.887255930341780186e-03 8 | 3.707774914801120758e-03 9.876776337623596191e-01 8.614539168775081635e-03 9 | 3.062302945181727409e-03 9.931066632270812988e-01 3.831033594906330109e-03 10 | 4.120482131838798523e-03 9.914488792419433594e-01 4.430601373314857483e-03 11 | 4.585805535316467285e-02 6.573219895362854004e-01 2.968198955059051514e-01 12 | 3.707774914801120758e-03 9.876776337623596191e-01 8.614539168775081635e-03 13 | 4.120482131838798523e-03 9.914488792419433594e-01 4.430601373314857483e-03 14 | 3.707774914801120758e-03 9.876776337623596191e-01 8.614539168775081635e-03 15 | 4.120482131838798523e-03 9.914488792419433594e-01 4.430601373314857483e-03 16 | 9.931260943412780762e-01 4.986637271940708160e-03 1.887255930341780186e-03 17 | 4.997885320335626602e-03 9.877855181694030762e-01 7.216583471745252609e-03 18 | 3.035875270143151283e-03 9.937592744827270508e-01 3.204780863597989082e-03 19 | 9.931260943412780762e-01 4.986637271940708160e-03 1.887255930341780186e-03 20 | 9.931260943412780762e-01 4.986637271940708160e-03 1.887255930341780186e-03 21 | 6.829013582319021225e-03 4.216176271438598633e-02 9.510092735290527344e-01 22 | 3.763528540730476379e-03 9.919819831848144531e-01 4.254468716681003571e-03 23 | 9.931260943412780762e-01 4.986637271940708160e-03 1.887255930341780186e-03 24 | 9.931260943412780762e-01 4.986637271940708160e-03 1.887255930341780186e-03 25 | 1.145840156823396683e-02 9.198825061321258545e-02 8.965533971786499023e-01 26 | 9.931260943412780762e-01 4.986637271940708160e-03 1.887255930341780186e-03 27 | 9.931260943412780762e-01 4.986637271940708160e-03 1.887255930341780186e-03 28 | 3.058079397305846214e-03 9.917369484901428223e-01 5.204926710575819016e-03 29 | 1.847001723945140839e-02 9.379600882530212402e-01 4.356982186436653137e-02 30 | 9.931260943412780762e-01 4.986637271940708160e-03 1.887255930341780186e-03 31 | -------------------------------------------------------------------------------- /test/scripts/breast_cancer_xgboost.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import xgboost as xgb 3 | from sklearn import datasets 4 | from sklearn.datasets import dump_svmlight_file 5 | from sklearn.model_selection import train_test_split 6 | 7 | X, y = datasets.load_breast_cancer(return_X_y=True) 8 | X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0) 9 | 10 | # For binary classification. 11 | dtrain = xgb.DMatrix(X_train, label=y_train) 12 | classification_param = {'max_depth': 4, 'eta': 1, 'objective': 'binary:logistic', 'nthread': 4, 'eval_metric': 'auc'} 13 | 14 | num_round = 10 15 | bst = xgb.train(classification_param, dtrain, num_round) 16 | y_pred = bst.predict(xgb.DMatrix(X_test)) 17 | 18 | np.savetxt('../data/breast_cancer_xgboost_true_prediction.txt', y_pred, delimiter='\t') 19 | dump_svmlight_file(X_test, y_test, '../data/breast_cancer_test.libsvm') 20 | bst.dump_model('../data/breast_cancer_xgboost_dump.json', dump_format='json') 21 | 22 | # Dump model with feature map. 23 | bst.dump_model('../data/breast_cancer_xgboost_dump_fmap.json', dump_format='json', 24 | fmap='../data/breast_cancer_fmap.txt') 25 | 26 | # For regression. 27 | y_train_mean = np.mean(y_train) 28 | regression_params = { 29 | 'base_score': y_train_mean, 30 | 'max_depth': 4, 31 | 'eta': 1, 32 | 'objective': 'reg:linear', 33 | 'eval_metric': 'mae', 34 | 'silent': 1 35 | } 36 | print("mean y_train is: {}".format(y_train_mean)) 37 | 38 | bst = xgb.train(params=regression_params, dtrain=dtrain, num_boost_round=num_round) 39 | y_pred = bst.predict(xgb.DMatrix(X_test)) 40 | np.savetxt('../data/breast_cancer_xgboost_true_prediction_regression.txt', y_pred, delimiter='\t') 41 | bst.dump_model('../data/breast_cancer_xgboost_dump_regression.json', dump_format='json') 42 | -------------------------------------------------------------------------------- /test/scripts/diamonds_xgboost.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | from sklearn.model_selection import train_test_split 3 | import numpy as np 4 | import xgboost as xgb 5 | from sklearn import datasets 6 | from sklearn.datasets import dump_svmlight_file 7 | 8 | # get data 9 | diamonds = pd.read_csv("../data/diamonds.csv") 10 | diamonds.price = 1 * (diamonds.price > 3000) 11 | 12 | cut = pd.get_dummies(diamonds.color, drop_first=True) 13 | cut.columns = [f"cut_{c}" for c in cut.columns.tolist()] 14 | diamonds = diamonds.drop('cut', axis = 1) 15 | diamonds = pd.concat([diamonds, cut], axis=1) 16 | 17 | clarity = pd.get_dummies(diamonds.clarity, drop_first=True) 18 | clarity.columns = [f"clarity_{c}" for c in clarity.columns.tolist()] 19 | diamonds = diamonds.drop('clarity', axis = 1) 20 | diamonds = pd.concat([diamonds, clarity], axis=1) 21 | 22 | color = pd.get_dummies(diamonds.color, drop_first=True) 23 | color.columns = [f"color{c}" for c in color.columns.tolist()] 24 | diamonds = diamonds.drop('color', axis = 1) 25 | diamonds = pd.concat([diamonds, color], axis=1) 26 | 27 | X, y = diamonds.drop('price', axis=1), diamonds[['price']] 28 | 29 | X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=1) 30 | 31 | # training 32 | model = xgb.XGBClassifier( 33 | n_estimators=100, 34 | max_depth=5, 35 | n_jobs=-1, 36 | verbose_eval=None, 37 | ) 38 | 39 | model.fit(X_train.values, y_train.values.ravel()) 40 | 41 | # inference 42 | bst = model.get_booster() 43 | y_pred_probas = model.predict_proba(X_test.values)[:,1] 44 | y_pred = model.predict(X_test.values) 45 | 46 | # save model 47 | np.savetxt('../data/diamonds_xgboost_true_prediction_proba.txt', y_pred_probas, delimiter='\t') 48 | dump_svmlight_file(X_test.values, y_test.values.ravel(), '../data/diamonds_test.libsvm') 49 | bst.dump_model('../data/diamonds_xgboost_dump.json', dump_format='json') -------------------------------------------------------------------------------- /test/scripts/iris_xgboost.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import xgboost as xgb 3 | from sklearn import datasets 4 | from sklearn.datasets import dump_svmlight_file 5 | from sklearn.model_selection import train_test_split 6 | 7 | 8 | def softmax(x): 9 | return np.exp(x) / np.expand_dims(np.sum(np.exp(x), axis=1), 1) 10 | 11 | 12 | X, y = datasets.load_iris(return_X_y=True) 13 | X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0) 14 | 15 | dtrain = xgb.DMatrix(X_train, label=y_train) 16 | param = {'max_depth': 4, 'eta': 1, 'objective': 'multi:softmax', 'nthread': 4, 17 | 'eval_metric': 'auc', 'num_class': 3} 18 | 19 | num_round = 10 20 | bst = xgb.train(param, dtrain, num_round) 21 | y_pred = bst.predict(xgb.DMatrix(X_test)) 22 | y_pred_proba = softmax(bst.predict(xgb.DMatrix(X_test), output_margin=True)) 23 | 24 | np.savetxt('../data/iris_xgboost_true_prediction.txt', y_pred, delimiter='\t') 25 | np.savetxt('../data/iris_xgboost_true_prediction_proba.txt', y_pred_proba, delimiter='\t') 26 | dump_svmlight_file(X_test, y_test, '../data/iris_test.libsvm') 27 | bst.dump_model('../data/iris_xgboost_dump.json', dump_format='json') 28 | -------------------------------------------------------------------------------- /test/xgbensemble_test.go: -------------------------------------------------------------------------------- 1 | package xgboost 2 | 3 | import ( 4 | "os" 5 | "testing" 6 | 7 | "gotest.tools/assert" 8 | 9 | xgb "github.com/Elvenson/xgboost-go" 10 | "github.com/Elvenson/xgboost-go/activation" 11 | "github.com/Elvenson/xgboost-go/mat" 12 | ) 13 | 14 | func TestEnsemble_PredictBreastCancer(t *testing.T) { 15 | modelPath := "data/breast_cancer_xgboost_dump.json" 16 | ensemble, err := xgb.LoadXGBoostFromJSON(modelPath, 17 | "", 1, 4, &activation.Logistic{}) 18 | assert.NilError(t, err) 19 | 20 | inputPath := "data/breast_cancer_test.libsvm" 21 | input, err := mat.ReadLibsvmFileToSparseMatrix(inputPath) 22 | assert.NilError(t, err) 23 | 24 | predictions, err := ensemble.PredictProba(input) 25 | assert.NilError(t, err) 26 | 27 | expectedPredPath := "data/breast_cancer_xgboost_true_prediction.txt" 28 | expectedClasses, err := mat.ReadCSVFileToDenseMatrix(expectedPredPath, "\t", 0.0) 29 | assert.NilError(t, err) 30 | 31 | err = mat.IsEqualMatrices(&predictions, &expectedClasses, 0.0001) 32 | assert.NilError(t, err) 33 | 34 | predictions, err = ensemble.Predict(input) 35 | assert.NilError(t, err) 36 | 37 | err = mat.IsEqualMatrices(&predictions, &expectedClasses, 0.0001) 38 | assert.NilError(t, err) 39 | 40 | // With undefined depth 41 | ensemble, err = xgb.LoadXGBoostFromJSON(modelPath, 42 | "", 1, 0, &activation.Logistic{}) 43 | assert.NilError(t, err) 44 | 45 | predictions, err = ensemble.PredictProba(input) 46 | assert.NilError(t, err) 47 | 48 | err = mat.IsEqualMatrices(&predictions, &expectedClasses, 0.0001) 49 | assert.NilError(t, err) 50 | 51 | predictions, err = ensemble.Predict(input) 52 | assert.NilError(t, err) 53 | 54 | err = mat.IsEqualMatrices(&predictions, &expectedClasses, 0.0001) 55 | assert.NilError(t, err) 56 | 57 | assert.Check(t, len(ensemble.Name()) != 0) 58 | 59 | // Load from byte arr 60 | data, err := os.ReadFile(modelPath) 61 | assert.NilError(t, err) 62 | ensemble, err = xgb.LoadXGBoostFromJSONBytes(data, 63 | "", 1, 4, &activation.Logistic{}) 64 | assert.NilError(t, err) 65 | predictions, err = ensemble.PredictProba(input) 66 | assert.NilError(t, err) 67 | err = mat.IsEqualMatrices(&predictions, &expectedClasses, 0.0001) 68 | assert.NilError(t, err) 69 | 70 | } 71 | 72 | func TestEnsemble_PredictBreastCancerFeatureMap(t *testing.T) { 73 | modelPath := "data/breast_cancer_xgboost_dump_fmap.json" 74 | ensemble, err := xgb.LoadXGBoostFromJSON(modelPath, 75 | "data/breast_cancer_fmap.txt", 1, 4, &activation.Logistic{}) 76 | assert.NilError(t, err) 77 | 78 | inputPath := "data/breast_cancer_test.libsvm" 79 | input, err := mat.ReadLibsvmFileToSparseMatrix(inputPath) 80 | assert.NilError(t, err) 81 | 82 | predictions, err := ensemble.PredictProba(input) 83 | assert.NilError(t, err) 84 | 85 | expectedPredPath := "data/breast_cancer_xgboost_true_prediction.txt" 86 | expectedClasses, err := mat.ReadCSVFileToDenseMatrix(expectedPredPath, "\t", 0.0) 87 | assert.NilError(t, err) 88 | 89 | err = mat.IsEqualMatrices(&predictions, &expectedClasses, 0.0001) 90 | assert.NilError(t, err) 91 | 92 | predictions, err = ensemble.Predict(input) 93 | assert.NilError(t, err) 94 | 95 | err = mat.IsEqualMatrices(&predictions, &expectedClasses, 0.0001) 96 | assert.NilError(t, err) 97 | 98 | // Load from byte arr 99 | data, err := os.ReadFile(modelPath) 100 | assert.NilError(t, err) 101 | ensemble, err = xgb.LoadXGBoostFromJSONBytes(data, 102 | "data/breast_cancer_fmap.txt", 1, 4, &activation.Logistic{}) 103 | assert.NilError(t, err) 104 | predictions, err = ensemble.PredictProba(input) 105 | assert.NilError(t, err) 106 | err = mat.IsEqualMatrices(&predictions, &expectedClasses, 0.0001) 107 | assert.NilError(t, err) 108 | } 109 | 110 | func TestEnsemble_BreastCancerRegression(t *testing.T) { 111 | modelPath := "data/breast_cancer_xgboost_dump_regression.json" 112 | ensemble, err := xgb.LoadXGBoostFromJSON(modelPath, 113 | "", 1, 4, &activation.Raw{}) 114 | assert.NilError(t, err) 115 | 116 | inputPath := "data/breast_cancer_test.libsvm" 117 | input, err := mat.ReadLibsvmFileToSparseMatrix(inputPath) 118 | assert.NilError(t, err) 119 | 120 | // base value is the target average value, check test/scripts/breast_cancer_xgboost.py for more detail. 121 | predictions, err := ensemble.PredictRegression(input, 0.6373626373626373) 122 | assert.NilError(t, err) 123 | 124 | expectedPredPath := "data/breast_cancer_xgboost_true_prediction_regression.txt" 125 | expectedClasses, err := mat.ReadCSVFileToDenseMatrix(expectedPredPath, "\t", 0.0) 126 | assert.NilError(t, err) 127 | 128 | err = mat.IsEqualMatrices(&predictions, &expectedClasses, 0.0001) 129 | assert.NilError(t, err) 130 | 131 | // Load from byte arr 132 | data, err := os.ReadFile(modelPath) 133 | assert.NilError(t, err) 134 | ensemble, err = xgb.LoadXGBoostFromJSONBytes(data, 135 | "", 1, 4, &activation.Raw{}) 136 | assert.NilError(t, err) 137 | predictions, err = ensemble.PredictRegression(input, 0.6373626373626373) 138 | assert.NilError(t, err) 139 | err = mat.IsEqualMatrices(&predictions, &expectedClasses, 0.0001) 140 | assert.NilError(t, err) 141 | } 142 | 143 | func TestEnsemble_Iris(t *testing.T) { 144 | modelPath := "data/iris_xgboost_dump.json" 145 | ensemble, err := xgb.LoadXGBoostFromJSON(modelPath, 146 | "", 3, 4, &activation.Softmax{}) 147 | assert.NilError(t, err) 148 | 149 | inputPath := "data/iris_test.libsvm" 150 | input, err := mat.ReadLibsvmFileToSparseMatrix(inputPath) 151 | assert.NilError(t, err) 152 | 153 | predictions, err := ensemble.Predict(input) 154 | assert.NilError(t, err) 155 | 156 | expectedClassesPath := "data/iris_xgboost_true_prediction.txt" 157 | expectedClasses, err := mat.ReadCSVFileToDenseMatrix(expectedClassesPath, "\t", 0.0) 158 | assert.NilError(t, err) 159 | 160 | err = mat.IsEqualMatrices(&predictions, &expectedClasses, 0.0000) 161 | assert.NilError(t, err) 162 | 163 | expectedProbPath := "data/iris_xgboost_true_prediction_proba.txt" 164 | expectedProb, err := mat.ReadCSVFileToDenseMatrix(expectedProbPath, "\t", 0.0) 165 | assert.NilError(t, err) 166 | 167 | predictions, err = ensemble.PredictProba(input) 168 | assert.NilError(t, err) 169 | 170 | err = mat.IsEqualMatrices(&predictions, &expectedProb, 0.0001) 171 | assert.NilError(t, err) 172 | 173 | // with undefined depth 174 | ensemble, err = xgb.LoadXGBoostFromJSON(modelPath, 175 | "", 3, 0, &activation.Softmax{}) 176 | assert.NilError(t, err) 177 | 178 | predictions, err = ensemble.Predict(input) 179 | assert.NilError(t, err) 180 | 181 | err = mat.IsEqualMatrices(&predictions, &expectedClasses, 0.0000) 182 | assert.NilError(t, err) 183 | 184 | predictions, err = ensemble.PredictProba(input) 185 | assert.NilError(t, err) 186 | 187 | err = mat.IsEqualMatrices(&predictions, &expectedProb, 0.0001) 188 | assert.NilError(t, err) 189 | 190 | // Load from byte arr 191 | data, err := os.ReadFile(modelPath) 192 | assert.NilError(t, err) 193 | ensemble, err = xgb.LoadXGBoostFromJSONBytes(data, 194 | "", 3, 0, &activation.Softmax{}) 195 | assert.NilError(t, err) 196 | predictions, err = ensemble.PredictProba(input) 197 | assert.NilError(t, err) 198 | err = mat.IsEqualMatrices(&predictions, &expectedProb, 0.0001) 199 | assert.NilError(t, err) 200 | } 201 | 202 | func TestEnsemble_Diamond(t *testing.T) { 203 | modelPath := "data/diamonds_xgboost_dump.json" 204 | ensemble, err := xgb.LoadXGBoostFromJSON(modelPath, 205 | "", 1, 5, &activation.Logistic{}) 206 | assert.NilError(t, err) 207 | 208 | inputPath := "data/diamonds_test.libsvm" 209 | input, err := mat.ReadLibsvmFileToSparseMatrix(inputPath) 210 | assert.NilError(t, err) 211 | 212 | expectedProbPath := "data/diamonds_xgboost_true_prediction_proba.txt" 213 | expectedProb, err := mat.ReadCSVFileToDenseMatrix(expectedProbPath, "\t", 0.0) 214 | assert.NilError(t, err) 215 | 216 | predictions, err := ensemble.Predict(input) 217 | assert.NilError(t, err) 218 | 219 | // predict and predict proba should output probabilities for logistic activation 220 | err = mat.IsEqualMatrices(&predictions, &expectedProb, 0.0001) 221 | assert.NilError(t, err) 222 | 223 | predictions, err = ensemble.PredictProba(input) 224 | assert.NilError(t, err) 225 | 226 | err = mat.IsEqualMatrices(&predictions, &expectedProb, 0.0001) 227 | assert.NilError(t, err) 228 | 229 | // with undefined depth 230 | ensemble, err = xgb.LoadXGBoostFromJSON(modelPath, 231 | "", 1, 0, &activation.Logistic{}) 232 | assert.NilError(t, err) 233 | 234 | predictions, err = ensemble.Predict(input) 235 | assert.NilError(t, err) 236 | 237 | err = mat.IsEqualMatrices(&predictions, &expectedProb, 0.0001) 238 | assert.NilError(t, err) 239 | 240 | predictions, err = ensemble.PredictProba(input) 241 | assert.NilError(t, err) 242 | 243 | err = mat.IsEqualMatrices(&predictions, &expectedProb, 0.0001) 244 | assert.NilError(t, err) 245 | } 246 | -------------------------------------------------------------------------------- /xgbensemble.go: -------------------------------------------------------------------------------- 1 | package xgboost 2 | 3 | import ( 4 | "github.com/Elvenson/xgboost-go/mat" 5 | ) 6 | 7 | type xgbEnsemble struct { 8 | Trees []*xgbTree 9 | name string 10 | numClasses int 11 | numFeat int 12 | } 13 | 14 | // Name returns name of ensemble model. 15 | func (e *xgbEnsemble) Name() string { 16 | return e.name 17 | } 18 | 19 | // NumClasses returns number of features for this ensemble model. 20 | func (e *xgbEnsemble) NumClasses() int { 21 | return e.numClasses 22 | } 23 | 24 | // PredictInner returns prediction of this ensemble model. 25 | func (e *xgbEnsemble) PredictInner(features mat.SparseVector) (mat.Vector, error) { 26 | // number of trees for 1 class. 27 | pred := make([]float32, e.numClasses) 28 | numTreesPerClass := len(e.Trees) / e.numClasses 29 | for i := 0; i < e.numClasses; i++ { 30 | for k := 0; k < numTreesPerClass; k++ { 31 | p, err := e.Trees[k*e.numClasses+i].predict(features) 32 | if err != nil { 33 | return mat.Vector{}, nil 34 | } 35 | pred[i] += p 36 | } 37 | } 38 | return pred, nil 39 | } 40 | -------------------------------------------------------------------------------- /xgbensembleio.go: -------------------------------------------------------------------------------- 1 | package xgboost 2 | 3 | import ( 4 | "bufio" 5 | "encoding/json" 6 | "fmt" 7 | "io" 8 | "os" 9 | "sort" 10 | "strconv" 11 | "strings" 12 | 13 | "github.com/Elvenson/xgboost-go/activation" 14 | "github.com/Elvenson/xgboost-go/inference" 15 | "github.com/chewxy/math32" 16 | ) 17 | 18 | type xgboostJSON struct { 19 | NodeID int `json:"nodeid,omitempty"` 20 | SplitFeatureID string `json:"split,omitempty"` 21 | SplitFeatureThreshold float32 `json:"split_condition,omitempty"` 22 | YesID int `json:"yes,omitempty"` 23 | NoID int `json:"no,omitempty"` 24 | MissingID int `json:"missing,omitempty"` 25 | LeafValue float32 `json:"leaf,omitempty"` 26 | Children []*xgboostJSON `json:"children,omitempty"` 27 | } 28 | 29 | func loadFeatureMap(filePath string) (map[string]int, error) { 30 | featureFile, err := os.Open(filePath) 31 | if err != nil { 32 | return nil, err 33 | } 34 | defer featureFile.Close() 35 | 36 | read := bufio.NewReader(featureFile) 37 | featureMap := make(map[string]int, 0) 38 | for { 39 | // feature map format: feature_index feature_name feature_type 40 | line, err := read.ReadString('\n') 41 | if err != nil { 42 | if err == io.EOF { 43 | break 44 | } 45 | return nil, err 46 | } 47 | tk := strings.Split(line, " ") 48 | if len(tk) != 3 { 49 | return nil, fmt.Errorf("wrong feature map format") 50 | } 51 | featIdx, err := strconv.Atoi(tk[0]) 52 | if err != nil { 53 | return nil, err 54 | } 55 | if _, ok := featureMap[tk[1]]; ok { 56 | return nil, fmt.Errorf("duplicate feature name") 57 | } 58 | featureMap[tk[1]] = featIdx 59 | } 60 | return featureMap, nil 61 | } 62 | 63 | func convertFeatToIdx(featureMap map[string]int, feature string) (int, error) { 64 | if featureMap != nil { 65 | if _, ok := featureMap[feature]; !ok { 66 | return 0, fmt.Errorf("cannot find feature %s in feature map", feature) 67 | } 68 | return featureMap[feature], nil 69 | 70 | } 71 | 72 | // if no feature map use the default feature name which are: f0, f1, f2, ... 73 | feature = feature[1:] 74 | idx, err := strconv.Atoi(feature) 75 | if err != nil { 76 | return 0, err 77 | } 78 | return idx, nil 79 | } 80 | 81 | func buildTree(xgbTreeJSON *xgboostJSON, maxDepth int, featureMap map[string]int) (*xgbTree, int, error) { 82 | stack := make([]*xgboostJSON, 0) 83 | maxFeatIdx := 0 84 | t := &xgbTree{} 85 | stack = append(stack, xgbTreeJSON) 86 | var node *xgbNode 87 | var maxNumNodes int 88 | var maxIdx int 89 | if maxDepth != 0 { 90 | maxNumNodes = int(math32.Pow(2, float32(maxDepth+1)) - 1) 91 | t.nodes = make([]*xgbNode, maxNumNodes) 92 | } 93 | for len(stack) > 0 { 94 | stackData := stack[len(stack)-1] 95 | stack = stack[:len(stack)-1] 96 | if stackData.Children == nil { 97 | // leaf node. 98 | node = &xgbNode{ 99 | NodeID: stackData.NodeID, 100 | Flags: isLeaf, 101 | LeafValues: stackData.LeafValue, 102 | } 103 | } else { 104 | featIdx, err := convertFeatToIdx(featureMap, stackData.SplitFeatureID) 105 | if err != nil { 106 | return nil, 0, err 107 | } 108 | if featIdx > maxFeatIdx { 109 | maxFeatIdx = featIdx 110 | } 111 | node = &xgbNode{ 112 | NodeID: stackData.NodeID, 113 | Threshold: stackData.SplitFeatureThreshold, 114 | No: stackData.NoID, 115 | Yes: stackData.YesID, 116 | Missing: stackData.MissingID, 117 | Feature: featIdx, 118 | } 119 | // find real length of the tree. 120 | if maxDepth != 0 { 121 | t := int(math32.Max(float32(stackData.NoID), float32(stackData.YesID))) 122 | if t > maxIdx { 123 | maxIdx = t 124 | } 125 | } 126 | for _, c := range stackData.Children { 127 | stack = append(stack, c) 128 | } 129 | } 130 | if maxNumNodes > 0 { 131 | if node.NodeID >= maxNumNodes { 132 | return nil, 0, fmt.Errorf("wrong tree max depth %d, please check your model again for the"+ 133 | " correct parameter", maxDepth) 134 | } 135 | t.nodes[node.NodeID] = node 136 | } else { 137 | // do not know the depth beforehand just append. 138 | t.nodes = append(t.nodes, node) 139 | } 140 | } 141 | if maxDepth == 0 { 142 | sort.SliceStable(t.nodes, func(i, j int) bool { 143 | return t.nodes[i].NodeID < t.nodes[j].NodeID 144 | }) 145 | } else { 146 | t.nodes = t.nodes[:maxIdx+1] 147 | } 148 | 149 | return t, maxFeatIdx, nil 150 | } 151 | 152 | func loadXGBoost( 153 | xgbEnsembleJSON []*xgboostJSON, 154 | featuresMapPath string, 155 | numClasses int, 156 | maxDepth int, 157 | activation activation.Activation) (*inference.Ensemble, error) { 158 | var featMap map[string]int 159 | var err error 160 | if len(featuresMapPath) != 0 { 161 | featMap, err = loadFeatureMap(featuresMapPath) 162 | if err != nil { 163 | return nil, err 164 | } 165 | } 166 | 167 | if maxDepth < 0 { 168 | return nil, fmt.Errorf("max depth cannot be smaller than 0: %d", maxDepth) 169 | } 170 | 171 | nTrees := len(xgbEnsembleJSON) 172 | if numClasses <= 0 { 173 | return nil, fmt.Errorf("num class cannot be 0 or smaller: %d", numClasses) 174 | } 175 | if nTrees == 0 { 176 | return nil, fmt.Errorf("no trees in file") 177 | } else if nTrees%numClasses != 0 { 178 | return nil, fmt.Errorf("wrong number of trees %d for number of class %d", nTrees, numClasses) 179 | } 180 | 181 | e := &xgbEnsemble{name: "xgboost", numClasses: numClasses} 182 | e.Trees = make([]*xgbTree, 0, nTrees) 183 | // TODO: Need to check if max feature index will be the last feature column. 184 | // if it is not the case we should find another way to find the number of features. 185 | maxFeat := 0 186 | for i := 0; i < nTrees; i++ { 187 | tree, numFeat, err := buildTree(xgbEnsembleJSON[i], maxDepth, featMap) 188 | if err != nil { 189 | return nil, fmt.Errorf("error while reading %d tree: %s", i, err.Error()) 190 | } 191 | e.Trees = append(e.Trees, tree) 192 | if numFeat > maxFeat { 193 | maxFeat = numFeat 194 | } 195 | } 196 | e.numFeat = maxFeat + 1 197 | 198 | return &inference.Ensemble{EnsembleBase: e, Activation: activation}, nil 199 | } 200 | 201 | // LoadXGBoostFromJSON loads xgboost model from json file. 202 | func LoadXGBoostFromJSON( 203 | modelPath, 204 | featuresMapPath string, 205 | numClasses int, 206 | maxDepth int, 207 | activation activation.Activation) (*inference.Ensemble, error) { 208 | var xgbEnsembleJSON []*xgboostJSON 209 | d, err := os.ReadFile(modelPath) 210 | if err != nil { 211 | return nil, err 212 | } 213 | 214 | err = json.Unmarshal(d, &xgbEnsembleJSON) 215 | if err != nil { 216 | return nil, err 217 | } 218 | 219 | return loadXGBoost(xgbEnsembleJSON, featuresMapPath, numClasses, maxDepth, activation) 220 | } 221 | 222 | // LoadXGBoostFromJSONBytes loads XGBoost model from bytes. 223 | func LoadXGBoostFromJSONBytes( 224 | jsonBytes []byte, 225 | featuresMapPath string, 226 | numClasses int, 227 | maxDepth int, 228 | activation activation.Activation) (*inference.Ensemble, error) { 229 | 230 | var xgbEnsembleJSON []*xgboostJSON 231 | 232 | err := json.Unmarshal(jsonBytes, &xgbEnsembleJSON) 233 | if err != nil { 234 | return nil, err 235 | } 236 | return loadXGBoost(xgbEnsembleJSON, featuresMapPath, numClasses, maxDepth, activation) 237 | } 238 | -------------------------------------------------------------------------------- /xgbtree.go: -------------------------------------------------------------------------------- 1 | package xgboost 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/Elvenson/xgboost-go/mat" 7 | ) 8 | 9 | // xgbtree constant values. 10 | const ( 11 | isLeaf = 1 12 | ) 13 | 14 | type xgbNode struct { 15 | NodeID int 16 | Threshold float32 17 | Yes int 18 | No int 19 | Missing int 20 | Feature int 21 | Flags uint8 22 | LeafValues float32 23 | } 24 | 25 | type xgbTree struct { 26 | nodes []*xgbNode 27 | } 28 | 29 | func (t *xgbTree) predict(features mat.SparseVector) (float32, error) { 30 | idx := 0 31 | for { 32 | node := t.nodes[idx] 33 | if node == nil { 34 | return 0, fmt.Errorf("nil node") 35 | } 36 | if node.Flags&isLeaf > 0 { 37 | return node.LeafValues, nil 38 | } 39 | v, ok := features[node.Feature] 40 | if !ok { 41 | // missing value will be represented as NaN value. 42 | idx = node.Missing 43 | } else if v >= node.Threshold { 44 | idx = node.No 45 | } else { 46 | idx = node.Yes 47 | } 48 | } 49 | } 50 | --------------------------------------------------------------------------------