实施梯度下降时出现问题



代码:

import numpy as np
import pandas as pd
from sklearn.linear_model import LinearRegression
from sklearn.metrics import r2_score
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
df = pd.read_csv("D:datadiabetes.csv")
y = df[["Outcome"]]
x = df.iloc[:, [1]]
# Applying linear regression
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3, random_state=2)
reg = LinearRegression()
reg.fit(x_train, y_train)
y_pred = reg.predict(x_test)
r2_score(y_test, y_pred)
# Applying gradient descent
class GDRegressor:
def __init__(self, learning_rate=0.01, epochs=100):
self.coef_ = None
self.intercept_ = None
self.lr = learning_rate
self.epochs = epochs

def fit(self, x_train, y_train):
# init your coefficients from X_train because coefficients are equal to the number of features
self.intercept_ = 0
self.coef_ = np.ones(x_train.shape[1])  # [1] take the columns from (353, 10) <-- shape of X_train
for i in range(self.epochs):
# update all the coefficients and the intercept
y_hat = np.dot(x_train, self.coef_) + self.intercept_
# print("Shape of y_hat",y_hat.shape)
intercept_der = -2 * np.mean(y_train - y_hat)
self.intercept_ = self.intercept_ - (self.lr * intercept_der)
coef_der = -2 * np.dot((y_train - y_hat), x_train) / x_train.shape[0]
self.coef_ = self.coef_ - (self.lr * coef_der)
print(self.intercept_, self.coef_)

def predict(self, x_test):
return np.dot(x_test, self.coef_) + self.intercept_
gdr = GDRegressor(epochs=100, learning_rate=0.5)
gdr.fit(x_train, y_train)

错误:

ValueError  Traceback (most recent call last)
<ipython-input-135-33c959c29314> in <module>
----> 1 gdr.fit(x_train,y_train)

<ipython-input-130-42d541ead6b9> in fit(self, x_train, y_train)
17             y_hat = np.dot(x_train,self.coef_) + self.intercept_
18             #print("Shape of y_hat",y_hat.shape)
---> 19             intercept_der = -2 * np.mean(y_train - y_hat)
20             self.intercept_ = self.intercept_ - (self.lr * intercept_der)
21 

~anaconda3libsite-packagespandascoreops__init__.py in f(self, other, axis, level, fill_value)
693     def f(self, other, axis=default_axis, level=None, fill_value=None):
694 
--> 695         other = _align_method_FRAME(self, other, axis)
696 
697         if isinstance(other, ABCDataFrame):

~anaconda3libsite-packagespandascoreops__init__.py in _align_method_FRAME(left, right, axis)
642 
643         if right.ndim == 1:
--> 644             right = to_series(right)
645 
646         elif right.ndim == 2:

~anaconda3libsite-packagespandascoreops__init__.py in to_series(right)
634             if len(left.columns) != len(right):
635                 raise ValueError(
--> 636                     msg.format(req_len=len(left.columns), given_len=len(right))
637                 )
638             right = left._constructor_sliced(right, index=left.columns)

ValueError: Unable to coerce to Series, length must be 1: given 537

问题来自此行中的点积:

coef_der = -2 * np.dot((y_train - y_hat), x_train) / x_train.shape[0]

需要替换为:

coef_der = - 2 * np.dot(x_train.T, (y_train - y_hat)) / x_train.shape[0]

一旦修复,GDRegressor的结果将与scikit的结果一致。学习LinearRegression,请参阅下面的代码。

import numpy as np
import pandas as pd
from sklearn.datasets import make_regression
from sklearn.linear_model import LinearRegression
from sklearn.metrics import r2_score
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
# Data
x, y = make_regression(n_samples=1000, n_features=4, n_informative=3, bias=2, noise=10, random_state=2)
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3, random_state=2)
# Preprocessing
scaler = StandardScaler().fit(x_train)
x_train = scaler.transform(x_train)
x_test = scaler.transform(x_test)
# Gradient Descent
class GDRegressor:
def __init__(self, learning_rate=0.01, epochs=100):
self.coef_ = None
self.intercept_ = None
self.lr = learning_rate
self.epochs = epochs
def fit(self, x_train, y_train):
self.intercept_ = 0
self.coef_ = np.ones(x_train.shape[1])
for i in range(self.epochs):
y_hat = np.dot(x_train, self.coef_) + self.intercept_
intercept_der = - 2 * np.mean(y_train - y_hat)
self.intercept_ = self.intercept_ - (self.lr * intercept_der)
coef_der = - 2 * np.dot(x_train.T, (y_train - y_hat)) / x_train.shape[0]
self.coef_ = self.coef_ - (self.lr * coef_der)
def predict(self, x_test):
return np.dot(x_test, self.coef_) + self.intercept_
gdr = GDRegressor(epochs=100, learning_rate=0.5)
gdr.fit(x_train, y_train)
y_pred_gdr = gdr.predict(x_test)
print(gdr.intercept_)
# 3.770775418017894
print(gdr.coef_)
# [-0.24833521 35.02590365 35.39315588 77.81917572]
print(r2_score(y_test, y_pred_gdr))
# 0.9889061967355228
# Linear regression
reg = LinearRegression()
reg.fit(x_train, y_train)
y_pred_reg = reg.predict(x_test)
print(reg.intercept_)
# 3.7707754180178954
print(reg.coef_)
# [-0.24833521 35.02590365 35.39315588 77.81917572]
print(r2_score(y_test, y_pred_reg))
# 0.9889061967355228

最新更新