使用梯度下降法的线性回归

我编写了以下Java程序来实现使用梯度下降法的线性回归。代码可以运行,但结果不够准确。预测的y值与实际的y值相差较大。例如,当x = 75时,预期的y值应为208,但输出结果为y = 193.784。

class LinReg {    double theta0, theta1;    void buildModel(double[] x, double[] y) {        double x_avg, y_avg, x_sum = 0.0, y_sum = 0.0;        double xy_sum = 0.0, xx_sum = 0.0;        int n = x.length, i;        for( i = 0; i < n; i++ ) {            x_sum += x[i];            y_sum += y[i];        }        x_avg = x_sum/n;        y_avg = y_sum/n;        for( i = 0; i < n; i++) {            xx_sum += (x[i] - x_avg) * (x[i] - x_avg);            xy_sum += (x[i] - x_avg) * (y[i] - y_avg);        }        theta1 = xy_sum/xx_sum;        theta0 = y_avg - (theta1 * x_avg);        System.out.println(theta0);        System.out.println(theta1);        gradientDescent(x, y, 0.1, 1500);    }    void gradientDescent(double x[], double y[], double alpha, int maxIter) {        double oldtheta0, oldtheta1;        oldtheta0 = 0.0;        oldtheta1 = 0.0;        int n = x.length;        for(int i = 0; i < maxIter; i++) {            if(hasConverged(oldtheta0, theta0) && hasConverged(oldtheta1, theta1))                break;            oldtheta0 = theta0;            oldtheta1 = theta1;            theta0 = oldtheta0 - (alpha * (summ0(x, y, oldtheta0, oldtheta1)/(double)n));            theta1 = oldtheta1 - (alpha * (summ1(x, y, oldtheta0, oldtheta1)/(double)n));            System.out.println(theta0);            System.out.println(theta1);        }    }    double summ0(double x[], double y[], double theta0, double theta1) {        double sum = 0.0;        int n = x.length, i;        for( i = 0; i < n; i++ ) {            sum += (hypothesis(theta0, theta1, x[i]) - y[i]);        }        return sum;    }    double summ1(double x[], double y[], double theta0, double theta1) {        double sum = 0.0;        int n = x.length, i;        for( i = 0; i < n; i++ ) {            sum += (((hypothesis(theta0, theta1, x[i]) - y[i]))*x[i]);        }        return sum;    }    boolean hasConverged(double oldTheta, double newTheta) {        return ((newTheta - oldTheta) < (double)0);    }    double predict(double x) {        return hypothesis(theta0, theta1, x);    }    double hypothesis(double thta0, double thta1, double x) {        return (thta0 + thta1 * x);    }}public class LinearRegression {    public static void main(String[] args) {        //Height data        double x[] = {63.0, 64.0, 66.0, 69.0, 69.0, 71.0, 71.0, 72.0, 73.0, 75.0};        //Weight data        double y[] = {127.0, 121.0, 142.0, 157.0, 162.0, 156.0, 169.0, 165.0, 181.0, 208.0};        LinReg model = new LinReg();        model.buildModel(x, y);        System.out.println("----------------------");        System.out.println(model.theta0);        System.out.println(model.theta1);        System.out.println(model.predict(75.0));    }}

回答:

没有问题。

我在R中验证了这个解决方案:

x <- c(63.0, 64.0, 66.0, 69.0, 69.0, 71.0, 71.0, 72.0, 73.0, 75.0)y <- c(127.0, 121.0, 142.0, 157.0, 162.0, 156.0, 169.0, 165.0, 181.0, 208.0)mod <- lm(y~x)summary(mod)
Call:lm(formula = y ~ x)Residuals:     Min       1Q   Median       3Q      Max -13.2339  -4.0804  -0.0963   4.6445  14.2158 Coefficients:             Estimate Std. Error t value Pr(>|t|)    (Intercept) -266.5344    51.0320  -5.223    8e-04 ***x              6.1376     0.7353   8.347 3.21e-05 ***---Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1Residual standard error: 8.641 on 8 degrees of freedomMultiple R-squared:  0.897,   Adjusted R-squared:  0.8841 F-statistic: 69.67 on 1 and 8 DF,  p-value: 3.214e-05

计算当X值为75时的y-hat值:

-266.5344 +(6.1376 *75)

[1] 193.784

这是正确的预测。我认为混淆可能在于对回归工作原理的理解。回归并不会精确地告诉你训练数据中对应于给定独立数据点的实际值。那样的话,它就只是一个字典,而不是统计模型(而且在这种情况下,它将无法进行插值或外推)。

回归是通过最小二乘法拟合一条直线到你的数据上,以估计一个模型方程,然后使用这个方程来预测给定独立变量值的因变量值。只有当你过度拟合模型时(这是不好的),这种方法才会精确地预测训练数据中的某个数据点。

更多信息和链接请参考:

https://en.wikipedia.org/wiki/Regression_analysis

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注