有没有人知道Java中的科学/数学库可以直接实现加权线性回归?一个函数行的东西,它接受3个参数并返回相应的系数:
linearRegression(x,y,weights)
这看起来相当简单,所以我想它存在于某个地方。
PS)我已经尝试过Flannigan的图书馆:http://www.ee.ucl.ac.uk/~mflanaga/java/Regression.html,它有正确的想法,但似乎偶尔崩溃并抱怨我的自由度?答案 0 :(得分:15)
不是图书馆,但代码已发布:http://www.codeproject.com/KB/recipes/LinReg.aspx (并包括代码的数学解释,这是一个巨大的优点)。 此外,似乎这里还有另一种相同算法的实现:http://sin-memories.blogspot.com/2009/04/weighted-linear-regression-in-java-and.html
最后,来自新西兰大学的一个lib似乎实现了它:http://www.cs.waikato.ac.nz/~ml/weka/(相当不错的javadocs)。具体方法如下: http://weka.sourceforge.net/doc/weka/classifiers/functions/LinearRegression.html
答案 1 :(得分:2)
我个人使用了Apache Math库的org.apache.commons.math.stat.regression.SimpleRegression类。
我还从普林斯顿大学找到了一个更轻量级的课程,但没有测试它:
http://introcs.cs.princeton.edu/java/97data/LinearRegression.java.html
答案 2 :(得分:0)
我也在寻找这个,但找不到任何东西。原因可能是您可以将问题简化为标准回归,如下所示:
没有残差的加权线性回归可以表示为
diag(sqrt(weights))y = diag(sqrt(weights))Xb
,其中diag(sqrt(weights))T
的意思是将T矩阵的每一行乘以不同的平方根权重。因此,加权和不加权回归无残差之间的转换是微不足道的。
要将具有残差y=Xb+u
的回归转换为无残差y=Xb
的回归,请在X上增加一列-新的只有一列的列。
现在您知道如何简化问题了,您可以使用任何库来求解标准线性回归。
以下是使用Apache Commons Math的示例:
void linearRegression(double[] xUnweighted, double[] yUnweighted, double[] weights) {
double[] y = new double[yUnweighted.length];
double[][] x = new double[xUnweighted.length][2];
for (int i = 0; i < y.length; i++) {
y[i] = Math.sqrt(weights[i]) * yUnweighted[i];
x[i][0] = Math.sqrt(weights[i]) * xUnweighted[i];
x[i][1] = Math.sqrt(weights[i]);
}
OLSMultipleLinearRegression regression = new OLSMultipleLinearRegression();
regression.setNoIntercept(true);
regression.newSampleData(y, x);
double[] regressionParameters = regression.estimateRegressionParameters();
double slope = regressionParameters[0];
double intercept = regressionParameters[1];
System.out.println("y = " + slope + "*x + " + intercept);
}
这可以直观地解释为,在u = 0的线性回归中,如果取任意点(x,y)并将其转换为(x C,y C),新点的误差也将乘以C。换句话说,线性回归已经将较高的权重应用于具有较高x的点。我们将平方误差减到最小,这就是为什么我们提取权重的根。
答案 3 :(得分:0)
这是C#代码的直接Java端口,用于从Aleadam答案的第一个链接进行加权线性回归: