Skip to content

Commit

Permalink
#3 correct variance and covariance usage in preparation for a replace…
Browse files Browse the repository at this point in the history
…ment by another algorithms
  • Loading branch information
mbok committed Aug 8, 2017
1 parent 87990e9 commit 3c26020
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,40 +30,40 @@ public Statistics calculate(final StatsModel model) {
final double[] slopeCoefficients = model.getSlopeCoefficients().getCoefficients();

final double responseVariance = model.getStatsSampling().getResponseVariance();
double squaredError = responseVariance;
double squaredMeanError = responseVariance;

for (int i = 0; i < featuresCount; i++) {
final double c = slopeCoefficients[i];
final double c2 = c * c;
// Minus double of feature response coefficient
squaredError -= 2 * featuresResponseCovariance[i] * c;
squaredMeanError -= 2 * featuresResponseCovariance[i] * c;

// Add values from covariance matrix of the derivation matrix
for (int j = 0; j <= i; j++) {
if (i == j) {
// Variance term
squaredError += c2 * covarianceLowerTriangularMatrix[i][j];
squaredMeanError += c2 * covarianceLowerTriangularMatrix[i][j];
} else {
// Covariance term
squaredError += 2 * c * slopeCoefficients[j] * covarianceLowerTriangularMatrix[i][j];
squaredMeanError += 2 * c * slopeCoefficients[j] * covarianceLowerTriangularMatrix[i][j];
}
}
}
final double rss = squaredError;
final double mse = squaredMeanError;
return new Statistics() {
@Override
public double getRss() {
return rss;
return mse * model.getStatsSampling().getCount();
}

@Override
public double getMse() {
return rss / model.getStatsSampling().getCount();
return mse;
}

@Override
public double getR2() {
return 1 - (rss / responseVariance);
return 1 - (getRss() / (responseVariance * model.getStatsSampling().getCount()));
}
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@ public class ExactCoefficientSquareTermSampling implements
* instability as well as to arithmetic overflow.
*/
private double[][] featuresProductSums;
private ExactSamplingContext context;
private final ExactSamplingContext context;

public ExactCoefficientSquareTermSampling(ExactSamplingContext context) {
public ExactCoefficientSquareTermSampling(final ExactSamplingContext context) {
this.context = context;
int featuresCount = context.getFeaturesCount();
final int featuresCount = context.getFeaturesCount();
this.featuresProductSums = new double[featuresCount][];
for (int i = 0; i < featuresCount; i++) {
this.featuresProductSums[i] = new double[featuresCount];
Expand All @@ -49,31 +49,31 @@ public ExactCoefficientSquareTermSampling(ExactSamplingContext context) {

@Override
public double[][] getCovarianceLowerTriangularMatrix() {
int featuresCount = this.context.getFeaturesCount();
long count = this.context.getCount();
double[][] covMatrix = new double[featuresCount][];
double[] averages = this.context.getFeaturesMean();
double[] featureSums = this.context.featureSums;
final int featuresCount = this.context.getFeaturesCount();
final long count = this.context.getCount();
final double[][] covMatrix = new double[featuresCount][];
final double[] averages = this.context.getFeaturesMean();
final double[] featureSums = this.context.featureSums;
for (int i = 0; i < featuresCount; i++) {
double avgI = averages[i];
final double avgI = averages[i];
covMatrix[i] = new double[featuresCount];
// Iterate until "i" due to the covariance matrix is symmetric and
// build only the lower triangle
for (int j = 0; j <= i; j++) {
double avgJ = averages[j];
covMatrix[i][j] =
final double avgJ = averages[j];
covMatrix[i][j] = (
this.featuresProductSums[i][j] - avgI * featureSums[j] - avgJ * featureSums[i]
+ count * avgI * avgJ;
+ count * avgI * avgJ) / count;
}
}
return covMatrix;
}

@Override
public void sample(final double[] featureValues, final double responseValue) {
int featuresCount = this.context.getFeaturesCount();
final int featuresCount = this.context.getFeaturesCount();
for (int i = 0; i < featuresCount; i++) {
double vi = featureValues[i];
final double vi = featureValues[i];
for (int j = 0; j < featuresCount; j++) {
this.featuresProductSums[i][j] += vi * featureValues[j];
}
Expand All @@ -82,7 +82,7 @@ public void sample(final double[] featureValues, final double responseValue) {

@Override
public void merge(final ExactCoefficientSquareTermSampling fromSample) {
int featuresCount = this.context.getFeaturesCount();
final int featuresCount = this.context.getFeaturesCount();
for (int i = 0; i < featuresCount; i++) {
for (int j = 0; j < featuresCount; j++) {
this.featuresProductSums[i][j] += fromSample.featuresProductSums[i][j];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,9 @@ public ExactResponseVarianceTermSampling(

@Override
public double getResponseVariance() {
return this.context.responseSquareSum
- this.context.responseSum / this.context.getCount() * this.context.responseSum;
return (this.context.responseSquareSum
- this.context.responseSum / this.context.getCount() * this.context.responseSum)
/ this.context.getCount();
}

@Override
Expand Down Expand Up @@ -106,10 +107,10 @@ public double[] getFeaturesResponseCovariance() {
final double[] featuresMean = this.context.getFeaturesMean();
final double responseMean = this.context.getResponseMean();
for (int i = 0; i < featuresCount; i++) {
covariance[i] =
covariance[i] = (
this.context.featuresResponseProductSum[i] - featuresMean[i] * this.context.responseSum
- responseMean * this.context.featureSums[i]
+ count * featuresMean[i] * responseMean;
+ count * featuresMean[i] * responseMean) / count;
}
return covariance;
}
Expand Down

0 comments on commit 3c26020

Please sign in to comment.