将 TruncatedSVD 与 hashingvector 一起使用时,精度会大大降低

数据挖掘 分类 scikit-学习 降维 文本
2022-03-01 18:52:57

我有大约 80 万个带有类别的产品描述。大约有280个类别。我想用给定的数据集训练一个模型,以便将来我可以预测给定产品描述的类别。由于数据集很大,我无法在该数据上使用 TF-IDF,它会抛出 MemoryError。

我发现 Hashingvector 在处理大数据时是可取的。但是当应用 Hashingvector 时,我发现它生成的数据具有 1048576 个特征。训练和 SGD 模型大约需要 1 小时,并产生 78% 的准确率。

代码:

import pandas as pd
from sklearn.feature_extraction.text import HashingVectorizer
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.decomposition import TruncatedSVD
from sklearn.linear_model import SGDClassifier
from sklearn.calibration import CalibratedClassifierCV

data_file = "Product_description.txt"
#Reading the input/ dataset
data = pd.read_csv(data_file, header = 0, delimiter= "\t", quoting = 3, encoding = "utf8")
data = data.dropna()

train_data, test_data, train_label,  test_label = train_test_split(data.Product_description, data.Category, 
                                                                   test_size=0.3, random_state=100, stratify=data.Category)

sgd_model = SGDClassifier(loss='hinge', n_iter=20, class_weight="balanced", n_jobs=-1,
                          random_state=42, alpha=1e-06, verbose=1)
vectorizer = HashingVectorizer(ngram_range=(1,3))
data_features = vectorizer.fit_transform(train_data.Product_description)
sgd_model.fit(data_features, train_label)
test_data_feature = vectorizer.transform(test_data.Product_Combined_Cleansed)
Output_predict = sgd_model.predict(test_data_feature)
print(accuracy_score(test_label, Output_predict))

输出:

Accuracy 77.01%

由于维度很高,我认为减小维度会提高准确性并减少训练时间。我使用 TrancatedSVD 来减少维度,但这大大降低了预测精度,但将训练时间减少到了 10 分钟。

代码2:

from sklearn.decomposition import TruncatedSVD
clf = TruncatedSVD(100)
clf.fit(data_features)

输出:

Accuracy 14%

编辑:

当我尝试使用 1000 作为限制的 TruncatedSVD 时,它会引发内存错误,所以只有我选择使用 100 作为限制。

据说减少 HashingVector 上的 n_features 会导致there can be collisions: distinct tokens can be mapped to the same feature index. However, in practice, this is rarely an issue if n_features is large enough (e.g. 2 ** 18 for text classification problems)scikit 站点发生冲突。

当我在 1 到 3 之间使用 ngram 时,我得到了最佳精度,所以只使用了它。

2个回答

一些可能的方向:

  • 当您不确定您的 BoW 模型如何工作时,请检查不同的 n-gram 范围(您是否甚至检查过它如何仅与 unigram 一起工作?)
  • TruncatedSVD 默认只迭代 5 次(n_iter),所以你可以增加它
  • 对于如此低的维度,分类质量发生如此剧烈的变化并不奇怪。您可能会问一些问题,为什么是 100 维?TSVD 是否可以工作 1000 维或类似的东西?什么是重建错误(TSVD 的explained_variance_ratio_外观如何)?
  • HashingVectorizer 还有一个参数可以控制特征的数量,即n_features.

从 1048576 个特征减少到 100 个特征使得输入特征维度减少了 99.99% 以上,因为知道 SVD 并不专注于寻找有趣的特征进行分类,而是从最初的向量空间创建一个不相关的向量空间。

您应该尝试增加 SVD 产生的维度(您是否查看过 100 个组件的保留方差?)但更具体地说,我建议您使用使用 chi2 分数等指标的特征选择管道,这可以为 a分类目标(但是计算时间可能更长)。