缺失值补全和变换
1、首先导入数据,然后进行变量的类型处理
df_tr = train.drop('Id',axis=1)
df_X = df_tr.drop('SalePrice',axis=1)
df_y = df_tr['SalePrice']
quantity = [attr for attr in df_X.columns if df_X.dtypes[attr] != 'object'] # 数值变量集合
quality = [attr for attr in df_X.columns if df_X.dtypes[attr] == 'object'] # 类型变量集合
for c in quality: # 类型变量缺失值补全
df_tr[c] = df_tr[c].astype('category')
if df_tr[c].isnull().any():
df_tr[c] = df_tr[c].cat.add_categories(['MISSING'])
df_tr[c] = df_tr[c].fillna('MISSING')
# 连续变量缺失值补全
quantity_miss_cal = df_tr[quantity].isnull().sum().sort_values(ascending=False) # 缺失量均在总数据量的10%以下
missing_cols = quantity_miss_cal[quantity_miss_cal>0].index
df_tr[missing_cols] = df_tr[missing_cols].fillna(0.) # 从这些变量的意义来看,缺失值很可能是取 0
df_tr[missing_cols].isnull().sum() # 验证缺失值是否都已补全
2、对于离散变量,我们可以进行一元方差分析,获得各个离散变量对房价方差的影响:
# 一元方差分析(类型变量)
from scipy import stats
def anova(frame, qualitative):
anv = pd.DataFrame()
anv['feature'] = qualitative
pvals = []
for c in qualitative:
samples = []
for cls in frame[c].unique():
s = frame[frame[c] == cls]['SalePrice'].values
samples.append(s) # 某特征下不同取值对应的房价组合形成二维列表
pval = stats.f_oneway(*samples)[1] # 一元方差分析得到 F,P,要的是 P,P越小,对方差的影响越大。
pvals.append(pval)
anv['pval'] = pvals
return anv.sort_values('pval')
a = anova(df_tr,quality)
a['disparity'] = np.log(1./a['pval'].values) # 悬殊度
fig, ax = plt.subplots(figsize=(16,8))
sns.barplot(data=a, x='feature', y='disparity')
x=plt.xticks(rotation=90)
plt.show()
3、由上图示分析可见,不少离散变量的具体取值对最终房价会产生较大影响(例如Neighborhood这个变量,实际上暗含了地段这个影响房价的重要因素),因此,我们可以按照各离散变量相应取值下房价的均值来给各个取值划定一个1,2,3,4来定量描述他们对房价的影响,也就是将离散变量转化为数值型的有序变量
def encode(frame, feature):
'''
对所有类型变量,依照各个类型变量的不同取值对应的样本集内房价的均值,按照房价均值高低
对此变量的当前取值确定其相对数值1,2,3,4等等,相当于对类型变量赋值使其成为连续变量。
此方法采用了与One-Hot编码不同的方法来处理离散数据,值得学习
注意:此函数会直接在原frame的DataFrame内创建新的一列来存放feature编码后的值。
'''
ordering = pd.DataFrame()
ordering['val'] = frame[feature].unique()
ordering.index = ordering.val
ordering['price_mean'] = frame[[feature, 'SalePrice']].groupby(feature).mean()['SalePrice']
# 上述 groupby()操作可以将某一feature下同一取值的数据整个到一起,结合mean()可以直接得到该特征不同取值的房价均值
ordering = ordering.sort_values('price_mean')
ordering['order'] = range(1, ordering.shape[0]+1)
ordering = ordering['order'].to_dict()
for attr_v, score in ordering.items():
# e.g. qualitative[2]: {'Grvl': 1, 'MISSING': 3, 'Pave': 2}
frame.loc[frame[feature] == attr_v, feature+'_E'] = score
quality_encoded = []
# 由于qualitative集合中包含了非数值型变量和伪数值型变量(多为评分、等级等,其取值为1,2,3,4等等)两类
# 因此只需要对非数值型变量进行encode()处理。
# 如果采用One-Hot编码,则整个qualitative的特征都要进行pd,get_dummies()处理
for q in quality:
encode(df_tr, q)
quality_encoded.append(q+'_E')
df_tr.drop(quality, axis=1, inplace=True) # 离散变量已经有了编码后的新变量,因此删去原变量
# df_tr.shape = (1460, 80)
print(quality_encoded, '\n{} qualitative attributes have been encoded.'.format(len(quality_encoded)))
这里大部分参考https://blog.csdn.net/qilixuening/article/details/75153131