4个超棒技巧,帮你搞定数据预处理与特征工程

222 阅读7分钟

全文共4514字,预计学习时长9分钟

开发机器学习模型最重要的两个步骤就是特征工程和预处理。特征工程包括特征的设计,而预处理则涉及数据清理。

我们经常花费大量时间,对数据进行精加工以用于建模。为使这一过程更加高效,本文将分享4个技巧,帮助你进行特征设计与预处理。

这些技巧可用于创建新特征、检测异常值、处理不平衡数据以及估算缺失值。

领域知识可能是设计特征期间最重要的几件事情之一。更好地了解你使用的特征,可以防止出现欠拟合和过拟合的情况。

1. 重新采样不平衡数据

实际上,你经常会遇到不平衡的数据。如果你的目标只是轻微的不平衡,那么这种不平衡当然不成问题。使用合适方式,例如平衡精确度、Precision-Recall 曲线或F1分数验证数据,就可解决这一问题。

不幸的是,情况并非总是如此,你的目标变量可能非常不平衡(例如,10:1)。那么,你可以对少数目标进行过采样,使用被称为SMOTE的技术引入平衡。

SMOTE

SMOTE全称为Synthetic Minority Oversampling Technique,是一种过采样技术,用于增加少数类的样本。

通过查看目标的特征空间、检测相邻目标,它能生成新样本。然后,仅选择相似样本,在相邻样本的特征空间内随机改变一列。

实现SMOTE的模块位于imbalanced-learn 文件夹中。你只需导入文件夹,应用fit_transform即可:

import pandas as pd
from imblearn.over_sampling import SMOTE

# Import data and create X, y
df = pd.read_csv('creditcard_small.csv')
X = df.iloc[:,:-1]
y = df.iloc[:,-1].map({1:'Fraud', 0:'No Fraud'})

# Resample data
X_resampled, y_resampled = SMOTE(sampling_strategy=
{"Fraud":1000}).fit_resample(X, y)
X_resampled = pd.DataFrame(X_resampled, columns=X.columns)
Original data (LEFT) versus oversampled data (RIGHT).

如图所示,模型成功地对目标变量进行了过采样。使用SMOTE进行过采样时,可以采取以下几种策略:

· 'minority': 仅对少数类重新采样;

· 'not minority': 对少数类之外的所有类重新采样;

· 'not majority': 对多数类之外的所有类重新采样;

· 'all': 对所有类重新采样;

· 输入dict时, 键对应于目标类,这些值对应于每个目标类所需的样本数。

我们选择使用词典,确定对数据进行过采样的程度。

附加提示1:如果数据集中有分类变量,SMOTE可能会为那些不可能发生的变量创建值。例如,如果你有一个名为isMale的变量,只能取0或1,那么SMOTE可能会创建0.365作为一个值。

此外,你可使用考虑了分类变量性质的SMOTENC。此版本也可在imbalanced-learn文件夹中使用。

附加提示2:确保在创建训练/测试分割后进行过采样,以便仅对训练数据进行过采样。你通常不希望在合成数据上测试模型。

2. 创建新特征

为提高模型的质量和预测能力,通常会创建现有变量的新特征。我们可以在每对变量间创建一些交互(例如,乘法或除法),寻找有趣的新特征。然而,这需要进行大量的编码,是一个漫长的过程。幸运的是,Deep Feature Synthesis可自动完成上述过程。

Deep Feature Synthesis

Deep Feature Synthesis(DFS)是一种算法,可快速创建具有不同深度的新变量。例如,可以将列对相乘,也可以选择先将列A与列B相乘,然后再加上列C.

首先介绍一下用于示例的数据。本文选择使用人力资源分析数据,因为其特征易于理解:

仅凭借直觉,我们可识别被number_project 区分的average_monthly_hours,作为一个有趣新变量。然而,如果只遵循直觉,我们可能会错过更多关系。

该软件包确实需要对实体使用有所了解。但是,如果使用单个表格,则只需按照以下代码操作即可:

import featuretools as ft
import pandas as pd

# Create Entity
turnover_df = pd.read_csv('turnover.csv')
es = ft.EntitySet(id = 'Turnover')
es.entity_from_dataframe(entity_id = 'hr', dataframe =
 turnover_df, index = 'index')

# Run deep feature synthesis with transformation primitives
feature_matrix, feature_defs = ft.dfs(entityset = es, target_entity =
 'hr', 
                             trans_primitives = ['add_numeric',
 'multiply_numeric'],

第一步是创建一个entity,必要时可与其他表建立关系。接下来,可以仅运行ft.dfs,创建新变量。使用参数trans_primitives确定创建变量的方式。选择将数值变量相加或相乘。

The output of DFS if verbose = True

正如如上图所示,仅用几行代码就创建了额外668个特征。特征创建的一些示例:

· last_evaluation 乘以satisfaction_level

· left 乘以 promotion_last_5years

· average_monthly_hours 乘以 satisfaction_level 加上 time_spend_company

附加提示1:请注意,此处行为相对基础。DFS的优点在于可从表之间的合并创建新变量(例如,事实和维度)。

附加提示2:运行ft.list_primitives()查看可以执行的完整合并列表。甚至可以处理时间戳、空值和long/lat信息。

3. 处理缺失值

同样,没有处理缺失值的最佳方法。仅使用某些组的均值或模式对数据进行填充就足够了。但是,有一些先进技术可使用已知的部分数据估算缺失值。

有一种这样的方法称为IterativeImputer,是基于流行的R算法输入缺失变量(MICE)的Scikit-Learn中的一个新软件包。

Iterative Imputer

虽然python是开发机器学习模型的一种很好的语言,但是仍然有很多其他方法在R中表现得更好。例如,R中完善的插补包:missForest、mi、mice等。

Iterative Imputer由Scikit-Learn开发,根据其他功能对缺失值的每个特征进行建模。它使用它作为估算的估算。在每个步骤中,选择一个特征作为输出y,并将所有其他特征视为输入X,然后在X和y上拟合回归量,用于预测y的缺失值。根据每个特征完成以上步骤。

看一个例子。使用的数据是众所周知的泰坦尼克号数据集。在此数据集中,列Age包含需要填充的缺失值。代码一如既往地简单明了:

# explicitly require this experimental feature
# now you can import normally from sklearn.impute
from sklearn.experimental import enable_iterative_imputer
  from sklearn.impute import IterativeImputer

from sklearn.ensemble import RandomForestRegressor
import pandas as pd

# Load data
titanic = pd.read_csv("titanic.csv")
titanic = titanic.loc[:, ['Pclass', 'Age', 'SibSp', 'Parch', 'Fare']]

这种方法的优点在于允许你使用所选的估算器。使用RandomForestRegressor模拟R中常用的missForest。

附加提示1:如果数据充足,那么仅删除缺失值数据的样本可能是个很有吸引力的选择。但是,请记住,这可能会在数据中产生偏差。也许缺失数据遵循的是你错过的模式。

附加提示2:Iterative Imputer允许使用不同估算器。经过测试,我们发现甚至可以使用Catboost作为估算器!不幸的是,由于随机状态名称不同,LightGBM和XGBoost不起作用。

4. Outlier Detection

如果不能很好地理解数据,就很难检测到异常值。如果可以很好地了解数据,则可以更轻松地确定使数据仍有意义的阈值。

有时这是不可能的,因为难以实现对数据的完美理解。相反,你可以使用异常检测算法,例如流行的Isolation Forest。

Isolation Forest

在Isolation Forest算法中,关键词是Isolation。实质上,该算法检查样本的分离容易程度。这会产生隔离数,其通过隔离样本所需的随机决策树中的分裂数进行计算,然后在所有树上对该隔离数进行平均。

Isolation Forest Procedure. Retrieved from: https://donghwa-kim.github.io/iforest.html

如果算法只需要进行一些拆分查找样本,那么它更可能成为异常值。分裂本身也是随机分割的,因此会产生较短的异常路径。因此,当所有树木的隔离数较低时,该样本很可能是异常值。

为显示示例,我们再次使用了之前使用过的信用卡数据集:

from sklearn.ensemble import IsolationForest
import pandas as pd
import seaborn as sns

# Predict and visualize outliers
credit_card = pd.read_csv('creditcard_small.csv').drop("Class", 1)
clf = IsolationForest(contamination=0.01, behaviour='new')
outliers = clf.fit_predict(credit_card)
sns.scatterplot(credit_card.V4, credit_card.V2, outliers,
 palette='Set1', legend=False)


附加提示1:隔离森林有一个扩展版本,可改善缺点。但评论不一。

带代码的笔记本:https://github.com/MaartenGr/feature-engineering/blob/master/Engineering%20Tips.ipynb

留言 点赞 关注

我们一起分享AI学习与发展的干货
欢迎关注全平台AI垂类自媒体 “读芯术”


(添加小编微信:dxsxbb,加入读者圈,一起讨论最新鲜的人工智能科技哦~)