菜鸡的学习之路^__^(自己学习,复习使用)
Task3:数据的特征工程(feature engineering)
将数据转换为更好滴表示潜在问题的特征,从而提高机器学习的性能。
下图是来自群里一位大佬整理的阿泽大佬直播的内容:(通过此图可以对特征工程有一个很完整的认识,膜拜·~~)
特征提取(feature extraction) | 特征创造(feature creation) | 特征选择(feature selection) |
---|---|---|
从文字,图像,声音等其他非结构化数据中提取新信息作为特征。比如说,从淘宝宝贝的名称中提取出产品类别,产品颜色,是否是网红产品等等。 | 把现有特征进行组合,或互相计算,得到新的特征。比如说,我们有一列特征是速度,一列特征是距离,我们就可以通过让两列相处,创造新的特征:通过距离所花的时间。 | 从所有的特征中,选择出有意义,对模型有帮助的特征,以避免必须将所有特征都导入模型去训练的情况。 |
常见的特征工程包括:
import numpy as np
import pandas as pd
import warnings
import os
from tqdm import tqdm
import lightgbm as lgb
import math
import matplotlib.pyplot as plt
import seaborn as sns
import gc
from datetime import datetime
project_path = os.path.dirname(os.path.abspath("__file__"))
# 设置动态路径
# 获取当前文件路径的上一级目录
warnings.filterwarnings('ignore')
pd.set_option('display.max_columns', None) # 设置DataFrame的输出显示,显示所有列
先把需要用到的库给导入进来,并设置好路径
df_train = pd.read_csv(project_path + r'\used_car_train_20200313.csv', sep=' ')
df_test = pd.read_csv(project_path + r'\used_car_testA_20200313.csv', sep=' ')
df_sub = pd.read_csv(project_path +r'\used_car_sample_submit.csv', sep=' ')
把数据也给弄进来
由于有了EDA的先验,就直接再在此基础上进行操作了。
df_feature = pd.concat([df_train, df_test], sort=False)
df_feature.haed()
df_feature['notRepairedDamage'] = df_feature['notRepairedDamage'].replace(
'-', 2)
df_feature['notRepairedDamage'] = df_feature['notRepairedDamage'].astype(
'float')
df_feature.tail(10)
这里我把 ‘notRepairedDamage’ 这一列特征中 ’ - '替换为2,即进行了缺失值处理,因为缺失值数目极少,我就不用1也不用0,防止主管因素造成错误。
del df_feature['seller']
del df_feature['offerType']
seller、offerType这两个特征可以删掉了,所有样本基本就一个取值,没什么用
# 数据平滑处理
df_feature['price'] = np.log1p(df_feature['price'])
# 计算count属性, 衡量热度信息
df_feature['name_count'] = df_feature.groupby(
['name'])['SaleID'].transform('count')
df_feature.head(10)
数据预处理时首先可以对偏度比较大的数据用np.log1p函数进行转化,使其更加服从高斯分布,此步处理可能会使我们后续的分类结果得到一个好的结果。
# 对日期格式进行转换,规范日期
def date_parse(x):
year = int(str(x)[:4])
month = int(str(x)[4:6])
day = int(str(x)[6:8])
if month < 1:
month = 1
date = datetime(year, month, day)
return date
df_feature['regDate'] = df_feature['regDate'].apply(date_parse)
df_feature['creatDate'] = df_feature['creatDate'].apply(date_parse)
# 对年份进行提取
df_feature['regDate_year'] = df_feature['regDate'].dt.year
对日期进行格式标准化,把汽车注册年份提取出来,并把不规范的日期进行处理,比如有些月份为0的,都给它搞为1。
df_feature['car_age_day'] = (df_feature['creatDate'] -
df_feature['regDate']).dt.days
df_feature['car_age_year'] = round(df_feature['car_age_day'] / 365, 1)
计算汽车从上市到注册的时间,并作相应提取。
# 简单统计
# group_by按行
# agg按列
def stat(df, df_merge, group_by, agg):
group = df.groupby(group_by).agg(agg)
columns = []
for on, methods in agg.items():
for method in methods:
columns.append('{}_{}_{}'.format('_'.join(group_by), on, method))
group.columns = columns
group.reset_index(inplace=True)
df_merge = df_merge.merge(group, on=group_by, how='left')
del (group)
gc.collect()
return df_merge
def statis_feat(df_know, df_unknow):
df_unknow = stat(df_know, df_unknow, ['model'], {'price': ['mean']})
df_unknow = stat(df_know, df_unknow, ['regionCode'], {'price': ['mean']})
df_unknow = stat(df_know, df_unknow, ['name'], {'price': ['mean']})
return df_unknow
分别按model、regionCode、name进行mean编码,其实就是所说的目标编码,我打算再多增加几个特征,目前只做了model、regionCode、name看看效果,后续会补充标准差编码、中位数编码,目前只搞了均值编码。
特征工程是比赛中最至关重要的的一块,特别的传统的比赛,大家的模型可能都差不多,调参带来的效果增幅是非常有限的,但特征工程的好坏往往会决定了最终的排名和成绩。
特征工程的主要目的还是在于将数据转换为能更好地表示潜在问题的特征,从而提高机器学习的性能。比如,异常值处理是为了去除噪声,填补缺失值可以加入先验知识等。
特征构造也属于特征工程的一部分,其目的是为了增强数据的表达。
有些比赛的特征是匿名特征,这导致我们并不清楚特征相互直接的关联性,这时我们就只有单纯基于特征进行处理,比如装箱,groupby,agg 等这样一些操作进行一些特征统计,此外还可以对特征进行进一步的 log,exp 等变换,或者对多个特征进行四则运算(如上面我们算出的使用时长),多项式组合等然后进行筛选。由于特性的匿名性其实限制了很多对于特征的处理,当然有些时候用 NN 去提取一些特征也会达到意想不到的良好效果。
对于知道特征含义(非匿名)的特征工程,特别是在工业类型比赛中,会基于信号处理,频域提取,丰度,偏度等构建更为有实际意义的特征,这就是结合背景的特征构建,在推荐系统中也是这样的,各种类型点击率统计,各时段统计,加用户属性的统计等等,这样一种特征构建往往要深入分析背后的业务逻辑或者说物理原理,从而才能更好的找到 magic。
当然特征工程其实是和模型结合在一起的,这就是为什么要为 LR NN 做分桶和特征归一化的原因,而对于特征的处理效果和特征重要性等往往要通过模型来验证。
Datawhale是一个专注于数据科学与AI领域的开源组织,汇集了众多领域院校和知名企业的优秀学习者,聚合了一群有开源精神和探索精神的团队成员。Datawhale 以“for the learner,和学习者一起成长”为愿景,鼓励真实地展现自我、开放包容、互信互助、敢于试错和勇于担当。同时 Datawhale 用开源的理念去探索开源内容、开源学习和开源方案,赋能人才培养,助力人才成长,建立起人与人,人与知识,人与企业和人与未来的联结。
在此特别感谢DataWhale提供的学习机会,为其开源精神点赞,希望自己能在自己的努力下不断进步,很幸运能遇到DataWhale这么优秀的平台。加油加油!!!!