[英]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))
}
現在,讓我們在示例X
, y
上考慮其實現。
oo <- GD(X, y, c(0,0), 5)
經過107次迭代后,收斂。 我們可以查看MSE的蹤跡:
plot(oo[[1]])
請注意,在最初的幾個步驟中,MSE下降非常快,但隨后幾乎保持平穩。 這揭示了梯度下降算法的根本缺點:隨着我們越來越接近最小值,收斂速度越來越慢。
現在,我們提取最終的估計系數:
oo[[2]][, 107]
我們還可以將其與QR因式分解的直接估計進行比較:
.lm.fit(X, y)$coef
他們非常接近。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.