50,530
社区成员
发帖
与我相关
我的任务
分享
public class MyLineRegression {
public static void main(String[] args) {
double[] x = {0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5};
double[] y = {0.01, 0.04, 0.08, 0.137, 0.207, 0.288, 0.386, 0.502, 0.631, 0.781};
double[] lnx = Arrays.stream(x).map(Math::log).toArray();
double[] lny = Arrays.stream(y).map(Math::log).toArray();
Map<String, Double> result = new MyLineRegression().lineRegression(lnx, lny);
System.out.println("a = " + Math.pow(Math.E, result.get("b").doubleValue()));
System.out.println("b = " + result.get("a").doubleValue());
System.out.println("r = " + result.get("r").doubleValue());
}
/**
* 最小二乘法
*
* @param X
* @param Y
* @return y = ax + b, r
*/
public Map<String, Double> lineRegression(double[] X, double[] Y) {
if (null == X || null == Y || 0 == X.length
|| 0 == Y.length || X.length != Y.length) {
throw new RuntimeException();
}
// x平方差和
double Sxx = varianceSum(X);
// y平方差和
double Syy = varianceSum(Y);
// xy协方差和
double Sxy = covarianceSum(X, Y);
double xAvg = arraySum(X) / X.length;
double yAvg = arraySum(Y) / Y.length;
double a = Sxy / Sxx;
double b = yAvg - a * xAvg;
// 相关系数
double r = Sxy / Math.sqrt(Sxx * Syy);
Map<String, Double> result = new HashMap<String, Double>();
result.put("a", a);
result.put("b", b);
result.put("r", r);
return result;
}
/**
* 计算方差和
*
* @param X
* @return
*/
private double varianceSum(double[] X) {
double xAvg = arraySum(X) / X.length;
return arraySqSum(arrayMinus(X, xAvg));
}
/**
* 计算协方差和
*
* @param X
* @param Y
* @return
*/
private double covarianceSum(double[] X, double[] Y) {
double xAvg = arraySum(X) / X.length;
double yAvg = arraySum(Y) / Y.length;
return arrayMulSum(arrayMinus(X, xAvg), arrayMinus(Y, yAvg));
}
/**
* 数组减常数
*
* @param X
* @param x
* @return
*/
private double[] arrayMinus(double[] X, double x) {
int n = X.length;
double[] result = new double[n];
for (int i = 0; i < n; i++) {
result[i] = X[i] - x;
}
return result;
}
/**
* 数组求和
*
* @param X
* @return
*/
private double arraySum(double[] X) {
double s = 0;
for (double x : X) {
s = s + x;
}
return s;
}
/**
* 数组平方求和
*
* @param X
* @return
*/
private double arraySqSum(double[] X) {
double s = 0;
for (double x : X) {
s = s + Math.pow(x, 2);
;
}
return s;
}
/**
* 数组对应元素相乘求和
*
* @param X
* @return
*/
private double arrayMulSum(double[] X, double[] Y) {
double s = 0;
for (int i = 0; i < X.length; i++) {
s = s + X[i] * Y[i];
}
return s;
}
}
得到
a = 2.7971554678111508
b = 1.8711560608493885
r = 0.9998278572384243