总代码
'''
任务1——可视化房屋数据
'''
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.linear_model import SGDRegressor
import joblib
df=pd.read_csv('D:/Python/chapter3/data/house.txt',sep=',',header=0)
plt.scatter(df['area'],df['price'],c='b')
'''
任务2——线性回归模型的训练
'''
df=(df-df.min())/(df.max()-df.min())
train_data=df.sample(frac=0.8,replace=False)
test_data=df.drop(train_data.index)
#转换数据
x_train=train_data['area'].values.reshape(-1, 1)
y_train=train_data['price'].values
x_test=test_data['area'].values.reshape(-1, 1)
y_test=test_data['price'].values
#构建并训练模型
model=SGDRegressor(max_iter=500,learning_rate='constant',eta0=0.01)
#训练模型
model.fit(x_train,y_train)
#输出训练结果
pre_score=model.score(x_train,y_train)
print('score=',pre_score)
print('coef=',model.coef_,'intercept=',model.intercept_)
#保存训练后的模型
joblib.dump(model,'D:/Python/chapter3/sava_model/SGDRegressor.model')
#3.3task3
'''
任务3——模型的测试及评价
'''
#加载训练好模型
model=joblib.load('D:/Python/chapter3/sava_model/SGDRegressor.model')
y_pred=model.predict(x_test)#得到预测值
print('测试集准确性得分=%.5f'%model.score(x_test,y_test))
#计算测试集的损失(用均方差)
MSE=np.mean((y_test - y_pred)**2)
print('损失MSE={:.5f}'.format(MSE))
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.figure(figsize=(10,4))
ax1=plt.subplot(121)
plt.scatter(x_test,y_test,label='测试集')
plt.plot(x_test,y_pred,'r',label='预测回归线')
ax1.set_xlabel('面积')
ax1.set_ylabel('价格')
plt.legend(loc='upper left')
ax2=plt.subplot(122)
x=range(0,len(y_test))
plt.plot(x,y_test,'g',label='真实值')
plt.plot(x,y_pred,'r',label='预测值')
ax2.set_xlabel('样本序号')
ax2.set_ylabel('价格')
plt.legend(loc='upper right')
plt.show()
任务一:可视化房屋数据
1.绘制散点图
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
df=pd.read_csv('D:/Python/chapter3/data/house.txt',sep=',',header=0)
plt.scatter(df['area'],df['price'],c='b')
plt.show()
先从数据集文件 house.txt 中读取数据,将一行数据的值(面积,价格)作为一个点的坐标值(xy),然后用散点函数绘制出所有点的分布图。代码行4读取CSV文件,由于文件的第0行是数据列名称,因此指定 header=0。代码行5中的c=‘b’指定散点的颜色是蓝色。
运行结果:
2.观察数据分布规律
由图可知,房屋整体样本数据呈现出线性分布的态势(见直线标识),所有样本点基本均匀分布在直线周围。因此,完全可以尝试使用线性回归模型来解决房屋价格预测的问题。
任务二:线性回归模型的训练
1.数据的归一化处理
为消除不同量纲数据带来的影响,尽量提高模型训练精度,对房屋样本数据按照min-max 标准化方法进行归一化处理,df数据范围为0~1,有利于后续模型的训练和测试,实现代码如下。
df=(df-df.min())/(df.max()-df.min())
2.产生训练集和测试集
在归一化处理房屋样本数据后,为了更好地训练和评估模型,通常将数据分成两份,份是用于训练模型的训练集,另一份是用于评估模型的测试集。显然,当样本数据足够多时,两份数据集的比例可以为1:1,因为无论对于训练还是测试而言,大量的数据都有利于模型参数调整和降低测试误差。本次样本数据只有870个,考虑到用更多的数据来训练模型可得到更可信的模型,同时兼顾一定的测试误差,将训练集和测试集的比例分配为4:1,代码如下。
train_data=df.sample(frac=0.8,replace=False)
test_data=df.drop(train_data.index)
#转换数据
x_train=train_data['area'].values.reshape(-1, 1)
y_train=train_data['price'].values
x_test=test_data['area'].values.reshape(-1, 1)
y_test=test_data['price'].values
3.构建并训练模型
采用机器学习库 scikit-lear 中的随机梯度下降回归模型函数 SGDRegressor 来构建模型,并利用归一化后的数据对它进行训练。如果没有安装 scikit-learn机器学习库,在终端输入以下指令(清华源)
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple scikit-learn
安装好scikit-learn机器学习库后,构建模型并对其进行训练
from sklearn.linear_model import SGDRegressor
import joblib
#构建并训练模型
model=SGDRegressor(max_iter=500,learning_rate='constant',eta0=0.01)
#训练模型
model.fit(x_train,y_train)
#输出训练结果
pre_score=model.score(x_train,y_train)
print('score=',pre_score)
print('coef=',model.coef_,'intercept=',model.intercept_)
#保存训练后的模型
joblib.dump(model,'D:/Python/chapter3/sava_model/SGDRegressor.model')
代码行 1-2分别导入随机梯度下降回归模型函数 SGDRegressor 和轻量级管道jobm库、代码行6构建线性回归模型,代码行8开始训练模型。随机梯度下降算法的主要思是:从样本中随机抽出一组、训练后按梯度更新一次,然后再抽取一组,再更新一次,在样本量极大的情况下,可能不用训练完所有的样本就可以获得一个损失值在可接受范围>内的模型。此处的随机是指在每次选代过程中,样本都要被随机打乱,以有效减少样本>间造成的参数更新抵消问题。该模型的优点是训练速度快;但缺点也很明显,即准确率低并不是全局最优、不易于并行实现。本次训练的选代次数是500,学习率初值是0.01,在学习过程中自动优化更新,其他训练系数采用默认值。
代码行10-11 计算并输出模型训练后的预测准确率得分,又叫判定系数,模型的score方法返回的值小于等于1,它反映了因变量y的波动有多少百分比能被自变量x的波动所描述,即表征因变量,的波动中有多少百分比可由控制的自变量x来解释。得分越高,则线性回归方程的拟合度越高,说明x对y的解释程度越高,自变量引起的波动占总波动的百分比越高、观察点在回归直线附近越密集。
代码行12分别输出模型训练后的自变量系数和截距,即线性回归方程中的和。代码行14保存训练后的模型到指定文件处,以便随后能及时调用这个训练好的模型。
任务三::模型的测试及其评估
1.计算均方误差
在训练好的模型上运用测试集x_test得到预测集y_pred;然后利用测试样本的真实值cst和对应的预测集y_pred来计算损失MSE,以此作为模型的评估标准。实现代码如下。
#加载训练好模型
model=joblib.load('D:/Python/chapter3/sava_model/SGDRegressor.model')
y_pred=model.predict(x_test)#得到预测值
print('测试集准确性得分=%.5f'%model.score(x_test,y_test))
#计算测试集的损失(用均方差)
MSE=np.mean((y_test - y_pred)**2)
print('损失MSE={:.5f}'.format(MSE))
运行结果
终端中显示
测试集准确率得分=0.70548
损失MSE=0.00678
代码行2加载前文训练好的模型,代码行3得到预测集,代码行4计算测试集的准确率得分,代码行6计算损失MSE,此损失值通过代码行输出。测试集的均方误差约为0.007,测试集准确率得分为0.70548,说明房屋价格的波动因素中约70%可由面积的波动来解释,拟合度还是不错的。
绘制预测效果图
为直观了解预测效果,在真实样本散点图上绘制出预测回归线,观察真实样本与预测回归线的整体分布是否趋于一致,然后对比真实值与预测值的分布折线图的拟合情况如何总之,当得到理想的模型后,就可以利用该模型对提供的自变量x预测出对应的y,从而完成房屋价格的预测工作。绘图代码如下。
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.figure(figsize=(10,4))
ax1=plt.subplot(121)
plt.scatter(x_test,y_test,label='测试集')
plt.plot(x_test,y_pred,'r',label='预测回归线')
ax1.set_xlabel('面积')
ax1.set_ylabel('价格')
plt.legend(loc='upper left')
ax2=plt.subplot(122)
x=range(0,len(y_test))
plt.plot(x,y_test,'g',label='真实值')
plt.plot(x,y_pred,'r',label='预测值')
ax2.set_xlabel('样本序号')
ax2.set_ylabel('价格')
plt.legend(loc='upper right')
plt.show()