如何从管道中的 sklearn TFIDF Vectorizer 返回数据帧?

Posted

技术标签:

【中文标题】如何从管道中的 sklearn TFIDF Vectorizer 返回数据帧?【英文标题】:How to return a dataframe from sklearn TFIDF Vectorizer within pipeline? 【发布时间】:2019-03-16 11:31:50 【问题描述】:

如何让 TFIDF Vectorizer 在用于交叉验证的 sklearn 管道中返回具有相应列名的 pandas 数据帧?

我有一个 Sklearn 管道,其中一个步骤是 TFIDF 矢量化器:

class InspectPipeline(BaseEstimator, TransformerMixin):

    def transform(self, x):
        return x

    def fit(self, x, y=None):
        self.df = x
        return self


pipeline = Pipeline(
        [
         ("selector", ItemSelector(key="text_column")),
         ("vectorizer", TfidfVectorizer()),
         ("debug", InspectPipeline()),
         ("classifier", RandomForestClassifier())
        ]
)

我创建了InspectPipeline 类,以便稍后检查传递给分类器的特征是什么(通过运行pipeline.best_estimator_.named_steps['debug'].df)。但是, TfidfVectorizer 返回一个稀疏矩阵,这是我在执行 pipeline.best_estimator_.named_steps['debug'].df 时得到的。我不想获得稀疏矩阵,而是将 TFIDF 向量作为 pandas 数据框,其中列名是相应的 tfidf 标记。

我知道tfidf_vectorizer.get_feature_names() 可以帮助了解列名。但是如何在管道中包含这个 + 将稀疏矩阵转换为数据帧?

【问题讨论】:

稀疏矩阵的密集版本是否足够小以适合内存? 是的@swhat,我有足够的内存来适应矩阵的密集版本。我的问题是如何在管道内进行转换 【参考方案1】:

您可以扩展 TfidfVectorizer 以返回具有所需列名的 DataFrame,并在您的管道中使用它。

from sklearn.feature_extraction.text import TfidfVectorizer
import pandas as pd

class DenseTfidfVectorizer(TfidfVectorizer):

    def transform(self, raw_documents, copy=True):
        X = super().transform(raw_documents, copy=copy)
        df = pd.DataFrame(X.toarray(), columns=self.get_feature_names())
        return df

    def fit_transform(self, raw_documents, y=None):
        X = super().fit_transform(raw_documents, y=y)
        df = pd.DataFrame(X.toarray(), columns=self.get_feature_names())
        return df

【讨论】:

这行得通!谢谢@swhat!我还必须在我的管道中替换 `("vectorizer", DenseTfidfVectorizer(TfidfVectorizer())` 编辑:必须在管道中使用以下内容:("vectorizer", DenseTfidfVectorizer(max_df=0.5))【参考方案2】:

根据docs,您可以使用以下方法

一个。直接访问管道外的.get_feature_names() 并检查那里的数据框(带有命名列)

b. apply .fit_transform on data管道外

pipeline = Pipeline(....)

# a. extract .get_feature_names() to use as column names in the dataframe
feature_names = (
                pipeline.best_estimator_
                        .named_steps['vectorizer']
                        .get_feature_names()
                )    

# b. get the TFIDF vector
data2 = (
         pipeline.best_estimator_
                 .named_steps['vectorizer']
                 .fit_transform(raw_data)
        )

# put into a pandas dataframe
transformed = pd.DataFrame(data2, columns=feature_names)

这样您也许可以完全跳过管道中的debug 步骤,并检查管道外的数据帧。

【讨论】:

以上是关于如何从管道中的 sklearn TFIDF Vectorizer 返回数据帧?的主要内容,如果未能解决你的问题,请参考以下文章

向 Sklearn 分类器添加功能

如何将不同的输入拟合到 sklearn 管道中?

使用 sklearn Pipeline 中的索引提取子管道时出错

使用sklearn Pipeline中的索引提取子管道时出错。

如何分析sklearn中tfidf矩阵的值?

Sklearn:有没有办法调试管道?