簡體   English   中英

用梯度下降(最陡下降)估計線性回歸

[英]Estimating linear regression with Gradient Descent (Steepest Descent)

示例數據

X<-matrix(c(rep(1,97),runif(97)) , nrow=97, ncol=2)
y<-matrix(runif(97), nrow= 97 , ncol =1)

我已經成功創建了成本函數

COST<-function(theta,X,y){
### Calculate half MSE 
    sum((X %*% theta - y)^2)/(2*length(y))
}

無論如何,當我運行此函數時,它似乎無法收斂100次以上的迭代。

theta <- matrix (0, nrow=2,ncol=1)
num.iters <- 1500
delta = 0 

GD<-function(X,y,theta,alpha,num.iters){
    for (i in num.iters){

        while (max(abs(delta)) < tolerance){

            error <- X %*% theta - y
            delta <- (t(X) %*% error) / length(y)
            theta <- theta - alpha * delta
            cost_histo[i] <- COST(theta,X,y)
            theta_histo[[i]] <- theta

  }
  }
        return (list(cost_histo, theta_histo))
  }

有人能幫我嗎 ?

干杯

實現的算法部分是正確的。 問題出在

  • GD的循環結構不正確; for循環是多余的,變量缺少適當的初始化。
  • 通過使用固定的alpha值簡單實現梯度下降很危險。 通常建議將此alpha選擇得足夠小,以希望我們總是向下搜索目標函數。 但是,這在實踐中很少見。 例如,多小就足夠了? 如果太小,那么收斂速度就會成為問題; 但是如果它很大,我們可能會陷入“之字形”的搜索路徑,甚至出現分歧!

這是梯度下降的可靠版本,用於估計線性回歸 改進來自逐步減半策略,以避免“鋸齒”或發散。 查看代碼中的注釋。 在這種策略下,使用大alpha是安全的。 保證融合。

# theta: initial guess on regression coef
# alpha: initial step scaling factor
GD <- function(X, y, theta, alpha) {
  cost_histo <- numeric(0)
  theta_histo <- numeric(0)
  # an arbitrary initial gradient, to pass the initial while() check
  delta <- rep(1, ncol(X))
  # MSE at initial theta
  old.cost <- COST(theta, X, y)
  # main iteration loop
  while (max(abs(delta)) > 1e-7) {
    # gradient 
    error <- X %*% theta - y
    delta <- crossprod(X, error) / length(y)
    # proposal step
    trial.theta <- theta - alpha * c(delta)
    trial.cost <- COST(trial.theta, X, y)
    # step halving to avoid divergence
    while (trial.cost >= old.cost) {
      trial.theta <- (theta + trial.theta) / 2
      trial.cost <- COST(trial.theta, X, y)
      }
    # accept proposal
    cost_histo <- c(cost_histo, trial.cost)
    theta_histo <- c(theta_histo, trial.theta)
    # update old.cost and theta
    old.cost <- trial.cost
    theta <- trial.theta
    }
  list(cost_histo, theta_histo = matrix(theta_histo, nrow = ncol(X)))
  }

返回時,

  • cost_histo的長度告訴您進行了多少次迭代(不包括減半);
  • theta_histo每一列theta_histo給出每次迭代的theta

實際上,將步數減半可大大加快收斂速度​​。 如果對COST使用更快的計算方法,則可以提高效率。 (對於大型數據集最有用。請參閱https://stackoverflow.com/a/40228894/4891738

COST<-function(theta,X, y) {
  c(crossprod(X %*% theta - y)) /(2*length(y))
  }

現在,讓我們在示例Xy上考慮其實現。

oo <- GD(X, y, c(0,0), 5)

經過107次迭代后,收斂。 我們可以查看MSE的蹤跡:

plot(oo[[1]])

請注意,在最初的幾個步驟中,MSE下降非常快,但隨后幾乎保持平穩。 這揭示了梯度下降算法的根本缺點:隨着我們越來越接近最小值,收斂速度越來越慢。

現在,我們提取最終的估計系數:

oo[[2]][, 107]

我們還可以將其與QR因式分解的直接估計進行比較:

.lm.fit(X, y)$coef

他們非常接近。

與以前的方法相比,crossprod的速度令人驚訝地慢:

以前的方法(50次迭代平均需要14秒):

在此處輸入圖片說明

Crossprod方法(50次迭代平均16秒):

在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM