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

我编写了以下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

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

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