说明:这篇就是为了让我们更好的利用scikit-learn做机器学习,现以简单的线性回归为例子了解下如何调用scikit-learn一些基本流程。每一块代码下面我们会进行一些分析。
任务:
基于usa_housing_price.csv数据,建立线性回归模型,预测合理房价:
1、以面积为输入变量,建立单因子模型,评估模型表现,可视化线性回归预测结果
2、以income、house age、numbers of rooms、population、area 为输入变量,建立多因子模型,评估模型表现
3、预测income = 65000,House Age = 5,Number of Rooms=5,Polulation = 30000,size = 200的合理房价
#load data
import pandas as pd
import numpy as np
data = pd.read_csv("./data/usa_housing_price.csv")
data.head()
分析:以上先加载数据集,pandas和numpy是进行数据科学运算的工具包,读取数据我们一般用pd.read_csv,读取后的数据是dataFrame类型,可以用head()查看前五行数据,你也可以查看更多行,head(10)就是查看前10行数据。可以从图表中看到地区平均收入,地区平均房龄,地区平均房屋数,地区人口量,房屋大小这几个特征,Price是房价,也是标签。
#先用散点图展示下 地区平均收入 和 房价 趋势
%matplotlib inline
from matplotlib import pyplot as plt
fig = plt.figure(figsize = (10,10)) # 定义图形大小
fig1 = plt.subplot(231) #231表示2行3列的第1幅图
plt.scatter(data.loc[:,'Avg. Area Income'],data.loc[:,'Price'])
plt.title('Price VS Income')
fig2 = plt.subplot(232)
plt.scatter(data.loc[:,'Avg. Area House Age'],data.loc[:,'Price'])
plt.title('Price VS House Age')
fig3 = plt.subplot(233)
plt.scatter(data.loc[:,'Avg. Area Number of Rooms'],data.loc[:,'Price'])
plt.title('Price VS Area Number of Rooms')
fig4 = plt.subplot(234)
plt.scatter(data.loc[:,'Area Population'],data.loc[:,'Price'])
plt.title('Price VS Area Population')
fig5 = plt.subplot(235)
plt.scatter(data.loc[:,'size'],data.loc[:,'Price'])
plt.title('Price VS size')
plt.show()
分析:我们拿到数据一般会画图比如散点图来看下特征和标签之间的关系,我们分别画了这5个特征和房价之间的关系,收入,房屋数,人口数,面积大小这四个特征,基本上越大,房价越高,呈上升趋势,而房龄越大房价会越低。
1.我们先单因子研究下算法,只看size和price的关系
#define X and y
X = data.loc[: ,'size']
y = data.loc[: ,'Price']
y.head()
结果:
0 1.059034e+06
1 1.505891e+06
2 1.058988e+06
3 1.260617e+06
4 6.309435e+05
Name: Price, dtype: float64
(X.shape)# 这里要进行类型转换,X要numpy.array类型,还要是矩阵。dataframe也行
结果:
(5000,)
X = np.array(X).reshape(-1,1)#np.array()先转换成列向量,reshape让其变成矩阵(-1,1)表示若干行,1列。
X
结果
array([[188.2142121],
[160.0425258],
[227.2735445],
…,
[139.4917852],
[184.845371 ],
[148.5894227]])
分析:以上我们通过dataframe的loc方法取出size特征和标签Price,但是注意,如果要放入scikit-learn中的模型拟合数据的话,特征必须是向量,我们的X显然不是向量,通过numpy.array变换,reshape变换转化成矩阵。
#set up the linear regression model
from sklearn.linear_model import LinearRegression
LR1 = LinearRegression()
#train the model
LR1.fit(X,y)
结果:
LinearRegression(copy_X=True, fit_intercept=True, n_jobs=1, normalize=False)
#这里还有瑕疵,就是拟合好的模型做预测应该是给测试数据集,但一开始我们没有分训练集合测试集。我们重点熟悉整个流程。
#calculate the price vs size
y_predict_1 = LR1.predict(X)
print(y_predict_1)
结果
[1276881.85636623 1173363.58767144 1420407.32457443 … 1097848.86467426 1264502.88144558 1131278.58816273]
#evaluate the model
from sklearn.metrics import mean_squared_error,r2_score
mean_squared_error_1 = mean_squared_error(y,y_predict_1)
r2_score_1 = r2_score(y,y_predict_1)
print(mean_squared_error_1,r2_score_1)
结果:
108771672553.6264 0.1275031240418234
fig6 = plt.figure(figsize = (8,5))
plt.scatter(X,y)
plt.plot(X,y_predict_1,'r')
plt.show()
分析:以上,我们调用了scikit中线性模型中的线性回归,fit就是在拟合数据,做好了训练过程。生成的LinearRegression(copy_X=True, fit_intercept=True, n_jobs=1, normalize=False)就是我们的模型!就是这么简单。然后我们对X进行了预测。以上mse我们不太好辨别,数据很大,毕竟是房价,但是r2我们知道越接近1模型效果越好。0.1275显然拟合的模型不好。最后我们通过图形查看拟合情况,更直观。
2.我们用多因子研究下算法,考虑所有的特征。
# define X_multi
# data.drop(['Price'],axis=1)
X_multi = data.loc[: ,['Avg. Area Income','Avg. Area House Age','Avg. Area Number of Rooms','Area Population','size']]
y = data.loc[: ,'Price']
X_multi.head()
#set up the linear regression model
from sklearn.linear_model import LinearRegression
LR_multi = LinearRegression()
#train the model
LR_multi.fit(X_multi,y)
结果:
LinearRegression(copy_X=True, fit_intercept=True, n_jobs=1, normalize=False)
分析:以上我们来看多因子拟合模型,说白了,多因子就是把所有特征都用于拟合模型,这时候我们X是dataframe类型,多行多列也算是矩阵,是可以被拟合的,不用做类型变换。因为单因子时X是一维数据,只有size,我们把它转化成矩阵才用fit拟合的,不然会报错,你们可以试验,会报类型错误。
y_predict_multi = LR_multi.predict(X_multi)
print(y_predict_multi)
结果
[1223968.89166087 1497306.33188629 1250884.31019438 … 1020693.92390376 1260503.36914585 1302737.79157629]
#evaluate the model
from sklearn.metrics import mean_squared_error,r2_score
mean_squared_error_multi = mean_squared_error(y,y_predict_multi)
r2_score_multi = r2_score(y,y_predict_multi)
print(mean_squared_error_multi,r2_score_multi)
结果:
10219846512.177862 0.9180229195220739
fig7 = plt.figure(figsize = (8,5))
plt.scatter(y,y_predict_multi)#对比y和y_predict_multi,这里我也不清楚,scatter都是x,y值画散点图,这里(x,y)位置分别用了两个y值,不是很明白。
plt.show()
分析:以上我们可以看到,通过多因子也就是把所有特征数据都用于拟合模型后,模型的效果好很多,从R2确定系数就能看出,0.918越接近1模型越好。
3.来用测试数据预测下房价
X_test = [65000,5,5,30000,200]
X_test = np.array(X_test).reshape(1,-1)#X_test还不是矩阵,转np,然后reshape转一行多列。(1,-1)表示1行多列。
print(X_test)
结果:
[[65000 5 5 30000 200]]
y_test_predict = LR_multi.predict(X_test)
print(y_test_predict)
结果:
[817052.19516299]
分析:X_test显然不是矩阵也不是dataframe类型,那么变换吧。然后做预测。
数据和代码:https://github.com/Sirow/Linear_Regression
总结:
这个流程很好的让我们学习了用scikit-learn如何进行机器学习实验,大致的框架。调用模型,模型评估,画图。
那我给大家提个问题,为啥用线性回归预测房价?我们的房价是连续值,不是分类,是回归问题。所以我们用线性回归。那为啥用R2来评估呢。因为线性回归模型评估重点就是MSE,SSE,R2确定系数。之后我还会补充更复杂的房租预测,比赛项目。特征很多,过程更复杂,设计特征工程,模型混合。其中官方比赛的评价函数规定用的就是R2。
关于线性回归模型评估我自己总结了一篇大家可以参考:
https://blog.csdn.net/Sirow/article/details/109630056