1.缺失值处理
缺失值的处理手段大体可以分为:删除、填充、映射到高维(当做类别处理)。
根据任务一,直接找到的缺失值情况是pu和pv;但是,根据特征nunique分布的分析,可以发现rentType存在"–“的情况,这也算是一种缺失值。
此外,诸如rentType的"未知方式”;houseToward的"暂无数据"等,本质上也算是一种缺失值,但是对于这些缺失方式,我们可以把它当做是特殊的一类处理,而不需要去主动修改或填充值。
1.1如何修改
将rentType的"–“转换成"未知方式"类别;
pv/pu的缺失值用均值填充;
buildYear存在"暂无信息”,将其用众数填充。
1.2具体操作
1.转换object类型数据
这里直接采用LabelEncoder的方式编码,详细的编码方式请自行查阅相关资料学习。
2.时间字段的处理
buildYear由于存在"暂无信息",所以需要主动将其转换int类型;
tradeTime,将其分割成月和日。
3.删除无关字段
ID是唯一码,建模无用,所以直接删除;
city只有一个SH值,也直接删除;
tradeTime已经分割成月和日,删除原来字段
def preprocessingData(data):
# 填充缺失值
data['rentType'][data['rentType'] == '--'] = '未知方式'
# 转换object类型数据
columns = ['rentType','communityName','houseType', 'houseFloor', 'houseToward', 'houseDecoration', 'region', 'plate']
for feature in columns:
data[feature] = LabelEncoder().fit_transform(data[feature])
# 将buildYear列转换为整型数据
buildYearmean = pd.DataFrame(data[data['buildYear'] != '暂无信息']['buildYear'].mode())
data.loc[data[data['buildYear'] == '暂无信息'].index, 'buildYear'] = buildYearmean.iloc[0, 0]
data['buildYear'] = data['buildYear'].astype('int')
# 处理pv和uv的空值
data['pv'].fillna(data['pv'].mean(), inplace=True)
data['uv'].fillna(data['uv'].mean(), inplace=True)
data['pv'] = data['pv'].astype('int')
data['uv'] = data['uv'].astype('int')
# 分割交易时间
def month(x):
month = int(x.split('/')[1])
return month
def day(x):
day = int(x.split('/')[2])
return day
data['month'] = data['tradeTime'].apply(lambda x: month(x))
data['day'] = data['tradeTime'].apply(lambda x: day(x))
# 去掉部分特征
data.drop('city', axis=1, inplace=True)
data.drop('tradeTime', axis=1, inplace=True)
data.drop('ID', axis=1, inplace=True)
return data
data_train = preprocessingData(data_train)
2.异常值处理
主要思路分析
针对area和tradeMoney两个维度处理:
针对tradeMoney,这里采用的是IsolationForest模型自动处理;
针对areahetotalFloor是主观+数据可视化的方式得到的结果。
2.1 tradeMoney
def IF_drop(train):
IForest = IsolationForest(contamination=0.01)
IForest.fit(train["tradeMoney"].values.reshape(-1,1))
y_pred = IForest.predict(train["tradeMoney"].values.reshape(-1,1))
drop_index = train.loc[y_pred==-1].index
print(drop_index)
train.drop(drop_index,inplace=True)
return train
data_train = IF_drop(data_train)
人为筛选不合常理的异常值
def dropData(train):
# 丢弃部分异常值
train = train[train.area <= 200]
train = train[(train.tradeMoney <=16000) & (train.tradeMoney >=700)]
train.drop(train[(train['totalFloor'] == 0)].index, inplace=True)
return train
#数据集异常值处理
data_train = dropData(data_train)
处理异常值后再次查看面积和租金分布图
plt.figure(figsize=(15,5))
sns.boxplot(data_train.area)
plt.show()
plt.figure(figsize=(15,5))
sns.boxplot(data_train.tradeMoney),
plt.show()
3深度清洗
针对每一个region的数据,对area和tradeMoney两个维度进行深度清洗。 采用主观+数据可视化的方式。
data = data_train.copy()
g= sns.lmplot('area','tradeMoney',hue='rentType',col='region', col_wrap=3,data=data,sharex=False, sharey=False,palette='husl',scatter_kws={
'alpha':0.3} )
plt.tight_layout(