使用弹性网络回归(Elastic Net Regression)算法来预测波士顿房屋价格。弹性网络回归是一种结合了L1和L2正则化惩罚的线性回归模型,能够处理高维数据和具有多重共线性的特征。弹性网络回归的目标函数包括数据拟合损失和正则化项:
m i n w 1 2 n ∣ ∣ y − X w ∣ ∣ 2 2 + α ( λ ∣ ∣ w ∣ ∣ 1 + 1 2 ( 1 − λ ) ∣ ∣ w ∣ ∣ 2 2 ) min_w\frac{1}{2n}||y-Xw||^2_2+\alpha(\lambda||w||_1+\frac12(1-\lambda)||w||^2_2) minw2n1∣∣y−Xw∣∣22+α(λ∣∣w∣∣1+21(1−λ)∣∣w∣∣22)
其中, y y y是目标变量向量, X X X是输入特征矩阵, w w w是模型的权重系数, n n n是样本数, α \alpha α是正则化强度参数, λ \lambda λ是 Elastic Net 混合参数,用来控制L1和L2正则化项的权重。
处理数据流程
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import ElasticNet
from sklearn.metrics import mean_squared_error
from matplotlib import pyplot as plt
import pandas as pd
import numpy as np
from tqdm import tqdm
import time
def ela_net(X_tr,X_te,y_tr,alpha,l1):
s = StandardScaler()
X_tr_s = s.fit_transform(X_tr)
X_te_s = s.fit_transform(X_te)
ela_model = ElasticNet(alpha=alpha,l1_ratio=l1,random_state=2023)
ela_model.fit(X_tr_s,y_tr)
y_pre = ela_model.predict(X_te_s)
return y_pre
data_url = "http://lib.stat.cmu.edu/datasets/boston"
raw_df = pd.read_csv(data_url, sep="\s+", skiprows=22, header=None)
data = np.hstack([raw_df.values[::2, :], raw_df.values[1::2, :2]])
target = raw_df.values[1::2, 2]
X, y = data, target
X_tr, X_te, y_tr, y_te = train_test_split(X, y, test_size=0.3, random_state=2023)
best_a,best_l,min_res = 0,0,float('inf')
for i in tqdm(np.arange(0.1,1,0.1).round(1)):
time.sleep(0.5)
for j in np.arange(0.1,1,0.1).round(1):
# print(i)
y_pre = ela_net(X_tr,X_te,y_tr,i,j)
mes = mean_squared_error(y_pre,y_te)
if mes < min_res:
min_res = mes
best_a,best_l = i,j
print(mes)
print("alpha:",best_a,",lambda:",best_l,",mse:",min_res)
目标是使用Lasso回归算法来建立一个预测模型,通过输入特征预测房屋价格中位数。Lasso回归是一种线性回归的扩展方法,它通过加入L1正则化项来进行特征选择和模型参数的压缩。Lasso回归的优化目标函数如下:
m i n ( ∑ i − 1 n ( y i − y i ^ ) 2 + α ∑ j − 1 p ∣ β j ∣ ) min(\sum_{i-1}^n(y_i-\hat{y_i})^2+\alpha\sum_{j-1}^p|\beta_j|) min(i−1∑n(yi−yi^)2+αj−1∑p∣βj∣)
其中, n n n 是样本数量, p p p 是特征数量, y i {y_i} yi 是实际观测值, y ^ i \hat{y}_i y^i 是预测值, β j \beta_j βj 是模型参数(系数), α \alpha α 是L1正则化项的权重。L1正则化项通过在优化过程中将某些模型参数变为0来实现特征选择的作用
。较大的 α \alpha α 值将更多的系数压缩到零,从而选择出更少的特征。较小的 α \alpha α 值将保留更多的特征。
通过生成一个惩罚函数是回归模型中的变量系数进行压缩,达到防止过度拟合,解决严重共线性的问题。Lasso回归通过引入L1正则化 (即Lasso惩罚项),可以将系数向量中小的权重变为0,从而实现特征选择和模型稀疏性。Lasso回归具备如下几个作用。
正则化的本质可以定义为我们对训练算法所做的任何改变,以减少泛化误差,而不是训练误差。有许多正则化策略。有的对模型进行了额外的约束,如对参数值进行约束;有的对目标函数进行了额外的约束,可以认为是对参数值进行了间接约束或软约束。
模型预测流程
StandardScaler:标准化数据减去均值,然后除以标准差,经过处理后数据符合标准正态分布,即均值为0,标准差为1;适用于本身服从正态分布的数据;基本可用于有outlier的情况,但在计算方差和均值时outliers仍然会影响计算。
MinMaxScaler:区间缩放,基于最大最小值,将数据转换到0,1区间上的,转换函数:x = (x-min) / (max-min);适用于分布范围较稳定的数据,当新数据的加入导致max/min变化,则需重新定义;因为outlier会影响最大值或最小值,因此对outlier非常敏感。
RobustScaler:使用具有鲁棒性的统计量缩放带有异常值(离群值)的数据,该缩放器删除中位数,并根据百分位数范围(默认值为IQR:四分位间距)缩放数据;适用于包含许多异常值的数据;x=(x-median)/(p75-p25):默认使用第一个四分位数(25%分位数)和第3个四分位数(75%分位数)之间的范围。
sklearn.metrics【指标】
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
data_url = "http://lib.stat.cmu.edu/datasets/boston"
raw_df = pd.read_csv(data_url, sep="\s+", skiprows=22, header=None)
data = np.hstack([raw_df.values[::2, :], raw_df.values[1::2, :2]])
target = raw_df.values[1::2, 2]
print(data.shape,"\t",target.shape)
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import RobustScaler
X_train,X_test,y_train,y_test = train_test_split(data,target,test_size=0.3,random_state=2023)
# ro = RobustScaler()
# X_train_r = ro.fit_transform(X_train)
# X_test_r = ro.fit_transform(X_test)
from sklearn.linear_model import Lasso
def lasso_net(alpha):
model = Lasso(alpha=alpha)
model.fit(X_train,y_train)
y_pre = model.predict(X_test)
return y_pre
from sklearn.metrics import r2_score
max_r , best_a= 0,0
for i in np.arange(0.1,1,0.1).round(1):
r2 = r2_score(lasso_net(i),y_test)
if r2>max_r:
max_r = r2
best_a = i
print(r2)
las = Lasso(best_a)
las.fit(X_train, y_train)
# 绘制特征系数变化图
features = ["CRIM","ZN","INDUS","CHAS","NOX","RM","AGE","DIS","RAD","PTRATIO","B","LSTAT","MEDV"]
plt.plot(range(data.shape[1]), las.coef_)
plt.xticks(range(data.shape[1]), features, rotation=90)
# 设置数字标签
for a, b in zip(range(data.shape[1]), las.coef_):
plt.text(a, b, b.round(2), ha='center', va='bottom', fontsize=12)
plt.xlabel('Features')
plt.ylabel('Coefficients')
plt.title('Lasso Regression Coefficients')
plt.show()
岭回归是一种用于处理多重共线性问题的线性回归方法,它通过对模型的系数进行约束,可以提高模型的稳定性和泛化能力。岭回归通过在损失函数中添加一个L2正则化项来控制模型的复杂度。L2正则化项基于模型的系数向量的平方和来惩罚大的系数值,从而有效地减小模型的过拟合风险。
λ ∑ j − 1 p w j 2 \lambda\sum_{j-1}^pw^2_j λj−1∑pwj2
其中, λ \lambda λ 是我们定义的正则化参数, p p p 是特征的数量, w j w_j wj 是第 j j j 个特征的系数。岭回归的目标是最小化以下损失函数: l o s s = M S E + λ ∑ j − 1 p w j 2 loss=MSE+\lambda\sum_{j-1}^pw^2_j loss=MSE+λ∑j−1pwj2。这里的 MSE \text{MSE} MSE 是均方误差,即预测值与真实值之间的平方差的平均值。通过添加正则化项,岭回归通过权衡模型的拟合能力和稳定性来提高泛化能力。
数据处理步骤
from sklearn.model_selection import train_test_split
import numpy as np
import pandas as pd
data_url = "http://lib.stat.cmu.edu/datasets/boston"
raw_df = pd.read_csv(data_url, sep="\s+", skiprows=22, header=None)
data = np.hstack([raw_df.values[::2, :], raw_df.values[1::2, :2]])
target = raw_df.values[1::2, 2]
Xtrain,Xtest,ytrain,ytest = train_test_split(data,target)
from sklearn.preprocessing import StandardScaler
s = StandardScaler()
Xtrains = s.fit_transform(Xtrain)
Xtests = s.fit_transform(Xtest)
from sklearn.linear_model import Ridge
def ri_net(xt,yt,xtest,alpha):
ri = Ridge(alpha=alpha)
ri.fit(xt,yt)
y_pre = ri.predict(xtest)
return y_pre
from sklearn.metrics import mean_absolute_percentage_error,r2_score,mean_squared_error
for i in np.arange(0.1,2,0.1):
ym = ri_net(Xtrains,ytrain,Xtests,i)
print(mean_absolute_percentage_error(ytest,ym),r2_score(ytest,ym),mean_squared_error(ytest,ym))
岭回归模型通过引入正则化项来对线性回归模型进行约束,以避免过拟合。使用了 Scikit-learn 中的 Ridge
类来实现岭回归,并使用均方误差来评估模型的性能。
使用多项式回归模型来学习这些特征和价格之间的关系,并预测新的房屋价格。多项式回归是一种回归分析中使用的方法,可以通过拟合一个关于自变量的多项式来预测因变量的数值。与简单线性回归模型只使用一个自变量不同,多项式回归模型可以使用多个自变量来进行拟合。通过引入高次特征变量,多项式回归模型可以更好地适应非线性关系。多项式回归模型的一般形式可以表示为:
Y = θ 0 + θ 1 X + θ 2 X 2 + … + θ n X n Y = \theta_0 + \theta_1X + \theta_2X^2 + \ldots + \theta_nX^n Y=θ0+θ1X+θ2X2+…+θnXn
其中, Y Y Y表示因变量, X X X表示自变量, θ 0 , θ 1 , … , θ n \theta_0, \theta_1, \ldots, \theta_n θ0,θ1,…,θn表示模型的参数, n n n表示多项式的阶数。假设我们有一组自变量 X = { x 1 , x 2 , … , x m } X = \{x_1, x_2, \ldots, x_m\} X={x1,x2,…,xm} 和对应的因变量 Y = { y 1 , y 2 , … , y m } Y = \{y_1, y_2, \ldots, y_m\} Y={y1,y2,…,ym},我们的目标是找到最佳拟合的二次多项式曲线。 Y = θ 0 + θ 1 X + θ 2 X 2 Y = \theta_0 + \theta_1X + \theta_2X^2 Y=θ0+θ1X+θ2X2。为了找到最佳拟合的参数值 θ 0 , θ 1 , θ 2 \theta_0, \theta_1, \theta_2 θ0,θ1,θ2,我们可以使用最小二乘法。我们需要最小化残差平方和(RSS):
R S S = ∑ i = 1 m ( y i − y ^ i ) 2 RSS = \sum_{i=1}^{m}(y_i - \hat{y}_i)^2 RSS=i=1∑m(yi−y^i)2
其中, y i y_i yi是观测到的因变量值, y ^ i \hat{y}_i y^i 是根据模型得到的预测值。
计算流程
from sklearn.metrics import r2_score
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression
import numpy as np
import pandas as pd
data_url = "http://lib.stat.cmu.edu/datasets/boston"
raw_df = pd.read_csv(data_url, sep="\s+", skiprows=22, header=None)
data = np.hstack([raw_df.values[::2, :], raw_df.values[1::2, :2]])
target = raw_df.values[1::2, 2]
poly = PolynomialFeatures(degree=3)
X_p = poly.fit_transform(data)
model = LinearRegression()
model.fit(X_p,target)
y_p = model.predict(X_p)
r2 = r2_score(target,y_p)
print(r2)
使用PolynomialFeatures
类将原始特征向量X
转换为多项式特征向量X_poly
。使用LinearRegression
类构建多项式回归模型并进行拟合。