机器学习基础-特征工程简析

在开始训练模型之前,我们需要对数据进行特征工程的操作,一个好的数据质量决定预测结果的上限,而好的模型只是无限逼近这个上限。
一个好的数据质量,应该满足“完全合一”

  • 完整性:数据是否存在空值,字段feature是否完善,是否有漏掉
  • 全面性:观察某一列的全部数值和特征值,是否存在单位、字段名与数值不匹配
  • 合法性:数据的类型、内容、大小的合法性
  • 唯一性:数据是否存在重复记录

以下是特征工程操作的一些常见步骤:

  • 建议将训练集和测试集concat到一起,方便后续操作。

  • 数据探索,观测数据与label之间的关系、数据的缺失值,异常值,数据分布等。

    data.info() #查看索引、数据类型和内存信息
    data.describe() #查看数值型列的汇总统计,返回计数、均值、标准差、最小最大值、25%50%75%分位数,percentiles0.05,0.95分位数
    data.unique() #快速查看数据列有哪些分类内容,类似groupby
    data.value_counts() #查看数据唯一值和计数
    df.corr() #返回行与列之间的相关系数,但是如果特征字段是object类型的,系统会略过识别不出来
    
    data.iloc[:] #数据索引切片
    data.loc[:] #数据索引名称切片
    
  • 对分类特征(文本特征等)、Label进行特征值编码 ==》OneHot Encoder / Label Encoder

    from sklearn.preprocessing import LabelEncoder
    le = LabelEncoder()
    data[feature] = le.fit_transform(data[[feature]]) #当对训练集进行fit_transform之后,对测试集只需要transform处理
    
    from sklearn.preprocessing import OneHotEncoder
    enc = OneHotEncoder()
    res = enc.fit_transform(data[[feature]]).toarray() #此处编码结果形式有些奇怪,最好将其转换为二维数组
    enc_feature = enc.get_feature_names() #获取onehot后的特征名称
    #取出编码后的结果和名称构造到data中
    for index,value in enumerate(enc_feature):
        data[value] = res[:,index]
    
  • 去除对结果影响不大的特征,或者噪点特征

    data.drop(columns = [useless_feature])
    
  • 除了树模型,在其他模型训练之前,需要对数据进行归一化 / 标准化处理

    from sklearn.preprocessing import StandardScaler #标准化处理
    stander = StandardScaler()
    X = stander.fit_transform(X)
    
  • 划分训练集和测试集

    #1.简单数据划分-简单快捷
    from sklearn.model_selection import train_test_split
    X_train,X_test,y_val,y_val = train_test_split(X,y,test_size = 0.3,random_state = 2021)
    
    #2.Kfold K折交叉验证-结果稳定,不会忽高忽低
    from sklearn.model_selection import KFold
    from sklearn.metrics import accuracy_score
    kf = KFold(n_split = '折的次数',random_state = ,shuffle = )
    score_list = []
    for train_index,val_index in kf.split(X):
        X_train,X_val = X[train_index],X[val_index]
        y_train,y_val = y[train_index],y[vall_index]
        model.fit(X_train,y_train) #每折叠划分一次,训练一次模型
        y_val_pred = model.predict(X_val) #每训练一次模型,做一次验证集的预测
        score = accuracy_score(y_val,y_val_pred) #每预测一次算一次分数
        score_list.append(score) #将每次预测分数放到一起
    res = np.mean(score_list) #将所有预测的分数做一次平均,得到最终的分数
    
  • 查看数据是否有缺失值或者异常值,用众数/平均数/中位数进行填充

    1. 对于数值特征 num_features,缺失值可以用中位数补全
    2. 对于类别特征 cat_features,缺失值可以用众数补全
    data.isnull().sum() #检查数据是否存在空值
    data.fillna(data[feature].median(),inplace=True) #填充缺失值-中位数
    data.fillna(data[feature].mode()[0],inplace=True) #填充缺失值-众数
    data.replace() #更改异常值
    
  • 如果是回归问题,可以通过条形图画出类别型特征与label之间的关系,并尝试将类别型特征与label做聚合交叉,针对不同的特征对label统计其最大,最小,平均值等等

    plt.bar(x,height,width) #画出特征与label的条形图,观察它们之间的关系
    
    #划分出类别型特征
    cat_columns = [c_1,c_2,c_3...]
    #遍历每个类别行特征,将其对应label的极大/小值、均值、std等等数据做个统计,并merge到data中作为新的特征
    for col in cat_columns:
        t = data.groupby(col,as_index = False)[label].agg({col+'_count':'count',col+'_label_max':'max',
                                                           col+'_label_median':'median',
             col+'_label_min':'min',col+'_label_sum':'sum',col+'_label_std':'std',col+'_label_mean':'mean'})
        data = data.merge(t,on = col,how = 'left')
    
  • 在匿名特征中,可以通过观察其与label之间的相关性,如果存在与label相关性很高的情况,可以将其两两之间做交叉组合

    data.corr() #观察不同特征与label之间的相关性
    '''
    通过高相关性的匿名特征之间做加减组合,构造新的匿名特征,查看效果
    '''
    
  • 对于时间特征,采用以下两种方法处理

    #1.划分时间多尺度,构造函数,将时间数据划分为单独的年、月、日的独立特征
    def func(x):
        #提取年月日
        year = int(str(x)[:])
        month = int(str(x)[:])
        day = int(str(x)[:])
        date = datetime(year,month,day)
        return date
    #2.将时间特征做时间差,构造新特征,一般时间差会与label存在一定线性关系
    data['diff_time'] = data['time_1'] - data['time_2']
    
  • 对于分类问题,不同类别特征,与label之间的关系,可以用sns.countplot()函数,以bar的形式展示每个类别的数量

    import matplotlib.pyplot as plt
    plt.figure(figsize = (20,16))
    sns.countplot(x = data['subGrade'],hue = data['isDefault'],ata = data)
    

在这里插入图片描述

  • 在特征训练过程中,可以将预处理好的数据进行临时保存,在下次进行处理时可以直接调用,无需再跑一次程序,从而节省时间。
#数据保存为pickle文件
data.to_pickle('./')

调用,读取pickle文件
import pickle
with open('./') as file:
	data = pickleload(file)
  • 在查看dataframe过程中,可能会遇到column数据被折叠的现象(即中间列数据被省略号替代),可以用以下方法进行操作。
import pandas as pd
pd.set_option('max_columns,None)
  • 在特征处理过程中,可以通过data.corr()指令查看特征之间得到相关性,如果特征之间的相关性很高>0.9(不包括label),应该考虑特征之间存在多重共线性,多重共线性会导致模型分析结果不稳定,使得本身是显著的特征变得不再显著。如果特征系数是正负相反,那么在计算过程会让两个特征的权重被抵消。
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr.Wiggles

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值