《特征工程入门与实践》--特征构建

我们会探讨如下主题:

  • 检查数据集;
  • 填充分类特征;
  • 编码分类变量;
  • 扩展数值特征;
  • 针对文本的特征构建。

《特征工程入门与实践》-特征构建

检查数据集

为了进行演示,本章会使用我们自己创建的数据集,以便展示不同的数据等级和类型。我们先设置数据的DataFrame。
用Pandas创建要使用的DataFrame,这也是Pandas的主要数据结构。这样做的优点是可以用很多属性和方法操作数据,从而对数据进行符合逻辑的操作,以深入了解我们使用的数据,以及如何最好地构建机器学习模型。
(1) 首先导入Pandas:

import pandas as pd

(2) 然后就可以设置DataFrame X了。我们用Pandas的DataFrame方法创建表格数据结构(带行和列的表格)。这个方法可以接受不同类型的数据(例如,NumPy数组和字典等)。在本例中,我们传入一个字典,其键是列标题、值是列表,每个列表代表一列:

X = pd.DataFrame({
'city':['tokyo', None, 'london', 'seattle', 'sanfrancisco','tokyo'],
'boolean':['yes', 'no', None, 'no', 'no', 'yes'],
'ordinal_column':['somewhat like', 'like', 'somewhat like', 'like',
                  'somewhat like', 'dislike'],
'quantitative_column':[1, 11, -.5, 10, None, 20]})
				  
print(X)

在这里插入图片描述

填充分类特征

利用Pandas DataFrame的isnull方法查看缺失值。这个方法返回一个布尔值对象,表示数据是否为空。然后调用sum方法查看哪列缺失数据:

X.isnull().sum()

boolean                1
city                   1
ordinal_column         0
quantitative_column    1
dtype: int64

可以看见,有3列存在缺失值。接下来当然要填充这些值。
scikit-learn的Imputer类,用于填充数值数据,有一个most_frequent方法可以用在定性数据上,但是只能处理整数型的分类数据。
我们要写一个自己的转换器,也就是一个填充每列缺失值的方法。这些转换器对转换数据帮助很大,而且可以进行Pandas和scikit-learn不支持的操作。

  • 对于数值数据,可以通过计算均值的方法填充缺失值;
  • 对于分类数据,我们也有类似的处理方法:计算出最常见的类别用于填充。

为此,需要找出定性列city列中最常见的类别。

注意,要对这个列使用value_counts方法。这样会返回一个对象,由高到低包含列中的各个元素——第一个元素就是最常出现的。

我们只需要对象中的第一个元素:

# 寻找city列中最常见的元素
X['city'].value_counts().index[0]

>>>>
'tokyo'

tokyo是最频繁出现的城市。我们知道了用tokyo来填充。fillna函数可以指定填充缺失值的方式:

# 用最常见的值填充city列
X['city'].fillna(X['city'].value_counts().index[0])

city列现在是这样的:
0            tokyo
1            tokyo
2           london
3          seattle
4    san francisco
5            tokyo
Name: city, dtype: object

对另一个列boolean依然存在缺失值。我们不再使用同样的方法,而是构建一个自定义填充器,用来处理分类数据的填充。

自定义填充器

回顾一下机器学习流水线:

  • 我们可以用流水线按顺序应用转换和最终的预测器;

  • 流水线的中间步骤只能是转换,这意味着它们必须实现fit和transform方法;

  • 最终的预测器只需要实现fit方法。

流水线的目的是将几个可以交叉验证的步骤组装在一起,并设置不同的参数。在为每个需要填充的列构建好自定义转换器后,就可以把它们传入流水线,一口气转换好数据。

自定义分类填充器

首先,用scikit-learn的TransformerMixin基类创建我们的自定义分类填充器。这个转换器会作为流水线的一环,实现fittransform方法。
代码仔细讲解:

from sklearn.base import TransformerMixin

#初始化这个自定义的类
class CustomCategoryImputer(TransformerMixin): 
    def __init__(self, cols=None): #__init__方法对属性进行了初始化
        self.cols = cols  #初始化一个实例属性self.cols(就是我们指定为参数的列)

    def transform(self, df):
        X = df.copy()
        for col in self.cols:     
		X[col].fillna(X[col].value_counts().index[0],inplace=True)
        return X

    def fit(self, *_):
        return self
  • 1.scikit-learn的TransformerMixin类,它包括一个.fit_transform方法,会调用我们创建的.fit.transform方法。这能让我们的转换器和scikit-learn的转换器保持结构一致。

  • 2.现在可以构建fit和transform方法了:

def transform(self, df):
        X = df.copy()
        for col in self.cols:    
		X[col].fillna(X[col].value_counts().index[0],inplace=True)
        return X
  • 3.上面是transform方法,它接收一个DataFrame。首先将这个DataFrame复制一份,命名为 X X X。然后遍历cols参数指定的列,填充缺失值。缺失值填充完毕后,返回DataFrame。然后是fit方法:
def fit(self, *_):
        return self

我们的fit方法只有return self一句话,和scikit-learn的标准.fit方法相同。

  • 4.有了自定义方法,可以填充分类数据了!我们在两列分类数据city和boolean上试验:
# 在列上应用自定义分类填充器

cci = CustomCategoryImputer(cols=['city', 'boolean'])
  • 5 我们初始化了一个自定义分类填充器,现在需要在数据集上调用fit_transform函数:
cci.fit_transform(X)

在这里插入图片描述

自定义定量填充器

我们使用的结构和自定义分类填充器类似。主要的区别在于,此处用scikit-learn的Imputer类实现一个自定义的转换器,对列进行转换

# 按名称对列进行转换的填充器

from sklearn.preprocessing import Imputer
class CustomQuantitativeImputer(TransformerMixin):
    def __init__(self, cols=None, strategy='mean'):
        self.cols = cols
        self.strategy = strategy

    def transform(self, df):
        X = df.copy()
        impute = Imputer(strategy=self.strategy)
        for col in self.cols:
            X[col] = impute.fit_transform(X[[col]])
        return X

    def fit(self, *_):
        return self

对于CustomQuantitativeImputer,我们添加了一个strategy参数,指定如何填充定量数据里的缺失值。这里用均值填充缺失值,依然使用transform和fit方法。
还是用fit_transform函数填充数据,这次我们指定要填充的列和strategy:

cqi = CustomQuantitativeImputer(cols=['quantitative_column'],
strategy='mean')

cqi.fit_transform(X)

也可以不分别调用并用fit_transform拟合转换CustomCategoryImputerCustomQuantitativeImputer,而是把它们放在流水线中。方法如下所示。
(1) 写import语句:

# 从sklearn导入Pipeline
from sklearn.pipeline import Pipeline

(2) 导入自定义填充器:

imputer = Pipeline([('quant', cqi), ('category', cci)])
imputer.fit_transform(X)

在这里插入图片描述

编码分类变量

定类等级的编码

主要方法是将分类数据转换为虚拟变量(dummy variable),有两种选择:

  • 用Pandas自动找到分类变量并进行编码;
  • 创建自定义虚拟变量编码器,在流水线中工作。

在深入探讨之前,我们先研究一下什么是虚拟变量。
虚拟变量的取值是1或0,代表某个类别的有无。虚拟变量是定性数据的代理,或者说是数值的替代。
考虑一个简单的工资回归分析问题。假设给定了性别(定性数据)和工龄(定量数据)。为了考察性别对工资的影响,我们用虚拟变量:female = 0代表男性,female = 1代表女性。

当使用虚拟变量时,需要小心虚拟变量陷阱。虚拟变量陷阱的意思是,自变量有多重共线性或高度相关。简单地说,这些变量能依据彼此来预测。在这个例子中,如果设置female和male两个虚拟变量,它们都可以取值为1或0,那么就出现了重复的类别,陷入了虚拟变量陷阱。我们可以直接推断female = 0代表男性。
为了避免虚拟变量陷阱,我们需要忽略一个常量或者虚拟类别。被忽略的虚拟变量可以作为基础类别,和其他变量进行比较。
回到数据集中,用第一种选择将分类数据编码成虚拟变量。Pandas有个很方便的get_dummies方法,可以找到所有的分类变量,并将其转换为虚拟变量:

pd.get_dummies(X, 
     columns = ['city', 'boolean'],  # 要虚拟化的列
     prefix_sep='__')  # 前缀(列名)和单元格值之间的分隔符

我们必须指定需要应用虚拟化的列,因为Pandas也会编码定序等级的列,这就没有意义了。
进行虚拟变量编码后,我们的数据如下表所示。

在这里插入图片描述

另一种选择是创建一个自定义虚拟化器,从而在流水线中一口气转换整个数据集。

再次使用之前两个自定义填充器的结构。在这里,我们的transform方法会利用Pandas的get_dummies方法,为指定的列创建虚拟变量。该自定义虚拟化器中唯一的参数是cols:

# 自定义虚拟变量编码器
class CustomDummifier(TransformerMixin):
    def __init__(self, cols&#
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值