使用CountVectorizer连接自定义特征

15 投票
1 回答
5365 浏览
提问于 2025-04-18 00:08

我有一堆包含文章的文件。每篇文章应该有一些特征,比如:文本长度文本垃圾邮件(这些都是整数或浮点数,通常应该从csv文件中加载)。我想做的是把这些特征和CountVectorizer结合起来,然后对这些文本进行分类。

我看了一些教程,但还是不知道怎么实现这些东西。我在这里找到了一些内容,但实际上无法满足我的需求。

有没有什么想法可以用scikit来实现这个?

谢谢。

我现在遇到的问题是:

from sklearn.feature_extraction import DictVectorizer
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.pipeline import FeatureUnion

measurements = [
    {'text_length': 1000, 'text_spam': 4.3},
    {'text_length': 2000, 'text_spam': 4.1},
]

corpus = [
    'some text',
    'some text 2 hooray',
]

vectorizer = DictVectorizer()
count_vectorizer = CountVectorizer(min_df=1)

first_x = vectorizer.fit_transform(measurements)
second_x = count_vectorizer.fit_transform(corpus)

combined_features = FeatureUnion([('first', first_x), ('second', second_x)])

对于这段代码,我不明白怎么加载“真实”的数据,因为训练集已经加载了。第二个问题是,怎么加载类别(fit函数的y参数)?

1 个回答

14

你可能误解了 FeatureUnion 的用法。它是用来处理两个转换器,而不是两个样本批次。

虽然你可以强行让它处理你已有的向量化工具,但其实把所有特征放到一个大袋子里,然后用一个 DictVectorizer 来把这些袋子变成向量会简单得多。

# make a CountVectorizer-style tokenizer
tokenize = CountVectorizer().build_tokenizer()

def features(document):
    terms = tokenize(document)
    d = {'text_length': len(terms), 'text_spam': whatever_this_means}
    for t in terms:
        d[t] = d.get(t, 0) + 1
    return d

vect = DictVectorizer()
X_train = vect.fit_transform(features(d) for d in documents)

别忘了用 sklearn.preprocessing.Normalizer 来进行归一化处理,并且要注意,即使经过归一化,text_length 这个特征在规模上还是会占据主导地位。使用 1. / text_length 或者 np.log(text_length) 可能会更明智。

第二个问题是 - 如何加载类别(y 参数用于 fit 函数)?

这取决于你的数据是如何组织的。scikit-learn 提供了很多辅助函数和类,但如果你的设置比较特殊,它会要求你自己写代码。

撰写回答