我有2个相等长度的数组。以下函数尝试使用这些数组计算斜率。它返回每个点之间的斜率的平均值。对于以下数据集,我似乎得到的值与Excel和Google Docs不同。
double[] x_values = { 1932, 1936, 1948, 1952, 1956, 1960, 1964, 1968,
1972, 1976, 1980 };
double[] y_values = { 197, 203, 198, 204, 212, 216, 218, 224, 223, 225,
236 };
public static double getSlope(double[] x_values, double[] y_values)
throws Exception {
if (x_values.length != y_values.length)
throw new Exception();
double slope = 0;
for (int i = 0; i < (x_values.length - 1); i++) {
double y_2 = y_values[i + 1];
double y_1 = y_values[i];
double delta_y = y_2 - y_1;
double x_2 = x_values[i + 1];
double x_1 = x_values[i];
double delta_x = x_2 - x_1;
slope += delta_y / delta_x;
}
System.out.println(x_values.length);
return slope / (x_values.length);
}
输出
Google:0.755
getSlope():0.962121212121212
Excel:0.7501
答案 0 :(得分:4)
我打赌其他两种方法是计算least-squares fit,而你不是。
当我使用R验证此猜想时,我也得到约0.755的斜率:
> summary(lm(y~x))
Call:
lm(formula = y ~ x)
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -1.265e+03 1.793e+02 -7.053 5.97e-05 ***
x 7.551e-01 9.155e-02 8.247 1.73e-05 ***
相关数字是7.551e-01
。值得注意的是,该线的截距约为-1265。
这是最小二乘拟合的图片:
关于在代码中实现此功能,请参阅Compute least squares using java
答案 1 :(得分:2)
此功能对您没有多大帮助,因为它没有考虑各个线段的宽度。考虑将它应用于点(0,0),(1000,1000)和(1001,2000)与(0,0),(1,1)和(2,1001)的差异。两种情况都有连续的斜率1和1000,但它们看起来大不相同。
您需要实施最小二乘方法:http://en.wikipedia.org/wiki/Least_squares以找到最接近您的数据集的行。
还有一条建议:永远不要抛出java.lang.Exception
。即使您必须自己编写课程,也要始终选择更具体的例外。使用您的代码的人需要处理java.lang.Exception
,这会严重干扰他们的其他代码。
答案 2 :(得分:0)
编辑:如果可以的话,使用Apache Commons Math类SimpleRegression 。 否则,这是一种计算坡度并进行截距的方法,其结果应与excel和apache相同:
private static double intercept(List<Double> yList, List<Double> xList) {
if (yList.size() != xList.size())
throw new IllegalArgumentException("Number of y and x must be the same");
if (yList.size() < 2)
throw new IllegalArgumentException("Need at least 2 y, x");
double yAvg = average(yList);
double xAvg = average(xList);
double sumNumerator = 0d;
double sumDenominator = 0d;
for (int i = 0; i < yList.size(); i++) {
double y = yList.get(i);
double x = xList.get(i);
double yDiff = y - yAvg;
double xDiff = x - xAvg;
double numerator = xDiff * yDiff;
double denominator = xDiff * xDiff;
sumNumerator += numerator;
sumDenominator += denominator;
}
double slope = sumNumerator / sumDenominator;
double intercept = yAvg - (slope * xAvg);
return intercept;
}
private static double average(Collection<Double> doubles) {
return doubles.stream().collect(Collectors.averagingDouble(d -> d));
}
答案 3 :(得分:-1)
你应该除以x_values.length - 1
。斜坡数量是成对的。
编辑:我的评论中的Wiki示例显示了如何计算确定线性回归线斜率的alpha和beta。