为 Scikit-Learn 向量化 Pandas 数据框

Posted

技术标签:

【中文标题】为 Scikit-Learn 向量化 Pandas 数据框【英文标题】:Vectorizing a Pandas dataframe for Scikit-Learn 【发布时间】:2013-11-30 05:36:26 【问题描述】:

假设我在 Pandas 中有一个如下所示的数据框:

> my_dataframe

col1   col2
A      foo
B      bar
C      something
A      foo
A      bar
B      foo

其中行代表实例,列输入特征(不显示目标标签,但这将用于分类任务),即我试图用my_dataframe构建X

我怎样才能有效地使用例如矢量化它? DictVectorizer?

我是否需要先将 DataFrame 中的每个条目都转换为字典? (这就是上面链接中的示例中完成的方式)。有没有更有效的方法来做到这一点?

【问题讨论】:

【参考方案1】:

你绝对可以使用DictVectorizer。因为DictVectorizer 需要一个可迭代的dict 类对象,您可以执行以下操作:

from sklearn.base import TransformerMixin
from sklearn.pipeline import make_pipeline
from sklearn.feature_extraction import DictVectorizer


class RowIterator(TransformerMixin):
    """ Prepare dataframe for DictVectorizer """
    def fit(self, X, y=None):
        return self

    def transform(self, X):
        return (row for _, row in X.iterrows())


vectorizer = make_pipeline(RowIterator(), DictVectorizer())

# now you can use vectorizer as you might expect, e.g.
vectorizer.fit_transform(df)

【讨论】:

【参考方案2】:

您想从包含分类(或简单的字符串)的 pandas DataFrame 构建设计矩阵,最简单的方法是使用 patsy,这是一个复制和扩展 R 公式功能的库。

使用您的示例,转换将是:

import pandas as pd
import patsy

my_df = pd.DataFrame('col1':['A', 'B', 'C', 'A', 'A', 'B'], 
                      'col2':['foo', 'bar', 'something', 'foo', 'bar', 'foo'])

patsy.dmatrix('col1 + col2', data=my_df) # With added intercept
patsy.dmatrix('0 + col1 + col2', data=my_df) # Without added intercept

生成的设计矩阵只是带有一些额外信息的 NumPy 数组,可以直接在 scikit-learn 中使用。

添加截距的示例结果:

DesignMatrix with shape (6, 5)
  Intercept  col1[T.B]  col1[T.C]  col2[T.foo]  col2[T.something]
          1          0          0            1                  0
          1          1          0            0                  0
          1          0          1            0                  1
          1          0          0            1                  0
          1          0          0            0                  0
          1          1          0            1                  0
  Terms:
    'Intercept' (column 0)
    'col1' (columns 1:3)
    'col2' (columns 3:5)

请注意,patsy 试图通过将Abar 的效果合并到截距中来避免多重共线性。这样,例如,col1[T.B] 预测变量应该被解释为 B 与归类为 A 的观察相关的附加效果。

【讨论】:

【参考方案3】:

首先,我不知道您的示例数组中的哪些位置是特征,以及观察值在哪里。

其次,DictVectorizer 不保存数据,仅用于转换实用程序和元数据存储。转换后,它存储特征名称和映射。它返回一个 numpy 数组,用于进一步计算。 Numpy 数组(特征矩阵)大小等于features count x number of observations,其值等于观察的特征值。因此,如果您了解自己的观察结果和特征,则可以以任何其他方式创建此数组。

如果您希望 sklearn 为您执行此操作,则不必手动重建 dict,因为可以将 to_dict 应用于转置数据帧:

>>> df
  col1 col2
0    A  foo
1    B  bar
2    C  foo
3    A  bar
4    A  foo
5    B  bar
>>> df.T.to_dict().values()
['col2': 'foo', 'col1': 'A', 'col2': 'bar', 'col1': 'B', 'col2': 'foo', 'col1': 'C', 'col2': 'bar', 'col1': 'A', 'col2': 'foo', 'col1': 'A', 'col2': 'bar', 'col1': 'B']

自 scikit-learn 0.13.0(2014 年 1 月 3 日)以来,to_dict() 方法有一个新参数 'records',因此现在您可以简单地使用此方法而无需额外操作:

>>> df = pandas.DataFrame('col1': ['A', 'B', 'C', 'A', 'A', 'B'], 'col2': ['foo', 'bar', 'foo', 'bar', 'foo', 'bar'])
>>> df
  col1 col2
0    A  foo
1    B  bar
2    C  foo
3    A  bar
4    A  foo
5    B  bar
>>> df.to_dict('records')
['col2': 'foo', 'col1': 'A', 'col2': 'bar', 'col1': 'B', 'col2': 'foo', 'col1': 'C', 'col2': 'bar', 'col1': 'A', 'col2': 'foo', 'col1': 'A', 'col2': 'bar', 'col1': 'B']

【讨论】:

每一行是一个实例,即一个样本或观察值,每一列是一个特征类型。在上面的示例中,我有 6 个样本,每个样本都是二维的,即我的特征矩阵 X 的大小为 (6,2)。任务是对 X 中的每一列进行矢量化,因为它们包含文本条目并且不能直接输入到分类器或回归器中。 @user815423426 终于明白了。您可能想关注马特的回答或使用to_dict 来获取所需的字典(请参阅更新)【参考方案4】:

查看sklearn-pandas,它提供了您正在寻找的内容。对应的 Github repo 是here。

【讨论】:

假设我有 40 列,我只想对几列进行矢量化,并将其余列保留在 DataFrame 中,这样我就可以将生成的 numpy 矩阵直接提供给 scikit-learn .这在 sklearn-pandas 中可行吗?我的意思是 sklearn-pandas 很好,但是当我调用 mapper.transform() 时,它只给我转换后的列,而不是所有列以及转换后的列。 只需column_stack 将转换后的特征和原始特征放在一起。类似:np.column_stack([mapper.transform(train), train[['c1', 'c2', ...]].values]),其中npimport numpy as np 您也可以在 sklearn DataFrameMapper 中使用 None 作为转换器,用于您想要保持不变的列。

以上是关于为 Scikit-Learn 向量化 Pandas 数据框的主要内容,如果未能解决你的问题,请参考以下文章

向量化 pandas.DataFrame 的集成

scikit-learn,将特征添加到矢量化文档集

python - 如何在python scikit-learn中进行字典向量化后预测单个新样本?

pandas数组(pandas Series)-向量化运算

向量化 Pandas 数据帧

向量化前瞻性函数 pandas 数据框