此線性回歸代碼無法達到收斂,也無法除錯代碼出了什么問題。有人可以幫忙嗎?程序:
- 從資料集中收集 x 和 y
- 通過在前面添加一列 1 來創建 x_updated
- 在平方誤差損失上應用梯度下降(分別寫了一個代碼來計算梯度和損失)
import pandas as pd
import numpy as np
class LinearReg:
def __init__(self,with_reg=False,learning_rate=0.001,stopping_threshold=0.0001,iterations=100000):
"""
Initialise the constructor of the linear regression
"""
#check if we need to fit the with reg loss model or not
self.with_reg=with_reg
#stopping rule for the gadient decent
self.stopping_threshold=stopping_threshold
self.iterations=iterations
#ddefine the learning rate required for gradient decent
self.learning_rate=learning_rate
def calc_naive_loss_gradient(self,weight_vector):
"""
Calculate the gradient decent for the non regularised
loss with with given x,y and weights
"""
first_comp=np.dot(np.dot(self.x_updated.transpose(),self.x_updated),weight_vector)
second_comp=np.dot(self.x_updated.transpose(),self.y)
return(first_comp-second_comp)
def calc_naive_loss(self,weight_vector):
"""
Calculate the naive loss function value
"""
return(np.sqrt(np.sum(np.dot(self.x_updated,weight_vector)**2)))
def gradient_decent(self,weight_vector_new,weight_vector_old):
"""
Function to apply gradient decent on the loss function
"""
print('Weight vector old: {}'.format(weight_vector_old))
while(True):
weight_vector_old=weight_vector_new.copy()
weight_vector_new=weight_vector_old-self.learning_rate*self.calc_naive_loss_gradient(weight_vector_old)
print('Updated loss: {}'.format(self.calc_naive_loss(weight_vector_new)))
dist_weights=np.sqrt(np.sum((weight_vector_new-weight_vector_old)**2))
if(dist_weights<self.stopping_threshold):
break;
return(weight_vector_new)
def fit(self,x,y):
"""
Function to fit the linear regression
"""
#define a column of vector 1
one_vector=np.ones(x.shape[0]).reshape(x.shape[0],1)
#concatenate the x vector with vector of 1
self.x_updated=np.concatenate((one_vector,x),axis=1)
self.y=y
#initialise a random weight
weight_vector=np.random.uniform(0,1,self.x_updated.shape[1])
#run gradient decent to get the best weights
best_weight=self.gradient_decent(weight_vector_new=weight_vector.copy(),
weight_vector_old=weight_vector.copy())
print('Best loss: {}'.format(self.calc_naive_loss(weight_vector=best_weight)))
a=LinearReg()
import numpy as np
from sklearn.utils import shuffle
from sklearn.datasets import make_regression
x, y = make_regression(n_features=5,n_samples=2010)
a.fit(x,y)
uj5u.com熱心網友回復:
更新梯度下降函式中的誤差和權重。然后在合適的范圍內。檢查下面的代碼。
import numpy as np
class LinearReg:
def __init__(self,with_reg=False,learning_rate=0.0001,
stopping_threshold=1e-8,iterations=100000):
self.stopping_threshold = stopping_threshold
self.iterations = iterations
self.learning_rate = learning_rate
def gradient_descent(self):
direction = self.x_updated.T @ (self.y - self.x_updated @ self.weights)
new = self.weights self.learning_rate * direction
self._error = np.linalg.norm(new - self.weights)
self.weights = new
def fit(self,x,y, intercept = False):
self.x_updated = np.c_[np.ones((y.size, 1)), x] if intercept else x
self.y=y
self.weights = np.random.uniform(0, 1, self.x_updated.shape[1])
for it in range(self.iterations):
self.gradient_descent()
if self._error<self.stopping_threshold:
print(f"Took {it} iterations to converge")
break
print(self.weights)
a = LinearReg()
from sklearn.datasets import make_regression
x, y = make_regression(n_features=5,n_samples=2010)
LinearReg(learning_rate=0.0005).fit(x,y)
Took 9 iterations to converge
[44.49799439 48.81286468 96.08803245 93.87028819 84.4267467 ]
# compare:
from sklearn.linear_model import LinearRegression
print(LinearRegression(fit_intercept = False).fit(x, y).coef_)
[44.49799439 48.81286468 96.08803245 93.87028819 84.4267467 ]
uj5u.com熱心網友回復:
這可以幫助您創建非常接近 sklearn 提供的 LinearRegression 類的東西。
class LinearRegression():
betas = None
def fit(self, x, y, learning_rate = 0.001):
beta_0 = beta_1 = 0
n = len(x)
while True:
y_pred = beta_0 (beta_1 * x)
cost = round(np.mean((y - y_pred) ** 2), 5)
beta_0_d = (-2/n) * sum(y - y_pred)
beta_1_d = (-2/n) * sum(x * (y - y_pred))
beta_0 = beta_0 - (beta_0_d * learning_rate)
beta_1 = beta_1 - (beta_1_d * learning_rate)
if cost == 0:
break
self.betas = (round(beta_0, 2), round(beta_1, 2))
def predict(self, x):
return self.betas[0] self.betas[1] * x
有關更多詳細資訊,您可以查看ml-concepts.com 關于梯度下降的這篇文章,該文章解釋了從 Scratch 創建線性回歸演算法的整個程序。
如果您只對代碼感興趣,那么您可以參考這個Google Colab 筆記本。
(全面披露——我是 ml-concepts.com 團隊的一員)
uj5u.com熱心網友回復:
代碼沒問題,除了計算損失函式的公式。正確的損失代碼將是:
def calc_naive_loss(self,weight_vector):
"""
Calculate the naive loss function value
"""
return(np.sum((self.y-self.x_updated@weight_vector)**2))
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/487614.html
