首先分别介绍一下这一对有趣的模型把:K-Means与随机森林(后文将其称为模型一),为什么要要介绍这一对模型呢?是因为小编在一次项目上机缘巧合的产生了这样一个想法:如果我先将数据集进行K-Means进行聚类,然后再分别对每一类进行预测,这样的出来的结果误差会不会更小呢?根据这次试验的结果,答案是肯定的,误差变小的原理小编也没怎么琢磨透,估计就是聚类后,已经将数据自觉地分为一类,这样可能会相对比起直接全部堆在一起误差会更小把?(小编的猜想)
今天小编要用这一对组合模型对房价进行预测实验,在这里小编将会放上一个对照模型:随机森林(后文将其称为模型二)。随后小编将分别用这两对模型进行预测,并将其结果的变化过程展示给各位童鞋看看!
那么先简单的介绍一下两个模型的原理:
一、K-Means
k均值聚类算法(k-means clustering algorithm)是一种迭代求解的聚类分析算法,其步骤是随机选取K个对象作为初始的聚类中心,然后计算每个对象与各个种子聚类中心之间的距离,把每个对象分配给距离它最近的聚类中心。聚类中心以及分配给它们的对象就代表一个聚类。每分配一个样本,聚类的聚类中心会根据聚类中现有的对象被重新计算。这个过程将不断重复直到满足某个终止条件。终止条件可以是没有(或最小数目)对象被重新分配给不同的聚类,没有(或最小数目)聚类中心再发生变化,误差平方和局部最小。
二、随机森林回归
首先利用bootstrap方法又放回的从原始训练集中随机抽取n个样本,并构建n个决策树;然后假设在训练样本数据中有m个特征,那么每次分裂时选择最好的特征进行分裂 每棵树都一直这样分裂下去,直到该节点的所有训练样例都属于同一类;接着让每颗决策树在不做任何修剪的前提下最大限度的生长;最后将生成的多棵分类树组成随机森林,用随机森林分类器对新的数据进行分类与回归。
对于回归问题,则由多棵树预测值的均值决定最终预测结果。
先给童鞋们看看数据的大概长什么样:
对,一共有76个变量,而最高房价与房价中位数是我们将要预测的两个变量。
模型一步骤如下:
1、先将数据进行聚类,分到直到没有缺失值的类别才停止
2、分别将每一类进行随机森林预测
代码如下:
import pandas as pd
import os
from sklearn.cluster import KMeans
import seaborn as sns
import matplotlib.pyplot as pltos.chdir(r'C:\Users\HHX\Desktop\神经网络预测')
data_1=pd.read_excel(r'test1.xlsx')
new_list_id=[]
new_list_content=[]
for i in range(5,30,1):
clf = KMeans(n_clusters=i)
s = clf.fit(data_1.iloc[:,:-3])
new_list_id.append(i)
new_list_content.append(clf.inertia_)
plt.figure()
plt.scatter(new_list_id,new_list_content)
sns.lineplot(x=new_list_id,y=new_list_content)
plt.show()clf = KMeans(n_clusters=10)
ypred = clf.fit_predict(data_1.iloc[:,:-3])
data_1['结果']=list(ypred)
最终小编将数据集分为了10类(这里你也可以试试15或20等,不过不建议太高)
接着将其进行随机森林预测,代码如下:
from sklearn.ensemble import RandomForestRegressor
rf = RandomForestRegressor(n_estimators=100,max_features= 0.7)test_data=data_1.loc[(data_1['结果']==2) & (data_1['房价中位数_201903']==0)]
train_data=data_1.loc[(data_1['结果']==2) & (data_1['房价中位数_201903']!=0)]#test_data=data_1.loc[(data_1['最高房价_201903']==0)]
#train_data=data_1.loc[(data_1['最高房价_201903']!=0)][:-4]X=train_data.iloc[:,1:-4]
y=train_data.iloc[:,-2]
#树
rf.fit(X,y)# 训练模型
test_data.iloc[:,-2]= rf.predict(test_data.iloc[:,1:-4])#把训练好的模型带入测试集并返回到测试集的表00plt.figure()
plt.scatter(train_data['_id'].tolist(),train_data['房价中位数_201903'].tolist())
plt.scatter(test_data['_id'].tolist(),test_data['房价中位数_201903'].tolist())
sns.lineplot(x=train_data['_id'].tolist(),y=train_data['房价中位数_201903'].tolist())
sns.lineplot(x=test_data['_id'].tolist(),y=test_data['房价中位数_201903'].tolist())
plt.show()train_mean=train_data.iloc[:,-2].mean()
test_mean=test_data.iloc[:,-2].mean()print(abs(test_mean-train_mean))
#final.to_csv('树回归all_predict.csv')
#dataset是包含poi和房中房低的数据#这个图表面在同一类的数据基本上都处于同一个区间,效果还不错
模型二:随机森林
步骤如下:
直接进行随机森林预测,代码如下:
test_data=data_1.loc[(data_1['房价中位数_201903']==0)]
train_data=data_1.loc[(data_1['房价中位数_201903']!=0)]X=train_data.iloc[:,1:-4]
y=train_data.iloc[:,-2]
#树
rf.fit(X,y)# 训练模型
test_data.iloc[:,-2]= rf.predict(test_data.iloc[:,1:-4])#把训练好的模型带入测试集并返回到测试集的表00
test_data_1=test_data.loc[(test_data['结果']==2)]
train_data_1=train_data.loc[(train_data['结果']==2)]train_mean=test_data_1.iloc[:,-2].mean()
test_mean=train_data_1.iloc[:,-2].mean()print(abs(test_mean-train_mean))
plt.figure()
plt.scatter(train_data_1['_id'].tolist(),train_data_1['房价中位数_201903'].tolist())
plt.scatter(test_data_1['_id'].tolist(),test_data_1['房价中位数_201903'].tolist())
sns.lineplot(x=train_data_1['_id'].tolist(),y=train_data_1['房价中位数_201903'].tolist())
sns.lineplot(x=test_data_1['_id'].tolist(),y=test_data_1['房价中位数_201903'].tolist())
plt.show()#同样都是一个类别,但是效果相差甚大
综合两个模型来看:
很明显,模型一(左)的准确性比模型二(右)的准确性高很多(都是同一个类别的数据)