- | - |
---|---|
名称 | 波士顿房价数据集(Boston House Prices dataset) |
特征简介 | CRIM - 城镇人均犯罪率 ZN - 占地面积超过25,000平方英尺的住宅用地比例 INDUS - 每个城镇非零售业务的比例 CHAS - Charles River虚拟变量 NOX - 一氧化氮浓度(每千万份) RM - 每间住宅的平均房间数 AGE - 1940年以前建造的自住单位比例 DIS - 波士顿的五个就业中心加权距离 RAD - 径向高速公路的可达性指数 TAX - 每10,000美元的全额物业税率 PTRATIO - 城镇的学生与教师比例 B - $ 1000*(Bk - 0.63)^2$其中Bk是城镇黑人的比例 LSTAT - 区域中被认为是低收入阶层的比率 MEDV - 自有住房的中位数报价, 单位1000美元 |
记录数 | 506条 |
分析目标 | 建立一个从已知特征预测波士顿未知房价的模型 |
分析思路和方法 | 采用线性回归和随机森林对房价进行预测,同时筛选出影响波士顿房价的主要因素 |
本文所用《波士顿房价数据集》数据来源于UCI的《Boston House Prices dataset》。
CRIM - 城镇人均犯罪率
ZN - 占地面积超过25,000平方英尺的住宅用地比例
INDUS - 每个城镇非零售业务的比例
CHAS - Charles River虚拟变量
NOX - 一氧化氮浓度(每千万份)
RM - 每间住宅的平均房间数
AGE - 1940年以前建造的自住单位比例
DIS - 波士顿的五个就业中心加权距离
RAD - 径向高速公路的可达性指数
TAX - 每10,000美元的全额物业税率
PTRATIO - 城镇的学生与教师比例
B - $ 1000*(Bk - 0.63)^2$其中Bk是城镇黑人的比例
LSTAT - 区域中被认为是低收入阶层的比率
MEDV - 自有住房的中位数报价, 单位1000美元
回归是一种运用广泛的统计分析方法,可以通过规定因变量和自变量来确定变量之间的因果关系,建立回归模型,并根据实测数据来求解模型的各参数,然后评价回归模型是否能够很好的拟合实测数据,如果能够很好的拟合,则可以根据自变量作进一步预测。
利用sklearn库,搭建线性回归模型和随机森林模型进行波士顿房价预测,同时比较二者相同数据集中的RMSE(均方根误差)的大小,对二者模型进行评估和挑选。利用随机森林对特征重要度进行排行,找出对波士顿房价影响最大的因素。
线性回归模型拟合较好,其中LSTAT(人口状况下降百分数)和RM(每间住宅平均房间数)对波士顿房价影响较大。其次,PTRATIO(城镇的学生与教师比例),CRIM(城镇人均犯罪率),INDUS(每个城镇非零售业务的比例),DIS(波士顿的五个就业中心加权距离)这几个因素对房价也产生些许影响。
- 陈书晗:负责线性回归模型和随机森林模型搭建
- 杨浩:负责分析图表的绘制
- 杨开友:负责文档的攥写
利用sklearn加载其自带的boston数据集。
from sklearn.datasets import load_boston
boston = load_boston()
将原来数据中的data项和prices项合并成一个新数据集。
#数据提取
data_df = pd.DataFrame(data,columns=feature_names)
prices_df = pd.DataFrame(prices,columns=['MEDV'])
boston_df = pd.DataFrame(data_df)
boston_df['MEDV'] = prices
boston_df.describe()
通过pandas的info()函数查看数据集中是否存在空缺值和数据集中各变量的属性。从结果可看出,无缺失值且各特征数值为float类型。
boston_df.info()
import seaborn as sns
sns.pairplot(boston_df)
plt.tick_params(labelsize=25)
plt.savefig('pairplot.png')
boston_df.hist(bins=15)
plt.savefig('hist.png')
boston_df.hist(bins=15)
plt.savefig('hist.png')
names = feature_names.tolist()
names.append('MEDV')
correction = boston_df.corr()
fig = plt.figure(figsize=(15,15))
ax = fig.add_subplot()
ax = sns.heatmap(correction,cmap='YlGnBu', linewidths=0.05,vmax=1, vmin=-1 ,annot=True,annot_kws={'size':14,'weight':'bold'})
plt.xticks(np.arange(15),names)
plt.yticks(np.arange(15),names)
ax.set_title('相关系数矩阵图')
plt.savefig('heatmap.png')
plt.show()
correction
sns.boxplot(data=boston_df[['INDUS','RM','RAD','LSTAT']])
plt.savefig("box.png")
sns.violinplot(data=boston_df[['INDUS','RM','RAD','LSTAT']])
plt.savefig("violin.png")
sns.distplot(boston_df['MEDV'])
plt.savefig('MEDV.png')
#正态分布验证图
from scipy import stats
res = stats.probplot(boston_df['MEDV'],plot=plt)
#导入所需库
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn import metrics
#数据自变量与因变量划分
X = data_df.drop(['MEDV'],axis=1)
y = data_df['MEDV']
#训练集与测试集划分
X_train,X_test,y_train,y_test = train_test_split(X,y,random_state=0)
#模型拟合
model = LinearRegression()
model.fit(X_train,y_train)
predict = model.predict(X_test)
#数据预测对比图
y_index = [x for x in range(len(y_test))]
plt.scatter(y_index,y_test,label="actual",c="orange")
plt.scatter(y_index,predict,label="predict",c="green")
plt.legend(fontsize=15,markerscale=1)
plt.tick_params(labelsize=25)
plt.grid()
plt.savefig('线性回归预测值与真实值.png')
plt.show()
#可决系数
print("R Square : {}".format(model.score(X_test,y_test)))
#均根方差
RMSE = np.sum(np.sqrt((predict-y_test)**2))/len(data_df)
print("RMSE : {}".format(RMSE))
R Square : 0.6354638433202131
RMSE : 0.9207073691961186
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import GridSearchCV
param_grid = {
'n_estimators':[5,10,20,50,100,200],#决策树的个数
'max_depth':[3,5,7],#最大树深
'max_features':[0.6,0.7,0.8,1]#特征采用划分
}
rf = RandomForestRegressor()
grid = GridSearchCV(rf,param_grid=param_grid,cv=3)
grid.fit(X_train,y_train)
from sklearn import tree
import pydotplus
from IPython.display import Image,display
rf_reg = grid.best_estimator_
estimator = rf_reg.estimators_[3]
dot_data = tree.export_graphviz(estimator,out_file=None,filled=True,rounded=True)
graph = pydotplus.graph_from_dot_data(dot_data)
graph.write_pdf('boston_price_predict_tree.pdf')
display(Image(graph.create_png()))
result['label'].plot(style='k.',c='orange',markersize=15)
result['prediction'].plot(style='r.',c='green',markersize=15)
plt.legend(fontsize=15,markerscale=1)
plt.tick_params(labelsize=25)
plt.grid()
plt.savefig("随机森林拟合结果.png")
feature_importances = rf_reg.feature_importances_
indices = np.argsort(feature_importances)[::-1]
sns.barplot(feature_names[indices],feature_importances[indices])
plt.savefig("features_importance.png")
#最优树模型参数
print("Best Params : {}".format(grid.best_params_))
#可决系数
print("R Square : {}".format(grid.best_score_))
#均根方差
MSE = metrics.mean_squared_error(y,rf_reg.predict(X))
RMSE = np.sqrt(MSE)
print("RMSE : {}".format(RMSE))
Best Params : {'max_depth': 7, 'max_features': 0.6, 'n_estimators': 200}
R Square : 0.8654507915978027
RMSE : 2.5590515715912807
1.城镇犯罪率(CRIM)越低位置,房价越高。
2.占地面积超过25,000平方英尺的住宅用地比例(ZN)与房价之间相关性较低
3.每个城镇非零售业务的比例(INDUS)较高位置,房价较低。但是,在INDUS较低的位置,也存在较低房价。
4.Charles River虚拟变量(CHAS)流域附近房价有高有低。
5.一氧化氮浓度(NOX)与房价相关性不明显。
6.每间住宅的平均房间数(RM)与房价呈正相关,房间数越多,房价越高。
7.1940年以前建造的自住单位比例(AGE)与房价相关性不高
8.波士顿的五个就业中心加权距离(DIS)越高,房价越高,但大部分房子的DIS处于4以下。
9.径向高速公路的可达性指数(RAD)与房价无相关性
10.每10,000美元的全额物业税率(TAX)处于400以下,房价有高有低。
11.城镇的学生与教师比例(PTRATIO)较高,低价房源也越多。
12.1000(Bk - 0.63)^2其中Bk是城镇黑人的比例(B)大多处于400左右,房价也在集中在2~4万美元。
13.区域中被认为是低收入阶层的比率(LSTAT)与房价呈负相关,LSTAT越高,房价越低。
从箱型图和小提琴图可知,MEDV大部分分布于1.5-2.5万美元内。其中最低房价在5000美元左右,但也存在部分房价高达5万美元以上。同时,对MEDV进行正态分布检验,结果显示,房价也是呈正态分布,且期望值$\mu$约等于2万美元。
大部分房子的房间数在6个左右,但最低不会低于3个,最多也不会超过10个。
线性回归的均根方差(RMSE)为0.92,可决系数(R Square)为0.64。从数据可知,线性回归对数据拟合较好,且预测值与实际值之间的误差也较低。这说明线性回归在此数据集上的预测效果较好。
随机森林模型的均根方差(RMSE)为2.56,可决系数(R Square)为0.87。从数据可知,随机森林模型对数据拟合优于线性回归,但预测值与实际值的误差却要远高于线性回归。这表明随机森林模型虽能较好拟合原始数据,但其预测准确度却较差。
从特征重要度排行图中可知,区域中被认为是低收入阶层的比率(LSTAT)与每间住宅的平均房间数(RM)对房价(MEDV)的影响较大,其为最主要的因素。当然,城镇的学生与教师比例(PTRATIO),犯罪率(CRIM),每个城镇非零售业务的比例(INDUS),波士顿的五个就业中心加权距离(DIS)这几个因素对房价影响也不容忽视。径向高速公路的可达性指数(RAD),占地面积超过25,000平方英尺的住宅用地比例(ZN),Charles River流域附近(CHAS)这几个因素对房价几乎不产生影响。
波士顿房价主要由低收入阶层的比率和房间数决定的,低收入阶层能承受的房价有限,这也就决定了当地房价的上限和均值。同时,房间数越多,占地就越多,其所需面积就越大,因此房价也就越贵。当然,学区房、当地犯罪率、以及房子周边购物便捷程度也起着很大的影响因素。学区房其价格决定于学生的消费承受能力,所以学区房的价格一般也不会太高。犯罪率低的地区,人们会更乐意去买房,这也就导致当地房价的抬高。城镇非零售业务的比例,换个指标来说就是购物便捷程度,购物便捷程度越高,房价自然也就较高。
上述结论都是从宏观上而言的,结论只具有一般性。若要具体到某个房子,则需要根据当地实际情况分析。同时,由于时间关系,我们只搭建并训练了线性回归和随机森林两个模型,希望在未来的研究中能加入更多模型,进行分析对比,选出最优模型,更好的进行预测。