2016-12-23 3 views
2

그래디언트 하강을 사용한 선형 회귀를 구현하기 위해 다음 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)); 
    } 
} 

답변

3

아무런 문제가 없습니다.

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 ‘ ’ 1 

Residual standard error: 8.641 on 8 degrees of freedom 
Multiple R-squared: 0.897, Adjusted R-squared: 0.8841 
F-statistic: 69.67 on 1 and 8 DF, p-value: 3.214e-05 

75의 X 값, Y 모자 계산치 :

-266.5344 +(6.1376 *75) 

[1] 193.784

난 R의 용액 검증

정확한 예측입니다. 혼란은 회귀가 어떻게 작용하는지에 관한 것이어야한다고 생각합니다. 회귀 분석은 주어진 독립 데이터 포인트에 해당하는 교육 데이터에서 데이터 포인트의 정확한 실제 값을 알려주지 않습니다. 그것은 통계 모델이 아닌 사전 일뿐입니다 (이 경우에는 보간하거나 추정 할 수 없습니다).

회귀 분석을 통해 모델 방정식을 추정 한 후 독립 변수 값이 주어질 때 종속 변수의 값을 예측하는 데 사용됩니다. 이 경우 정확하게 훈련 데이터의 데이터 요소를 예측하는 것은 모델을 과밀 (overfit)했을 때입니다. 자세한 내용 및 링크는

:

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

+1

은 네는 회귀 및 그라데이션 하강의 개념과 혼동했다. 답변 해주셔서 감사합니다. – noober

+1

@noober 도와 드리겠습니다. ML 및 회귀 분석을위한 훌륭한 Java 라이브러리를 원한다면 Weka를 통해 Weka를 추천합니다. –