MultipleLinearRegressionCalculator.java
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.extension.siddhi.execution.timeseries.linreg;
import Jama.Matrix;
import org.apache.commons.math3.distribution.TDistribution;
import java.util.LinkedList;
import java.util.List;
/**
* This class handles multiple linear regressions in real time.
*/
public class
MultipleLinearRegressionCalculator extends RegressionCalculator {
private List<double[]> yValueList = new LinkedList<double[]>();
private List<double[]> xValueList = new LinkedList<double[]>();
public MultipleLinearRegressionCalculator(int paramCount, int calcInt, int limit, double ci) {
super(paramCount, calcInt, limit, ci);
}
@Override
protected void addEvent(Object[] data) {
incCounter++;
eventCount++;
double[] dataX = new double[xParameterCount + 1];
double[] dataY = new double[1];
dataX[0] = 1.0;
dataY[0] = ((Number) data[0]).doubleValue();
for (int i = 1; i <= xParameterCount; i++) {
dataX[i] = ((Number) data[i]).doubleValue();
}
xValueList.add(dataX);
yValueList.add(dataY);
}
@Override
protected void removeEvent() {
xValueList.remove(0);
yValueList.remove(0);
}
@Override
protected Object[] processData() {
double[][] xArray = xValueList.toArray(new double[eventCount][xParameterCount + 1]);
double[][] yArray = yValueList.toArray(new double[eventCount][1]);
double[] betaErrors = new double[xParameterCount + 1];
double[] tStats = new double[xParameterCount + 1];
double sse = 0.0; // sum of square error
double df = eventCount - xParameterCount - 1; // Degrees of Freedom for Confidence Interval
double p = 1 - confidenceInterval; // P value of specified confidence interval
double pValue;
Object[] regResults = new Object[xParameterCount + 2];
// Calculate Betas
try {
Matrix matY = new Matrix(yArray);
Matrix matX = new Matrix(xArray);
Matrix matXTranspose = matX.transpose();
Matrix matXTXInverse = matXTranspose.times(matX).inverse();
Matrix matBetas = matXTXInverse.times(matXTranspose).times(matY);
Matrix yHat = matX.times(matBetas);
// Calculate Sum of Squares
for (int i = 0; i < eventCount; i++) {
sse += (yHat.get(i, 0) - yArray[i][0]) * (yHat.get(i, 0) - yArray[i][0]);
}
// Calculating Errors
double mse = sse / df;
regResults[0] = Math.sqrt(mse); // Standard Error of Regression
TDistribution t = new TDistribution(df);
// Calculating beta errors and tstats
for (int j = 0; j <= xParameterCount; j++) {
betaErrors[j] = Math.sqrt(matXTXInverse.get(j, j) * mse);
tStats[j] = matBetas.get(j, 0) / betaErrors[j];
// Eliminating statistically weak coefficients
pValue = 2 * (1 - t.cumulativeProbability(Math.abs(tStats[j])));
if (pValue > p) {
regResults[j + 1] = 0.0;
} else {
regResults[j + 1] = matBetas.get(j, 0);
}
}
} catch (RuntimeException e) {
regResults[0] = 0.0;
for (int j = 0; j <= xParameterCount; j++) {
regResults[j + 1] = 0.0;
}
return regResults;
}
return regResults;
}
}