训练具有多个特征的 sklearn 分类器

Posted

技术标签:

【中文标题】训练具有多个特征的 sklearn 分类器【英文标题】:Training a sklearn classifier with more than a single feature 【发布时间】:2019-10-21 03:33:13 【问题描述】:

我目前正在使用单个特征向量器训练 LinearSVC 分类器。我正在处理新闻,这些新闻存储在单独的文件中。这些文件最初有标题、正文、日期、作者,有时还有图像。但我最终删除了除正文以外的所有内容作为特征。我是这样做的:

# Loading the files (Plain files with just the news content. Nor date, author or other features.)

data_train = load_files(self.TRAIN_FOLDER, encoding=self.ENCODING)  # data_train
data_test = load_files(self.TEST_FOLDER, encoding=self.ENCODING)
unlabeled = load_files(self.UNLABELED_FOLDER, encoding=self.ENCODING)
categories = data_train.target_names

# Get the sparse matrix of each dataset
y_train = data_train.target
y_test = data_test.target

# Vectorizing 
vectorizer = TfidfVectorizer(encoding=self.ENCODING, use_idf=True, norm='l2', binary=False, sublinear_tf=True, min_df=0.001, max_df=1.0, ngram_range=(1, 2), analyzer='word')

X_train = vectorizer.fit_transform(data_train.data)
X_test = vectorizer.transform(data_test.data)
X_unlabeled = vectorizer.transform(self.data_unlabeled.data)

# Instantiating the classifier
clf = LinearSVC(loss='squared_hinge', penalty='l2', dual=False, tol=1e-3)

# Fitting the model according to the training set and predicting
scaler = preprocessing.StandardScaler(with_mean=False) 
scaler = scaler.fit(X_train) 

normalized_X_train = scaler.transform(X_train) 
clf.fit(normalized_X_train, y_train) 

normalized_X_test = scaler.transform(X_test) 
pred = clf.predict(normalized_X_test)

accuracy_score = metrics.accuracy_score(y_test, pred)
recall_score = metrics.recall_score(y_test, pred)
precision_score = metrics.precision_score(y_test, pred)

但现在我想包括其他特征,如日期或作者,我发现的所有更简单的例子都是使用一个特征。所以我不确定如何进行。我应该将所有信息放在一个文件中吗?如何区分作者和内容?我应该为每个功能使用矢量化器吗?如果是这样,我应该拟合具有不同矢量化特征的模型吗?或者我应该为每个功能使用不同的分类器?你能给我推荐一些读物吗(向新手解释)?

提前致谢,

【问题讨论】:

【参考方案1】:

TfidfVectorizer 的输出是一个scipy.sparse.csr.csr_matrix 对象。您可以使用hstack 添加更多功能(如here)。或者,您可以将上面已有的特征空间转换为 numpy 数组或 pandas df,然后将新特征(您可能从其他矢量化器创建的)添加为新列。无论哪种方式,您最终的 X_train 和 X_test 都应该在一个地方包含所有功能。在进行培训之前,您可能还需要对它们进行标准化 (here)。你这里好像没有这样做。

我没有你的数据,所以这里是一些虚拟数据的示例:

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

corpus = [
    'This is the first document.',
    'This document is the second document.',
    'And this is the third one.',
    'Is this the first document?',
]

vectorizer = TfidfVectorizer()
X_train = vectorizer.fit_transform(corpus)

X_train = pd.DataFrame(X_train.todense())

X_train['has_image'] = [1, 0, 0, 1]  # just adding a dummy feature for demonstration

【讨论】:

非常感谢您提供的所有信息和链接! 关于规范化,我应该在我的代码中添加以下内容吗? data = scale(X_train) clf.fit(data, y_train) pred = clf.predict(data) (我更新了问题中的代码,因为在那里更容易阅读)。感谢您指出我的不足! 你的好像不行。 Scaler 应该适合 X_train,然后这个适合的 scaler 应用于 X_train 和 X_test。我实际上已经在另一篇帖子here 中解释了这一点。各种缩放器的演示也可以找到here 非常感谢!我更新了代码以防它帮助其他人。我最终使用了 StandardScaler(with_mean=False),因为数据很大,否则会引发错误。而且我还标准化了未标记的集合,以便以后在决策函数中使用它。谢谢!! 太棒了。我的荣幸。

以上是关于训练具有多个特征的 sklearn 分类器的主要内容,如果未能解决你的问题,请参考以下文章

忽略训练数据中不存在的测试特征

如何使用具有面部特征的 openCV 训练支持向量机(svm)分类器?

如何在 Sklearn 的随机森林分类器中将训练模型用于另一个数据集?

Sklearn:异质特征的FeatureUnion与管道中的分类器产生不兼容的行尺寸错误

sklearn:朴素贝叶斯分类器的准确性低

具有 PredefinedSplit 评分的 Sklearn GridSearch 与独立分类器不匹配