我正在尝试在 pytn 中从头开始创建多元线性回归模型。使用的数据集:Boston Housing Dataset
fromSklearn
。由于我的重点是模型构建我没有对数据执行任何预处理步骤。但是,我使用 OLS 模型计算 p 值并从数据中删除 3 个特征。之后,我使用线性回归模型找出每个特征的权重。
import pandas as pd
from sklearn.datasets import load_boston
from sklearn.linear_model import LinearRegression
X=load_boston()
data=pd.DataFrame(X.data,columns=X.feature_names)
y=X.target
data.head()
#dropping three features
data=data.drop(['INDUS','NOX','AGE'],axis=1)
#new shape of the data (506,10) not including the target variable
#Ped the wle dataset to Linear Regression Model
model_lr=LinearRegression()
model_lr.fit(data,y)
model_lr.score(data,y)
0.7278959820021539
model_lr.intercept_
22.60536462807957 #----- intercept value
model_lr.coef_
array([-0.09649731, 0.05281081, 2.3802989 , 3.94059598, -1.05476566,
0.28259531, -0.01572265, -0.75651996, 0.01023922, -0.57069861]) #--- coefficients
现在我想在 pytn 中创建模型之前在 excel 中手动计算系数。为了计算每个功能的权重,我使用了这个公式:
Calculating the Weights of the Features为了计算截距,我使用了公式 b0 = 均值(y)-b1 * 均值(x1)-b2 *(均值(x2)……-bn * 均值(xn)
从我的计算截距值为 22.63551387(几乎相同的模型)
问题是我计算的特征的权重与 sklearn 线性模型的权重相差甚远。
-0.002528644 #-- CRIM
-0.001028914 #-- Zn
-0.038663314 #-- CHAS
-0.035026972 #-- RM
-0.014275311 #-- DIS
-0.004058291 #-- RAD
-0.000241103 #-- TAX
-0.015035534 #-- PTRATIO
-0.000318376 #-- B
-0.006411897 #-- LSTAT
使用第一行作为测试数据来检查我的计算,我得到 22.73167044199992,而线性回归模型预测 30.42657776。原始值为 24。
但是,只要我检查其他行,sklearn 模型就会有更多的变化,而我计算的权重所做的预测都显示接近 22 的值。
我想我在计算权重时犯了一个错误,但我不确定问题在哪里?我的计算有错误吗?为什么我所有的计算系数都如此接近 0?
这是我的计算系数的代码:(初学者在这里)
x_1=[]
x_2=[]
for i,j in zip(data['CRIM'],y):
mean_x=data['CRIM'].mean()
mean_y=np.mean(y)
c=i-mean_x*(j-mean_y)
d=(i-mean_x)**2
x_1.append(c)
x_2.append(d)
print(sum(x_1)/sum(x_2))
谢谢你读这篇文章,我很感激。
看来麻烦在于系数计算,你给出的计算系数的公式是标量形式,用于线性回归的最简单情况,即只有一个特征 x。
编辑
现在,在查看了用于系数计算的代码之后,问题变得更加清晰。您不能使用此方程式来计算彼此的每个特征的系数,因为每个系数将取决于所有特征。我建议您在简单情况here和一般情况here下查看此最小二乘优化问题的解的推导。作为通用的提示,只要可以实现,矩阵就会更有效。
However, in this case we have a 10-dimensional feature vector, and so in matrix notation it becomes.
请参见派生here
我怀疑你在这里犯了一些计算错误,因为使用标量公式在 pytn 中实现这个比矩阵等效更乏味和不整洁。
下面是如何实现它的一个例子:
def calc_coefficients(X,Y):
X=np.mat(X)
Y = np.mat(Y)
return np.dot((np.dot(np.transpose(X),X))**(-1),np.transpose(np.dot(Y,X)))
def score_r2(y_pred,y_true):
ss_tot=np.power(y_true-y_true.mean(),2).sum()
ss_res = np.power(y_true -y_pred,2).sum()
return 1 -ss_res/ss_tot
X = np.ones(shape=(506,11))
X[:,1:] = data.values
B=calc_coefficients(X,y)
##### Coeffcients
B[:]
matrix([[ 2.26053646e+01],
[-9.64973063e-02],
[ 5.28108077e-02],
[ 2.38029890e+00],
[ 3.94059598e+00],
[-1.05476566e+00],
[ 2.82595310e-01],
[-1.57226536e-02],
[-7.56519964e-01],
[ 1.02392192e-02],
[-5.70698610e-01]])
#### Intercept
B[0]
matrix([[22.60536463]])
y_pred = np.dot(np.transpose(B),np.transpose(X))
##### First 5 rows predicted
np.array(y_pred)[0][:5]
array([30.42657776, 24.80818347, 30.69339701, 29.35761397, 28.6004966 ])
##### First 5 rows Ground Truth
y[:5]
array([24. , 21.6, 34.7, 33.4, 36.2])
### R^2 score
score_r2(y_pred,y)
0.7278959820021539
完整解决方案-2020-波士顿数据集
正如另一个人所说,要计算线性回归的系数,你必须计算
β = (X^T X)^-1 X^T y
这给你的系数(所有的 B 为特征 + 截距)。
请确保在 X 中添加一个包含所有 1 的列,以计算截距(代码中有更多内容)
Main.pyfrom sklearn.datasets import load_boston
import numpy as np
from CustomLibrary import CustomLinearRegression
from CustomLibrary import CustomMeanSquaredError
boston = load_boston()
X = np.array(boston.data, dtype="f")
Y = np.array(boston.target, dtype="f")
regression = CustomLinearRegression()
regression.fit(X, Y)
print("Projection matrix sk:", regression.coefficients, "\n")
print("bias sk:", regression.intercept, "\n")
Y_pred = regression.predict(X)
loss_sk = CustomMeanSquaredError(Y, Y_pred)
print("Model performance:")
print("--------------------------------------")
print("MSE is {}".format(loss_sk))
print("\n")
CustomLibrary.py
import numpy as np
cl CustomLinearRegression():
def __init__(self):
self.coefficients = None
self.intercept = None
def fit(self, x , y):
x = self.add_one_column(x)
x_T = np.transpose(x)
inverse = np.linalg.inv(np.dot(x_T, x))
pseudo_inverse = inverse.dot(x_T)
coef = pseudo_inverse.dot(y)
self.intercept = coef[0]
self.coefficients = coef[1:]
return coef
def add_one_column(self, x):
'''
the fit metd with x feature return x coefficients ( include the intercept)
so for have the intercept + x feature coefficients we have to add one column ( in the beginning )
with all 1ones
'''
X = np.ones(shape=(x.shape[0], x.shape[1] +1))
X[:, 1:] = x
return X
def predict(self, x):
predicted = np.array([])
for sample in x:
result = self.intercept
for idx, feature_value_in_sample in enumerate(sample):
result += feature_value_in_sample * self.coefficients[idx]
predicted = np.append(predicted, result)
return predicted
def CustomMeanSquaredError(Y, Y_pred):
mse = 0
for idx,data in enumerate(Y):
mse += (data - Y_pred[idx])**2
return mse * (1 / len(Y))
本站系公益性非盈利分享网址,本文来自用户投稿,不代表边看边学立场,如若转载,请注明出处
评论列表(13条)