自动特征工程工具包

1、Featuretools

1.1 Featuretools介绍

Featuretools使用一种称为深度特征合成(Deep Feature Synthesis,DFS)的算法,该算法遍历通过关系数据库的模式描述的关系路径。当DFS遍历这些路径时,它通过应用于数据的操作(包括和、平均值和计数)生成综合特征。例如,对来自给定字段client_id的事务列表应用sum操作,并将这些事务聚合到一个列中。尽管这是一个深度操作,但该算法可以遍历更深层的特征。Featuretools最大的优点是其可靠性和处理信息泄漏的能力,同时可以用来对时间序列数据进行处理。
Featuretools是一个用于执行自动特征工程的开源库,旨在快速推进特征生成过程,从而有更多时间专注于机器学习模型构建的其他方面。

在使用Featuretools之前,我们要了解这个库的三个主要组件:

  • 实体Entities

  • 深度特征合成Deep Feature Synthesis

  • 特征基元Feature primitives

实体可看作是Pandas中数据帧的表征,多个实体的集合称为实体集Entityset。

深度特征合成(DFS)与深度学习无关。作为一种特征工程方法,它实际上是Featuretools库的核心。它支持从单个数据帧和多个数据帧中创建新特征。

DFS通过把特征基元应用于实体集中的实体关系来创建特征。这些基元经常被用来手动生成特征,比如,基元“mean”可在聚合级别找到变量均值。

1.2Featuretools实现

BigMart Sales数据集面临的挑战是建立一个预测模型来估算某个商店中每种产品的销售额。这将有助于BigMart决策者寻找每个产品或商店的特性,这对提高整体销售额起着关键作用。在给定数据集中,包括10个商店中的1559种产品。

下表给出了数据中提供的特征:

数据集下载地址:
https://datahack.analyticsvidhya.com/contest/practice-problem-big-mart-sales-iii/

1.2.1 安装

Featuretools适用于Python 2.7、3.5和3.6,可使用pip命令快速安装Featuretools。

pip install featurePython

1.2.2加载外部库和数据

import featuretools as ft 
import numpy as np 
import pandas as pd 
train = pd.read_csv("Train_UWu5bXk.csv") 
test = pd.read_csv("Test_u94Q5KV.csv")

1.2.3准备数据

首先,我们把目标Item_Outlet_Sales存储到sales变量,把test_Item_Identifier和test_Outlet_Identifier存储到id变量。

# saving identifiers 
test_Item_Identifier = test['Item_Identifier'] 
test_Outlet_Identifier = test['Outlet_Identifier'] 
sales = train['Item_Outlet_Sales'] 
train.drop(['Item_Outlet_Sales'], axis=1, inplace=True)

然后,组合训练集和测试集,这样省去两次执行相同步骤的麻烦。

combi = train.append(test, ignore_index=True)

接着,检查数据集中的缺失值。

combi.isnull().sum()

变量Item_Weight和Outlet_size中有相当多缺失值,用下面方法快速处理:

# imputing missing data 
combi['Item_Weight'].fillna(combi['Item_Weight'].mean(), 
                            inplace = True) 
combi['Outlet_Size'].fillna("missing", inplace = True)

1.2.4数据预处理

这里不会涉及过多预处理操作,因为本文的主要目的是介绍Featuretools。

combi['Item_Fat_Content'].value_counts()

Item_Fat_Content似乎只包含两个类别,即“低脂”和“常规”,未涉及到“冗余”类别,所以我们把它转换成二进制变量。

# dictionary to replace the categories 
fat_content_dict = {'Low Fat':0, 'Regular':1, 'LF':0, 'reg':1, 
                    'low fat':0} 
combi['Item_Fat_Content'] = combi['Item_Fat_Content'].replace(   
                            fat_content_dict, regex=True)

1.2.5使用Featuretools执行特征工程

在这节,我们要使用Featuretools来执行自动特征工程。

对于数据集,必须具有唯一标识符特征,但是我们的数据集目前还没有。因此,我们要为这个组合数据集创建唯一ID。你可能会注意到,数据集中有两个ID,一个用于item,另一个用于outlet。因此,对这两者简单相加会得到一个唯一ID。

combi['id'] = combi['Item_Identifier'] + combi['Outlet_Identifier'] 
combi.drop(['Item_Identifier'], axis=1, inplace=True)

要注意,由于不再需要,我删除了特征Item_Identifier。但是,我保留了特征Outlet_Identifier,因为我稍后还要用到它。

接着,我们要创建一个实体集EntitySet。实体集是一种包含多个数据帧及其之间关系的结构。那么,我们创建一个EntitySet并添加数据帧组合。

# creating and entity set 'es' 
es = ft.EntitySet(id = 'sales') 
# adding a dataframe 
es.entity_from_dataframe(entity_id = 'bigmart', 
                         dataframe = combi, 
                         index = 'id')

我们数据中包含两个级别的信息,即 item级别和 outlet级别。Featuretools能把一个数据集拆分成多个表格。我们根据outlet ID Outlet_Identifier从BigMart表中创建一个新表“outlet”。

es.normalize_entity(base_entity_id='bigmart', 
                    new_entity_id='outlet', 
                    index = 'Outlet_Identifier', 
                    additional_variables =   
                    ['Outlet_Establishment_Year', 'Outlet_Size',  
                     'Outlet_Location_Type', 'Outlet_Type'])

下面打印出实体集EntitySet的组成。

print(es)

如上所示,它包含两个实体,为bigmart和outlet。这两个表之间也形成了一种关系,用Outlet_Identifier连接。这种关系将在生成新特征中发挥关键作用。

现在我们要使用DFS来自动创建新特征。上面提到,DFS使用特征基元和实体集中给出的多个表来创建特征。

feature_matrix, feature_names = ft.dfs(entityset=es, 
                                       target_entity = 'bigmart', 
                                       max_depth = 2, 
                                       verbose = 1, 
                                       n_jobs = 3)

target_entity只是创建新特征的实体ID,这种情况下为实体“bigmart”。参数max_depth控制着通过堆叠基元生成的要素复杂性。参数n_jobs通过使用多个内核来辅助并行特征计算。

这就是使用Featuretools的过程,它已经产生了许多新特征。

来看下这些新创建的特征。

feature_matrix.columns

DFS在这么短的时间内创建了29个新特征,而手动操作需要更长时间。如果数据集包含多个相互关联的表,Featuretools仍然有效。在这种情况下,你不必对表进行标准化,因为多个表已经可用。

下面打印出feature_matrix的前几行。

feature_matrix.head()

这个数据帧存在一个问题,即未正确排序。我们必须根据combi数据帧中的id变量对其进行排序。

feature_matrix = feature_matrix.reindex(index=combi['id']) feature_matrix = feature_matrix.reset_index()

现在,数据帧feature_matrix已正确排序。

1.2.6 构建模型

现在该验证这些生成特征的效果了。我们将使用它们来构建模型并预测Item_Outlet_Sales值。由于最终数据feature_matrix具有多个分类特征,因此我决定使用CatBoost算法。它可以直接使用分类特征,并且本质上是可扩展的。有关CatBoost的更多内容可阅读这篇文章:
https://www.analyticsvidhya.com/blog/2017/08/catboost-automated-categorical-data/。

from catboost import CatBoostRegressor

CatBoost要求所有分类变量都使用字符串格式。因此,我们首先将数据中的分类变量转换为字符串:

categorical_features = np.where(feature_matrix.dtypes =='object')[0] 
for i in categorical_features: 
    feature_matrix.iloc[:,i]=feature_matrix.iloc[:,i].astype('str')

接着把feature_matrix分解为训练集和测试集。

feature_matrix.drop(['id'], axis=1, inplace=True) 
train = feature_matrix[:8523] 
test = feature_matrix[8523:]
# removing uneccesary variables 
train.drop(['Outlet_Identifier'], axis=1, inplace=True) test.drop(['Outlet_Identifier'], axis=1, inplace=True)
# identifying categorical features categorical_features = np.where(train.dtypes == 'object')[0]

然后把训练数据拆分为训练和验证集,并本地验证模型性能。

from sklearn.model_selection import train_test_split 
# splitting train data into training and validation set 
xtrain, xvalid, ytrain, yvalid = train_test_split(train, sales, 
                                                  test_size=0.25, 
                                                  random_state=11)

最后,训练模型时,我们使用的评估指标是RMSE(均方根误差)。

model_cat = CatBoostRegressor(iterations=100, learning_rate=0.3, 
                              depth=6, eval_metric='RMSE',  
                              random_seed=7) 
# training model 
model_cat.fit(xtrain, ytrain, cat_features=categorical_features, 
              use_best_model=True)
# validation score 
model_cat.score(xvalid, yvalid)

训练完成后,模型在验证集上的RMSE值大约为1092.24。

这个模型在公共排行榜上的得分为1155.12。在没有任何特征工程的情况下,在验证集和公共排行榜上的得分大约分别为1103和1183。因此,Featuretools创建的特征不只是随机特征,它们非常有价值和有效果。最重要的是,它在特征工程中节省的时间是令人难以置信的。

1.3 Featuretools可解释性

让数据科学模型具有可解释性是执行机器学习中一个很重要的方面。Featuretools生成的特征甚至能很容易地解释给非技术人员,因为它们是基于容易理解的基元构建的。

例如,特征outlet.SUM(bigmart.Item_Weight)和outlet.STD(bigmart.Item_MRP)分别表示items中权重的outlet级总和和items中成本的标准偏差。

这使得那些不是机器学习专家的使用者能够在他们的专业领域中理解和应用这个方法。

2、Boruta

Boruta主要是用来进行特征选择。所以严格意义上,Boruta并不是我们所需要的自动化特征工程包。

Boruta-py是brouta特征约简策略的一种实现,在该策略中,问题以一种完全相关的方式构建,算法保留对模型有显著贡献的所有特征。这与许多特征约简算法所应用的最小最优特征集相反。boruta方法通过创建由目标特征的随机重排序值组成的合成特征来确定特征的重要性,然后在原始特征集的基础上训练一个简单的基于树的分类器,在这个分类器中,目标特征被合成特征所替代。所有特性的性能差异用于计算相对重要性。

Boruta函数通过循环的方式评价各变量的重要性,在每一轮迭代中,对原始变量和影子变量进行重要性比较。如果原始变量的重要性显著高于影子变量的重要性,则认为该原始变量是重要的;如果原始变量的重要性明显低于影子变量的重要性,则认为该原始变量是不重要的。其中,原始变量就是我们输入的要进行特征选择的变量;影子变量就是根据原始变量生成的变量

生成规则是:

先向原始变量中加入随机干扰项,这样得到的是扩展后的变量
从扩展后的变量中进行抽样,得到影子变量

3、tsfresh

tsfresh是基于可伸缩假设检验的时间序列特征提取工具。该包包含多种特征提取方法和鲁棒特征选择算法。

tsfresh可以自动地从时间序列中提取100多个特征。这些特征描述了时间序列的基本特征,如峰值数量、平均值或最大值,或更复杂的特征,如时间反转对称性统计量等。

posted @ 2019-10-30 11:50  0-1-world  阅读(1200)  评论(0编辑  收藏  举报