fit method

void fit(
  1. List<List<double>> X,
  2. List<double> y
)

Implementation

void fit(List<List<double>> X, List<double> y) {
  final n = X.length;
  if (n == 0) return;
  final m = X[0].length;
  _init = y.reduce((a, b) => a + b) / n;
  var preds = List<double>.filled(n, _init);
  for (var t = 0; t < nEstimators; t++) {
    final residuals = List<double>.generate(n, (i) => y[i] - preds[i]);
    _Stump bestStump = _Stump();
    var bestError = double.infinity;
    for (var f = 0; f < m; f++) {
      final vals = X.map((r) => r[f]).toSet().toList()..sort();
      for (var i = 1; i < vals.length; i++) {
        final thresh = (vals[i - 1] + vals[i]) / 2.0;
        final left = <double>[];
        final right = <double>[];
        for (var r = 0; r < n; r++) {
          if (X[r][f] <= thresh) {
            left.add(residuals[r]);
          } else {
            right.add(residuals[r]);
          }
        }
        if (left.isEmpty || right.isEmpty) continue;
        final leftMean = left.reduce((a, b) => a + b) / left.length;
        final rightMean = right.reduce((a, b) => a + b) / right.length;
        var err = 0.0;
        for (var v in left) {
          err += (v - leftMean) * (v - leftMean);
        }
        for (var v in right) {
          err += (v - rightMean) * (v - rightMean);
        }
        if (err < bestError) {
          bestError = err;
          bestStump =
              _Stump()
                ..feature = f
                ..threshold = thresh
                ..leftValue = leftMean
                ..rightValue = rightMean;
        }
      }
    }
    _stumps.add(bestStump);
    for (var i = 0; i < n; i++) {
      final add =
          X[i][bestStump.feature] <= bestStump.threshold
              ? bestStump.leftValue
              : bestStump.rightValue;
      preds[i] += learningRate * add;
    }
  }
}