go-ml.dev/pkg/base@v0.0.0-20200610162856-60c38abac71b/model/metrics.go (about)

     1  package model
     2  
     3  import (
     4  	"go-ml.dev/pkg/base/fu"
     5  	"go-ml.dev/pkg/base/tables"
     6  	"math"
     7  	"reflect"
     8  )
     9  
    10  /*
    11  TestCol is the default name of Test column containing a boolean flag
    12  */
    13  const TestCol = "Test"
    14  
    15  /*
    16  PredictedCol is the default name of column containing a result of prediction
    17  */
    18  const PredictedCol = "Predicted"
    19  
    20  /*
    21  LabelCol is the default name of column containing a training label
    22  */
    23  const LabelCol = "Label"
    24  
    25  /*
    26  FeatureCol is the default name of single feature column
    27  */
    28  const FeatureCol = "Feature"
    29  
    30  /*
    31  SubsetCol is the Subset column naime
    32  */
    33  const SubsetCol = "Subset"
    34  
    35  /*
    36  IterationCol is the Iteration column name
    37  */
    38  const IterationCol = "Iteration"
    39  
    40  /*
    41  LossCol is the Loss column name
    42  */
    43  const LossCol = "Loss"
    44  
    45  /*
    46  ErrorCol is the Error column name
    47  */
    48  const ErrorCol = "Error"
    49  
    50  /*
    51  RmseCol is the Root Mean fo Squared Error column name
    52  */
    53  const RmseCol = "Rmse"
    54  
    55  /*
    56  MaeCol is the Mean of Absolute Error column name
    57  */
    58  const MaeCol = "Mae"
    59  
    60  /*
    61  MaeCol is the Mean of Error column name
    62  */
    63  const MeCol = "Me"
    64  
    65  /*
    66  AccuracyCol is the Error column name
    67  */
    68  const AccuracyCol = "Accuracy"
    69  
    70  /*
    71  SensitivityCol is the Sensitivity column name
    72  */
    73  const SensitivityCol = "Sensitivity"
    74  
    75  /*
    76  PrecisionCol is the Precision column name
    77  */
    78  const PrecisionCol = "Precision"
    79  
    80  /*
    81  F1ScoreCol is the F1score column name
    82  */
    83  const F1ScoreCol = "F1score"
    84  
    85  /*
    86  TotalCol is the Total column name
    87  */
    88  const TotalCol = "Total"
    89  
    90  /*
    91  CorrectCol i th Correct column name
    92  */
    93  const CorrectCol = "Correct"
    94  
    95  /*
    96  TestSubset is the Subset column item value for test rows
    97  */
    98  const TestSubset = "test"
    99  
   100  /*
   101  TrainSubset is the Subset column item value for train rows
   102  */
   103  const TrainSubset = "train"
   104  
   105  /*
   106  MetricsUpdater interface
   107  */
   108  type MetricsUpdater interface {
   109  	// updates metrics with prediction result and label
   110  	// loss is an optional and can be used in LossScore on the training
   111  	Update(result, label reflect.Value, loss float64)
   112  	Complete() (fu.Struct, bool)
   113  }
   114  
   115  /*
   116  Metrics interface
   117  */
   118  type Metrics interface {
   119  	New(iteration int, subset string) MetricsUpdater
   120  	Names() []string
   121  }
   122  
   123  /*
   124  Score is the type of function calculating a metrics score
   125  */
   126  type Score func(train, test fu.Struct) float64
   127  
   128  /*
   129  BatchUpdateMetrics updates metrics for a batch of training results
   130  */
   131  func BatchUpdateMetrics(result, label *tables.Column, mu MetricsUpdater) {
   132  	rc, _ := result.Raw()
   133  	lc, _ := label.Raw()
   134  	for i := 0; i < rc.Len(); i++ {
   135  		mu.Update(rc.Index(i), lc.Index(i), 0)
   136  	}
   137  }
   138  
   139  /*
   140  Error of an ML algorithm, can have any value
   141  */
   142  func Error(lr fu.Struct) float64 { return lr.Float(ErrorCol) }
   143  
   144  /*
   145  ErrorScore scores error in interval [0,1], Greater is better
   146  */
   147  func ErrorScore(train, test fu.Struct) float64 {
   148  	a := 1 / math.Exp(Error(train))
   149  	b := 1 / math.Exp(Error(test))
   150  	return fu.Mind(a, b)
   151  }
   152  
   153  /*
   154  Accuracy of an ML algorithm, has a value in the interval [0,1]
   155  */
   156  func Accuracy(lr fu.Struct) float64 { return lr.Float(AccuracyCol) }
   157  
   158  /*
   159  AccuracyScore scores accuracy in interval [0,1], Greater is better
   160  */
   161  func AccuracyScore(train, test fu.Struct) float64 {
   162  	a1, a2 := Accuracy(train), Accuracy(test)
   163  	if a1 > a2 {
   164  		a2, a1 = a1, a2
   165  	}
   166  	return (a1 - (a2-a1)/2)
   167  }
   168  
   169  /*
   170  Loss is the maen of the ML algorithm loss function. It can have any float value
   171  */
   172  func Loss(lr fu.Struct) float64 { return lr.Float(LossCol) }
   173  
   174  /*
   175  LossScore scores loss in interval [0,1], Greater is better
   176  */
   177  func LossScore(train, test fu.Struct) float64 {
   178  	a := 1 / (1 + math.Exp(Loss(train)))
   179  	b := 1 / (1 + math.Exp(Loss(test)))
   180  	return fu.Mind(a, b)
   181  }