Free cookie consent management tool by TermsFeed Policy Generator

Changeset 3807


Ignore:
Timestamp:
05/14/10 14:18:00 (15 years ago)
Author:
gkronber
Message:

Made linear scaling operator more numerically stable. #938

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/SymbolicRegressionScaledMeanSquaredErrorEvaluator.cs

    r3532 r3807  
    9393    private static IEnumerable<double> CalculateScaledEstimatedValues(ISymbolicExpressionTreeInterpreter interpreter, SymbolicExpressionTree solution, Dataset dataset, string targetVariable, int start, int end, out double beta, out double alpha) {
    9494      int targetVariableIndex = dataset.GetVariableIndex(targetVariable);
    95       var estimatedValues = interpreter.GetSymbolicExpressionTreeValues(solution, dataset, Enumerable.Range(start, end - start)).ToList();
     95      var estimatedValues = interpreter.GetSymbolicExpressionTreeValues(solution, dataset, Enumerable.Range(start, end - start)).ToArray();
    9696      var originalValues = dataset.GetVariableValues(targetVariable, start, end);
    9797      CalculateScalingParameters(originalValues, estimatedValues, out beta, out alpha);
    98       for (int i = 0; i < estimatedValues.Count; i++)
     98      for (int i = 0; i < estimatedValues.Length; i++)
    9999        estimatedValues[i] = estimatedValues[i] * beta + alpha;
    100100      return estimatedValues;
     
    103103
    104104    public static void CalculateScalingParameters(IEnumerable<double> original, IEnumerable<double> estimated, out double beta, out double alpha) {
    105       var originalEnumerator = original.GetEnumerator();
    106       var estimatedEnumerator = estimated.GetEnumerator();
     105      double[] originalValues = original.ToArray();
     106      double[] estimatedValues = estimated.ToArray();
     107      if (originalValues.Length != estimatedValues.Length) throw new ArgumentException();
     108      var filteredResult = (from row in Enumerable.Range(0, originalValues.Length)
     109                            let t = originalValues[row]
     110                            let e = estimatedValues[row]
     111                            where IsValidValue(t)
     112                            where IsValidValue(e)
     113                            select new { Estimation = e, Target = t })
     114                   .OrderBy(x => Math.Abs(x.Target))            // make sure small values are considered before large values
     115                   .ToArray();     
    107116
    108       double tMean = original.Average();
    109       double xMean = estimated.Average();
    110       double sumXT = 0;
    111       double sumXX = 0;
    112       while (originalEnumerator.MoveNext() & estimatedEnumerator.MoveNext()) {
    113         // calculate alpha and beta on the subset of rows with valid values
    114         if (IsValidValue(originalEnumerator.Current) && IsValidValue(estimatedEnumerator.Current)) {
    115           double x = estimatedEnumerator.Current;
    116           double t = originalEnumerator.Current;
     117      // calculate alpha and beta on the subset of rows with valid values
     118      originalValues = filteredResult.Select(x => x.Target).ToArray();
     119      estimatedValues = filteredResult.Select(x => x.Estimation).ToArray();
     120      int n = originalValues.Length;
     121      if (n > 2) {
     122        double tMean = originalValues.Average();
     123        double xMean = estimatedValues.Average();
     124        double sumXT = 0;
     125        double sumXX = 0;
     126        for (int i = 0; i < n; i++) {
     127          // calculate alpha and beta on the subset of rows with valid values
     128          double x = estimatedValues[i];
     129          double t = originalValues[i];
    117130          sumXT += (x - xMean) * (t - tMean);
    118131          sumXX += (x - xMean) * (x - xMean);
    119132        }
     133        if (!sumXX.IsAlmost(0.0)) {
     134          beta = sumXT / sumXX;
     135        } else {
     136          beta = 1;
     137        }
     138        alpha = tMean - beta * xMean;
     139      } else {
     140        alpha = 0.0;
     141        beta = 1.0;
    120142      }
    121       if (estimatedEnumerator.MoveNext() || originalEnumerator.MoveNext()) {
    122         throw new ArgumentException("Number of elements in estimated and original doesn't match.");
    123       }
    124       if (sumXX != 0) {
    125         beta = sumXT / sumXX;
    126       } else {
    127         beta = 1;
    128       }
    129       alpha = tMean - beta * xMean;
    130143    }
    131144
    132145    private static bool IsValidValue(double d) {
    133       return !double.IsInfinity(d) && !double.IsNaN(d);
     146      return !double.IsInfinity(d) && !double.IsNaN(d) && d > -1.0E07 && d < 1.0E07;  // don't consider very large or very small values for scaling
    134147    }
    135148  }
Note: See TracChangeset for help on using the changeset viewer.