关于特征工程
在数据的预处理中经常会遇到特征工程,这里做一下笔记。
数据的拼接
特征工程最好针对所有数据,也就是训练集和测试集都要进行特征工程的处理,因此第一步可以是将两个数据集拼接,注意要处理好index的关系。
可以使用pandas的concat函数,如
all_data=pd.concat((train,test)).reset_index(drop=True)#如果没有reset_index(),那么两个数据集的index无法串行下去
拼接完后去掉train数据集中的标签值,因为这一项我们不做处理,用drop()即可
缺失值处理
首先计算缺失值的占比,可以用数字表示,也可以进一步用柱状图等表示
这时可以使用热图对数据的相关性进行查看
查到有缺失的特征后,就要对其进行编辑
在这里,有的特征需要用0或者其他数据(如中位数、众数等)进行填充,有的就需要用None等进行填充,这一般取决于特征原有数据的类型。
处理完后要在检验一下缺失值占比,确保已经没有缺失值了。
数据类型转换
有的数据需要进行类型的转换,比如表示楼层的数字是数值型变量或者房子售出的时间(年份、月份),但是我们有时候需要将它置为字符型,这需要具体分析
另外,有的文本型数据需要转换为数值型数据,作为标签标注,比如,街区特征里由五个项,那么我们就可以用1~5表示,在这里我们可以这样操作:
from sklearn.preprocessing import LableEncoder
lbl=LabelEncoder()
lbl.fit(list(all_data['Streets'].values))
all_data['streets']=lbl.transform(list(all_data['streets'].values))
组合构建一些新的特征
有时候一些特征组合起来是一个不错的选择,比如,将每一层的面积加起来作为新的特征‘总面积’
偏度和峰度的计算
我们一般都期望数据的分布 符合正态,但是有时候实际得到的数据不是这样的。
首先我们检查数值型特征数据的偏度(skewness),但是要注意,object类型的数据无法计算skewness,因此计算的时候要过滤掉object数据。
对于偏度过大的特征数据利用sklearn的box-cox转换函数,以降低数据的偏度,如下:
numerical_feats=all_data.dtypes[all_data.dtype !='object'].index#排除object类型的特征
skewed_feats=all_data[numerical_feats].apply(lambda x: skew(x.dropna())).sort_values(ascending=False)#解算偏度
skewness=pd.DataFrame({'Skew' :skewed_feats})#数据类型转换
skewness =skewness[abs(skewness)>0.75]#选择偏度大于0.75的特征
print('there are {} skewed numerical features to box cox transform'.format(skewness.shape[0]))
from scipy.special import boxcox1p
skewed_features=skewness.index
lam=0.15
for feat in skewed_features:
all_data[feat]=boxcox1p(all_data[feat],lam)#boxcox1p对数据进行转化
注意一点:一定注意all_data的有效index,随时明确是在对哪些数据进行操作。
one-hot编码
离散的特征数据一般无法直接在算法中使用,因此要对其进行编码,通常使用one-hot编码。假设出生地这个特征有三个取值,北京、天津、上海,那么经过one-hot编码后,出生地这个特征会被三个新特征代替,出生地-北京、出生地-天津、出生地-上海,一行数据对应的这三个特征的取值是001或010或100.代码如下:
all_data=pd.get_dummies(all_data)
注意,经过one-hot编码后,会多出许多列数据,这时重新编码后的新的特征。
新的数据集
最后,不要忘记将训练集和测试集从all_data里分开。整个数据的处理过程不要打乱数据的顺序。