在 scikit-learn 中使用 Featureunion 为 tfidf 组合两个 Pandas 列 [英] use Featureunion in scikit-learn to combine two pandas columns for tfidf

查看:21
本文介绍了在 scikit-learn 中使用 Featureunion 为 tfidf 组合两个 Pandas 列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

虽然使用 this 作为模型对于垃圾邮件分类,我想添加主题和正文的附加功能.

While using this as a model for spam classification, I'd like to add an additional feature of the Subject plus the body.

我的所有功能都在一个 Pandas 数据框中.例如,主题是df['Subject'],正文是df['body_text'],垃圾邮件/火腿标签是df['ham/spam']

I have all of my features in a pandas dataframe. For example, the subject is df['Subject'], the body is df['body_text'] and the spam/ham label is df['ham/spam']

我收到以下错误:类型错误:FeatureUnion"对象不可迭代

I receive the following error: TypeError: 'FeatureUnion' object is not iterable

如何在通过管道函数运行 df['Subject'] 和 df['body_text'] 时将它们都用作特征?

How can I use both df['Subject'] and df['body_text'] as features all while running them through the pipeline function?

from sklearn.pipeline import FeatureUnion
features = df[['Subject', 'body_text']].values
combined_2 = FeatureUnion(list(features))

pipeline = Pipeline([
('count_vectorizer',  CountVectorizer(ngram_range=(1, 2))),
('tfidf_transformer',  TfidfTransformer()),
('classifier',  MultinomialNB())])

pipeline.fit(combined_2, df['ham/spam'])

k_fold = KFold(n=len(df), n_folds=6)
scores = []
confusion = numpy.array([[0, 0], [0, 0]])
for train_indices, test_indices in k_fold:
    train_text = combined_2.iloc[train_indices]
    train_y = df.iloc[test_indices]['ham/spam'].values

    test_text = combined_2.iloc[test_indices]
    test_y = df.iloc[test_indices]['ham/spam'].values

    pipeline.fit(train_text, train_y)
    predictions = pipeline.predict(test_text)
    prediction_prob = pipeline.predict_proba(test_text)

    confusion += confusion_matrix(test_y, predictions)
    score = f1_score(test_y, predictions, pos_label='spam')
    scores.append(score)

推荐答案

FeatureUnion 不应该以这种方式使用.相反,它需要两个特征提取器/矢量化器并将它们应用于输入.它不会按照显示的方式在构造函数中获取数据.

FeatureUnion was not meant to be used that way. It instead takes two feature extractors / vectorizers and applies them to the input. It does not take data in the constructor the way it is shown.

CountVectorizer 需要一个字符串序列.提供它的最简单方法是将字符串连接在一起.这会将两列中的文本都传递给相同的 CountVectorizer.

CountVectorizer is expecting a sequence of strings. The easiest way to provide it with that is to concatenate the strings together. That would pass both the text in both columns to the same CountVectorizer.

combined_2 = df['Subject'] + ' '  + df['body_text']

另一种方法是在每列上单独运行 CountVectorizer 和可选的 TfidfTransformer,然后堆叠结果.

An alternative method would be to run CountVectorizer and optionally TfidfTransformer individually on each column, and then stack the results.

import scipy.sparse as sp

subject_vectorizer = CountVectorizer(...)
subject_vectors = subject_vectorizer.fit_transform(df['Subject'])

body_vectorizer = CountVectorizer(...)
body_vectors = body_vectorizer.fit_transform(df['body_text'])

combined_2 = sp.hstack([subject_vectors, body_vectors], format='csr')

第三种选择是实现您自己的转换器来提取数据帧列.

A third option is to implement your own transformer that would extract a dataframe column.

class DataFrameColumnExtracter(TransformerMixin):

    def __init__(self, column):
        self.column = column

    def fit(self, X, y=None):
        return self

    def transform(self, X, y=None):
        return X[self.column]

在这种情况下,您可以在两个管道上使用 FeatureUnion,每个管道包含您的自定义转换器,然后是 CountVectorizer.

In that case you could use FeatureUnion on two pipelines, each containing your custom transformer, then CountVectorizer.

subj_pipe = make_pipeline(
       DataFrameColumnExtracter('Subject'), 
       CountVectorizer()
)

body_pipe = make_pipeline(
       DataFrameColumnExtracter('body_text'), 
       CountVectorizer()
)

feature_union = make_union(subj_pipe, body_pipe)

管道的此功能联合将采用数据帧,每个管道将处理其列.它将从给定的两列中生成术语计数矩阵的串联.

This feature union of pipelines will take the dataframe and each pipeline will process its column. It will produce the concatenation of term count matrices from the two columns given.

 sparse_matrix_of_counts = feature_union.fit_transform(df)

此功能联合也可以作为更大管道的第一步添加.

This feature union can also be added as the first step in a larger pipeline.

这篇关于在 scikit-learn 中使用 Featureunion 为 tfidf 组合两个 Pandas 列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆