数据主要包括2014年5月至2015年5月美国King County的房屋销售价格以及房屋的基本信息。
数据分为训练数据和测试数据,分别保存在kc_train.csv和kc_test.csv两个文件中。
其中训练数据主要包括10000条记录,14个字段,主要字段说明如下:
第一列“销售日期”:2014年5月到2015年5月房屋出售时的日期
第二列“销售价格”:房屋交易价格,单位为美元,是目标预测值
第三列“卧室数”:房屋中的卧室数目
第四列“浴室数”:房屋中的浴室数目
第五列“房屋面积”:房屋里的生活面积
第六列“停车面积”:停车坪的面积
第七列“楼层数”:房屋的楼层数
第八列“房屋评分”:King County房屋评分系统对房屋的总体评分
第九列“建筑面积”:除了地下室之外的房屋建筑面积
第十列“地下室面积”:地下室的面积
第十一列“建筑年份”:房屋建成的年份
第十二列“修复年份”:房屋上次修复的年份
第十三列"纬度":房屋所在纬度
第十四列“经度”:房屋所在经度
销售日期 卧室数 浴室数 房屋面积 停车面积 楼层数 房屋评分 建筑面积 地下室面积 建筑年份 修复年份 纬度 经度
20150302 3 2.25 1670 6240 1.0 8 1240 430 1974 0 47.6413 -122.113
第二列“销售价格”就是目标。
理论上讲,价格应该与卧室数,浴室数,房屋面积,停车面积,楼屋数,房屋评分,建筑面积,地下室面积成正比,跟建筑年份成反比,跟修复年份(不清楚),跟纬度经度有聚类的关系。
<1> 初步分析:
方法1:1v1的看
![](https://img.haomeiwen.com/i4559317/e49fd6e281ad7ffb.png)
![](https://img.haomeiwen.com/i4559317/d3e72b7e7b389fe3.png)
![](https://img.haomeiwen.com/i4559317/1a33e7b36b0d84e6.png)
![](https://img.haomeiwen.com/i4559317/26cb271ab802006e.png)
![](https://img.haomeiwen.com/i4559317/bb9c951d2f1cdfb1.png)
![](https://img.haomeiwen.com/i4559317/e7e4d4fad02a6b9e.png)
![](https://img.haomeiwen.com/i4559317/b845bfed24065121.png)
- 建筑年龄与修复时间与价格的关联性不是特别清楚:
![](https://img.haomeiwen.com/i4559317/c00d9ae850fd1c08.png)
![](https://img.haomeiwen.com/i4559317/7ee0eebec039b35d.png)
![](https://img.haomeiwen.com/i4559317/44cc20e7d914016d.png)
1v1的示例代码:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
data=pd.read_csv("kc_train.csv")
test="停车面积"
temp=data
d=dict(data[test].value_counts())
df = pd.DataFrame({})
for i in d:
d[i]=0
p1=[]
p2=[]
for i in d:
p1.append(i)
d[i]=temp.loc[temp[test]==i]['销售价格'].mean()
p2.append(d[i])
df[test]=p1
df['销售价格']=p2
sns.set(font='SimHei',font_scale=0.8) # 解决Seaborn中文显示问题并调整字体大小
sns.barplot(y="销售价格", x=test, data=df)
plt.show()
方法2:当然也可以1v多:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
data=pd.read_csv("kc_train.csv")
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False
corrmat = data.corr()
plt.subplots(figsize=(12,9))
sns.heatmap(corrmat, vmax=0.9, square=True,center=2.0)
![](https://img.haomeiwen.com/i4559317/4c1c602bd7613c53.png)
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
plt.rcParams['figure.dpi'] = 90 #分辨率
data=pd.read_csv("kc_train.csv")
corrmat = data.corr()
# 特征相关系数
k = 10
cols = corrmat.nlargest(k, '销售价格')['销售价格'].index
# 只取关联性前k的特征
# 淘汰了 '销售日期', '停车面积', '建筑年份', '经度' 四个特征
cm = np.corrcoef(data[cols].values.T)
# corrcoef(x,y):计算列向量x、y的相关系数,要求x、y具有相等的元素个数,T是翻转矩阵的意思
# values返回一个array
sns.set(font_scale=0.7)
hm = sns.heatmap(cm, cbar=True, annot=True, square=True, fmt='.2f', annot_kws={'size': 10}, yticklabels=cols.values, xticklabels=cols.values)
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
plt.show()
![](https://img.haomeiwen.com/i4559317/842b6dfed8d32567.png)
<2> 数据清洗
-
检查是否存在空值:
'True' in data.isnull()
发现没有 -
去噪
<3> 划分训练集和验证集
训练集,测试集比例为7:3。
def Data(IO):
X=IO
Y = X['销售价格']
X= X.drop('销售价格'],axis = 1)
X_train, X_test, y_train, y_test = \
cross_validation.train_test_split( X, Y, test_size=0.3, random_state=0)
return (X_train, X_test, y_train, y_test)
<4> 尝试各种算法:
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split
data=pd.read_csv("kc_train.csv")
def Data(IO):
X=IO
Y = X['销售价格']
X= X.drop(['销售价格'],axis = 1)
X_train, X_test, y_train, y_test = train_test_split( X, Y, test_size=0.3, random_state=0)
return (X_train, X_test, y_train, y_test)
x_train, x_test, y_train, y_test=Data(data)
def loss(y_test,predicted):
cost=0
a=y_test.values
for i in range(len(predicted)):
cost+=(predicted[i]-a[i])**2
return cost/(10000*3000)
def RF(X_train, X_test, y_train, y_test): #随机森林
from sklearn.ensemble import RandomForestClassifier
model= RandomForestClassifier(n_estimators=10)
model.fit(X_train, y_train)
predicted= model.predict(X_test)
score = loss(y_test, predicted)
return (score)
# RF: 7752700.0793058
# RF 50 : 5863878.750277567
# RF 100 : 5107723.136976433 / 4840716.8811414
# RF 120 : 4765230.745854666
# RF 150 : 4318322.8558068
rf={"RF:":RF(x_train, x_test, y_train, y_test)}
def LOR(X_train, X_test, y_train, y_test): #逻辑回归
from sklearn.linear_model import LogisticRegression
lor = LogisticRegression(penalty='l1',C=100,multi_class='ovr')
# C是正则化强度的倒数,越小越强
lor.fit(X_train, y_train)
predicted= lor.predict(X_test)
score = loss(y_test, predicted)
return (score)
# LOR: 9709095.706138566
lor={"LOR:":LOR(x_train, x_test, y_train, y_test)}
def Svm(X_train, X_test, y_train, y_test): #支持向量机
from sklearn import svm
model = svm.SVC(kernel='rbf')
model.fit(X_train, y_train)
predicted= model.predict(X_test)
score = loss(y_test, predicted)
return (score)
# Svm: 12909610.382325433
svm={"Svm:":Svm(x_train, x_test, y_train, y_test)}
def LR(X_train, X_test, y_train, y_test): #线性回归
from sklearn.linear_model import LinearRegression
LR = LinearRegression()
LR.fit(X_train, y_train)
predicted = LR.predict(X_test)
score = loss(y_test, predicted)
return (score)
# LR: 4597743.434822384
lr={"LR":LR(x_train, x_test, y_train, y_test)}
ans=dict(lr,**lor,**rf,**svm)
ans=sorted(ans.items(),key=lambda ans:ans[1],reverse=True)
print(ans)
网友评论