Beispiel #1
0
 public final double lgrad(double u, double a, Loss loss) {
   assert loss.isForNumeric() : "Loss function " + loss + " not applicable to numerics";
   switch (loss) {
     case Quadratic:
       return 2 * (u - a);
     case Absolute:
       return Math.signum(u - a);
     case Huber:
       return Math.abs(u - a) <= 1 ? u - a : Math.signum(u - a);
     case Poisson:
       assert a >= 0 : "Poisson loss L(u,a) requires variable a >= 0";
       return Math.exp(u) - a;
     case Hinge:
       // return a*u <= 1 ? -a : 0;
       return a == 0
           ? (-u <= 1 ? 1 : 0)
           : (u <= 1 ? -1 : 0); // Booleans are coded as {0,1} instead of {-1,1}
     case Logistic:
       // return -a/(1+Math.exp(a*u));
       return a == 0
           ? 1 / (1 + Math.exp(-u))
           : -1 / (1 + Math.exp(u)); // Booleans are coded as {0,1} instead of {-1,1}
     case Periodic:
       return ((2 * Math.PI) / _period) * Math.sin((a - u) * (2 * Math.PI) / _period);
     default:
       throw new RuntimeException("Unknown loss function " + loss);
   }
 }
Beispiel #2
0
 public final double loss(double u, double a, Loss loss) {
   assert loss.isForNumeric() : "Loss function " + loss + " not applicable to numerics";
   switch (loss) {
     case Quadratic:
       return (u - a) * (u - a);
     case Absolute:
       return Math.abs(u - a);
     case Huber:
       return Math.abs(u - a) <= 1 ? 0.5 * (u - a) * (u - a) : Math.abs(u - a) - 0.5;
     case Poisson:
       assert a >= 0 : "Poisson loss L(u,a) requires variable a >= 0";
       return Math.exp(u)
           + (a == 0 ? 0 : -a * u + a * Math.log(a) - a); // Since \lim_{a->0} a*log(a) = 0
     case Hinge:
       // return Math.max(1-a*u,0);
       return Math.max(1 - (a == 0 ? -u : u), 0); // Booleans are coded {0,1} instead of {-1,1}
     case Logistic:
       // return Math.log(1 + Math.exp(-a * u));
       return Math.log(
           1 + Math.exp(a == 0 ? u : -u)); // Booleans are coded {0,1} instead of {-1,1}
     case Periodic:
       return 1 - Math.cos((a - u) * (2 * Math.PI) / _period);
     default:
       throw new RuntimeException("Unknown loss function " + loss);
   }
 }
Beispiel #3
0
 // Read the 'tree' columns, do model-specific math and put the results in the
 // fs[] array, and return the sum.  Dividing any fs[] element by the sum
 // turns the results into a probability distribution.
 @Override
 protected float score1(Chunk chks[], float fs[ /*nclass*/], int row) {
   if (_nclass == 1) // Classification?
   return (float) chk_tree(chks, 0).at0(row); // Regression.
   if (_nclass == 2) { // The Boolean Optimization
     // This optimization assumes the 2nd tree of a 2-class system is the
     // inverse of the first.  Fill in the missing tree
     fs[1] = (float) Math.exp(chk_tree(chks, 0).at0(row));
     fs[2] = 1.0f / fs[1]; // exp(-d) === 1/d
     return fs[1] + fs[2];
   }
   float sum = 0;
   for (int k = 0; k < _nclass; k++) // Sum across of likelyhoods
   sum += (fs[k + 1] = (float) Math.exp(chk_tree(chks, k).at0(row)));
   return sum;
 }
    protected void calcModelStats(
        CoxPHModel model, final double[] newCoef, final double newLoglik) {
      CoxPHModel.CoxPHParameters p = model._parms;
      CoxPHModel.CoxPHOutput o = model._output;

      final int n_coef = o.coef.length;
      final Matrix inv_hessian = new Matrix(o.hessian).inverse();
      for (int j = 0; j < n_coef; ++j) {
        for (int k = 0; k <= j; ++k) {
          final double elem = -inv_hessian.get(j, k);
          o.var_coef[j][k] = elem;
          o.var_coef[k][j] = elem;
        }
      }
      for (int j = 0; j < n_coef; ++j) {
        o.coef[j] = newCoef[j];
        o.exp_coef[j] = Math.exp(o.coef[j]);
        o.exp_neg_coef[j] = Math.exp(-o.coef[j]);
        o.se_coef[j] = Math.sqrt(o.var_coef[j][j]);
        o.z_coef[j] = o.coef[j] / o.se_coef[j];
      }
      if (o.iter == 0) {
        o.null_loglik = newLoglik;
        o.maxrsq = 1 - Math.exp(2 * o.null_loglik / o.n);
        o.score_test = 0;
        for (int j = 0; j < n_coef; ++j) {
          double sum = 0;
          for (int k = 0; k < n_coef; ++k) sum += o.var_coef[j][k] * o.gradient[k];
          o.score_test += o.gradient[j] * sum;
        }
      }
      o.loglik = newLoglik;
      o.loglik_test = -2 * (o.null_loglik - o.loglik);
      o.rsq = 1 - Math.exp(-o.loglik_test / o.n);
      o.wald_test = 0;
      for (int j = 0; j < n_coef; ++j) {
        double sum = 0;
        for (int k = 0; k < n_coef; ++k) sum -= o.hessian[j][k] * (o.coef[k] - p.init);
        o.wald_test += (o.coef[j] - p.init) * sum;
      }
    }
Beispiel #5
0
 public static double impute(double u, Loss loss) {
   assert loss.isForNumeric() : "Loss function " + loss + " not applicable to numerics";
   switch (loss) {
     case Quadratic:
     case Absolute:
     case Huber:
     case Periodic:
       return u;
     case Poisson:
       return Math.exp(u) - 1;
     case Hinge:
     case Logistic:
       return u > 0 ? 1 : 0; // Booleans are coded as {0,1} instead of {-1,1}
     default:
       throw new RuntimeException("Unknown loss function " + loss);
   }
 }
Beispiel #6
0
 @Override
 protected float[] score0(double[] data, float[] preds) {
   float[] p = super.score0(data, preds);
   if (nclasses() > 1) { // classification
     // Because we call Math.exp, we have to be numerically stable or else
     // we get Infinities, and then shortly NaN's.  Rescale the data so the
     // largest value is +/-1 and the other values are smaller.
     // See notes here:  http://www.hongliangjie.com/2011/01/07/logsum/
     float maxval = Float.NEGATIVE_INFINITY;
     float dsum = 0;
     if (nclasses() == 2) p[2] = -p[1];
     // Find a max
     for (int k = 1; k < p.length; k++) maxval = Math.max(maxval, p[k]);
     assert !Float.isInfinite(maxval)
         : "Something is wrong with GBM trees since returned prediction is "
             + Arrays.toString(p);
     for (int k = 1; k < p.length; k++) dsum += (p[k] = (float) Math.exp(p[k] - maxval));
     div(p, dsum);
     p[0] = getPrediction(p, data);
   } else { // regression
     // do nothing for regression
   }
   return p;
 }
    @Override
    protected void processRow(long gid, Row row) {
      n++;
      double[] response = row.response;
      int ncats = row.nBins;
      int[] cats = row.numIds;
      double[] nums = row.numVals;
      final double weight = _has_weights_column ? response[0] : 1.0;
      if (weight <= 0) throw new IllegalArgumentException("weights must be positive values");
      final long event = (long) response[response.length - 1];
      final int t1 =
          _has_start_column ? (int) (((long) response[response.length - 3] + 1) - _min_time) : -1;
      final int t2 = (int) (((long) response[response.length - 2]) - _min_time);
      if (t1 > t2)
        throw new IllegalArgumentException("start times must be strictly less than stop times");
      final int numStart = _dinfo.numStart();
      sumWeights += weight;
      for (int j = 0; j < ncats; ++j) sumWeightedCatX[cats[j]] += weight;
      for (int j = 0; j < nums.length; ++j) sumWeightedNumX[j] += weight * nums[j];
      double logRisk = 0;
      for (int j = 0; j < ncats; ++j) logRisk += _beta[cats[j]];
      for (int j = 0; j < nums.length - _n_offsets; ++j) logRisk += nums[j] * _beta[numStart + j];
      for (int j = nums.length - _n_offsets; j < nums.length; ++j) logRisk += nums[j];
      final double risk = weight * Math.exp(logRisk);
      logRisk *= weight;
      if (event > 0) {
        countEvents[t2]++;
        sizeEvents[t2] += weight;
        sumLogRiskEvents[t2] += logRisk;
        sumRiskEvents[t2] += risk;
      } else sizeCensored[t2] += weight;
      if (_has_start_column) {
        for (int t = t1; t <= t2; ++t) sizeRiskSet[t] += weight;
        for (int t = t1; t <= t2; ++t) rcumsumRisk[t] += risk;
      } else {
        sizeRiskSet[t2] += weight;
        rcumsumRisk[t2] += risk;
      }

      final int ntotal = ncats + (nums.length - _n_offsets);
      final int numStartIter = numStart - ncats;
      for (int jit = 0; jit < ntotal; ++jit) {
        final boolean jIsCat = jit < ncats;
        final int j = jIsCat ? cats[jit] : numStartIter + jit;
        final double x1 = jIsCat ? 1.0 : nums[jit - ncats];
        final double xRisk = x1 * risk;
        if (event > 0) {
          sumXEvents[t2][j] += weight * x1;
          sumXRiskEvents[t2][j] += xRisk;
        }
        if (_has_start_column) {
          for (int t = t1; t <= t2; ++t) rcumsumXRisk[t][j] += xRisk;
        } else {
          rcumsumXRisk[t2][j] += xRisk;
        }
        for (int kit = 0; kit < ntotal; ++kit) {
          final boolean kIsCat = kit < ncats;
          final int k = kIsCat ? cats[kit] : numStartIter + kit;
          final double x2 = kIsCat ? 1.0 : nums[kit - ncats];
          final double xxRisk = x2 * xRisk;
          if (event > 0) sumXXRiskEvents[t2][j][k] += xxRisk;
          if (_has_start_column) {
            for (int t = t1; t <= t2; ++t) rcumsumXXRisk[t][j][k] += xxRisk;
          } else {
            rcumsumXXRisk[t2][j][k] += xxRisk;
          }
        }
      }
    }