日萌社
人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度学习实战(不定时更新)
数据集下载链接:https://pan.baidu.com/s/13OtaUv6j4x8dD7cgD4sL5g
提取码:7tze
库安装:pip install xgboost
数据初步分析
In [1]:
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')#忽略一些警告
# plt.rcParams['font.sans-serif']=['SimHei']
# plt.rcParams['axes.unicode_minus']=False
导入数据
In [2]:
train=pd.read_csv("data/train.csv")
test=pd.read_csv("data/test.csv")
train.head()
Out[2]:
时间 | 小区名 | 小区房屋出租数量 | 楼层 | 总楼层 | 房屋面积 | 房屋朝向 | 居住状态 | 卧室数量 | 厅的数量 | 卫的数量 | 出租方式 | 区 | 位置 | 地铁线路 | 地铁站点 | 距离 | 装修情况 | 月租金 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 3072 | 0.128906 | 2 | 0.236364 | 0.008628 | 东南 | NaN | 1 | 1 | 1 | NaN | 11.0 | 118.0 | 2.0 | 40.0 | 0.764167 | NaN | 5.602716 |
1 | 1 | 3152 | 0.132812 | 1 | 0.381818 | 0.017046 | 东 | NaN | 1 | 0 | 0 | NaN | 10.0 | 100.0 | 4.0 | 58.0 | 0.709167 | NaN | 16.977929 |
2 | 1 | 5575 | 0.042969 | 0 | 0.290909 | 0.010593 | 东南 | NaN | 2 | 1 | 2 | NaN | 12.0 | 130.0 | 5.0 | 37.0 | 0.572500 | NaN | 8.998302 |
3 | 1 | 3103 | 0.085938 | 2 | 0.581818 | 0.019199 | 南 | NaN | 3 | 2 | 2 | NaN | 7.0 | 90.0 | 2.0 | 63.0 | 0.658333 | NaN | 5.602716 |
4 | 1 | 5182 | 0.214844 | 0 | 0.545455 | 0.010427 | 东北 | NaN | 2 | 1 | 1 | NaN | 3.0 | 31.0 | NaN | NaN | NaN | NaN | 7.300509 |
In [4]:
train.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 196539 entries, 0 to 196538
Data columns (total 19 columns):
时间 196539 non-null int64
小区名 196539 non-null int64
小区房屋出租数量 195538 non-null float64
楼层 196539 non-null int64
总楼层 196539 non-null float64
房屋面积 196539 non-null float64
房屋朝向 196539 non-null object
居住状态 20138 non-null float64
卧室数量 196539 non-null int64
厅的数量 196539 non-null int64
卫的数量 196539 non-null int64
出租方式 24230 non-null float64
区 196508 non-null float64
位置 196508 non-null float64
地铁线路 91778 non-null float64
地铁站点 91778 non-null float64
距离 91778 non-null float64
装修情况 18492 non-null float64
月租金 196539 non-null float64
dtypes: float64(12), int64(6), object(1)
memory usage: 28.5+ MB
In [5]:
train.describe()
Out[5]:
时间 | 小区名 | 小区房屋出租数量 | 楼层 | 总楼层 | 房屋面积 | 居住状态 | 卧室数量 | 厅的数量 | 卫的数量 | 出租方式 | 区 | 位置 | 地铁线路 | 地铁站点 | 距离 | 装修情况 | 月租金 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
count | 196539.000000 | 196539.000000 | 195538.000000 | 196539.000000 | 196539.000000 | 196539.000000 | 20138.000000 | 196539.000000 | 196539.000000 | 196539.000000 | 24230.000000 | 196508.000000 | 196508.000000 | 91778.000000 | 91778.000000 | 91778.000000 | 18492.000000 | 196539.000000 |
mean | 2.115229 | 3224.116562 | 0.124151 | 0.955449 | 0.408711 | 0.013139 | 2.725196 | 2.236635 | 1.299625 | 1.223818 | 0.900289 | 7.905139 | 67.945982 | 3.284850 | 57.493735 | 0.551202 | 3.589228 | 7.949313 |
std | 0.786980 | 2023.073726 | 0.133299 | 0.851511 | 0.183100 | 0.008104 | 0.667763 | 0.896961 | 0.613169 | 0.487234 | 0.299621 | 4.025696 | 43.522394 | 1.477147 | 35.191414 | 0.247268 | 1.996912 | 6.310609 |
min | 1.000000 | 0.000000 | 0.007812 | 0.000000 | 0.000000 | 0.000000 | 1.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 1.000000 | 1.000000 | 0.001667 | 1.000000 | 0.000000 |
25% | 1.000000 | 1388.000000 | 0.039062 | 0.000000 | 0.290909 | 0.009268 | 3.000000 | 2.000000 | 1.000000 | 1.000000 | 1.000000 | 4.000000 | 33.000000 | 2.000000 | 23.000000 | 0.356667 | 2.000000 | 4.923599 |
50% | 2.000000 | 3086.000000 | 0.082031 | 1.000000 | 0.418182 | 0.012910 | 3.000000 | 2.000000 | 1.000000 | 1.000000 | 1.000000 | 9.000000 | 61.000000 | 4.000000 | 59.000000 | 0.554167 | 2.000000 | 6.621392 |
75% | 3.000000 | 5199.000000 | 0.160156 | 2.000000 | 0.563636 | 0.014896 | 3.000000 | 3.000000 | 2.000000 | 1.000000 | 1.000000 | 11.000000 | 103.000000 | 5.000000 | 87.000000 | 0.745833 | 6.000000 | 8.998302 |
max | 3.000000 | 6627.000000 | 1.000000 | 2.000000 | 1.000000 | 1.000000 | 3.000000 | 11.000000 | 8.000000 | 8.000000 | 1.000000 | 14.000000 | 152.000000 | 5.000000 | 119.000000 | 1.000000 | 6.000000 | 100.000000 |
数据探索
基本信息
In [6]:
train.head()
Out[6]:
时间 | 小区名 | 小区房屋出租数量 | 楼层 | 总楼层 | 房屋面积 | 房屋朝向 | 居住状态 | 卧室数量 | 厅的数量 | 卫的数量 | 出租方式 | 区 | 位置 | 地铁线路 | 地铁站点 | 距离 | 装修情况 | 月租金 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 3072 | 0.128906 | 2 | 0.236364 | 0.008628 | 东南 | NaN | 1 | 1 | 1 | NaN | 11.0 | 118.0 | 2.0 | 40.0 | 0.764167 | NaN | 5.602716 |
1 | 1 | 3152 | 0.132812 | 1 | 0.381818 | 0.017046 | 东 | NaN | 1 | 0 | 0 | NaN | 10.0 | 100.0 | 4.0 | 58.0 | 0.709167 | NaN | 16.977929 |
2 | 1 | 5575 | 0.042969 | 0 | 0.290909 | 0.010593 | 东南 | NaN | 2 | 1 | 2 | NaN | 12.0 | 130.0 | 5.0 | 37.0 | 0.572500 | NaN | 8.998302 |
3 | 1 | 3103 | 0.085938 | 2 | 0.581818 | 0.019199 | 南 | NaN | 3 | 2 | 2 | NaN | 7.0 | 90.0 | 2.0 | 63.0 | 0.658333 | NaN | 5.602716 |
4 | 1 | 5182 | 0.214844 | 0 | 0.545455 | 0.010427 | 东北 | NaN | 2 | 1 | 1 | NaN | 3.0 | 31.0 | NaN | NaN | NaN | NaN | 7.300509 |
缺失值比例
In [7]:
train_missing = (train.isnull().sum()/len(train))*100# 每列的缺失值个数/总行数
train_missing = train_missing.drop(train_missing[train_missing==0].index).sort_values(ascending=False)#去掉缺失比例为0的列
miss_data = pd.DataFrame({'缺失百分比':train_missing})
miss_data
Out[7]:
缺失百分比 | |
---|---|
装修情况 | 90.591180 |
居住状态 | 89.753688 |
出租方式 | 87.671658 |
距离 | 53.302907 |
地铁站点 | 53.302907 |
地铁线路 | 53.302907 |
小区房屋出租数量 | 0.509314 |
位置 | 0.015773 |
区 | 0.015773 |
目标值分布
In [8]:
plt.figure(figsize=(12,6))
plt.subplot(211)
plt.title('月租金分布')
sns.distplot(train['月租金'])#价格的数量分布曲线
plt.subplot(212)
plt.scatter(range(train.shape[0]),np.sort(train['月租金'].values))
plt.show()
所有特征分布
直方图和柱状分布图
In [9]:
train.hist(figsize=(20,20),bins=50,grid=False)
plt.show()
相关性分析
连续特征和目标值的散点图
In [10]:
train.columns
Out[10]:
Index(['时间', '小区名', '小区房屋出租数量', '楼层', '总楼层', '房屋面积', '房屋朝向', '居住状态', '卧室数量',
'厅的数量', '卫的数量', '出租方式', '区', '位置', '地铁线路', '地铁站点', '距离', '装修情况', '月租金'],
dtype='object')
In [11]:
#通过散点图观察特征和目标值之间的关系
continuous_cols=['时间','小区房屋出租数量', '总楼层','房屋面积', '卧室数量',
'厅的数量', '卫的数量', '距离']
for col in continuous_cols:
sns.jointplot(x=col,y='月租金',data=train,alpha=0.3,size=4)
特征和目标相关性分析
皮尔森相关性热力图
In [12]:
columns=['时间', '小区名', '小区房屋出租数量', '楼层', '总楼层', '房屋面积', '房屋朝向', '居住状态', '卧室数量',
'厅的数量', '卫的数量', '出租方式', '区', '位置', '地铁线路', '地铁站点', '距离', '装修情况', '月租金']
corrmat = train.corr()#计算皮尔森相关性
plt.figure(figsize=(12,12))
sns.heatmap(corrmat, vmax=.8, square=True,annot=True);
皮尔森相关
In [13]:
plt.figure(figsize=(12,6))
train.corr()['月租金'][continuous_cols].sort_values(ascending=False).plot(
'barh',figsize=(12,6),title='特征和月租金皮尔森相关性分析'
)
plt.show()
斯皮尔曼相关
In [14]:
from scipy.stats import spearmanr
rs=[]
for key in continuous_cols:
r,p=spearmanr(train[key],train['月租金']) #计算特征与目标值之间的斯皮尔曼相关性
rs.append(r)
rs=pd.Series(data=rs,index=continuous_cols).dropna()
rs.sort_values(ascending=False).plot(
'barh',figsize=(12,6),title='特征和月租金斯皮尔曼相关性分析'
)
plt.show()
离散特征和月租金关系分析
均值比较
In [15]:
import math
#负责绘制每个特征不同组的月租金均值图
def plot(names,ylabel,data,cols=3):
n=len(data)
rows=math.ceil(n/cols)
fig,ax=plt.subplots(nrows=rows,ncols=cols,figsize=(20,rows*8))
for i in range(n):
x=range(data[i].shape[0])
y=data[i].values
xticks=data[i].index
r=i//cols
c=i%cols
ax[r][c].bar(x,y)
ax[r][c].set_xticks(x)
ax[r][c].set_xticklabels(xticks)
ax[r][c].set_xlabel(names[i])
ax[r][c].set_ylabel(ylabel)
ax[r][c].set_title(names[i]+str(i)+ylabel+"均值比较")
plt.show()
In [16]:
category_cols=['时间','小区名','楼层', '房屋朝向', '居住状态',
'出租方式', '区', '位置', '地铁线路', '地铁站点', '装修情况']
means=[]
for key in category_cols:
means.append(train.groupby(key)['月租金'].mean())
In [17]:
plot(category_cols,"月租金",means)
绘制箱线图
In [18]:
def plot_box(names,x,data,cols=1):
n=len(names)
for i in range(n):
plt.figure(figsize=(12,10))
sns.boxplot(y=names[i],x=x,data=data,orient='h')#绘制箱线图
plt.show()
In [19]:
category_cols2=['时间','楼层', '居住状态',
'出租方式', '区', '地铁线路', '装修情况']
plot_box(category_cols2,"月租金",train)
异常值分析
这里我们主要分析跟月租金相关性较大的房屋面积的异常值
In [20]:
def plot_reg(xs,y,data,cols=1):
n=len(xs)
for i in range(n):
plt.figure(figsize=(10,10))
sns.regplot(x=data[xs[i]],y=data[y])
plt.show()
In [21]:
reg_cols=['房屋面积']
plot_reg(reg_cols,"月租金",train)
问题数据
房间朝向列有多个值
In [22]:
train['房屋朝向'].value_counts()
Out[22]:
南 54770
东南 54359
东 31962
西南 17470
北 10428
...
东南 南 西南 西 1
东 西南 北 1
东南 西 北 1
南 西南 西 西北 1
西南 西 东北 1
Name: 房屋朝向, Length: 64, dtype: int64
In [24]:
def split(text,i):
"""
实现对字符串进行分割,并取出结果中下标i对应的值
"""
items=text.split(" ")
if i<len(items):
return items[i]
else:
return np.nan
for i in range(5):
train['朝向_'+str(i)]=train['房屋朝向'].map(lambda x:split(x,i))
# train['房屋地铁站点朝向'].map(lambda x:x.split(" ")).map(lambda x:len(x)).max()
In [ ]:
names=["朝向_{}".format(i) for i in range(5)]
train[names].info()
同一个小区属于不同的区
In [25]:
train.columns
Out[25]:
Index(['时间', '小区名', '小区房屋出租数量', '楼层', '总楼层', '房屋面积', '房屋朝向', '居住状态', '卧室数量',
'厅的数量', '卫的数量', '出租方式', '区', '位置', '地铁线路', '地铁站点', '距离', '装修情况', '月租金',
'朝向_0', '朝向_1', '朝向_2', '朝向_3', '朝向_4'],
dtype='object')
In [26]:
#去掉'小区名','区','位置'三个列重复之后 有5578个不重复值
neighbors1=train[['小区名','区','位置']]
neighbors1.shape
Out[26]:
(196539, 3)
In [27]:
#去掉'小区名','区','位置'三个列重复之后 有5577个不重复值
neighbors1=train[['小区名','位置']].drop_duplicates().dropna()
neighbors1.shape
Out[27]:
(5577, 2)
In [28]:
#而有位置的小区名只有5547个不重复值 说明有31个小区位于不同的位置
train[train['位置'].notnull()].drop_duplicates(['小区名']).shape
Out[28]:
(5546, 24)
In [29]:
#neighbors1按照小区名分组后保留分组条数大于1的小区名
count=neighbors1.groupby('小区名')['位置'].count()
ids=count[count>1].index
ids
Out[29]:
Int64Index([ 284, 385, 418, 701, 783, 1455, 1870, 2228, 2468, 2513, 2611,
2916, 3183, 3268, 3482, 3645, 3967, 4054, 4071, 4471, 4767, 4859,
5320, 5699, 5844, 5968, 6020, 6122, 6515, 6626, 6627],
dtype='int64', name='小区名')
In [30]:
#在原数据中筛选出这些小区的信息
neighbors_has_problem=train[['小区名','位置']][train['小区名'].isin(ids)].sort_values(by='小区名')
neighbors_has_problem
Out[30]:
小区名 | 位置 | |
---|---|---|
105800 | 284 | 102.0 |
105988 | 284 | 102.0 |
105228 | 284 | 102.0 |
105076 | 284 | 102.0 |
105074 | 284 | 102.0 |
... | ... | ... |
131530 | 6627 | 86.0 |
158621 | 6627 | 136.0 |
56569 | 6627 | 86.0 |
39956 | 6627 | 86.0 |
161162 | 6627 | 136.0 |
843 rows × 2 columns
In [31]:
#找到每个小区的位置众数
#这里要注意x.mode有可能返回多个众数,所以用一个np.max拿到最值最大的众数作为最终的结果
position_mode_of_neighbors=neighbors_has_problem.groupby('小区名').apply(lambda x:np.max(x['位置'].mode()))
#位置缺失值就用这个数据来进行填充,对于已有的一个小区位于不同的位置,考虑到可能是因为小区太大导致,并不能认为是逻辑错误,保持不变
position_mode_of_neighbors
Out[31]:
小区名
284 102.0
385 108.0
418 122.0
701 92.0
783 134.0
1455 40.0
1870 106.0
2228 101.0
2468 43.0
2513 86.0
2611 112.0
2916 31.0
3183 136.0
3268 86.0
3482 64.0
3645 121.0
3967 100.0
4054 1.0
4071 129.0
4471 15.0
4767 18.0
4859 73.0
5320 95.0
5699 120.0
5844 143.0
5968 40.0
6020 109.0
6122 18.0
6515 130.0
6626 86.0
6627 86.0
dtype: float64
同一个小区地铁线路不同的问题
In [32]:
#去掉'小区名','地铁线路'两个列重复之后 有3412个不重复值
lines=train[['小区名','地铁线路']].drop_duplicates().dropna()
lines.shape
Out[32]:
(3412, 2)
In [33]:
#而有地铁的小区名只有3330个不重复值 说明有112个小区有多个地铁线路
train[train['地铁线路'].notnull()].drop_duplicates(['小区名']).shape
Out[33]:
(3330, 24)
In [34]:
#lines按照小区名分组后保留分组条数大于1的小区名 最终有多条地铁的小区有79个
#这个地铁线路分位置可能有关系 因为同一个小区位于不同的位置,地铁线路也有可能不同
count=lines.groupby('小区名')['地铁线路'].count()
ids=count[count>1].index
ids.shape
Out[34]:
(79,)
研究一下位置和地铁线路的关系
In [35]:
#去掉'位置','地铁线路'两个列重复之后 有184个不重复值
pos_lines=train[['位置','地铁线路']].drop_duplicates().dropna()
pos_lines.shape
Out[35]:
(184, 2)
In [36]:
#我们在来看一下有地铁的位置中有多少个不同的 120个
pos_lines['位置'].value_counts()
Out[36]:
113.0 4
100.0 4
118.0 3
63.0 3
106.0 3
..
22.0 1
34.0 1
151.0 1
28.0 1
99.0 1
Name: 位置, Length: 120, dtype: int64
In [37]:
#pos_lines按照位置分组后保留分组条数大于1的位置 最终有多条地铁的位置有49个
count=pos_lines.groupby('位置')['地铁线路'].count()
ids=count[count>1].index
ids.shape
Out[37]:
(49,)
研究一下位置和地铁站点的关系
In [38]:
#去掉'位置','地铁站点'两个列重复之后 有339个不重复值
pos_stations=train[['位置','地铁站点']].drop_duplicates().dropna()
pos_stations.shape
Out[38]:
(339, 2)
In [39]:
#我们在来看一下有地铁的位置中有多少个不同的 120个
pos_stations['位置'].value_counts()
Out[39]:
63.0 9
136.0 7
106.0 6
100.0 6
143.0 6
..
17.0 1
12.0 1
67.0 1
82.0 1
148.0 1
Name: 位置, Length: 120, dtype: int64
In [40]:
#pos_stations按照位置分组后保留分组条数大于1的位置 最终有多个站点的位置有97个
count=pos_stations.groupby('位置')['地铁站点'].count()
ids=count[count>1].index
ids.shape
Out[40]:
(97,)
研究一下小区名,位置,地铁线路,站点的关系
In [41]:
#去掉'位置','地铁站点'两个列重复之后 有3575个不重复值
neighbor_pos_stations=train[['小区名','位置','地铁线路','地铁站点']].drop_duplicates().dropna()
neighbor_pos_stations.shape
Out[41]:
(3575, 4)
In [42]:
#看一下是否存在下小区名,位置一样的情况下,地铁线路不一样的情况
#可以看出:3575-3414=161条小区名,位置,地铁线路同样的情况下,地铁站点不一样
#3414-3342=72条小区名,位置一样,地铁线路不一样
#这种情况可能是因为数据错误,也有可能是实际情况,后面对此我们不做处理
print(neighbor_pos_stations[['小区名','位置','地铁线路']].drop_duplicates().dropna().shape)
print(neighbor_pos_stations[['小区名','位置']].drop_duplicates().dropna().shape)
(3414, 3)
(3342, 2)
研究一下是否有换乘站的存在
用站点分组,然后统计地铁线路数
In [43]:
#结果说明没有换乘站点存在,因为每个站点仅仅属于一条地铁线路
train[['地铁线路','地铁站点']].drop_duplicates().dropna().groupby('地铁站点').count().max(0)
Out[43]:
地铁线路 1
dtype: int64
研究一下每个位置的地铁线路数和站点数
In [44]:
#每个位置的线路数 这个可以作为新特征加入
a=train[['位置','地铁线路']].drop_duplicates().dropna().groupby('位置').count()
a
Out[44]:
地铁线路 | |
---|---|
位置 | |
0.0 | 1 |
1.0 | 2 |
2.0 | 1 |
3.0 | 2 |
4.0 | 1 |
... | ... |
146.0 | 2 |
147.0 | 2 |
148.0 | 1 |
150.0 | 1 |
151.0 | 1 |
120 rows × 1 columns
In [45]:
#每个位置的站点数 也可以作为新特征加入
b=train[['位置','地铁站点']].drop_duplicates().dropna().groupby('位置').count()
b
Out[45]:
地铁站点 | |
---|---|
位置 | |
0.0 | 1 |
1.0 | 3 |
2.0 | 1 |
3.0 | 4 |
4.0 | 1 |
... | ... |
146.0 | 3 |
147.0 | 2 |
148.0 | 1 |
150.0 | 4 |
151.0 | 1 |
120 rows × 1 columns
In [46]:
#两者的相关性
al=pd.concat([a,b],axis=1)
al.corr()
Out[46]:
地铁线路 | 地铁站点 | |
---|---|---|
地铁线路 | 1.000000 | 0.685211 |
地铁站点 | 0.685211 | 1.000000 |
研究一下位置缺失的样本地铁站点是否也是缺失的
In [47]:
#发现存在地铁线路为缺失而位置缺失的情况 说明后面在填充位置缺失值的时候可以用地铁站点来进行填充
pos_lines=train[['位置','地铁站点']].drop_duplicates()
pos_lines['位置'].isnull().sum()
Out[47]:
15
In [48]:
#每个站点的位置数 也可以作为新特征加入
train[['位置','地铁站点']].drop_duplicates().dropna().groupby('地铁站点').count()
Out[48]:
位置 | |
---|---|
地铁站点 | |
1.0 | 4 |
2.0 | 1 |
3.0 | 5 |
4.0 | 1 |
5.0 | 5 |
... | ... |
115.0 | 3 |
116.0 | 2 |
117.0 | 1 |
118.0 | 2 |
119.0 | 4 |
118 rows × 1 columns
位置和区的关系校验
In [49]:
#说明每个位置仅仅属于一个区,不存在同一个位置属于两个区的现象
train[['位置','区']].drop_duplicates().dropna().groupby('位置').count().max()
Out[49]:
区 1
dtype: int64
小区名和位置的关系
In [50]:
train[train['小区名']==6626]
Out[50]:
时间 | 小区名 | 小区房屋出租数量 | 楼层 | 总楼层 | 房屋面积 | 房屋朝向 | 居住状态 | 卧室数量 | 厅的数量 | ... | 地铁线路 | 地铁站点 | 距离 | 装修情况 | 月租金 | 朝向_0 | 朝向_1 | 朝向_2 | 朝向_3 | 朝向_4 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1513 | 1 | 6626 | 0.050781 | 0 | 0.581818 | 0.009070 | 南 | NaN | 1 | 1 | ... | 1.0 | 10.0 | 0.965000 | NaN | 5.942275 | 南 | NaN | NaN | NaN | NaN |
6622 | 1 | 6626 | 0.050781 | 2 | 0.545455 | 0.022840 | 南 | NaN | 3 | 3 | ... | 5.0 | 16.0 | 0.974167 | NaN | 4.244482 | 南 | NaN | NaN | NaN | NaN |
10951 | 1 | 6626 | 0.050781 | 0 | 0.581818 | 0.009103 | 西 | NaN | 1 | 1 | ... | 1.0 | 10.0 | 0.965000 | NaN | 5.602716 | 西 | NaN | NaN | NaN | NaN |
12327 | 1 | 6626 | 0.050781 | 1 | 0.545455 | 0.014234 | 东南 | NaN | 3 | 1 | ... | 5.0 | 16.0 | 0.974167 | NaN | 6.960951 | 东南 | NaN | NaN | NaN | NaN |
14738 | 1 | 6626 | 0.050781 | 1 | 0.545455 | 0.008039 | 东 | NaN | 1 | 1 | ... | 5.0 | 16.0 | 0.974167 | NaN | 5.602716 | 东 | NaN | NaN | NaN | NaN |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
177641 | 3 | 6626 | 0.085938 | 0 | 0.545455 | 0.014068 | 东南 | 1.0 | 2 | 1 | ... | 5.0 | 16.0 | 0.974167 | 2.0 | 7.300509 | 东南 | NaN | NaN | NaN | NaN |
177725 | 3 | 6626 | 0.085938 | 1 | 0.545455 | 0.014234 | 东南 | NaN | 3 | 1 | ... | 5.0 | 16.0 | 0.974167 | NaN | 6.960951 | 东南 | NaN | NaN | NaN | NaN |
191611 | 3 | 6626 | 0.085938 | 1 | 0.545455 | 0.014730 | 东 | 3.0 | 3 | 2 | ... | 5.0 | 16.0 | 0.974167 | 6.0 | 8.998302 | 东 | NaN | NaN | NaN | NaN |
194534 | 3 | 6626 | 0.085938 | 2 | 0.581818 | 0.013846 | 东南 | 3.0 | 2 | 1 | ... | 1.0 | 10.0 | 0.965000 | 2.0 | 8.319185 | 东南 | NaN | NaN | NaN | NaN |
195236 | 3 | 6626 | 0.085938 | 0 | 0.581818 | 0.012744 | 东南 | NaN | 2 | 1 | ... | 1.0 | 10.0 | 0.965000 | NaN | 5.602716 | 东南 | NaN | NaN | NaN | NaN |
105 rows × 24 columns
In [51]:
#在数据清洗的过程中发现一个问题 3269这个小区可能比较特殊
train[train['小区名']==3269].shape
Out[51]:
(31, 24)
In [52]:
#正好位置缺失31条
train.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 196539 entries, 0 to 196538
Data columns (total 24 columns):
时间 196539 non-null int64
小区名 196539 non-null int64
小区房屋出租数量 195538 non-null float64
楼层 196539 non-null int64
总楼层 196539 non-null float64
房屋面积 196539 non-null float64
房屋朝向 196539 non-null object
居住状态 20138 non-null float64
卧室数量 196539 non-null int64
厅的数量 196539 non-null int64
卫的数量 196539 non-null int64
出租方式 24230 non-null float64
区 196508 non-null float64
位置 196508 non-null float64
地铁线路 91778 non-null float64
地铁站点 91778 non-null float64
距离 91778 non-null float64
装修情况 18492 non-null float64
月租金 196539 non-null float64
朝向_0 196539 non-null object
朝向_1 9285 non-null object
朝向_2 322 non-null object
朝向_3 45 non-null object
朝向_4 4 non-null object
dtypes: float64(12), int64(6), object(6)
memory usage: 36.0+ MB
我们看一下小区名和位置,地铁站点的关系
上面可以看出3269这个小区位置缺失,但是我们发现他的地铁线路和站点非常多,这有些异常,我们对比一下其他小区的情况
In [53]:
#可以看出,正常的小区最多属于不同的2个位置
train[['位置','小区名']].drop_duplicates().dropna().groupby('小区名').count().max()
Out[53]:
位置 2
dtype: int64
In [54]:
#可以看出,除了3269这个小区外,其他小区最多只有4个站点相关
#因此可以断定3269这个小区是统计不祥的数据,可以作为异常值丢弃
counts=train[['地铁站点','小区名']].drop_duplicates().dropna().groupby('小区名').count()
counts[counts['地铁站点']>3]
Out[54]:
地铁站点 | |
---|---|
小区名 | |
602 | 4 |
1728 | 4 |
3269 | 14 |
看一下小区名过多的问题
In [4]:
neighbors=train['小区名'].value_counts()
In [5]:
neighbors
Out[5]:
5512 1880
1085 1155
5208 1136
6221 1066
6011 1020
...
5829 1
1351 1
711 1
327 1
0 1
Name: 小区名, Length: 5547, dtype: int64
In [8]:
#观察条目数超过50的小区有多少
(neighbors>50).sum()
Out[8]:
933
In [9]:
#观察条目数超过100的小区有多少
(neighbors>100).sum()
Out[9]:
511
数据清洗
In [8]:
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')#忽略一些警告
#显示所有结果
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False
导入数据
In [66]:
train=pd.read_csv("data/train.csv")
test=pd.read_csv("data/test.csv")
train.head()
Out[66]:
时间 | 小区名 | 小区房屋出租数量 | 楼层 | 总楼层 | 房屋面积 | 房屋朝向 | 居住状态 | 卧室数量 | 厅的数量 | 卫的数量 | 出租方式 | 区 | 位置 | 地铁线路 | 地铁站点 | 距离 | 装修情况 | 月租金 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 3072 | 0.128906 | 2 | 0.236364 | 0.008628 | 东南 | NaN | 1 | 1 | 1 | NaN | 11.0 | 118.0 | 2.0 | 40.0 | 0.764167 | NaN | 5.602716 |
1 | 1 | 3152 | 0.132812 | 1 | 0.381818 | 0.017046 | 东 | NaN | 1 | 0 | 0 | NaN | 10.0 | 100.0 | 4.0 | 58.0 | 0.709167 | NaN | 16.977929 |
2 | 1 | 5575 | 0.042969 | 0 | 0.290909 | 0.010593 | 东南 | NaN | 2 | 1 | 2 | NaN | 12.0 | 130.0 | 5.0 | 37.0 | 0.572500 | NaN | 8.998302 |
3 | 1 | 3103 | 0.085938 | 2 | 0.581818 | 0.019199 | 南 | NaN | 3 | 2 | 2 | NaN | 7.0 | 90.0 | 2.0 | 63.0 | 0.658333 | NaN | 5.602716 |
4 | 1 | 5182 | 0.214844 | 0 | 0.545455 | 0.010427 | 东北 | NaN | 2 | 1 | 1 | NaN | 3.0 | 31.0 | NaN | NaN | NaN | NaN | 7.300509 |
In [67]:
train.shape
Out[67]:
(196539, 19)
In [68]:
# train["出租方式"].value_counts()
# train["装修情况"].value_counts()
train["居住状态"].value_counts()
Out[68]:
3.0 17087
1.0 2483
2.0 568
Name: 居住状态, dtype: int64
In [69]:
train.drop_duplicates(['小区名','地铁线路'])[['小区名','地铁线路']].sort_values(by='小区名')
Out[69]:
小区名 | 地铁线路 | |
---|---|---|
107337 | 0 | 3.0 |
3620 | 1 | 3.0 |
41286 | 2 | 5.0 |
8211 | 4 | NaN |
55962 | 5 | NaN |
... | ... | ... |
45347 | 6625 | NaN |
6622 | 6626 | 5.0 |
1513 | 6626 | 1.0 |
1727 | 6627 | NaN |
2542 | 6627 | 1.0 |
6052 rows × 2 columns
设置后面要用的填充量
In [70]:
space_threshold=0.3
dist_value_for_fill=2#为什么是2,因为距离的最大值是1,没有地铁 意味着很远
line_value_for_fill=0
station_value_for_fill=0
area_value_for_fill=train["区"].mode().values[0]
# 拿到每个区的位置众数
position_by_area=train.groupby('区').apply(lambda x:x["位置"].mode())
position_value_for_fill=position_by_area[position_by_area.index==area_value_for_fill].values[0][0]
state_value_for_fill=0#train["居住状态"].mode().values[0]
decration_value_for_fill=-1#train["装修情况"].mode().values[0]
rent_value_for_fill=-1#train["出租方式"].mode().values[0]
In [38]:
#拿到每个小区房屋出租数量的众数
ratio_by_neighbor=train.groupby('小区名').apply(lambda x:x["小区房屋出租数量"].mode())
index=[x[0] for x in ratio_by_neighbor.index]
ratio_by_neighbor.index=index
ratio_by_neighbor=ratio_by_neighbor.to_dict()
ratio_mode=train["小区房屋出租数量"].mode().values[0]
缺失值处理
缺失值的处理方式有:
- 删除带有缺失值的特征,最简单也最浪费信息的方式
- 用均值,众数或固定的数等填充,比1好,但仍不够好
- 考虑缺失的含义,把缺失值作为一种信息
- 用未缺失的数据训练模型,预测缺失的数据(分类型变量用分类算法,数值型变量用回归)
思路:
- 首先利用没有缺失值的小区名以及有值的地铁站点信息,填充区和位置缺失值
- 利用小区和位置信息填充地铁线路和地铁站点和距离
- 还没有填充的地铁站点和地铁线路用固定值填充,单独作为一类(即没有地铁),同时对应的距离填充为2(即距离地铁较远)
- 按照同名小区的小区房屋出租数量的众数来填充小区房屋出租数量
缺失值比例
In [71]:
# 缺失值比例
def ratio_of_null():
train_missing = (train.isnull().sum()/len(train))*100
train_missing = train_missing.drop(train_missing[train_missing==0].index).sort_values(ascending=False)
return pd.DataFrame({'缺失百分比':train_missing})
ratio_of_null()
Out[71]:
缺失百分比 | |
---|---|
装修情况 | 90.591180 |
居住状态 | 89.753688 |
出租方式 | 87.671658 |
距离 | 53.302907 |
地铁站点 | 53.302907 |
地铁线路 | 53.302907 |
小区房屋出租数量 | 0.509314 |
位置 | 0.015773 |
区 | 0.015773 |
填充区和位置
根据数据初步分析时的情况可以看出,位置缺失的就是3269这个小区的,所以选择全部丢弃
In [72]:
train=train[train['小区名']!=3269]
In [73]:
ratio_of_null()
Out[73]:
缺失百分比 | |
---|---|
装修情况 | 90.591732 |
居住状态 | 89.754107 |
出租方式 | 87.673275 |
距离 | 53.303682 |
地铁站点 | 53.303682 |
地铁线路 | 53.303682 |
小区房屋出租数量 | 0.508885 |
地铁站点,距离 处理
- 先用每个同名小区名和同位置的地铁线路,地铁站点,距离众数来填充
- 剩下的地铁站点,距离,地铁线路的缺失值作为一种特征,表示该房屋附近没有地铁
In [92]:
1.#先按照小区名和位置分组,然后获取每组的站点众数
station_by_nb_pos=train[['小区名','位置','地铁站点','距离']].drop_duplicates().dropna().groupby(['小区名','位置'])['地铁站点','距离'].apply(lambda x:np.max(x.mode()))
station_by_nb_pos
Out[92]:
地铁站点 | 距离 | ||
---|---|---|---|
小区名 | 位置 | ||
0 | 59.0 | 57.0 | 0.478333 |
1 | 59.0 | 57.0 | 0.563333 |
2 | 40.0 | 33.0 | 0.971667 |
11 | 24.0 | 103.0 | 0.914167 |
12 | 28.0 | 69.0 | 0.633333 |
... | ... | ... | ... |
6625 | 41.0 | 88.0 | 0.931667 |
6626 | 86.0 | 16.0 | 0.974167 |
136.0 | 16.0 | 0.974167 | |
6627 | 86.0 | 10.0 | 0.985000 |
136.0 | 10.0 | 0.985000 |
3342 rows × 2 columns
In [93]:
station_by_nb=train[['小区名','地铁站点','距离']].drop_duplicates().dropna().groupby('小区名')['地铁站点','距离'].apply(lambda x:np.max(x.mode()))
station_by_nb
Out[93]:
地铁站点 | 距离 | |
---|---|---|
小区名 | ||
0 | 57.0 | 0.478333 |
1 | 57.0 | 0.563333 |
2 | 33.0 | 0.971667 |
11 | 103.0 | 0.914167 |
12 | 69.0 | 0.633333 |
... | ... | ... |
6622 | 25.0 | 0.245000 |
6623 | 119.0 | 0.410000 |
6625 | 88.0 | 0.931667 |
6626 | 16.0 | 0.974167 |
6627 | 10.0 | 0.985000 |
3329 rows × 2 columns
In [84]:
#拿到每个站点对应的线路
lines_by_station=train[['地铁站点','地铁线路']].drop_duplicates().dropna().groupby('地铁站点')['地铁线路'].min()
In [97]:
def fill_stations(line,s_by_np,s_by_n,l_by_s):
"""
s_by_np:接收station_by_nb_pos
s_by_n:接收station_by_nb
l_by_s:接收lines_by_station
"""
#首先判断line行地铁站点是否缺失
#注意这里最好用pd.isna,不要用np.isnull
if not pd.isna(line['地铁站点']):#不是空,就直接返回原行
return line
#如果小区名和位置组合在数据索引中,就查找进行填充
if (line['小区名'],line['位置']) in s_by_np:
line['地铁站点']=s_by_np.loc[(line['小区名'],line['位置']),'地铁站点']
line['距离']=s_by_np.loc[(line['小区名'],line['位置']),'距离']
line['地铁线路']=l_by_s[line['地铁站点']]
elif line['小区名'] in s_by_n.index:
line['地铁站点']=s_by_n.loc[line['小区名'],'地铁站点']#用小区众数填充
line['距离']=s_by_n.loc[line['小区名'],'距离']
line['地铁线路']=l_by_s[line['地铁站点']]
else:#小区名也找不到的情况下 单独作为一类,即没有地铁
line['地铁站点']=0
line['距离']=2#距离用2填充
line['地铁线路']=0
return line
train=train.apply(fill_stations,s_by_np=station_by_nb_pos,s_by_n=station_by_nb,l_by_s=lines_by_station,axis=1)
ratio_of_null()
Out[97]:
缺失百分比 | |
---|---|
装修情况 | 90.591732 |
居住状态 | 89.754107 |
出租方式 | 87.673275 |
小区房屋出租数量 | 0.508885 |
小区房屋出租数量处理
用每个小区的房屋出租数量众数填充
In [105]:
#拿到每个小区房屋出租数量的众数
ratio_by_neighbor=train[['小区名','小区房屋出租数量']].dropna().groupby('小区名').apply(lambda x:np.mean(x["小区房屋出租数量"].mode()))
ratio_by_neighbor
Out[105]:
小区名
0 0.007812
1 0.011719
2 0.007812
4 0.017578
5 0.009766
...
6623 0.011719
6624 0.013672
6625 0.011719
6626 0.076172
6627 0.093750
Length: 5535, dtype: float64
In [99]:
#拿到所有小区的“小区房屋出租数量”众数
ratio_mode=train["小区房屋出租数量"].mode().values[0]
ratio_mode
Out[99]:
0.01953125
In [106]:
def fill_by_key(x,k,v,values,mode):
if not pd.isna(x[v]):
return x
else:
if x[k] in values.index:
x[v]=values[x[k]]
else:
x[v]=mode
return x
# train['小区房屋出租数量']=train['小区房屋出租数量'].map()
train=train.apply(fill_by_key,k="小区名",v="小区房屋出租数量",values=ratio_by_neighbor,mode=ratio_mode,axis=1)
In [107]:
ratio_of_null()
Out[107]:
缺失百分比 | |
---|---|
装修情况 | 90.591732 |
居住状态 | 89.754107 |
出租方式 | 87.673275 |
装修,居住状态,出租方式--作为单独一类
In [108]:
train["出租方式"]=train["出租方式"].fillna(int(-1))
train["装修情况"]=train["装修情况"].fillna(int(-1))
train["居住状态"]=train["居住状态"].fillna(int(0))
In [109]:
ratio_of_null()
Out[109]:
清除异常样本
针对房屋面集存在的异常值,去掉房屋面积异常的样本
In [110]:
train=train[train['房屋面积']<space_threshold]
train.shape
Out[110]:
(196499, 19)
纠偏
针对目标值月租金普遍分布过散,进行对数平滑
In [111]:
train["log_rent"] = np.log1p(train["月租金"])#np.log1p log(1+x) inf
In [112]:
#纠正之前
plt.figure(figsize=(10,5))
sns.boxplot(x="月租金",data=train,orient='h')
plt.show()
In [113]:
#纠正之后
plt.figure(figsize=(10,5))
sns.boxplot(x="log_rent",data=train,orient='h')
plt.show()
In [114]:
train.head()
Out[114]:
时间 | 小区名 | 小区房屋出租数量 | 楼层 | 总楼层 | 房屋面积 | 房屋朝向 | 居住状态 | 卧室数量 | 厅的数量 | 卫的数量 | 出租方式 | 区 | 位置 | 地铁线路 | 地铁站点 | 距离 | 装修情况 | 月租金 | log_rent | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 3072 | 0.128906 | 2 | 0.236364 | 0.008628 | 东南 | 0.0 | 1 | 1 | 1 | -1.0 | 11.0 | 118.0 | 2.0 | 40.0 | 0.764167 | -1.0 | 5.602716 | 1.887481 |
1 | 1 | 3152 | 0.132812 | 1 | 0.381818 | 0.017046 | 东 | 0.0 | 1 | 0 | 0 | -1.0 | 10.0 | 100.0 | 4.0 | 58.0 | 0.709167 | -1.0 | 16.977929 | 2.889145 |
2 | 1 | 5575 | 0.042969 | 0 | 0.290909 | 0.010593 | 东南 | 0.0 | 2 | 1 | 2 | -1.0 | 12.0 | 130.0 | 5.0 | 37.0 | 0.572500 | -1.0 | 8.998302 | 2.302415 |
3 | 1 | 3103 | 0.085938 | 2 | 0.581818 | 0.019199 | 南 | 0.0 | 3 | 2 | 2 | -1.0 | 7.0 | 90.0 | 2.0 | 63.0 | 0.658333 | -1.0 | 5.602716 | 1.887481 |
4 | 1 | 5182 | 0.214844 | 0 | 0.545455 | 0.010427 | 东北 | 0.0 | 2 | 1 | 1 | -1.0 | 3.0 | 31.0 | 0.0 | 0.0 | 2.000000 | -1.0 | 7.300509 | 2.116317 |
问题数据处理
房间朝向列有多个值,这里我们只要第一个
In [115]:
def split(text,i):
items=text.split(" ")
if i<len(items):
return items[i]
else:
return np.nan
train['新朝向']=train['房屋朝向'].map(lambda x:split(x,0))
In [116]:
train.head()
train['新朝向'].value_counts()
Out[116]:
南 59605
东南 55854
东 34282
西南 17750
北 10490
西 9972
西北 5259
东北 3287
Name: 新朝向, dtype: int64
存储数据
In [117]:
train.to_csv("data/train_etl.csv",index=None)
In [30]:
import pickle
time_for_fill=train_data['时间'].mode().values[0]
neighbor_for_fill=train_data['小区名'].mode().values[0]
ting_for_fill=train_data['厅的数量'].mode().values[0]
wei_for_fill=train_data['卫的数量'].mode().values[0]
bed_for_fill=train_data['卧室数量'].mode().values[0]
direction_for_fill=train_data['新朝向'].mode().values[0]
mianji_for_fill=train_data['房屋面积'].mean()
louceng_for_fill=train_data['楼层'].mode().values[0]
zonglouceng_for_fill=train_data['总楼层'].mode().values[0]
values={
'距离':dist_value_for_fill,
'地铁线路':line_value_for_fill,
'地铁站点':station_value_for_fill,
'区':area_value_for_fill,
'位置':position_value_for_fill,
'居住状态':state_value_for_fill,
'装修情况':decration_value_for_fill,
'出租方式':rent_value_for_fill,
'ratio_by_neighbor':ratio_by_neighbor,
'小区房屋出租数量':ratio_mode,
'时间':time_for_fill,
'小区名':neighbor_for_fill,
'厅的数量':ting_for_fill,
'卫的数量':wei_for_fill,
'卧室数量':bed_for_fill,
'新朝向':direction_for_fill,
'房屋面积':mianji_for_fill,
'楼层':louceng_for_fill,
'总楼层':zonglouceng_for_fill,
'所有朝向':list(np.unique(train_data['新朝向']))
}
with open("data/values.pkl",'wb') as f:
pickle.dump(values,f)
In [31]:
values
Out[31]:
{'距离': 2,
'地铁线路': 0,
'地铁站点': 0,
'区': 12.0,
'位置': 52.0,
'居住状态': 0,
'装修情况': -1,
'出租方式': -1,
'ratio_by_neighbor': {0: 0.0078125,
1: 0.01171875,
2: 0.0078125,
4: 0.01953125,
5: 0.01171875,
8: 0.0078125,
9: 0.0234375,
。。。。。。
1181: 0.0078125,
1183: 0.01171875,
...},
'小区房屋出租数量': 0.01953125,
'时间': 3,
'小区名': 5512,
'厅的数量': 1,
'卫的数量': 1,
'卧室数量': 2,
'新朝向': '南',
'房屋面积': 0.013104835639490475,
'楼层': 0,
'总楼层': 0.3090909090909091,
'所有朝向': ['东', '东北', '东南', '北', '南', '西', '西北', '西南']}
特征工程
In [1]:
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')#忽略一些警告
In [2]:
train=pd.read_csv("data/train_etl.csv")
train.head()
Out[2]:
时间 | 小区名 | 小区房屋出租数量 | 楼层 | 总楼层 | 房屋面积 | 房屋朝向 | 居住状态 | 卧室数量 | 厅的数量 | ... | 出租方式 | 区 | 位置 | 地铁线路 | 地铁站点 | 距离 | 装修情况 | 月租金 | log_rent | 新朝向 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 3072 | 0.128906 | 2 | 0.236364 | 0.008628 | 东南 | 0.0 | 1 | 1 | ... | -1.0 | 11.0 | 118.0 | 2.0 | 40.0 | 0.764167 | -1.0 | 5.602716 | 1.887481 | 东南 |
1 | 1 | 3152 | 0.132812 | 1 | 0.381818 | 0.017046 | 东 | 0.0 | 1 | 0 | ... | -1.0 | 10.0 | 100.0 | 4.0 | 58.0 | 0.709167 | -1.0 | 16.977929 | 2.889145 | 东 |
2 | 1 | 5575 | 0.042969 | 0 | 0.290909 | 0.010593 | 东南 | 0.0 | 2 | 1 | ... | -1.0 | 12.0 | 130.0 | 5.0 | 37.0 | 0.572500 | -1.0 | 8.998302 | 2.302415 | 东南 |
3 | 1 | 3103 | 0.085938 | 2 | 0.581818 | 0.019199 | 南 | 0.0 | 3 | 2 | ... | -1.0 | 7.0 | 90.0 | 2.0 | 63.0 | 0.658333 | -1.0 | 5.602716 | 1.887481 | 南 |
4 | 1 | 5182 | 0.214844 | 0 | 0.545455 | 0.010427 | 东北 | 0.0 | 2 | 1 | ... | -1.0 | 3.0 | 31.0 | 0.0 | 0.0 | 2.000000 | -1.0 | 7.300509 | 2.116317 | 东北 |
5 rows × 21 columns
In [3]:
train.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 196499 entries, 0 to 196498
Data columns (total 21 columns):
时间 196499 non-null int64
小区名 196499 non-null int64
小区房屋出租数量 196499 non-null float64
楼层 196499 non-null int64
总楼层 196499 non-null float64
房屋面积 196499 non-null float64
房屋朝向 196499 non-null object
居住状态 196499 non-null float64
卧室数量 196499 non-null int64
厅的数量 196499 non-null int64
卫的数量 196499 non-null int64
出租方式 196499 non-null float64
区 196499 non-null float64
位置 196499 non-null float64
地铁线路 196499 non-null float64
地铁站点 196499 non-null float64
距离 196499 non-null float64
装修情况 196499 non-null float64
月租金 196499 non-null float64
log_rent 196499 non-null float64
新朝向 196499 non-null object
dtypes: float64(13), int64(6), object(2)
memory usage: 31.5+ MB
根据房间,厅,卫,房屋面积构造新特征
In [4]:
train["房+卫+厅"]=train["卧室数量"]+train["厅的数量"]+train["卫的数量"]
train["房/总"]=train["卧室数量"]/(train["房+卫+厅"]+1)
train["卫/总"]=train["卫的数量"]/(train["房+卫+厅"]+1)
train["厅/总"]=train["厅的数量"]/(train["房+卫+厅"]+1)
train['卧室面积']=train['房屋面积']/(train['卧室数量']+1)#加1是为了防止分母=0出现结果为inf无穷大的现象
train['楼层比']=train['楼层']/(train["总楼层"]+1)#加1是为了防止分母=0出现结果为inf无穷大的现象
train['户型']=train[['卧室数量','厅的数量','卫的数量']].apply(lambda x:str(x['卧室数量'])+str(x['厅的数量'])+str(x['卫的数量']),axis=1)
构建租金平均值特征
In [5]:
rent_means=train[['小区名','新朝向','地铁站点','位置','log_rent']].groupby(['小区名','新朝向','地铁站点','位置'],as_index=False).mean()
rent_means.columns=['小区名','新朝向','地铁站点','位置','平均值特征1']
train=pd.merge(train,rent_means,how='left',on=['小区名','新朝向','地铁站点','位置'])
In [6]:
rent_means2=train[['小区名','log_rent']].groupby(['小区名'],as_index=False).mean()
rent_means2.columns=['小区名','小区平均值特征']
train=pd.merge(train,rent_means2,how='left',on=['小区名'])
In [7]:
rent_means3=train[['新朝向','log_rent']].groupby(['新朝向'],as_index=False).mean()
rent_means3.columns=['新朝向','朝向平均值特征']
train=pd.merge(train,rent_means3,how='left',on=['新朝向'])
In [8]:
rent_means4=train[['地铁站点','log_rent']].groupby(['地铁站点'],as_index=False).mean()
rent_means4.columns=['地铁站点','站点平均值特征']
train=pd.merge(train,rent_means4,how='left',on=['地铁站点'])
In [9]:
rent_means5=train[['位置','log_rent']].groupby(['位置'],as_index=False).mean()
rent_means5.columns=['位置','位置平均值特征']
train=pd.merge(train,rent_means5,how='left',on=['位置'])
构造是否有地铁
In [10]:
train["有地铁"]=(train["地铁站点"]>-1).map(int)
In [11]:
train.columns
Out[11]:
Index(['时间', '小区名', '小区房屋出租数量', '楼层', '总楼层', '房屋面积', '房屋朝向', '居住状态', '卧室数量',
'厅的数量', '卫的数量', '出租方式', '区', '位置', '地铁线路', '地铁站点', '距离', '装修情况', '月租金',
'log_rent', '新朝向', '房+卫+厅', '房/总', '卫/总', '厅/总', '卧室面积', '楼层比', '户型',
'平均值特征1', '小区平均值特征', '朝向平均值特征', '站点平均值特征', '位置平均值特征', '有地铁'],
dtype='object')
构造聚类特征
In [12]:
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import KMeans
features=train[['房屋面积','卧室数量','厅的数量','卫的数量','距离','楼层比']]
trans=StandardScaler()
new_features=trans.fit_transform(features)
kmeans=KMeans(n_clusters=5)
kmeans.fit(new_features)
train['聚类特征']=kmeans.predict(new_features).astype(str)
#计算每个聚类特征的月租金平均值
cluster_means=train[['聚类特征','log_rent']].groupby('聚类特征',as_index=False).mean()
cluster_means.columns=['聚类特征','平均值特征2']
train=pd.merge(train,cluster_means,how='left',on=['聚类特征'])
保存标准化和聚类模型
In [13]:
import pickle
with open("data/kmeans.pkl",'wb') as f:
pickle.dump({
"std_transer":trans,
"kmeans":kmeans
},f)
构造地铁线路数特征
In [14]:
lines_count1=train[['小区名','地铁线路']].drop_duplicates().groupby('小区名').count()
lines_count2=train[['位置','地铁线路']].drop_duplicates().groupby('位置').count()
lines_count2.columns=['位置线路数']
lines_count1.columns=['小区线路数']
In [15]:
train=pd.merge(train,lines_count1,how='left',on=['小区名'])
train=pd.merge(train,lines_count2,how='left',on=['位置'])
去掉出现数量较少的小区
In [16]:
neighbors=train['小区名'].value_counts()
train['新小区名']=train.apply(lambda x: x['小区名'] if neighbors[x['小区名']]>100 else -1,axis=1)
train['小区条数大于100']=train.apply(lambda x: 1 if neighbors[x['小区名']]>100 else 0,axis=1)
In [17]:
train.info()
train['新小区名'].value_counts()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 196499 entries, 0 to 196498
Data columns (total 40 columns):
时间 196499 non-null int64
小区名 196499 non-null int64
小区房屋出租数量 196499 non-null float64
楼层 196499 non-null int64
总楼层 196499 non-null float64
房屋面积 196499 non-null float64
房屋朝向 196499 non-null object
居住状态 196499 non-null float64
卧室数量 196499 non-null int64
厅的数量 196499 non-null int64
卫的数量 196499 non-null int64
出租方式 196499 non-null float64
区 196499 non-null float64
位置 196499 non-null float64
地铁线路 196499 non-null float64
地铁站点 196499 non-null float64
距离 196499 non-null float64
装修情况 196499 non-null float64
月租金 196499 non-null float64
log_rent 196499 non-null float64
新朝向 196499 non-null object
房+卫+厅 196499 non-null int64
房/总 196499 non-null float64
卫/总 196499 non-null float64
厅/总 196499 non-null float64
卧室面积 196499 non-null float64
楼层比 196499 non-null float64
户型 196499 non-null object
平均值特征1 196499 non-null float64
小区平均值特征 196499 non-null float64
朝向平均值特征 196499 non-null float64
站点平均值特征 196499 non-null float64
位置平均值特征 196499 non-null float64
有地铁 196499 non-null int64
聚类特征 196499 non-null object
平均值特征2 196499 non-null float64
小区线路数 196499 non-null int64
位置线路数 196499 non-null int64
新小区名 196499 non-null int64
小区条数大于100 196499 non-null int64
dtypes: float64(24), int64(12), object(4)
memory usage: 61.5+ MB
Out[17]:
-1 72488
5512 1880
1085 1155
5208 1136
6221 1066
...
244 102
6461 102
5906 102
1654 102
5196 101
Name: 新小区名, Length: 512, dtype: int64
转换类型
In [41]:
#将离散特征转换成字符串类型
colunms = ['时间', '小区名', '居住状态', '出租方式', '区','位置','地铁线路','地铁站点','装修情况']
for col in colunms:
train[col] = train[col].astype(str)
In [14]:
train.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 196499 entries, 0 to 196498
Data columns (total 34 columns):
时间 196499 non-null object
小区名 196499 non-null object
小区房屋出租数量 196499 non-null float64
楼层 196499 non-null int64
总楼层 196499 non-null float64
房屋面积 196499 non-null float64
房屋朝向 196499 non-null object
居住状态 196499 non-null object
卧室数量 196499 non-null int64
厅的数量 196499 non-null int64
卫的数量 196499 non-null int64
出租方式 196499 non-null object
区 196499 non-null object
位置 196499 non-null object
地铁线路 196499 non-null object
地铁站点 196499 non-null object
距离 196499 non-null float64
装修情况 196499 non-null object
月租金 196499 non-null float64
log_rent 196499 non-null float64
新朝向 196499 non-null object
房+卫+厅 196499 non-null int64
房/总 196499 non-null float64
卫/总 196499 non-null float64
厅/总 196499 non-null float64
卧室面积 196499 non-null float64
楼层比 196499 non-null float64
户型 196499 non-null object
平均值特征1 196499 non-null float64
有地铁 196499 non-null int64
聚类特征 196499 non-null object
平均值特征2 196499 non-null float64
小区线路数 196499 non-null int64
位置线路数 196499 non-null int64
dtypes: float64(13), int64(8), object(13)
memory usage: 52.5+ MB
In [18]:
#保存处理后的数据
train.to_csv("data/onehot_feature.csv")
In [11]:
x_columns=['时间', '小区名', '小区房屋出租数量', '楼层', '总楼层', '房屋面积','居住状态', '卧室数量',
'厅的数量', '卫的数量', '出租方式', '区', '位置', '地铁线路', '地铁站点', '距离', '装修情况',
'新朝向', '房+卫+厅', '房/总', '卫/总', '厅/总', '卧室面积', '楼层比', '户型',
'有地铁']
x=train[x_columns]
y=train['月租金']
构建数据清洗和特征工程函数
In [61]:
# 'dist_value_for_fill':dist_value_for_fill,
# 'line_value_for_fill':line_value_for_fill,
# 'station_value_for_fill':station_value_for_fill,
# 'area_value_for_fill':area_value_for_fill,
# 'position_value_for_fill':position_value_for_fill,
# 'state_value_for_fill':state_value_for_fill,
# 'decration_value_for_fill':decration_value_for_fill,
# 'rent_value_for_fill':rent_value_for_fill,
# 'ratio_by_neighbor':ratio_by_neighbor,
# 'ratio_mode':ratio_mode,
# 'time_for_fill':time_for_fill,
# 'neighbor_for_fill':neighbor_for_fill,
# 'ting_for_fill':ting_for_fill,
# 'wei_for_fill':wei_for_fill,
# 'bed_for_fill':bed_for_fill,
# 'direction_for_fill':direction_for_fill,
# 'mianji_for_fill':mianji_for_fill,
# 'louceng_for_fill':louceng_for_fill,
# 'zonglouceng_for_fill':zonglouceng_for_fill
# def process(x,values,models):
# x=x.to_dict()
# keys=['时间', '小区名', '楼层', '总楼层', '房屋面积', '居住状态', '卧室数量',
# '厅的数量', '卫的数量', '出租方式', '区', '位置', '地铁线路', '地铁站点', '距离', '装修情况']
# #原特征缺失值填充
# for key in keys:
# if pd.isna(x[key]):
# x[key]=values[key]
# #小区房屋出租数量
# if pd.isna(str(x['小区房屋出租数量'])):
# if x['小区名'] in values['ratio_by_neighbor']:
# x['小区房屋出租数量']=values['ratio_by_neighbor'][x['小区名']]
# else:
# x['小区房屋出租数量']=values['小区房屋出租数量']
# #房屋朝向问题
# # print(x['房屋朝向'])
# if pd.isna(x['房屋朝向']):
# x['新朝向']=values['新朝向']
# else:
# chaoxiang=x['房屋朝向'].split(" ")[0]
# if chaoxiang in values['所有朝向']:
# x['新朝向']=chaoxiang
# else:
# x['新朝向']=values['新朝向']
# #构造特征
# x["房+卫+厅"]=x["卧室数量"]+x["厅的数量"]+x["卫的数量"]
# x["房/总"]=x["卧室数量"]/x["房+卫+厅"]
# x["卫/总"]=x["卫的数量"]/x["房+卫+厅"]
# x["厅/总"]=x["厅的数量"]/x["房+卫+厅"]
# x['卧室面积']=x['房屋面积']/x['卧室数量']
# x['楼层比']=x['楼层']/(x["总楼层"]+1)#加1是为了防止分母=0出现结果为inf无穷大的现象
# x['户型']=str(x['卧室数量'])+str(x['厅的数量'])+str(x['卫的数量'])
# if x["地铁站点"]>-1:
# x["有地铁"]=1
# else:
# x["有地铁"]=0
# #构造聚类特征
# features=np.array([[x['房屋面积'],x['卧室数量'],x['厅的数量'],x['卫的数量'],x['距离'],x['楼层比']]])
# models['std_transer'].transform(features)
# x['聚类特征']=models['kmeans'].predict(new_features).astype(str)[0]
# return pd.Series(x)
In [66]:
test=pd.read_csv('data/test.csv')
test.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 56279 entries, 0 to 56278
Data columns (total 19 columns):
id 56279 non-null int64
时间 56279 non-null int64
小区名 56279 non-null int64
小区房屋出租数量 56257 non-null float64
楼层 56279 non-null int64
总楼层 56279 non-null float64
房屋面积 56279 non-null float64
房屋朝向 56279 non-null object
居住状态 4483 non-null float64
卧室数量 56279 non-null int64
厅的数量 56279 non-null int64
卫的数量 56279 non-null int64
出租方式 4971 non-null float64
区 56269 non-null float64
位置 56269 non-null float64
地铁线路 26494 non-null float64
地铁站点 26494 non-null float64
距离 26494 non-null float64
装修情况 4207 non-null float64
dtypes: float64(11), int64(7), object(1)
memory usage: 8.2+ MB
In [46]:
with open("data/kmeans.pkl",'rb') as f:
models=pickle.load(f)
In [47]:
with open("data/values.pkl",'rb') as f:
values=pickle.load(f)
In [65]:
test.iloc[:100,:].apply(process,models=models,values=values,axis=1)
Out[65]:
id | 时间 | 小区名 | 小区房屋出租数量 | 楼层 | 总楼层 | 房屋面积 | 房屋朝向 | 居住状态 | 卧室数量 | ... | 新朝向 | 房+卫+厅 | 房/总 | 卫/总 | 厅/总 | 卧室面积 | 楼层比 | 户型 | 有地铁 | 聚类特征 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 4 | 6011 | 0.382812 | 1 | 0.600000 | 0.007117 | 东 | 3.0 | 2 | ... | 东 | 4 | 0.500000 | 0.250000 | 0.250000 | 0.003558 | 0.625000 | 211 | 1 | 2 |
1 | 2 | 4 | 1697 | 0.152344 | 1 | 0.472727 | 0.007448 | 东 | 0.0 | 2 | ... | 东 | 4 | 0.500000 | 0.250000 | 0.250000 | 0.003724 | 0.679012 | 211 | 1 | 2 |
2 | 3 | 4 | 754 | 0.207031 | 2 | 0.709091 | 0.014068 | 东南 | 0.0 | 3 | ... | 东南 | 7 | 0.428571 | 0.285714 | 0.285714 | 0.004689 | 1.170213 | 322 | 1 | 2 |
3 | 4 | 4 | 1285 | 0.011719 | 0 | 0.090909 | 0.008937 | 南 | 0.0 | 2 | ... | 南 | 4 | 0.500000 | 0.250000 | 0.250000 | 0.004469 | 0.000000 | 211 | 1 | 2 |
4 | 5 | 4 | 4984 | 0.035156 | 1 | 0.218182 | 0.008606 | 东南 | 0.0 | 2 | ... | 东南 | 4 | 0.500000 | 0.250000 | 0.250000 | 0.004303 | 0.820896 | 211 | 1 | 2 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
95 | 96 | 4 | 5239 | 0.433594 | 0 | 0.545455 | 0.006202 | 北 | 0.0 | 1 | ... | 北 | 2 | 0.500000 | 0.500000 | 0.000000 | 0.006202 | 0.000000 | 101 | 1 | 2 |
96 | 97 | 4 | 1027 | 0.046875 | 0 | 0.727273 | 0.007779 | 南 | 0.0 | 2 | ... | 南 | 4 | 0.500000 | 0.250000 | 0.250000 | 0.003889 | 0.000000 | 211 | 1 | 2 |
97 | 98 | 4 | 300 | 0.140625 | 2 | 0.454545 | 0.013744 | 西 | 0.0 | 2 | ... | 西 | 5 | 0.400000 | 0.200000 | 0.400000 | 0.006872 | 1.375000 | 221 | 1 | 2 |
98 | 99 | 4 | 1021 | 0.269531 | 0 | 0.581818 | 0.013860 | 东南 | 0.0 | 3 | ... | 东南 | 7 | 0.428571 | 0.285714 | 0.285714 | 0.004620 | 0.000000 | 322 | 1 | 2 |
99 | 100 | 4 | 2644 | 0.300781 | 0 | 0.309091 | 0.014896 | 东南 | 0.0 | 3 | ... | 东南 | 6 | 0.500000 | 0.166667 | 0.333333 | 0.004965 | 0.000000 | 321 | 1 | 2 |
100 rows × 29 columns
建模
In [21]:
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import seaborn as sns
import warnings
import xgboost as xgb
import copy
from sklearn.model_selection import train_test_split,GridSearchCV
from sklearn.feature_extraction import DictVectorizer
from sklearn.ensemble import RandomForestRegressor,GradientBoostingRegressor
from sklearn.metrics import mean_squared_error
warnings.filterwarnings('ignore')#忽略一些警告
读取数据
In [22]:
data=pd.read_csv("data/onehot_feature.csv")
data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 196499 entries, 0 to 196498
Data columns (total 41 columns):
Unnamed: 0 196499 non-null int64
时间 196499 non-null int64
小区名 196499 non-null int64
小区房屋出租数量 196499 non-null float64
楼层 196499 non-null int64
总楼层 196499 non-null float64
房屋面积 196499 non-null float64
房屋朝向 196499 non-null object
居住状态 196499 non-null float64
卧室数量 196499 non-null int64
厅的数量 196499 non-null int64
卫的数量 196499 non-null int64
出租方式 196499 non-null float64
区 196499 non-null float64
位置 196499 non-null float64
地铁线路 196499 non-null float64
地铁站点 196499 non-null float64
距离 196499 non-null float64
装修情况 196499 non-null float64
月租金 196499 non-null float64
log_rent 196499 non-null float64
新朝向 196499 non-null object
房+卫+厅 196499 non-null int64
房/总 196499 non-null float64
卫/总 196499 non-null float64
厅/总 196499 non-null float64
卧室面积 196499 non-null float64
楼层比 196499 non-null float64
户型 196499 non-null int64
平均值特征1 196499 non-null float64
小区平均值特征 196499 non-null float64
朝向平均值特征 196499 non-null float64
站点平均值特征 196499 non-null float64
位置平均值特征 196499 non-null float64
有地铁 196499 non-null int64
聚类特征 196499 non-null int64
平均值特征2 196499 non-null float64
小区线路数 196499 non-null int64
位置线路数 196499 non-null int64
新小区名 196499 non-null int64
小区条数大于100 196499 non-null int64
dtypes: float64(24), int64(15), object(2)
memory usage: 61.5+ MB
In [23]:
#将离散特征转换成字符串类型
colunms = ['时间', '新小区名', '居住状态', '出租方式', '区','位置','地铁线路','地铁站点','装修情况','户型','聚类特征']
for col in colunms:
data[col] = data[col].astype(str)
获取x和y
In [24]:
data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 196499 entries, 0 to 196498
Data columns (total 41 columns):
Unnamed: 0 196499 non-null int64
时间 196499 non-null object
小区名 196499 non-null int64
小区房屋出租数量 196499 non-null float64
楼层 196499 non-null int64
总楼层 196499 non-null float64
房屋面积 196499 non-null float64
房屋朝向 196499 non-null object
居住状态 196499 non-null object
卧室数量 196499 non-null int64
厅的数量 196499 non-null int64
卫的数量 196499 non-null int64
出租方式 196499 non-null object
区 196499 non-null object
位置 196499 non-null object
地铁线路 196499 non-null object
地铁站点 196499 non-null object
距离 196499 non-null float64
装修情况 196499 non-null object
月租金 196499 non-null float64
log_rent 196499 non-null float64
新朝向 196499 non-null object
房+卫+厅 196499 non-null int64
房/总 196499 non-null float64
卫/总 196499 non-null float64
厅/总 196499 non-null float64
卧室面积 196499 non-null float64
楼层比 196499 non-null float64
户型 196499 non-null object
平均值特征1 196499 non-null float64
小区平均值特征 196499 non-null float64
朝向平均值特征 196499 non-null float64
站点平均值特征 196499 non-null float64
位置平均值特征 196499 non-null float64
有地铁 196499 non-null int64
聚类特征 196499 non-null object
平均值特征2 196499 non-null float64
小区线路数 196499 non-null int64
位置线路数 196499 non-null int64
新小区名 196499 non-null object
小区条数大于100 196499 non-null int64
dtypes: float64(17), int64(11), object(13)
memory usage: 61.5+ MB
In [25]:
x_columns=['时间', '新小区名', '小区房屋出租数量', '楼层', '总楼层', '房屋面积','居住状态', '卧室数量',
'厅的数量', '卫的数量', '出租方式', '区', '位置', '地铁线路', '地铁站点', '距离', '装修情况',
'新朝向', '房+卫+厅', '房/总', '卫/总', '厅/总', '卧室面积', '楼层比', '户型','平均值特征1',
'平均值特征2','有地铁','小区线路数','位置线路数','小区条数大于100','小区平均值特征','朝向平均值特征',
'站点平均值特征','位置平均值特征']
y_label='log_rent'
x=data[x_columns]
y=data[y_label]
y.isnull().sum()
Out[25]:
0
构建训练函数
In [26]:
def feature_transformer(x,y,test_size=0.3,random_state=12):
"""
负责分割数据集并转换onehot特征,返回转换后的稀疏矩阵和特征名
"""
#1.重新命名列名
#原列名
cols=['时间', '新小区名', '小区房屋出租数量', '楼层', '总楼层', '房屋面积','居住状态', '卧室数量',
'厅的数量', '卫的数量', '出租方式', '区', '位置', '地铁线路', '地铁站点', '距离', '装修情况',
'新朝向', '房+卫+厅', '房/总', '卫/总', '厅/总', '卧室面积', '楼层比', '户型','平均值特征1',
'平均值特征2','有地铁','小区线路数','位置线路数','小区条数大于100','小区平均值特征','朝向平均值特征',
'站点平均值特征','位置平均值特征']
#新列名
new_cols=[chr(65+s)+str(i) for s in range(len(cols)//10+1) for i in range(10)]
new_cols=new_cols[:len(cols)]
#特征名映射字典
cols_map={k:v for k,v in zip(cols,new_cols)}
#重新命名列
x.columns=[cols_map[k] for k in x.columns]
#2.分割数据集
train_x,test_x,train_y,test_y=train_test_split(x,y,test_size=test_size,random_state=random_state)
#3.转换onehot特征
#返回稀疏矩阵,有两个优点:
#1.占用内存大幅减小,让并行成为可能,不然并行的话,内存爆掉
#2.可以加速xgboost训练
vector=DictVectorizer(sparse=True)
x_train=vector.fit_transform(train_x.to_dict(orient='records'))
x_test=vector.transform(test_x.to_dict(orient='records'))
features=vector.get_feature_names()
#4.构建原始特征对应的新下标字典
#原始特征名
#离散列特征下标字典
feature_map={k:[] for k in cols}
for i in range(len(features)):
for col in cols:
if features[i].startswith(cols_map[col]):#如果新特征以老特征开头
feature_map[col].append(i)
break
return (x_train,x_test,train_y,test_y),feature_map,cols_map
def train(cols,data,feature_map,num_round = 500):
"""
负责完成一次xgboost训练,返回测试集rmse
"""
#1.获取数据集
train_x,test_x,train_y,test_y=data
#获取原始特征对应的新特征下标
index=[]
for col in cols:
index.extend(feature_map[col])
x_train=train_x[:,index]
x_test=test_x[:,index]
#3.构建数据格式
#构建DMatrix数据,可以有效利用硬盘缓存,减少内存占用
dtrain = xgb.DMatrix(x_train,train_y)
dtest = xgb.DMatrix(x_test,test_y)
#4.设置训练参数
param = {'max_depth':5,
'eta':0.01,
'verbosity':1,
'objective':'reg:linear',
'silent': 1,
'gamma': 0.01,
'min_child_weight': 1,
}
#5.模型训练
bst = xgb.train(param, dtrain, num_round)
#6.模型预测
preds = bst.predict(dtest)
preds=np.exp(preds)-1#转换成真实的租金
y_true=np.exp(test_y)-1
#7.模型评估
return np.sqrt(mean_squared_error(y_true,preds))
In [27]:
#完成特征分割和转换
d,f_map,c_map=feature_transformer(x,y)
模型特征筛选
In [26]:
# #构造列名类
# class ColData:
# cols=np.array(['时间', '小区名', '小区房屋出租数量', '楼层', '总楼层', '房屋面积','居住状态', '卧室数量',
# '厅的数量', '卫的数量', '出租方式', '区', '位置', '地铁线路', '地铁站点', '距离', '装修情况',
# '新朝向', '房+卫+厅', '房/总', '卫/总', '厅/总', '卧室面积', '楼层比', '户型','平均值特征1',
# '有地铁','聚类特征','小区线路数','位置线路数'])
# def __init__(self,ids):
# self.ids=ids
# def include_names(self):
# print(type(ColData.cols))
# return list(ColData.cols[self.ids])
# def exclude_names(self):
# non_ids=list(set(range(ColData.cols.shape[0]))-set(self.ids))
# return list(ColData.cols[non_ids])
In [28]:
#构造筛选特征函数
def select_features(cols,min_score):
include_features=cols
exclude_features=[]
cols=np.array(cols)
for i in range(cols.shape[0]):
#选中的特征
features=list(cols[list(set(range(cols.shape[0]))-set([i]))])
print("开始第{}次训练:".format(i))
print("未选中特征:",cols[i])
rmse=train(features,d,f_map,2500)
print("开始第{}次训练测试集成绩{}:".format(i,rmse))
print("-"*10)
if rmse<=min_score:
exclude_features=cols[i]
include_features=features
min_score=rmse
return min_score,include_features,exclude_features
In [29]:
min_score=train(x_columns,d,f_map)
In [30]:
features=x_columns
min_score
Out[30]:
2.627438015769018
In [31]:
i=1
while len(features)>0:
print("开始第{}轮筛选:\n".format(i))
ms,include_f,exclude_f=select_features(features,min_score)
if len(exclude_f)<=0:
break
features=include_f
min_score=ms
print("第{}次筛选成绩:{}\n".format(i,min_score))
i=i+1
print("保留特征:",include_f)
print("排除特征:",exclude_f)
print("\n*************************\n")
print("最终特征:",features)
print("最好成绩:",min_score)
开始第1轮筛选:
开始第0次训练:
未选中特征: 时间
开始第0次训练测试集成绩2.3425739100557874:
----------
开始第1次训练:
未选中特征: 新小区名
开始第1次训练测试集成绩2.3159098956260884:
----------
开始第2次训练:
未选中特征: 小区房屋出租数量
开始第2次训练测试集成绩2.3610726419651975:
----------
开始第3次训练:
未选中特征: 楼层
开始第3次训练测试集成绩2.3482224666430156:
----------
开始第4次训练:
未选中特征: 总楼层
开始第4次训练测试集成绩2.3548737824509476:
----------
开始第5次训练:
未选中特征: 房屋面积
开始第5次训练测试集成绩2.3528631046347734:
----------
开始第6次训练:
未选中特征: 居住状态
开始第6次训练测试集成绩2.343644368107605:
----------
开始第7次训练:
未选中特征: 卧室数量
开始第7次训练测试集成绩2.3447264002503947:
----------
开始第8次训练:
未选中特征: 厅的数量
开始第8次训练测试集成绩2.3488349025371353:
----------
开始第9次训练:
未选中特征: 卫的数量
开始第9次训练测试集成绩2.3455068228561444:
----------
开始第10次训练:
未选中特征: 出租方式
开始第10次训练测试集成绩2.347907742954758:
----------
开始第11次训练:
未选中特征: 区
开始第11次训练测试集成绩2.3470549409629813:
----------
开始第12次训练:
未选中特征: 位置
开始第12次训练测试集成绩2.3442351978396916:
----------
开始第13次训练:
未选中特征: 地铁线路
开始第13次训练测试集成绩2.3457640963554747:
----------
开始第14次训练:
未选中特征: 地铁站点
开始第14次训练测试集成绩2.3514284469336877:
----------
开始第15次训练:
未选中特征: 距离
开始第15次训练测试集成绩2.3536807483560542:
----------
开始第16次训练:
未选中特征: 装修情况
开始第16次训练测试集成绩2.3748498709037094:
----------
开始第17次训练:
未选中特征: 新朝向
开始第17次训练测试集成绩2.3442905601261614:
----------
开始第18次训练:
未选中特征: 房+卫+厅
开始第18次训练测试集成绩2.340930304773355:
----------
开始第19次训练:
未选中特征: 房/总
开始第19次训练测试集成绩2.3480559804451464:
----------
开始第20次训练:
未选中特征: 卫/总
开始第20次训练测试集成绩2.3465279974923803:
----------
开始第21次训练:
未选中特征: 厅/总
开始第21次训练测试集成绩2.348225921086065:
----------
开始第22次训练:
未选中特征: 卧室面积
开始第22次训练测试集成绩2.352140741124247:
----------
开始第23次训练:
未选中特征: 楼层比
开始第23次训练测试集成绩2.3495753059171336:
----------
开始第24次训练:
未选中特征: 户型
开始第24次训练测试集成绩2.355693315193697:
----------
开始第25次训练:
未选中特征: 平均值特征1
开始第25次训练测试集成绩2.544232443156709:
----------
开始第26次训练:
未选中特征: 平均值特征2
开始第26次训练测试集成绩2.3445018995961795:
----------
开始第27次训练:
未选中特征: 有地铁
开始第27次训练测试集成绩2.3481264617837376:
----------
开始第28次训练:
未选中特征: 小区线路数
开始第28次训练测试集成绩2.3481264617837376:
----------
开始第29次训练:
未选中特征: 位置线路数
开始第29次训练测试集成绩2.3504238672632107:
----------
开始第30次训练:
未选中特征: 小区条数大于100
开始第30次训练测试集成绩2.3481264617837376:
----------
开始第31次训练:
未选中特征: 小区平均值特征
开始第31次训练测试集成绩2.349284024062191:
----------
开始第32次训练:
未选中特征: 朝向平均值特征
开始第32次训练测试集成绩2.3424697168707467:
----------
开始第33次训练:
未选中特征: 站点平均值特征
开始第33次训练测试集成绩2.357579803345613:
----------
开始第34次训练:
未选中特征: 位置平均值特征
开始第34次训练测试集成绩2.370372655988748:
----------
第1次筛选成绩:2.3159098956260884
保留特征: ['时间', '小区房屋出租数量', '楼层', '总楼层', '房屋面积', '居住状态', '卧室数量', '厅的数量', '卫的数量', '出租方式', '区', '位置', '地铁线路', '地铁站点', '距离', '装修情况', '新朝向', '房+卫+厅', '房/总', '卫/总', '厅/总', '卧室面积', '楼层比', '户型', '平均值特征1', '平均值特征2', '有地铁', '小区线路数', '位置线路数', '小区条数大于100', '小区平均值特征', '朝向平均值特征', '站点平均值特征', '位置平均值特征']
排除特征: 新小区名
*************************
开始第2轮筛选:
开始第0次训练:
未选中特征: 时间
开始第0次训练测试集成绩2.319998668753389:
----------
开始第1次训练:
未选中特征: 小区房屋出租数量
开始第1次训练测试集成绩2.322355105258432:
----------
开始第2次训练:
未选中特征: 楼层
开始第2次训练测试集成绩2.3158954168386106:
----------
开始第3次训练:
未选中特征: 总楼层
开始第3次训练测试集成绩2.329094243429236:
----------
开始第4次训练:
未选中特征: 房屋面积
开始第4次训练测试集成绩2.3258240532005727:
----------
开始第5次训练:
未选中特征: 居住状态
开始第5次训练测试集成绩2.318009433185204:
----------
开始第6次训练:
未选中特征: 卧室数量
开始第6次训练测试集成绩2.317658870332904:
----------
开始第7次训练:
未选中特征: 厅的数量
开始第7次训练测试集成绩2.317469293657488:
----------
开始第8次训练:
未选中特征: 卫的数量
In [21]:
cols=['小区房屋出租数量','房屋面积', '居住状态', '出租方式', '位置', '地铁站点', '距离', '装修情况', '新朝向', '房+卫+厅', '房/总', '卫/总', '卧室面积', '楼层比', '平均值特征1', '平均值特征2', '小区线路数', '位置线路数','小区条数大于100']
train(cols,d,f_map)
Out[21]:
1.6355982447085897
参数搜索
构建交叉验证和参数搜索函数
In [32]:
from sklearn.model_selection import KFold
#构建交叉验证函数
def train_cv(data,target,params,num_round=200,k_fold=5,silent=0):
"""
负责完成一种参数组合的情况下k_flod折交叉验证的平均rmse值
"""
rmses=[]
#数据分割
kfold= KFold(n_splits=k_fold,random_state =None,shuffle=True)
for i,(train_index,val_index) in zip(range(k_fold),kfold.split(data,target)):
train_x,val_x,train_y,val_y=data[train_index,:],data[val_index,:],target[train_index],target[val_index]
#构建DMatrix数据
dtrain = xgb.DMatrix(train_x,train_y)
dtest = xgb.DMatrix(val_x,val_y)
if silent==0:
print("开始第{}/{}折验证:".format(i,k_fold))
#模型训练
bst = xgb.train(params, dtrain, num_round)
#6.模型预测
preds = bst.predict(dtest)
preds=np.exp(preds)-1#转换成真实的租金
y_true=np.exp(val_y)-1
rmse=np.sqrt(mean_squared_error(y_true,preds))
if silent==0:
print("第{}/{}折验证rmse:{}".format(i,k_fold,rmse))
rmses.append(rmse)
return sum(rmses)/k_fold
def search_params(x,y,params_grid,n_estimators=200,cv=3,silent=0):
min_rmse=9999
best_params=None
params_list=[[]]
#根据参数表格构建所有参数组合
for k,v in params_grid.items():
if isinstance(v,list):
temp=params_list
params_list=[i+[j] for j in v for i in temp]
else:
params_list=[i+[v] for i in params_list]
params_list=[{k:v for k,v in zip(params_grid.keys(),v_list)} for v_list in params_list]
for i,params in zip(range(len(params_list)),params_list):
if silent==0:
print("开始实验第{}组参数:".format(i),params)
rmse=train_cv(data=x,target=y,params=params,num_round=n_estimators,k_fold=cv)
if silent==0:
print("第{}组参数平均rmse:{}".format(i,rmse))
print("-"*50)
if rmse<min_rmse:
min_rmse=rmse
best_params=params
return min_rmse,best_params
开始搜索
In [34]:
params_dict={
"objective":'reg:linear',
'eta':[0.01,0.1,0.5],
'gamma': [0.01,0.05,0.1],
'silent': 1,
'max_depth':[15,25,35],
'min_child_weight':[0.5,1,3],
}
cols=['小区房屋出租数量', '楼层', '总楼层', '房屋面积','居住状态', '卧室数量',
'卫的数量', '位置', '地铁站点', '距离', '装修情况',
'新朝向', '房+卫+厅', '房/总', '卫/总', '厅/总', '卧室面积', '楼层比', '户型','平均值特征1',
'平均值特征2','有地铁','小区线路数','位置线路数','小区条数大于100','小区平均值特征','朝向平均值特征',
'站点平均值特征','位置平均值特征']
#1.获取数据集
train_x,test_x,train_y,test_y=d
#获取原始特征对应的新特征下标
index=[]
for col in cols:
index.extend(f_map[col])
x_train=train_x[:50000,index]#只用前50000条数据做运算
x_test=test_x[:,index]
#由于要用新下标访问,所以要重置索引
train_y=train_y.reset_index(drop=True)[:50000]
test_y=test_y.reset_index(drop=True)
search_params(x=x_train,y=train_y,params_grid=params_dict,n_estimators=1000)
开始实验第0组参数: {'objective': 'reg:linear', 'eta': 0.01, 'gamma': 0.01, 'silent': 1, 'max_depth': 15, 'min_child_weight': 0.5}
开始第0/3折验证:
第0/3折验证rmse:2.1063645180292268
开始第1/3折验证:
第1/3折验证rmse:2.270438488734099
开始第2/3折验证:
第2/3折验证rmse:2.140966941345831
第0组参数平均rmse:2.172589982703052
--------------------------------------------------
开始实验第1组参数: {'objective': 'reg:linear', 'eta': 0.1, 'gamma': 0.01, 'silent': 1, 'max_depth': 15, 'min_child_weight': 0.5}
开始第0/3折验证:
第0/3折验证rmse:2.1029110307375034
开始第1/3折验证:
第1/3折验证rmse:2.151089425447841
开始第2/3折验证:
第2/3折验证rmse:2.2555141001168315
第1组参数平均rmse:2.169838185434059
--------------------------------------------------
开始实验第2组参数: {'objective': 'reg:linear', 'eta': 0.5, 'gamma': 0.01, 'silent': 1, 'max_depth': 15, 'min_child_weight': 0.5}
开始第0/3折验证:
第0/3折验证rmse:2.4535784391141995
开始第1/3折验证:
第1/3折验证rmse:2.424286846886855
开始第2/3折验证:
第2/3折验证rmse:2.1266645639199573
第2组参数平均rmse:2.334843283307004
--------------------------------------------------
开始实验第3组参数: {'objective': 'reg:linear', 'eta': 0.01, 'gamma': 0.05, 'silent': 1, 'max_depth': 15, 'min_child_weight': 0.5}
开始第0/3折验证:
第0/3折验证rmse:2.1509258765444517
开始第1/3折验证:
第1/3折验证rmse:2.2639212917057883
开始第2/3折验证:
第2/3折验证rmse:2.208002017298694
第3组参数平均rmse:2.207616395182978
--------------------------------------------------
开始实验第4组参数: {'objective': 'reg:linear', 'eta': 0.1, 'gamma': 0.05, 'silent': 1, 'max_depth': 15, 'min_child_weight': 0.5}
开始第0/3折验证:
第0/3折验证rmse:2.224230101453484
开始第1/3折验证:
第1/3折验证rmse:2.194730061107077
开始第2/3折验证:
第2/3折验证rmse:2.104946600682978
第4组参数平均rmse:2.1746355877478463
--------------------------------------------------
开始实验第5组参数: {'objective': 'reg:linear', 'eta': 0.5, 'gamma': 0.05, 'silent': 1, 'max_depth': 15, 'min_child_weight': 0.5}
开始第0/3折验证:
第0/3折验证rmse:2.4173987601952147
开始第1/3折验证:
第1/3折验证rmse:2.3193751890787064
开始第2/3折验证:
第2/3折验证rmse:2.350550916955072
第5组参数平均rmse:2.362441622076331
--------------------------------------------------
开始实验第6组参数: {'objective': 'reg:linear', 'eta': 0.01, 'gamma': 0.1, 'silent': 1, 'max_depth': 15, 'min_child_weight': 0.5}
开始第0/3折验证:
第0/3折验证rmse:2.150912061182521
开始第1/3折验证:
第1/3折验证rmse:2.1842688983958243
开始第2/3折验证:
第2/3折验证rmse:2.4129215673670013
第6组参数平均rmse:2.249367508981782
--------------------------------------------------
开始实验第7组参数: {'objective': 'reg:linear', 'eta': 0.1, 'gamma': 0.1, 'silent': 1, 'max_depth': 15, 'min_child_weight': 0.5}
开始第0/3折验证:
第0/3折验证rmse:2.2327447467966457
开始第1/3折验证:
第1/3折验证rmse:2.4065138418376923
开始第2/3折验证:
第2/3折验证rmse:2.286097658735343
第7组参数平均rmse:2.30845208245656
--------------------------------------------------
开始实验第8组参数: {'objective': 'reg:linear', 'eta': 0.5, 'gamma': 0.1, 'silent': 1, 'max_depth': 15, 'min_child_weight': 0.5}
开始第0/3折验证:
第0/3折验证rmse:2.3313455873087507
开始第1/3折验证:
第1/3折验证rmse:2.4397538237904057
开始第2/3折验证:
第2/3折验证rmse:2.31328569652659
第8组参数平均rmse:2.361461702541915
--------------------------------------------------
开始实验第9组参数: {'objective': 'reg:linear', 'eta': 0.01, 'gamma': 0.01, 'silent': 1, 'max_depth': 25, 'min_child_weight': 0.5}
开始第0/3折验证:
第0/3折验证rmse:2.351802702595958
开始第1/3折验证:
第1/3折验证rmse:2.230930544499273
开始第2/3折验证:
第2/3折验证rmse:2.251661755576135
第9组参数平均rmse:2.278131667557122
--------------------------------------------------
开始实验第10组参数: {'objective': 'reg:linear', 'eta': 0.1, 'gamma': 0.01, 'silent': 1, 'max_depth': 25, 'min_child_weight': 0.5}
开始第0/3折验证:
第0/3折验证rmse:2.327051827692085
开始第1/3折验证:
第1/3折验证rmse:2.3296903644220945
开始第2/3折验证:
第2/3折验证rmse:2.384475189364813
第10组参数平均rmse:2.347072460492998
--------------------------------------------------
开始实验第11组参数: {'objective': 'reg:linear', 'eta': 0.5, 'gamma': 0.01, 'silent': 1, 'max_depth': 25, 'min_child_weight': 0.5}
开始第0/3折验证:
第0/3折验证rmse:2.630278587228796
开始第1/3折验证:
第1/3折验证rmse:2.222563695431261
开始第2/3折验证:
第2/3折验证rmse:2.2461094587201518
第11组参数平均rmse:2.366317247126736
--------------------------------------------------
开始实验第12组参数: {'objective': 'reg:linear', 'eta': 0.01, 'gamma': 0.05, 'silent': 1, 'max_depth': 25, 'min_child_weight': 0.5}
开始第0/3折验证:
第0/3折验证rmse:2.125414735583022
开始第1/3折验证:
第1/3折验证rmse:2.2014928222849846
开始第2/3折验证:
第2/3折验证rmse:2.097238703895008
第12组参数平均rmse:2.141382087254338
--------------------------------------------------
开始实验第13组参数: {'objective': 'reg:linear', 'eta': 0.1, 'gamma': 0.05, 'silent': 1, 'max_depth': 25, 'min_child_weight': 0.5}
开始第0/3折验证:
第0/3折验证rmse:2.4197639273877596
开始第1/3折验证:
第1/3折验证rmse:2.146503225999798
开始第2/3折验证:
第2/3折验证rmse:2.1724123431688636
第13组参数平均rmse:2.2462264988521405
--------------------------------------------------
开始实验第14组参数: {'objective': 'reg:linear', 'eta': 0.5, 'gamma': 0.05, 'silent': 1, 'max_depth': 25, 'min_child_weight': 0.5}
开始第0/3折验证:
第0/3折验证rmse:2.512321338137171
开始第1/3折验证:
第1/3折验证rmse:2.4320489841732864
开始第2/3折验证:
第2/3折验证rmse:2.283527320349841
第14组参数平均rmse:2.4092992142200997
--------------------------------------------------
开始实验第15组参数: {'objective': 'reg:linear', 'eta': 0.01, 'gamma': 0.1, 'silent': 1, 'max_depth': 25, 'min_child_weight': 0.5}
开始第0/3折验证:
第0/3折验证rmse:2.1677308366792225
开始第1/3折验证:
第1/3折验证rmse:2.255620150072001
开始第2/3折验证:
第2/3折验证rmse:2.3948376802971194
第15组参数平均rmse:2.272729555682781
--------------------------------------------------
开始实验第16组参数: {'objective': 'reg:linear', 'eta': 0.1, 'gamma': 0.1, 'silent': 1, 'max_depth': 25, 'min_child_weight': 0.5}
开始第0/3折验证:
第0/3折验证rmse:2.347093266421053
开始第1/3折验证:
第1/3折验证rmse:2.3134536451552785
开始第2/3折验证:
第2/3折验证rmse:2.2327661973592092
第16组参数平均rmse:2.297771036311847
--------------------------------------------------
开始实验第17组参数: {'objective': 'reg:linear', 'eta': 0.5, 'gamma': 0.1, 'silent': 1, 'max_depth': 25, 'min_child_weight': 0.5}
开始第0/3折验证:
第0/3折验证rmse:2.3748013645667525
开始第1/3折验证:
第1/3折验证rmse:2.358196569845885
开始第2/3折验证:
第2/3折验证rmse:2.4795866533195476
第17组参数平均rmse:2.404194862577395
--------------------------------------------------
开始实验第18组参数: {'objective': 'reg:linear', 'eta': 0.01, 'gamma': 0.01, 'silent': 1, 'max_depth': 35, 'min_child_weight': 0.5}
开始第0/3折验证:
第0/3折验证rmse:2.240512423440991
开始第1/3折验证:
第1/3折验证rmse:2.1091848489427965
开始第2/3折验证:
第2/3折验证rmse:2.288639830011804
第18组参数平均rmse:2.212779034131864
--------------------------------------------------
开始实验第19组参数: {'objective': 'reg:linear', 'eta': 0.1, 'gamma': 0.01, 'silent': 1, 'max_depth': 35, 'min_child_weight': 0.5}
开始第0/3折验证:
第0/3折验证rmse:2.1775090908414034
开始第1/3折验证:
第1/3折验证rmse:2.202914246471916
开始第2/3折验证:
第2/3折验证rmse:2.3757522648670806
第19组参数平均rmse:2.2520585340601333
--------------------------------------------------
开始实验第20组参数: {'objective': 'reg:linear', 'eta': 0.5, 'gamma': 0.01, 'silent': 1, 'max_depth': 35, 'min_child_weight': 0.5}
开始第0/3折验证:
第0/3折验证rmse:2.412426495391516
开始第1/3折验证:
第1/3折验证rmse:2.3243322412870735
开始第2/3折验证:
第2/3折验证rmse:2.3949040510708914
第20组参数平均rmse:2.377220929249827
--------------------------------------------------
开始实验第21组参数: {'objective': 'reg:linear', 'eta': 0.01, 'gamma': 0.05, 'silent': 1, 'max_depth': 35, 'min_child_weight': 0.5}
开始第0/3折验证:
第0/3折验证rmse:2.269681476252998
开始第1/3折验证:
第1/3折验证rmse:2.146913481367659
开始第2/3折验证:
第2/3折验证rmse:2.2304382113812
第21组参数平均rmse:2.2156777230006193
--------------------------------------------------
开始实验第22组参数: {'objective': 'reg:linear', 'eta': 0.1, 'gamma': 0.05, 'silent': 1, 'max_depth': 35, 'min_child_weight': 0.5}
开始第0/3折验证:
第0/3折验证rmse:2.438955492998712
开始第1/3折验证:
第1/3折验证rmse:2.1329319198071146
开始第2/3折验证:
第2/3折验证rmse:2.124099501339859
第22组参数平均rmse:2.2319956380485624
--------------------------------------------------
开始实验第23组参数: {'objective': 'reg:linear', 'eta': 0.5, 'gamma': 0.05, 'silent': 1, 'max_depth': 35, 'min_child_weight': 0.5}
开始第0/3折验证:
第0/3折验证rmse:2.503644611663843
开始第1/3折验证:
第1/3折验证rmse:2.528994032876117
开始第2/3折验证:
第2/3折验证rmse:2.312941463640303
第23组参数平均rmse:2.4485267027267543
--------------------------------------------------
开始实验第24组参数: {'objective': 'reg:linear', 'eta': 0.01, 'gamma': 0.1, 'silent': 1, 'max_depth': 35, 'min_child_weight': 0.5}
开始第0/3折验证:
第0/3折验证rmse:2.237095467623757
开始第1/3折验证:
第1/3折验证rmse:2.4029885243008007
开始第2/3折验证:
第2/3折验证rmse:2.2734978813307447
第24组参数平均rmse:2.3045272910851007
--------------------------------------------------
开始实验第25组参数: {'objective': 'reg:linear', 'eta': 0.1, 'gamma': 0.1, 'silent': 1, 'max_depth': 35, 'min_child_weight': 0.5}
开始第0/3折验证:
第0/3折验证rmse:2.306825279691586
开始第1/3折验证:
第1/3折验证rmse:2.244977467458515
开始第2/3折验证:
第2/3折验证rmse:2.1922851419755007
第25组参数平均rmse:2.2480292963752
--------------------------------------------------
开始实验第26组参数: {'objective': 'reg:linear', 'eta': 0.5, 'gamma': 0.1, 'silent': 1, 'max_depth': 35, 'min_child_weight': 0.5}
开始第0/3折验证:
第0/3折验证rmse:2.3549137991155114
开始第1/3折验证:
第1/3折验证rmse:2.592401863979216
开始第2/3折验证:
第2/3折验证rmse:2.29801882782804
第26组参数平均rmse:2.4151114969742555
--------------------------------------------------
开始实验第27组参数: {'objective': 'reg:linear', 'eta': 0.01, 'gamma': 0.01, 'silent': 1, 'max_depth': 15, 'min_child_weight': 1}
开始第0/3折验证:
第0/3折验证rmse:2.171764054695917
开始第1/3折验证:
第1/3折验证rmse:2.2142377501924937
开始第2/3折验证:
第2/3折验证rmse:2.284722624617894
第27组参数平均rmse:2.223574809835435
--------------------------------------------------
开始实验第28组参数: {'objective': 'reg:linear', 'eta': 0.1, 'gamma': 0.01, 'silent': 1, 'max_depth': 15, 'min_child_weight': 1}
开始第0/3折验证:
第0/3折验证rmse:2.1858975633007525
开始第1/3折验证:
第1/3折验证rmse:2.4068418601897177
开始第2/3折验证:
第2/3折验证rmse:2.0969563799576494
第28组参数平均rmse:2.229898601149373
--------------------------------------------------
开始实验第29组参数: {'objective': 'reg:linear', 'eta': 0.5, 'gamma': 0.01, 'silent': 1, 'max_depth': 15, 'min_child_weight': 1}
开始第0/3折验证:
第0/3折验证rmse:2.388813347279593
开始第1/3折验证:
第1/3折验证rmse:2.284844842576387
开始第2/3折验证:
第2/3折验证rmse:2.4146204135428695
第29组参数平均rmse:2.362759534466283
--------------------------------------------------
开始实验第30组参数: {'objective': 'reg:linear', 'eta': 0.01, 'gamma': 0.05, 'silent': 1, 'max_depth': 15, 'min_child_weight': 1}
开始第0/3折验证:
第0/3折验证rmse:2.2487871387994858
开始第1/3折验证:
第1/3折验证rmse:2.1714058400384646
开始第2/3折验证:
第2/3折验证rmse:2.184533044019575
第30组参数平均rmse:2.2015753409525085
--------------------------------------------------
开始实验第31组参数: {'objective': 'reg:linear', 'eta': 0.1, 'gamma': 0.05, 'silent': 1, 'max_depth': 15, 'min_child_weight': 1}
开始第0/3折验证:
第0/3折验证rmse:2.2972859501336935
开始第1/3折验证:
第1/3折验证rmse:2.2362463997194886
开始第2/3折验证:
第2/3折验证rmse:2.2898365113716483
第31组参数平均rmse:2.2744562870749436
--------------------------------------------------
开始实验第32组参数: {'objective': 'reg:linear', 'eta': 0.5, 'gamma': 0.05, 'silent': 1, 'max_depth': 15, 'min_child_weight': 1}
开始第0/3折验证:
第0/3折验证rmse:2.419329912099752
开始第1/3折验证:
第1/3折验证rmse:2.6154375686147384
开始第2/3折验证:
第2/3折验证rmse:2.230305815806549
第32组参数平均rmse:2.4216910988403466
--------------------------------------------------
开始实验第33组参数: {'objective': 'reg:linear', 'eta': 0.01, 'gamma': 0.1, 'silent': 1, 'max_depth': 15, 'min_child_weight': 1}
开始第0/3折验证:
第0/3折验证rmse:2.200577515646503
开始第1/3折验证:
第1/3折验证rmse:2.2299424412995243
开始第2/3折验证:
第2/3折验证rmse:2.3140760122142896
第33组参数平均rmse:2.2481986563867724
--------------------------------------------------
开始实验第34组参数: {'objective': 'reg:linear', 'eta': 0.1, 'gamma': 0.1, 'silent': 1, 'max_depth': 15, 'min_child_weight': 1}
开始第0/3折验证:
第0/3折验证rmse:2.57849663446406
开始第1/3折验证:
第1/3折验证rmse:2.116087043730732
开始第2/3折验证:
第2/3折验证rmse:2.274100944461905
第34组参数平均rmse:2.3228948742188993
--------------------------------------------------
开始实验第35组参数: {'objective': 'reg:linear', 'eta': 0.5, 'gamma': 0.1, 'silent': 1, 'max_depth': 15, 'min_child_weight': 1}
开始第0/3折验证:
第0/3折验证rmse:2.3050644007916503
开始第1/3折验证:
第1/3折验证rmse:2.5075464973857162
开始第2/3折验证:
第2/3折验证rmse:2.3930588500403567
第35组参数平均rmse:2.4018899160725744
--------------------------------------------------
开始实验第36组参数: {'objective': 'reg:linear', 'eta': 0.01, 'gamma': 0.01, 'silent': 1, 'max_depth': 25, 'min_child_weight': 1}
开始第0/3折验证:
第0/3折验证rmse:2.276957221983997
开始第1/3折验证:
第1/3折验证rmse:2.3703205041784905
开始第2/3折验证:
第2/3折验证rmse:2.1867592895461
第36组参数平均rmse:2.278012338569529
--------------------------------------------------
开始实验第37组参数: {'objective': 'reg:linear', 'eta': 0.1, 'gamma': 0.01, 'silent': 1, 'max_depth': 25, 'min_child_weight': 1}
开始第0/3折验证:
第0/3折验证rmse:2.2507333499616866
开始第1/3折验证:
第1/3折验证rmse:2.2480253735311346
开始第2/3折验证:
第2/3折验证rmse:2.2176798693697006
第37组参数平均rmse:2.238812864287507
--------------------------------------------------
开始实验第38组参数: {'objective': 'reg:linear', 'eta': 0.5, 'gamma': 0.01, 'silent': 1, 'max_depth': 25, 'min_child_weight': 1}
开始第0/3折验证:
第0/3折验证rmse:2.2951887068467824
开始第1/3折验证:
第1/3折验证rmse:2.3602517398138096
开始第2/3折验证:
第2/3折验证rmse:2.3994056671768162
第38组参数平均rmse:2.351615371279136
--------------------------------------------------
开始实验第39组参数: {'objective': 'reg:linear', 'eta': 0.01, 'gamma': 0.05, 'silent': 1, 'max_depth': 25, 'min_child_weight': 1}
开始第0/3折验证:
第0/3折验证rmse:2.1837643392924027
开始第1/3折验证:
第1/3折验证rmse:2.2504664193983692
开始第2/3折验证:
第2/3折验证rmse:2.135889446314574
第39组参数平均rmse:2.190040068335115
--------------------------------------------------
开始实验第40组参数: {'objective': 'reg:linear', 'eta': 0.1, 'gamma': 0.05, 'silent': 1, 'max_depth': 25, 'min_child_weight': 1}
开始第0/3折验证:
第0/3折验证rmse:2.0869573705948192
开始第1/3折验证:
第1/3折验证rmse:2.2127491322380353
开始第2/3折验证:
第2/3折验证rmse:2.3164522580246296
第40组参数平均rmse:2.2053862536191615
--------------------------------------------------
开始实验第41组参数: {'objective': 'reg:linear', 'eta': 0.5, 'gamma': 0.05, 'silent': 1, 'max_depth': 25, 'min_child_weight': 1}
开始第0/3折验证:
第0/3折验证rmse:2.188863229863099
开始第1/3折验证:
第1/3折验证rmse:2.400519116701612
开始第2/3折验证:
第2/3折验证rmse:2.4379628348438347
第41组参数平均rmse:2.3424483938028486
--------------------------------------------------
开始实验第42组参数: {'objective': 'reg:linear', 'eta': 0.01, 'gamma': 0.1, 'silent': 1, 'max_depth': 25, 'min_child_weight': 1}
开始第0/3折验证:
第0/3折验证rmse:2.454450166538962
开始第1/3折验证:
第1/3折验证rmse:2.0656417463376475
开始第2/3折验证:
第2/3折验证rmse:2.3655598707868464
第42组参数平均rmse:2.295217261221152
--------------------------------------------------
开始实验第43组参数: {'objective': 'reg:linear', 'eta': 0.1, 'gamma': 0.1, 'silent': 1, 'max_depth': 25, 'min_child_weight': 1}
开始第0/3折验证:
第0/3折验证rmse:2.1824157942948537
开始第1/3折验证:
第1/3折验证rmse:2.3676364588012406
开始第2/3折验证:
第2/3折验证rmse:2.145039852244817
第43组参数平均rmse:2.2316973684469708
--------------------------------------------------
开始实验第44组参数: {'objective': 'reg:linear', 'eta': 0.5, 'gamma': 0.1, 'silent': 1, 'max_depth': 25, 'min_child_weight': 1}
开始第0/3折验证:
第0/3折验证rmse:2.396458431999462
开始第1/3折验证:
第1/3折验证rmse:2.4112866277165343
开始第2/3折验证:
第2/3折验证rmse:2.383011977510674
第44组参数平均rmse:2.39691901240889
--------------------------------------------------
开始实验第45组参数: {'objective': 'reg:linear', 'eta': 0.01, 'gamma': 0.01, 'silent': 1, 'max_depth': 35, 'min_child_weight': 1}
开始第0/3折验证:
第0/3折验证rmse:2.3398767792743698
开始第1/3折验证:
第1/3折验证rmse:2.150834454625684
开始第2/3折验证:
第2/3折验证rmse:2.3983698308079955
第45组参数平均rmse:2.296360354902683
--------------------------------------------------
开始实验第46组参数: {'objective': 'reg:linear', 'eta': 0.1, 'gamma': 0.01, 'silent': 1, 'max_depth': 35, 'min_child_weight': 1}
开始第0/3折验证:
第0/3折验证rmse:2.1467337553620087
开始第1/3折验证:
第1/3折验证rmse:2.067141831677618
开始第2/3折验证:
第2/3折验证rmse:2.246084426708412
第46组参数平均rmse:2.1533200045826795
--------------------------------------------------
开始实验第47组参数: {'objective': 'reg:linear', 'eta': 0.5, 'gamma': 0.01, 'silent': 1, 'max_depth': 35, 'min_child_weight': 1}
开始第0/3折验证:
第0/3折验证rmse:2.291145736550947
开始第1/3折验证:
第1/3折验证rmse:2.4679262622671856
开始第2/3折验证:
第2/3折验证rmse:2.3334840777758163
第47组参数平均rmse:2.3641853588646495
--------------------------------------------------
开始实验第48组参数: {'objective': 'reg:linear', 'eta': 0.01, 'gamma': 0.05, 'silent': 1, 'max_depth': 35, 'min_child_weight': 1}
开始第0/3折验证:
第0/3折验证rmse:2.2070883532476704
开始第1/3折验证:
第1/3折验证rmse:2.0854684885544548
开始第2/3折验证:
第2/3折验证rmse:2.190895382039525
第48组参数平均rmse:2.1611507412805504
--------------------------------------------------
开始实验第49组参数: {'objective': 'reg:linear', 'eta': 0.1, 'gamma': 0.05, 'silent': 1, 'max_depth': 35, 'min_child_weight': 1}
开始第0/3折验证:
第0/3折验证rmse:2.2406075908241965
开始第1/3折验证:
第1/3折验证rmse:2.1997157111560504
开始第2/3折验证:
第2/3折验证rmse:2.3159740377238247
第49组参数平均rmse:2.2520991132346904
--------------------------------------------------
开始实验第50组参数: {'objective': 'reg:linear', 'eta': 0.5, 'gamma': 0.05, 'silent': 1, 'max_depth': 35, 'min_child_weight': 1}
开始第0/3折验证:
第0/3折验证rmse:2.4411125744725406
开始第1/3折验证:
第1/3折验证rmse:2.45578081917117
开始第2/3折验证:
第2/3折验证rmse:2.2108615863413847
第50组参数平均rmse:2.3692516599950317
--------------------------------------------------
开始实验第51组参数: {'objective': 'reg:linear', 'eta': 0.01, 'gamma': 0.1, 'silent': 1, 'max_depth': 35, 'min_child_weight': 1}
开始第0/3折验证:
第0/3折验证rmse:2.3555601196130684
开始第1/3折验证:
第1/3折验证rmse:2.1563837142863638
开始第2/3折验证:
第2/3折验证rmse:2.2789944615773194
第51组参数平均rmse:2.2636460984922504
--------------------------------------------------
开始实验第52组参数: {'objective': 'reg:linear', 'eta': 0.1, 'gamma': 0.1, 'silent': 1, 'max_depth': 35, 'min_child_weight': 1}
开始第0/3折验证:
第0/3折验证rmse:2.2950794012987616
开始第1/3折验证:
第1/3折验证rmse:2.2213071464839884
开始第2/3折验证:
第2/3折验证rmse:2.169220925172176
第52组参数平均rmse:2.2285358243183087
--------------------------------------------------
开始实验第53组参数: {'objective': 'reg:linear', 'eta': 0.5, 'gamma': 0.1, 'silent': 1, 'max_depth': 35, 'min_child_weight': 1}
开始第0/3折验证:
第0/3折验证rmse:2.3781817980568287
开始第1/3折验证:
第1/3折验证rmse:2.2231348209756074
开始第2/3折验证:
第2/3折验证rmse:2.452517601712933
第53组参数平均rmse:2.3512780735817898
--------------------------------------------------
开始实验第54组参数: {'objective': 'reg:linear', 'eta': 0.01, 'gamma': 0.01, 'silent': 1, 'max_depth': 15, 'min_child_weight': 3}
开始第0/3折验证:
第0/3折验证rmse:2.1697340094788573
开始第1/3折验证:
第1/3折验证rmse:2.1152437442840575
开始第2/3折验证:
第2/3折验证rmse:2.2024548685544176
第54组参数平均rmse:2.162477540772444
--------------------------------------------------
开始实验第55组参数: {'objective': 'reg:linear', 'eta': 0.1, 'gamma': 0.01, 'silent': 1, 'max_depth': 15, 'min_child_weight': 3}
开始第0/3折验证:
第0/3折验证rmse:2.209310097715091
开始第1/3折验证:
第1/3折验证rmse:2.138762610248193
开始第2/3折验证:
第2/3折验证rmse:2.2925897483081115
第55组参数平均rmse:2.2135541520904654
--------------------------------------------------
开始实验第56组参数: {'objective': 'reg:linear', 'eta': 0.5, 'gamma': 0.01, 'silent': 1, 'max_depth': 15, 'min_child_weight': 3}
开始第0/3折验证:
第0/3折验证rmse:2.396555278419278
开始第1/3折验证:
第1/3折验证rmse:2.363139367149146
开始第2/3折验证:
第2/3折验证rmse:2.2318443518447233
第56组参数平均rmse:2.330512999137716
--------------------------------------------------
开始实验第57组参数: {'objective': 'reg:linear', 'eta': 0.01, 'gamma': 0.05, 'silent': 1, 'max_depth': 15, 'min_child_weight': 3}
开始第0/3折验证:
第0/3折验证rmse:2.350916617214958
开始第1/3折验证:
第1/3折验证rmse:2.426769178733778
开始第2/3折验证:
第2/3折验证rmse:2.1294132232677314
第57组参数平均rmse:2.3023663397388225
--------------------------------------------------
开始实验第58组参数: {'objective': 'reg:linear', 'eta': 0.1, 'gamma': 0.05, 'silent': 1, 'max_depth': 15, 'min_child_weight': 3}
开始第0/3折验证:
第0/3折验证rmse:2.2718710349597204
开始第1/3折验证:
第1/3折验证rmse:2.2724245754078067
开始第2/3折验证:
第2/3折验证rmse:2.1415978768994695
第58组参数平均rmse:2.228631162422332
--------------------------------------------------
开始实验第59组参数: {'objective': 'reg:linear', 'eta': 0.5, 'gamma': 0.05, 'silent': 1, 'max_depth': 15, 'min_child_weight': 3}
开始第0/3折验证:
第0/3折验证rmse:2.501290093920802
开始第1/3折验证:
第1/3折验证rmse:2.381049210488406
开始第2/3折验证:
第2/3折验证rmse:2.2750317759288943
第59组参数平均rmse:2.3857903601127006
--------------------------------------------------
开始实验第60组参数: {'objective': 'reg:linear', 'eta': 0.01, 'gamma': 0.1, 'silent': 1, 'max_depth': 15, 'min_child_weight': 3}
开始第0/3折验证:
第0/3折验证rmse:2.3181114399810796
开始第1/3折验证:
第1/3折验证rmse:2.2154998493769624
开始第2/3折验证:
第2/3折验证rmse:2.4049210337342464
第60组参数平均rmse:2.3128441076974293
--------------------------------------------------
开始实验第61组参数: {'objective': 'reg:linear', 'eta': 0.1, 'gamma': 0.1, 'silent': 1, 'max_depth': 15, 'min_child_weight': 3}
开始第0/3折验证:
第0/3折验证rmse:2.3851664509564388
开始第1/3折验证:
第1/3折验证rmse:2.3030068446632947
开始第2/3折验证:
第2/3折验证rmse:2.280847797963317
第61组参数平均rmse:2.3230070311943503
--------------------------------------------------
开始实验第62组参数: {'objective': 'reg:linear', 'eta': 0.5, 'gamma': 0.1, 'silent': 1, 'max_depth': 15, 'min_child_weight': 3}
开始第0/3折验证:
第0/3折验证rmse:2.417937402473705
开始第1/3折验证:
第1/3折验证rmse:2.3997823968592797
开始第2/3折验证:
第2/3折验证rmse:2.380405546022984
第62组参数平均rmse:2.399375115118656
--------------------------------------------------
开始实验第63组参数: {'objective': 'reg:linear', 'eta': 0.01, 'gamma': 0.01, 'silent': 1, 'max_depth': 25, 'min_child_weight': 3}
开始第0/3折验证:
第0/3折验证rmse:2.174178876935193
开始第1/3折验证:
第1/3折验证rmse:2.266418809440447
开始第2/3折验证:
第2/3折验证rmse:2.045909029982191
第63组参数平均rmse:2.16216890545261
--------------------------------------------------
开始实验第64组参数: {'objective': 'reg:linear', 'eta': 0.1, 'gamma': 0.01, 'silent': 1, 'max_depth': 25, 'min_child_weight': 3}
开始第0/3折验证:
第0/3折验证rmse:2.1185599029996527
开始第1/3折验证:
第1/3折验证rmse:2.2976351878015926
开始第2/3折验证:
第2/3折验证rmse:2.371055913517158
第64组参数平均rmse:2.262417001439468
--------------------------------------------------
开始实验第65组参数: {'objective': 'reg:linear', 'eta': 0.5, 'gamma': 0.01, 'silent': 1, 'max_depth': 25, 'min_child_weight': 3}
开始第0/3折验证:
第0/3折验证rmse:2.4192265174807486
开始第1/3折验证:
第1/3折验证rmse:2.547778062631276
开始第2/3折验证:
第2/3折验证rmse:2.453398370601104
第65组参数平均rmse:2.4734676502377098
--------------------------------------------------
开始实验第66组参数: {'objective': 'reg:linear', 'eta': 0.01, 'gamma': 0.05, 'silent': 1, 'max_depth': 25, 'min_child_weight': 3}
开始第0/3折验证:
第0/3折验证rmse:2.3116700347493646
开始第1/3折验证:
第1/3折验证rmse:2.142077163214947
开始第2/3折验证:
第2/3折验证rmse:2.1577471460239233
第66组参数平均rmse:2.203831447996078
--------------------------------------------------
开始实验第67组参数: {'objective': 'reg:linear', 'eta': 0.1, 'gamma': 0.05, 'silent': 1, 'max_depth': 25, 'min_child_weight': 3}
开始第0/3折验证:
第0/3折验证rmse:2.260847355749237
开始第1/3折验证:
第1/3折验证rmse:2.038611778956116
开始第2/3折验证:
第2/3折验证rmse:2.5484310808888635
第67组参数平均rmse:2.2826300718647388
--------------------------------------------------
开始实验第68组参数: {'objective': 'reg:linear', 'eta': 0.5, 'gamma': 0.05, 'silent': 1, 'max_depth': 25, 'min_child_weight': 3}
开始第0/3折验证:
第0/3折验证rmse:2.3981763646113885
开始第1/3折验证:
第1/3折验证rmse:2.2875108174804377
开始第2/3折验证:
第2/3折验证rmse:2.414449111458425
第68组参数平均rmse:2.3667120978500837
--------------------------------------------------
开始实验第69组参数: {'objective': 'reg:linear', 'eta': 0.01, 'gamma': 0.1, 'silent': 1, 'max_depth': 25, 'min_child_weight': 3}
开始第0/3折验证:
第0/3折验证rmse:2.28888986741368
开始第1/3折验证:
第1/3折验证rmse:2.2767189333146267
开始第2/3折验证:
第2/3折验证rmse:2.33555813056071
第69组参数平均rmse:2.3003889770963393
--------------------------------------------------
开始实验第70组参数: {'objective': 'reg:linear', 'eta': 0.1, 'gamma': 0.1, 'silent': 1, 'max_depth': 25, 'min_child_weight': 3}
开始第0/3折验证:
第0/3折验证rmse:2.1262568065515675
开始第1/3折验证:
第1/3折验证rmse:2.2618381987583054
开始第2/3折验证:
第2/3折验证rmse:2.1984332633424066
第70组参数平均rmse:2.1955094228840935
--------------------------------------------------
开始实验第71组参数: {'objective': 'reg:linear', 'eta': 0.5, 'gamma': 0.1, 'silent': 1, 'max_depth': 25, 'min_child_weight': 3}
开始第0/3折验证:
第0/3折验证rmse:2.503310188661614
开始第1/3折验证:
第1/3折验证rmse:2.3547656436918927
开始第2/3折验证:
第2/3折验证rmse:2.305990528979543
第71组参数平均rmse:2.3880221204443495
--------------------------------------------------
开始实验第72组参数: {'objective': 'reg:linear', 'eta': 0.01, 'gamma': 0.01, 'silent': 1, 'max_depth': 35, 'min_child_weight': 3}
开始第0/3折验证:
第0/3折验证rmse:2.121248127368896
开始第1/3折验证:
第1/3折验证rmse:2.297606544576462
开始第2/3折验证:
第2/3折验证rmse:2.127186689902887
第72组参数平均rmse:2.1820137872827483
--------------------------------------------------
开始实验第73组参数: {'objective': 'reg:linear', 'eta': 0.1, 'gamma': 0.01, 'silent': 1, 'max_depth': 35, 'min_child_weight': 3}
开始第0/3折验证:
第0/3折验证rmse:2.1410764654177217
开始第1/3折验证:
第1/3折验证rmse:2.264051683017106
开始第2/3折验证:
第2/3折验证rmse:2.272036190864403
第73组参数平均rmse:2.225721446433077
--------------------------------------------------
开始实验第74组参数: {'objective': 'reg:linear', 'eta': 0.5, 'gamma': 0.01, 'silent': 1, 'max_depth': 35, 'min_child_weight': 3}
开始第0/3折验证:
第0/3折验证rmse:2.282223990590916
开始第1/3折验证:
第1/3折验证rmse:2.4344388315143215
开始第2/3折验证:
第2/3折验证rmse:2.1473976008596702
第74组参数平均rmse:2.2880201409883028
--------------------------------------------------
开始实验第75组参数: {'objective': 'reg:linear', 'eta': 0.01, 'gamma': 0.05, 'silent': 1, 'max_depth': 35, 'min_child_weight': 3}
开始第0/3折验证:
第0/3折验证rmse:2.2557078363373244
开始第1/3折验证:
第1/3折验证rmse:2.012167036686711
开始第2/3折验证:
第2/3折验证rmse:2.187687495347084
第75组参数平均rmse:2.151854122790373
--------------------------------------------------
开始实验第76组参数: {'objective': 'reg:linear', 'eta': 0.1, 'gamma': 0.05, 'silent': 1, 'max_depth': 35, 'min_child_weight': 3}
开始第0/3折验证:
第0/3折验证rmse:2.2177760911023863
开始第1/3折验证:
第1/3折验证rmse:2.06291663889677
开始第2/3折验证:
第2/3折验证rmse:2.2830701173735686
第76组参数平均rmse:2.187920949124242
--------------------------------------------------
开始实验第77组参数: {'objective': 'reg:linear', 'eta': 0.5, 'gamma': 0.05, 'silent': 1, 'max_depth': 35, 'min_child_weight': 3}
开始第0/3折验证:
第0/3折验证rmse:2.3170419334417427
开始第1/3折验证:
第1/3折验证rmse:2.366394134764698
开始第2/3折验证:
第2/3折验证rmse:2.3975321343351474
第77组参数平均rmse:2.3603227341805293
--------------------------------------------------
开始实验第78组参数: {'objective': 'reg:linear', 'eta': 0.01, 'gamma': 0.1, 'silent': 1, 'max_depth': 35, 'min_child_weight': 3}
开始第0/3折验证:
第0/3折验证rmse:2.1943993462539413
开始第1/3折验证:
第1/3折验证rmse:2.389702628638741
开始第2/3折验证:
第2/3折验证rmse:2.087077836239587
第78组参数平均rmse:2.2237266037107566
--------------------------------------------------
开始实验第79组参数: {'objective': 'reg:linear', 'eta': 0.1, 'gamma': 0.1, 'silent': 1, 'max_depth': 35, 'min_child_weight': 3}
开始第0/3折验证:
第0/3折验证rmse:2.183353747113912
开始第1/3折验证:
第1/3折验证rmse:2.209950759672495
开始第2/3折验证:
第2/3折验证rmse:2.2352641756192404
第79组参数平均rmse:2.209522894135216
--------------------------------------------------
开始实验第80组参数: {'objective': 'reg:linear', 'eta': 0.5, 'gamma': 0.1, 'silent': 1, 'max_depth': 35, 'min_child_weight': 3}
开始第0/3折验证:
第0/3折验证rmse:2.3471298414272037
开始第1/3折验证:
第1/3折验证rmse:2.2745681485301392
开始第2/3折验证:
第2/3折验证rmse:2.386511745091769
第80组参数平均rmse:2.3360699116830372
--------------------------------------------------
Out[34]:
(2.141382087254338,
{'objective': 'reg:linear',
'eta': 0.01,
'gamma': 0.05,
'silent': 1,
'max_depth': 25,
'min_child_weight': 0.5})
In [35]:
#1.获取数据集
train_x,test_x,train_y,test_y=d
#获取原始特征对应的新特征下标
index=[]
for col in cols:
index.extend(f_map[col])
x_train=train_x[:,index]
x_test=test_x[:,index]
#由于要用新下标访问,所以要重置索引
train_y=train_y.reset_index(drop=True)
test_y=test_y.reset_index(drop=True)
利用搜索的参数训练模型
In [36]:
# xgb_model = xgb.XGBRegressor(max_depth=5, learning_rate=0.01, n_estimators=500,verbosity=1, objective='reg:linear',random_state=12,)
# xgb_model.fit(new_train_x, train_y, early_stopping_rounds=10, eval_metric="rmse",
# eval_set=[(new_test_x, test_y)])
params={
"objective":'reg:linear',
'eta':0.01,
'gamma': 0.05,
'silent': 1,
'max_depth':25,
'min_child_weight':0.5,
'sub_sample':0.6,
'reg_alpha':0.5,
'reg_lambda':0.8,
'colsample_bytree':0.5
}
dtrain = xgb.DMatrix(x_train,train_y)
dtest = xgb.DMatrix(x_test,test_y)
bst = xgb.train(params, dtrain, num_boost_round=1500)
#6.模型预测
preds = bst.predict(dtest)
preds=np.exp(preds)-1#转换成真实的租金
y_true=np.exp(test_y)-1
rmse=np.sqrt(mean_squared_error(y_true,preds))
rmse
Out[36]:
1.4322241873197603
In [124]:
# cv_params = {'n_estimators': [400, 500, 600, 700, 800]}
# other_params = {'learning_rate': 0.1, 'n_estimators': 500, 'max_depth': 5, 'min_child_weight': 1, 'seed': 0,
# 'subsample': 0.8, 'colsample_bytree': 0.8, 'gamma': 0, 'reg_alpha': 0, 'reg_lambda': 1}
# model = xgb.XGBRegressor(**other_params)
# optimized_GBM = GridSearchCV(estimator=model, param_grid=cv_params, scoring='r2', cv=5, verbose=1)
# optimized_GBM.fit(new_train_x, train_y)
# evalute_result = optimized_GBM.grid_scores_
# print('每轮迭代运行结果:{0}'.format(evalute_result))
# print('参数的最佳取值:{0}'.format(optimized_GBM.best_params_))
# print('最佳模型得分:{0}'.format(optimized_GBM.best_score_))
rmse
Out[124]:
1.5180160328127699
模型融合
In [1]:
from sklearn.linear_model import RidgeCV,LassoCV,Ridge,Lasso
from sklearn.svm import LinearSVR,SVR
from sklearn.ensemble import RandomForestRegressor,AdaBoostRegressor,GradientBoostingRegressor
from sklearn.neural_network import MLPRegressor
from sklearn.model_selection import train_test_split,GridSearchCV
from sklearn.feature_extraction import DictVectorizer
from sklearn.preprocessing import StandardScaler,PolynomialFeatures
from sklearn.decomposition import PCA
import pandas as pd
import numpy as np
from sklearn.metrics import mean_squared_error
In [ ]:
#没有用bagging和boosting
#stacking 先用几个不同的模型做预测 输出预测值 然后将这几个模型输出的预测值作为特征来训练一个新的模型
获取数据
In [2]:
data=pd.read_csv("data/onehot_feature.csv")
data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 196499 entries, 0 to 196498
Data columns (total 41 columns):
Unnamed: 0 196499 non-null int64
时间 196499 non-null int64
小区名 196499 non-null int64
小区房屋出租数量 196499 non-null float64
楼层 196499 non-null int64
总楼层 196499 non-null float64
房屋面积 196499 non-null float64
房屋朝向 196499 non-null object
居住状态 196499 non-null float64
卧室数量 196499 non-null int64
厅的数量 196499 non-null int64
卫的数量 196499 non-null int64
出租方式 196499 non-null float64
区 196499 non-null float64
位置 196499 non-null float64
地铁线路 196499 non-null float64
地铁站点 196499 non-null float64
距离 196499 non-null float64
装修情况 196499 non-null float64
月租金 196499 non-null float64
log_rent 196499 non-null float64
新朝向 196499 non-null object
房+卫+厅 196499 non-null int64
房/总 196499 non-null float64
卫/总 196499 non-null float64
厅/总 196499 non-null float64
卧室面积 196499 non-null float64
楼层比 196499 non-null float64
户型 196499 non-null int64
平均值特征1 196499 non-null float64
小区平均值特征 196499 non-null float64
朝向平均值特征 196499 non-null float64
站点平均值特征 196499 non-null float64
位置平均值特征 196499 non-null float64
有地铁 196499 non-null int64
聚类特征 196499 non-null int64
平均值特征2 196499 non-null float64
小区线路数 196499 non-null int64
位置线路数 196499 non-null int64
新小区名 196499 non-null int64
小区条数大于100 196499 non-null int64
dtypes: float64(24), int64(15), object(2)
memory usage: 61.5+ MB
In [3]:
#将离散特征转换成字符串类型
colunms = ['时间', '新小区名', '居住状态', '出租方式', '区','位置','地铁线路','地铁站点','装修情况','户型','聚类特征']
for col in colunms:
data[col] = data[col].astype(str)
In [4]:
x_columns=['小区房屋出租数量','新小区名', '楼层', '总楼层', '房屋面积','居住状态', '卧室数量',
'卫的数量', '位置', '地铁站点', '距离', '装修情况',
'新朝向', '房+卫+厅', '房/总', '卫/总', '厅/总', '卧室面积', '楼层比', '户型','平均值特征1',
'平均值特征2','有地铁','小区线路数','位置线路数','小区条数大于100','小区平均值特征','朝向平均值特征',
'站点平均值特征','位置平均值特征']
y_label='log_rent'
x=data[x_columns]
y=data[y_label]
In [5]:
#2.分割数据集
train_x,test_x,train_y,test_y=train_test_split(x,y,test_size=0.3,random_state=12)
In [6]:
#3.特征转换
vector=DictVectorizer(sparse=True)
x_train=vector.fit_transform(train_x.to_dict(orient='records'))
x_test=vector.transform(test_x.to_dict(orient='records'))
In [7]:
x_train.shape
Out[7]:
(137549, 964)
In [8]:
#4.降维----线性回归和svm可以采用降维后的特征
pca=PCA(0.98)
pca_x_train=pca.fit_transform(x_train.toarray())
pca_x_test=pca.transform(x_test.toarray())
In [9]:
pca_x_train.shape
Out[9]:
(137549, 407)
In [10]:
#5.特征标准化
trans=StandardScaler()
new_x_train=trans.fit_transform(pca_x_train)
new_x_test=trans.transform(pca_x_test)
In [11]:
new_x_train.shape
Out[11]:
(137549, 407)
In [12]:
# ploy=PolynomialFeatures(degree=2,interaction_only=True)
# ploy_x_train=ploy.fit_transform(new_x_train)
# ploy_x_test=ploy.transform(new_x_test)
In [13]:
# ploy_x_train.shape
In [14]:
def rmse(y_true,y_pred):
y_pred=np.exp(y_pred)-1#转换成真实的租金
y_true=np.exp(y_true)-1
return np.sqrt(mean_squared_error(y_true,y_pred))
构建子模型
构建岭回归模型
In [15]:
# #1.参数搜索
# ridge=Ridge()
# params={
# "alpha":[0.005,0.01,1,5,10,20,50]
# }
# model1=GridSearchCV(ridge,param_grid=params,cv=5,n_jobs=-1)
# model1.fit(new_x_train,train_y)
# model1.best_params_
# #{'alpha': 10, 'fit_intercept': True}
In [16]:
#利用搜索出的最优参数构建模型
ridge=Ridge(alpha=0.005)
ridge.fit(new_x_train,train_y)
Out[16]:
Ridge(alpha=0.005, copy_X=True, fit_intercept=True, max_iter=None,
normalize=False, random_state=None, solver='auto', tol=0.001)
In [17]:
y_pred_test=ridge.predict(new_x_test)
y_pred_train=ridge.predict(new_x_train)
print("训练集rmse:",rmse(train_y,y_pred_train))
print("测试集rmse:",rmse(test_y,y_pred_test))
训练集rmse: 3.162947362147576
测试集rmse: 3.1450837952700987
构建lasso回归
In [18]:
# #1.参数搜索
# lasso=Lasso()
# params={
# "alpha":[0.001,0.01,0.05,0.1,0.5,1,5,10],
# "fit_intercept":[True,False]
# }
# model2=GridSearchCV(lasso,param_grid=params,cv=5,n_jobs=-1)
# model2.fit(new_x_train,train_y)
# model2.best_params_
# #{'alpha': 0.001, 'fit_intercept': True}
In [19]:
#利用搜索出的最优参数构建模型
lasso=Lasso(alpha=0.001)
lasso.fit(new_x_train,train_y)
Out[19]:
Lasso(alpha=0.001, copy_X=True, fit_intercept=True, max_iter=1000,
normalize=False, positive=False, precompute=False, random_state=None,
selection='cyclic', tol=0.0001, warm_start=False)
In [20]:
y_pred_test=lasso.predict(new_x_test)
y_pred_train=lasso.predict(new_x_train)
print("训练集rmse:",rmse(train_y,y_pred_train))
print("测试集rmse:",rmse(test_y,y_pred_test))
训练集rmse: 3.17469838175572
测试集rmse: 3.1600537035148
构建随机森林
In [55]:
# #1.参数搜索
# rf=RandomForestRegressor(max_features='sqrt')#设置max_features='sqrt',不然太耗时间
# params={
# "n_estimators":[200],#[200,500,700],
# "max_depth":[40,50,60],
# "min_samples_split":[20,50,100],
# "min_samples_leaf":[10,20,30]
# }
# model3=GridSearchCV(rf,param_grid=params,cv=5,n_jobs=-1,verbose=2)
# model3.fit(x_train,train_y)
# model3.best_params_
# # {'max_depth': 50,
# # 'min_samples_leaf': 10,
# # 'min_samples_split': 20,
# # 'n_estimators': 200}
Fitting 5 folds for each of 27 candidates, totalling 135 fits
[Parallel(n_jobs=-1)]: Using backend LokyBackend with 20 concurrent workers.
[Parallel(n_jobs=-1)]: Done 1 tasks | elapsed: 5.1min
[Parallel(n_jobs=-1)]: Done 135 out of 135 | elapsed: 35.5min finished
Out[55]:
{'max_depth': 50,
'min_samples_leaf': 10,
'min_samples_split': 20,
'n_estimators': 200}
In [ ]:
# import time
# print time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
In [21]:
#利用搜索出的最优参数构建模型
rf=RandomForestRegressor(n_estimators=200,
max_features=0.8,
max_depth=50,
min_samples_split=20,
min_samples_leaf=10,
n_jobs=-1)
rf.fit(x_train,train_y)
Out[21]:
RandomForestRegressor(bootstrap=True, criterion='mse', max_depth=50,
max_features=0.8, max_leaf_nodes=None,
min_impurity_decrease=0.0, min_impurity_split=None,
min_samples_leaf=10, min_samples_split=20,
min_weight_fraction_leaf=0.0, n_estimators=200, n_jobs=-1,
oob_score=False, random_state=None, verbose=0,
warm_start=False)
In [22]:
y_pred_test=rf.predict(x_test)
y_pred_train=rf.predict(x_train)
print("训练集rmse:",rmse(train_y,y_pred_train))
print("测试集rmse:",rmse(test_y,y_pred_test))
训练集rmse: 1.8016406346453875
测试集rmse: 2.078690010364972
构建决策树
In [93]:
# tree=DecisionTreeRegressor()
# params={
# "max_depth":[40,50,60,70],
# "min_samples_split":[5,10,20,30,40,50],
# "min_samples_leaf":[2,3,5,7,9,11]
# }
# model4=GridSearchCV(tree,param_grid=params,cv=5,n_jobs=-1)
# model4.fit(x_train,train_y)
# model4.best_params_
# {'max_depth': 60, 'min_samples_leaf': 2, 'min_samples_split': 5}
Out[93]:
{'max_depth': 60, 'min_samples_leaf': 2, 'min_samples_split': 5}
In [94]:
from sklearn.tree import DecisionTreeRegressor
#利用搜索出的最优参数构建模型
tree=DecisionTreeRegressor(max_depth=60,min_samples_leaf=2,min_samples_split=5)
tree.fit(x_train,train_y)
Out[94]:
DecisionTreeRegressor(criterion='mse', max_depth=60, max_features=None,
max_leaf_nodes=None, min_impurity_decrease=0.0,
min_impurity_split=None, min_samples_leaf=2,
min_samples_split=5, min_weight_fraction_leaf=0.0,
presort=False, random_state=None, splitter='best')
In [95]:
y_pred_test=tree.predict(x_test)
y_pred_train=tree.predict(x_train)
print("训练集rmse:",rmse(train_y,y_pred_train))
print("测试集rmse:",rmse(test_y,y_pred_test))
训练集rmse: 0.7147616009940363
测试集rmse: 1.5876633153093507
In [96]:
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False
plt.figure(figsize=(20,20),dpi=100)
plt.scatter(test_y,y_pred_test)
plt.xlabel("真实值")
plt.ylabel("预测值")
plt.show()
构建支持向量机
In [1]:
# #1.参数搜索----数据量大 svm太耗时,调参几乎不可能
# svr=SVR()
# params={
# "gamma":[0.001,0.01,0.1,0.5,1,5],
# "C":[0.001,0.1,0.5,1,5]
# }
# model5=GridSearchCV(svr,param_grid=params,cv=5,n_jobs=-1,verbose=10)
# model5.fit(new_x_train,train_y)
# model5.best_params_
In [ ]:
# #随意选一组参数 --- 耗时太长 放弃该模型
# svr=SVR(gamma=0.1,C=0.5)
# svr.fit(new_x_train,train_y)
# y_pred=svr.predict(new_x_test)
# rmse(test_y,y_pred)
构建xgboost模型
In [25]:
import xgboost as xgb
params={
"objective":'reg:linear',
'eta':0.1,
'gamma': 0.05,
'silent': 1,
'max_depth':45,
'min_child_weight':0.5,
'sub_sample':0.6,
'reg_alpha':0.5,
'reg_lambda':0.8,
'colsample_bytree':0.5
}
dtrain = xgb.DMatrix(x_train,train_y)
dtest = xgb.DMatrix(x_test,test_y)
bst = xgb.train(params, dtrain, num_boost_round=2000)
/root/anaconda3/envs/ml/lib/python3.6/site-packages/xgboost/core.py:587: FutureWarning: Series.base is deprecated and will be removed in a future version
if getattr(data, 'base', None) is not None and \
In [66]:
y_pred_test=bst.predict(dtest)
y_pred_train=bst.predict(dtrain)
print("训练集rmse:",rmse(train_y,y_pred_train))
print("测试集rmse:",rmse(test_y,y_pred_test))
训练集rmse: 0.8318620679177371
测试集rmse: 1.3412344636800162
In [68]:
import matplotlib.pyplot as plt
plt.figure(figsize=(20,20),dpi=100)
plt.scatter(test_y,y_pred_test)
plt.xlabel("真实值")
plt.ylabel("预测值")
plt.show()
Stacking融合
In [97]:
#获取每个子模型的预测结果作为特征
train_features=[]
train_features.append(ridge.predict(new_x_train))#将每个模型预测值保存起来
train_features.append(lasso.predict(new_x_train))
# train_features.append(svr.predict(new_x_train))#这个太慢了 不要了
train_features.append(rf.predict(x_train))
train_features.append(tree.predict(x_train))
train_features.append(bst.predict(dtrain))
test_features=[]
test_features.append(ridge.predict(new_x_test))
test_features.append(lasso.predict(new_x_test))
# test_features.append(svr.predict(new_x_test))
test_features.append(rf.predict(x_test))
test_features.append(tree.predict(x_test))
test_features.append(bst.predict(dtest))
In [98]:
mx_train=np.vstack(train_features).T
mx_test=np.vstack(test_features).T
mx_train.shape
Out[98]:
(137549, 5)
In [110]:
stack_model=Ridge(fit_intercept=False)
params={
"alpha":np.logspace(-2,3,20)
}
model=GridSearchCV(stack_model,param_grid=params,cv=5,n_jobs=-1)
model.fit(mx_train,train_y)
model.best_params_
Out[110]:
{'alpha': 0.20691380811147891}
In [120]:
stack_model=Ridge(alpha=0.206,fit_intercept=False)
stack_model.fit(mx_train,train_y)
y_pred=stack_model.predict(mx_test)
y_pred_train=stack_model.predict(mx_train)
print("训练集rmse:",rmse(train_y,y_pred_train))
print("测试集rmse:",rmse(test_y,y_pred))
训练集rmse: 0.6824409675644203
测试集rmse: 1.3588850206739824
In [121]:
stack_model.coef_
Out[121]:
array([-0.01476048, -0.01601146, 0.04143987, 0.55925897, 0.43009737])
模型保存
In [ ]:
import pickle
with open("data/model.pkl","wb") as f:
pickle.dump({
"vector":vector,
"pca":pca,
"sc":trans,
"ridge":ridge,
"lasso":lasso,
"rf":rf,
"tree":tree,
"bst":bst,
"stack":stack_model
},f)
数据处理
In [1]:
import pandas as pd
In [2]:
train = pd.read_csv("./data/train.csv")
In [3]:
test = pd.read_csv("./data/test.csv")
In [4]:
train.head()
Out[4]:
时间 | 小区名 | 小区房屋出租数量 | 楼层 | 总楼层 | 房屋面积 | 房屋朝向 | 居住状态 | 卧室数量 | 厅的数量 | 卫的数量 | 出租方式 | 区 | 位置 | 地铁线路 | 地铁站点 | 距离 | 装修情况 | 月租金 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 3072 | 0.128906 | 2 | 0.236364 | 0.008628 | 东南 | NaN | 1 | 1 | 1 | NaN | 11.0 | 118.0 | 2.0 | 40.0 | 0.764167 | NaN | 5.602716 |
1 | 1 | 3152 | 0.132812 | 1 | 0.381818 | 0.017046 | 东 | NaN | 1 | 0 | 0 | NaN | 10.0 | 100.0 | 4.0 | 58.0 | 0.709167 | NaN | 16.977929 |
2 | 1 | 5575 | 0.042969 | 0 | 0.290909 | 0.010593 | 东南 | NaN | 2 | 1 | 2 | NaN | 12.0 | 130.0 | 5.0 | 37.0 | 0.572500 | NaN | 8.998302 |
3 | 1 | 3103 | 0.085938 | 2 | 0.581818 | 0.019199 | 南 | NaN | 3 | 2 | 2 | NaN | 7.0 | 90.0 | 2.0 | 63.0 | 0.658333 | NaN | 5.602716 |
4 | 1 | 5182 | 0.214844 | 0 | 0.545455 | 0.010427 | 东北 | NaN | 2 | 1 | 1 | NaN | 3.0 | 31.0 | NaN | NaN | NaN | NaN | 7.300509 |
In [5]:
test.head()
Out[5]:
id | 时间 | 小区名 | 小区房屋出租数量 | 楼层 | 总楼层 | 房屋面积 | 房屋朝向 | 居住状态 | 卧室数量 | 厅的数量 | 卫的数量 | 出租方式 | 区 | 位置 | 地铁线路 | 地铁站点 | 距离 | 装修情况 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 4 | 6011 | 0.382812 | 1 | 0.600000 | 0.007117 | 东 | 3.0 | 2 | 1 | 1 | 1.0 | 10.0 | 5.0 | NaN | NaN | NaN | 6.0 |
1 | 2 | 4 | 1697 | 0.152344 | 1 | 0.472727 | 0.007448 | 东 | NaN | 2 | 1 | 1 | NaN | 3.0 | 0.0 | NaN | NaN | NaN | NaN |
2 | 3 | 4 | 754 | 0.207031 | 2 | 0.709091 | 0.014068 | 东南 | NaN | 3 | 2 | 2 | NaN | 10.0 | 9.0 | 4.0 | 74.0 | 0.400833 | NaN |
3 | 4 | 4 | 1285 | 0.011719 | 0 | 0.090909 | 0.008937 | 南 | NaN | 2 | 1 | 1 | NaN | 6.0 | 96.0 | 5.0 | 17.0 | 0.384167 | NaN |
4 | 5 | 4 | 4984 | 0.035156 | 1 | 0.218182 | 0.008606 | 东南 | NaN | 2 | 1 | 1 | NaN | 6.0 | 61.0 | 3.0 | 114.0 | 0.598333 | NaN |
In [7]:
train.shape
Out[7]:
(196539, 19)
In [8]:
import seaborn as sns
In [11]:
# 图形可视化,查看数据分布
import seaborn as sns
import matplotlib.pyplot as plt
sns.countplot(train.时间)
plt.show()
In [14]:
train1 = train[train.时间 == 1]
train1.shape
Out[14]:
(50843, 19)
In [15]:
train2 = train[train.时间 == 2]
train2.shape
Out[15]:
(72206, 19)
In [16]:
train3 = train[train.时间 == 3]
train3.shape
Out[16]:
(73490, 19)
In [21]:
train2.index
Out[21]:
Int64Index([ 50843, 50844, 50845, 50846, 50847, 50848, 50849, 50850,
50851, 50852,
...
123039, 123040, 123041, 123042, 123043, 123044, 123045, 123046,
123047, 123048],
dtype='int64', length=72206)
In [22]:
train3.index
Out[22]:
Int64Index([123049, 123050, 123051, 123052, 123053, 123054, 123055, 123056,
123057, 123058,
...
196529, 196530, 196531, 196532, 196533, 196534, 196535, 196536,
196537, 196538],
dtype='int64', length=73490)
In [31]:
train2.月租金.values
Out[31]:
array([7.64006791, 4.24448217, 6.62139219, ..., 5.60271647, 7.30050934,
6.96095076])
In [32]:
plt.figure()
plt.plot(train2.index.values, train2.月租金.values)
plt.show()
In [33]:
plt.figure()
plt.plot(train3.index.values, train3.月租金.values)
plt.show()
In [37]:
train_ = train[:150539]
In [38]:
# 图形可视化,查看数据分布
import seaborn as sns
import matplotlib.pyplot as plt
sns.countplot(train_.时间)
plt.show()
In [39]:
plt.figure()
plt.plot(train_.index.values, train_.月租金.values)
plt.show()
In [42]:
train_.index.values
Out[42]:
array([ 0, 1, 2, ..., 150536, 150537, 150538])
In [43]:
test_ = train[150539:]
In [44]:
test_.index.values
Out[44]:
array([150539, 150540, 150541, ..., 196536, 196537, 196538])
In [45]:
test_.shape
Out[45]:
(46000, 19)
In [46]:
test_.head()
Out[46]:
时间 | 小区名 | 小区房屋出租数量 | 楼层 | 总楼层 | 房屋面积 | 房屋朝向 | 居住状态 | 卧室数量 | 厅的数量 | 卫的数量 | 出租方式 | 区 | 位置 | 地铁线路 | 地铁站点 | 距离 | 装修情况 | 月租金 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
150539 | 3 | 3882 | 0.035156 | 1 | 0.436364 | 0.013075 | 东南 | NaN | 3 | 1 | 1 | NaN | 8.0 | 94.0 | 4.0 | 76.0 | 0.383333 | NaN | 6.281834 |
150540 | 3 | 6353 | 0.078125 | 1 | 0.436364 | 0.012248 | 东南 | NaN | 3 | 1 | 1 | NaN | 3.0 | 33.0 | 3.0 | 23.0 | 1.000000 | NaN | 6.281834 |
150541 | 3 | 1493 | 0.203125 | 1 | 0.381818 | 0.023006 | 南 | NaN | 4 | 2 | 2 | NaN | 12.0 | 60.0 | 5.0 | 115.0 | 0.945000 | NaN | 23.259762 |
150542 | 3 | 1532 | 0.414062 | 1 | 0.600000 | 0.019695 | 东南 | NaN | 3 | 2 | 2 | NaN | 1.0 | 40.0 | NaN | NaN | NaN | NaN | 2.886248 |
150543 | 3 | 1251 | 0.226562 | 1 | 0.381818 | 0.014730 | 东 | NaN | 3 | 1 | 1 | NaN | 12.0 | 52.0 | NaN | NaN | NaN | NaN | 10.696095 |
In [50]:
id = [i for i in range(1, 46001)]
id
test_["id"] = id
In [52]:
test_.head()
Out[52]:
时间 | 小区名 | 小区房屋出租数量 | 楼层 | 总楼层 | 房屋面积 | 房屋朝向 | 居住状态 | 卧室数量 | 厅的数量 | 卫的数量 | 出租方式 | 区 | 位置 | 地铁线路 | 地铁站点 | 距离 | 装修情况 | 月租金 | id | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
150539 | 3 | 3882 | 0.035156 | 1 | 0.436364 | 0.013075 | 东南 | NaN | 3 | 1 | 1 | NaN | 8.0 | 94.0 | 4.0 | 76.0 | 0.383333 | NaN | 6.281834 | 1 |
150540 | 3 | 6353 | 0.078125 | 1 | 0.436364 | 0.012248 | 东南 | NaN | 3 | 1 | 1 | NaN | 3.0 | 33.0 | 3.0 | 23.0 | 1.000000 | NaN | 6.281834 | 2 |
150541 | 3 | 1493 | 0.203125 | 1 | 0.381818 | 0.023006 | 南 | NaN | 4 | 2 | 2 | NaN | 12.0 | 60.0 | 5.0 | 115.0 | 0.945000 | NaN | 23.259762 | 3 |
150542 | 3 | 1532 | 0.414062 | 1 | 0.600000 | 0.019695 | 东南 | NaN | 3 | 2 | 2 | NaN | 1.0 | 40.0 | NaN | NaN | NaN | NaN | 2.886248 | 4 |
150543 | 3 | 1251 | 0.226562 | 1 | 0.381818 | 0.014730 | 东 | NaN | 3 | 1 | 1 | NaN | 12.0 | 52.0 | NaN | NaN | NaN | NaN | 10.696095 | 5 |
In [74]:
train_.to_csv("./train.csv", index=False)
In [54]:
test_.to_csv("./test_result.csv")
In [57]:
test_1 = test_.drop(["月租金"], axis=1)
In [59]:
test_1.head()
Out[59]:
时间 | 小区名 | 小区房屋出租数量 | 楼层 | 总楼层 | 房屋面积 | 房屋朝向 | 居住状态 | 卧室数量 | 厅的数量 | 卫的数量 | 出租方式 | 区 | 位置 | 地铁线路 | 地铁站点 | 距离 | 装修情况 | id | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
150539 | 3 | 3882 | 0.035156 | 1 | 0.436364 | 0.013075 | 东南 | NaN | 3 | 1 | 1 | NaN | 8.0 | 94.0 | 4.0 | 76.0 | 0.383333 | NaN | 1 |
150540 | 3 | 6353 | 0.078125 | 1 | 0.436364 | 0.012248 | 东南 | NaN | 3 | 1 | 1 | NaN | 3.0 | 33.0 | 3.0 | 23.0 | 1.000000 | NaN | 2 |
150541 | 3 | 1493 | 0.203125 | 1 | 0.381818 | 0.023006 | 南 | NaN | 4 | 2 | 2 | NaN | 12.0 | 60.0 | 5.0 | 115.0 | 0.945000 | NaN | 3 |
150542 | 3 | 1532 | 0.414062 | 1 | 0.600000 | 0.019695 | 东南 | NaN | 3 | 2 | 2 | NaN | 1.0 | 40.0 | NaN | NaN | NaN | NaN | 4 |
150543 | 3 | 1251 | 0.226562 | 1 | 0.381818 | 0.014730 | 东 | NaN | 3 | 1 | 1 | NaN | 12.0 | 52.0 | NaN | NaN | NaN | NaN | 5 |
In [60]:
test_1.to_csv("./test.csv")
In [62]:
test = pd.read_csv("./test.csv")
In [63]:
test.head()
Out[63]:
Unnamed: 0 | id | 时间 | 小区名 | 小区房屋出租数量 | 楼层 | 总楼层 | 房屋面积 | 房屋朝向 | 居住状态 | 卧室数量 | 厅的数量 | 卫的数量 | 出租方式 | 区 | 位置 | 地铁线路 | 地铁站点 | 距离 | 装修情况 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 1 | 3 | 3882 | 0.035156 | 1 | 0.436364 | 0.013075 | 东南 | NaN | 3 | 1 | 1 | NaN | 8.0 | 94.0 | 4.0 | 76.0 | 0.383333 | NaN |
1 | 2 | 2 | 3 | 6353 | 0.078125 | 1 | 0.436364 | 0.012248 | 东南 | NaN | 3 | 1 | 1 | NaN | 3.0 | 33.0 | 3.0 | 23.0 | 1.000000 | NaN |
2 | 3 | 3 | 3 | 1493 | 0.203125 | 1 | 0.381818 | 0.023006 | 南 | NaN | 4 | 2 | 2 | NaN | 12.0 | 60.0 | 5.0 | 115.0 | 0.945000 | NaN |
3 | 150542 | 4 | 3 | 1532 | 0.414062 | 1 | 0.600000 | 0.019695 | 东南 | NaN | 3 | 2 | 2 | NaN | 1.0 | 40.0 | NaN | NaN | NaN | NaN |
4 | 150543 | 5 | 3 | 1251 | 0.226562 | 1 | 0.381818 | 0.014730 | 东 | NaN | 3 | 1 | 1 | NaN | 12.0 | 52.0 | NaN | NaN | NaN | NaN |
In [65]:
test = test.drop(["Unnamed: 0"], axis=1)
In [68]:
test.to_csv("./test.csv", index=False)
In [72]:
test = pd.read_csv("./test.csv")
test.head()
Out[72]:
id | 时间 | 小区名 | 小区房屋出租数量 | 楼层 | 总楼层 | 房屋面积 | 房屋朝向 | 居住状态 | 卧室数量 | 厅的数量 | 卫的数量 | 出租方式 | 区 | 位置 | 地铁线路 | 地铁站点 | 距离 | 装修情况 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 3 | 3882 | 0.035156 | 1 | 0.436364 | 0.013075 | 东南 | NaN | 3 | 1 | 1 | NaN | 8.0 | 94.0 | 4.0 | 76.0 | 0.383333 | NaN |
1 | 2 | 3 | 6353 | 0.078125 | 1 | 0.436364 | 0.012248 | 东南 | NaN | 3 | 1 | 1 | NaN | 3.0 | 33.0 | 3.0 | 23.0 | 1.000000 | NaN |
2 | 3 | 3 | 1493 | 0.203125 | 1 | 0.381818 | 0.023006 | 南 | NaN | 4 | 2 | 2 | NaN | 12.0 | 60.0 | 5.0 | 115.0 | 0.945000 | NaN |
3 | 4 | 3 | 1532 | 0.414062 | 1 | 0.600000 | 0.019695 | 东南 | NaN | 3 | 2 | 2 | NaN | 1.0 | 40.0 | NaN | NaN | NaN | NaN |
4 | 5 | 3 | 1251 | 0.226562 | 1 | 0.381818 | 0.014730 | 东 | NaN | 3 | 1 | 1 | NaN | 12.0 | 52.0 | NaN | NaN | NaN | NaN |
In [73]:
test.shape
Out[73]:
(46000, 19)
In [79]:
train = pd.read_csv("./train.csv")
train.head()
Out[79]:
时间 | 小区名 | 小区房屋出租数量 | 楼层 | 总楼层 | 房屋面积 | 房屋朝向 | 居住状态 | 卧室数量 | 厅的数量 | 卫的数量 | 出租方式 | 区 | 位置 | 地铁线路 | 地铁站点 | 距离 | 装修情况 | 月租金 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 3072 | 0.128906 | 2 | 0.236364 | 0.008628 | 东南 | NaN | 1 | 1 | 1 | NaN | 11.0 | 118.0 | 2.0 | 40.0 | 0.764167 | NaN | 5.602716 |
1 | 1 | 3152 | 0.132812 | 1 | 0.381818 | 0.017046 | 东 | NaN | 1 | 0 | 0 | NaN | 10.0 | 100.0 | 4.0 | 58.0 | 0.709167 | NaN | 16.977929 |
2 | 1 | 5575 | 0.042969 | 0 | 0.290909 | 0.010593 | 东南 | NaN | 2 | 1 | 2 | NaN | 12.0 | 130.0 | 5.0 | 37.0 | 0.572500 | NaN | 8.998302 |
3 | 1 | 3103 | 0.085938 | 2 | 0.581818 | 0.019199 | 南 | NaN | 3 | 2 | 2 | NaN | 7.0 | 90.0 | 2.0 | 63.0 | 0.658333 | NaN | 5.602716 |
4 | 1 | 5182 | 0.214844 | 0 | 0.545455 | 0.010427 | 东北 | NaN | 2 | 1 | 1 | NaN | 3.0 | 31.0 | NaN | NaN | NaN | NaN | 7.300509 |
In [80]:
train.shape
Out[80]:
(150539, 19)