初试机器学习回归模型案例 (预测房价)
——————By 李志鹏
数据集下载地址https://pan.baidu.com/s/1o8xbwIQ
探索房屋数据集
importpandasaspd
df=pd.read_csv('house_data.csv')
df.head()
# CRIM犯罪率 RM房间数 AGE建造时长 LSTAT人口比例 MEDV平均房价
可视化房屋数据集的特征
importmatplotlib.pyplotasplt
importseabornassns
sns.set(context='notebook')
cols= ['LSTAT','AGE','DIS','CRIM','MEDV','TAX','RM']
sns.pairplot(df[cols],size=2.5)
plt.show()
实现线性回归模型通过梯度下降法计算回归参数,实现线性回归模型
importnumpyasnp
classLinerRegressionByMySelf(object):
def__init__(self,learn_rate=0.001,epoch=20):
"""
learn_rate : 学习率
epoch : 迭代次数
"""
self.learn_rate=learn_rate
self.epoch=epoch
pass
deffit(self,x,y):
"""
训练方法
x : 原始数据 (其他特征)
y : 标签数据 (房价)
"""
self.w=np.zeros(1+x.shape[1])# x前系数初始化为零向量
self.cost_list= []# 误差初始化为空列表
foriinrange(self.epoch):
output=self.regression_input(x)# 得到估计值
error= (y-output)# 得到误差
self.w[1:] +=self.learn_rate*x.T.dot(error)# 更新x前系数
self.w[] +=self.learn_rate*error.sum()# 更新截距
cost= (error**2).sum()/2.0# 计算残差平方和
self.cost_list.append(cost)
pass
returnself
pass
defregression_input(self,x):
returnnp.dot(x,self.w[1:])+self.w[]# y = wx + w0
pass
defpredict(self,x):
"""
预测方法
"""
returnself.regression_input(x)
pass
x=df[['LSTAT']].values# 自变量维度
y=df['MEDV'].values# 因变量维度
fromsklearn.preprocessingimportStandardScaler# 数据归一化库
StandardScaler_x=StandardScaler()
StandardScaler_y=StandardScaler()
x_Standard=StandardScaler_x.fit_transform(x)
# y_Standard = StandardScaler_y.fit_transform(y) # 不知道为什么对y进行归一化会报错
y_Standard=y
model=LinerRegressionByMySelf()
model.fit(x_Standard,y_Standard)
plt.plot(range(1,model.epoch+1),model.cost_list)# 画图 横坐标迭代次数,纵坐标误差值
plt.xlabel('epoch(迭代次数)')
plt.ylabel('SSE(残差平方和)')
plt.show()
defRegression_plot(x,y,model):
plt.scatter(x,y,c='blue')# 散点图
plt.plot(x,model.predict(x),color='red')
returnNone
Regression_plot(x_Standard,y_Standard,model)
plt.xlabel('Percentage of the population')# 人口百分比
plt.ylabel('House price')# 房价
plt.show()
Rercentage_standard=StandardScaler_x.transform([[2.5]])# 归一化 是transform 不是fix_transform
Price_standard=model.predict(Rercentage_standard)
print("House price: %.3f"%Price_standard)# 预测值32.179
House price: 32.179
In[29]:
print("斜率 Slope: %.3f"%model.w[1])# 斜率
斜率 Slope: -6.778
In[30]:
print("截距 Intercept: %.3f"%model.w[])# 截距
截距 Intercept: 22.533
使用sklearn来构建回归模型
fromsklearn.linear_modelimportLinearRegression
sk_model=LinearRegression()
sk_model.fit(x,y)
LinearRegression(copy_X=True, fit_intercept=True, n_jobs=1, normalize=False)
print("斜率 Slope: %.3f"%sk_model.coef_[])# 斜率
斜率 Slope: -0.950
print("截距 Intercept: %.3f"%sk_model.intercept_)# 截距
截距 Intercept: 34.554
Regression_plot(x,y,sk_model)
plt.xlabel('Percentage of the population')# 人口百分比
plt.ylabel('House price')# 房价
plt.show()
评估线性模型交叉验证 训练集 + 测试集
fromsklearn.cross_validationimporttrain_test_split
cols= ['LSTAT','AGE','DIS','CRIM','TAX','RM']
x=df[cols].values
y=df[['MEDV']].values
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.25,random_state=)
sk_model=LinearRegression()
sk_model.fit(x_train,y_train)
y_train_predict=sk_model.predict(x_train)# 训练集
y_test_predict=sk_model.predict(x_test)# 测试集
plt.scatter(y_train_predict,y_train_predict-y_train,c='red',marker='x',label='Train data')
plt.scatter(y_test_predict,y_test_predict-y_test,c='black',marker='o',label='Test data')
plt.xlabel('Predicted values')# 预测值
plt.ylabel('Residuals')# 残差
plt.legend(loc='upper left')# 图例
plt.hlines(y=,xmin=-10,xmax=50,lw=1,color='green')# 在残差为0处画水平线
plt.xlim(-10,50)# 设置x轴范围
plt.show()
如上图所示,训练集和测试集残差差不多,说明这个拟合还算可以
fromsklearn.metricsimportmean_squared_error# 均方误差模块
print('MSE train %.3f, test %.3f'%(
mean_squared_error(y_train,y_train_predict),
mean_squared_error(y_test,y_test_predict),
))
MSE train 25.106, test 36.671
数字告诉我们训练集误差比较低,可能出现过拟合
fromsklearn.metricsimportr2_score# R^2评分 即相关系数平方
print('R^2 train %.3f, test %.3f'%(
r2_score(y_train,y_train_predict),
r2_score(y_test,y_test_predict),
))
R^2 train 0.706, test 0.551
数字告诉我们训练集相关程度比较大,可能出现过拟合建模房屋数据集里的非线性关系(多项式回归)
x=df[['RM']].values# 房间数
y=df[['MEDV']].values# 房价
regression_model=LinearRegression()
fromsklearn.preprocessingimportPolynomialFeatures# 多项式特征库
quadratic=PolynomialFeatures(degree=2)# 二次回归
cubic=PolynomialFeatures(degree=3)# 三次回归
x_squared=quadratic.fit_transform(x)# 二次变换
x_cubic=cubic.fit_transform(x)# 三次变换
x_fit=np.arange(x.min(),x.max(),0.01)[: ,np.newaxis]# 增加一维 一维变二维
linear_model=regression_model.fit(x,y)# 得到线性回归模型
y_line_fit=linear_model.predict(x_fit)# 计算线性回归预测值
linear_r2=r2_score(y,linear_model.predict(x))# 计算线性回归相关系数平方
squared_model=regression_model.fit(x_squared,y)# 得到平方回归模型
y_squared_fit=squared_model.predict(quadratic.fit_transform(x_fit))# 计算平方回归预测值
squared_r2=r2_score(y,squared_model.predict(x_squared))# 计算平方回归相关系数平方
cubic_model=regression_model.fit(x_cubic,y)# 得到立方回归模型
y_cubic_fit=squared_model.predict(cubic.fit_transform(x_fit))# 计算立方回归预测值
cubic_r2=r2_score(y,cubic_model.predict(x_cubic))# 计算立方回归相关系数平方
plt.scatter(x,y,label='Training point',color='lightgray')# 真值 灰色散点图
plt.plot(x_fit,y_line_fit,label='linear, $R^2=%.2f$'%linear_r2,color='blue',linestyle=':')# 线性回归 蓝色点画线
plt.plot(x_fit,y_squared_fit,label='quadratic, $R^2=%.2f$'%squared_r2,color='red',linestyle='-')# 平方回归 红色实线
plt.plot(x_fit,y_cubic_fit,label='cubic, $R^2=%.2f$'%cubic_r2,color='green',linestyle='--')# 立方回归 绿色虚线
plt.xlabel('room number')# 房间数量
plt.ylabel('House Pricer')# 房价
plt.legend(loc='upper left')# 左上角图例
plt.show()
领取专属 10元无门槛券
私享最新 技术干货