java 计算一系列值的斜率
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15431914/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Calculating the slope of a series of values
提问by Nyx
I have 2 arrays of equal length. The following function attempts to calculate the slope using these arrays. It returns the average of the slope between each points. For the following data set, I seem to be getting different values than Excel and Google Docs.
我有 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);
}
Output
输出
Google: 0.755
getSlope(): 0.962121212121212
Excel: 0.7501
谷歌:0.755
getSlope(): 0.962121212121212
卓越:0.7501
采纳答案by NPE
I bet the other two methods are computing the least-squares fit, whereas you are not.
我敢打赌,其他两种方法正在计算最小二乘拟合,而您不是。
When I verify this conjecture using R, I too get the slope of about 0.755:
当我使用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 ***
The relevant number is the 7.551e-01
. It is also worth noting that the line has an intercept of about -1265.
相关编号是7.551e-01
。还值得注意的是,该线的截距约为 -1265。
Here is a picture of the least-squares fit:
这是最小二乘拟合的图片:
As to implementing this in your code, see Compute least squares using java
至于在您的代码中实现这一点,请参阅使用 java 计算最小二乘法
回答by Eric Jablow
This function will not help you much, as it does not take into account the breadths of the various line segments. Consider the differences in applying it to the points (0,0), (1000,1000), and (1001, 2000) versus (0,0), (1,1), and (2, 1001). Both cases have successive slopes 1 and 1000, yet they look greatly different.
这个函数对你没有多大帮助,因为它没有考虑到各个线段的宽度。考虑将其应用于 (0,0)、(1000,1000) 和 (1001, 2000) 与 (0,0)、(1,1) 和 (2, 1001) 的差异。两种情况都有连续的斜率 1 和 1000,但它们看起来大不相同。
You need to implement the method of least squares: http://en.wikipedia.org/wiki/Least_squaresto find the line that best approximates your data set.
您需要实现最小二乘法:http: //en.wikipedia.org/wiki/Least_squares以找到最接近您的数据集的线。
One more piece of advice: never throw a java.lang.Exception
. Always choose a more-specific exception, even if you must write the class yourself. People using your code will need to handle java.lang.Exception
, which interferes badly with their other code.
还有一条建议:永远不要抛出java.lang.Exception
. 始终选择更具体的异常,即使您必须自己编写类。使用你的代码的人需要处理java.lang.Exception
,这会严重干扰他们的其他代码。
回答by Manuel
Edit: use Apache Commons Math class SimpleRegression if that's an option. Else, here's a method that calculates slope and also intercept, should yield the same results as excel and apache:
编辑:如果这是一个选项,请使用 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));
}
回答by karmanaut
You should be dividing by x_values.length - 1
. Number of slopes is pairwise.
你应该除以x_values.length - 1
。斜率的数量是成对的。
Edit : Wiki example in my comments shows how to calculate the alpha and beta which determines the slope of the linear regression line.
编辑:我评论中的 Wiki 示例显示了如何计算确定线性回归线斜率的 alpha 和 beta。