【发布时间】:2020-09-27 19:05:49
【问题描述】:
我使用 TF-IDF 和非 TF-IDF 特征运行随机森林算法。
特征总数约为 130k(在对 TF-IDF 特征进行特征选择后),训练集的观察数约为 120k。
其中大约 500 个是非 TF-IDF 特征。
问题在于随机森林在同一测试集上的准确性等与
- 只有非 TF-IDF 特征是 87%
- TF-IDF 和非 TF-IDF 特征为 76%
准确度的这种显着恶化在我的脑海中引发了一些问题。
我与模型训练相关的代码如下:
drop_columns = ['labels', 'complete_text_1', 'complete_text_2']
# Split to predictors and targets
X_train = df.drop(columns=drop_columns).values
y_train = df['labels'].values
# Instantiate, train and transform with tf-idf models
vectorizer_1 = TfidfVectorizer(analyzer="word", ngram_range=(1,2), vocabulary=tf_idf_feature_names_selected)
X_train_tf_idf_1 = vectorizer_1.fit_transform(df['complete_text_1'])
vectorizer_2 = TfidfVectorizer(analyzer="word", ngram_range=(1,2), vocabulary=tf_idf_feature_names_selected)
X_train_tf_idf_2 = vectorizer_2.fit_transform(df['complete_text_2'])
# Covert the general features to sparse array
X_train = np.array(X_train, dtype=float)
X_train = csr_matrix(X_train)
# Concatenate the general features and tf-idf features array
X_train_all = hstack([X_train, X_train_tf_idf_1, X_train_tf_idf_2])
# Instantiate and train the model
rf_classifier = RandomForestClassifier(n_estimators=150, random_state=0, class_weight='balanced', n_jobs=os.cpu_count()-1)
rf_classifier.fit(X_train_all, y_train)
就个人而言,我没有在我的代码中看到任何错误(上面的这段代码和一般情况)。
我为解释这种准确性下降而制定的假设如下。
- 非 TF-IDF 特征的数量只有 500 个(总共 130k 特征)
- 这提供了一些机会,即非 TF-IDF 特征在每次被随机森林的树分割时不会被挑选那么多(例如,因为
max_features等) - 因此,如果非 TF-IDF 功能确实很重要,那么这将产生问题,因为它们没有得到足够的考虑。
与此相关,当我在训练后检查随机森林的特征重要性时,我发现非 TF-IDF 特征的重要性非常低(尽管我不确定特征重要性的指标有多可靠尤其是包含 TF-IDF 功能)。
您能否以不同的方式解释我的分类器准确度下降的原因?
无论如何,你会建议做什么?
结合 TF-IDF 和非 TF-IDF 功能的其他一些想法如下。
一种选择是拥有两个独立的(随机森林)模型 - 一个用于 TF-IDF 功能,一个用于非 TF-IDF 功能。 然后这两个模型的结果将通过(加权)投票或元分类进行组合。
【问题讨论】:
-
在此处提供有关您的任务的更多信息会非常有帮助,例如:任务是什么、损失函数、您使用的数据点数量等。
-
我的意思是从代码来看,您似乎对具有交叉熵损失的文本文档有一个二进制分类任务,但明确地拼写它会使阅读您的问题更简单一些。当然,数据点的数量也非常重要(在任何地方都没有提到)。
-
@AlexanderPivovarov,好点。在这里提供所有这些信息有点太费时了,这就是为什么我到目前为止还没有。首先,训练集的观测数约为 120k。
-
如果您查看
max_features的文档,默认情况下它将使用sqrt(n_features),这大约是任何给定树将看到的 360 个特征。即使不同树之间的这些特征没有重叠,150*360 = 54k。所以你的 130k 特征中的大部分将永远不会被模型看到。 -
@Swier,我当然同意
max_features,这也是我在帖子中提到这个的原因。但是,除非我遗漏了什么,否则请记住,每次在每次拆分时并且不仅在每棵树上都会选择一组新的特征,这些特征基于随机森林,但也基于RandomForestClassifier(max_features{“auto”, “sqrt”, “log2”}, int or float, default=”auto” The number of features to consider when looking for the best split:) 的 SkLearn 文档。
标签: python machine-learning random-forest tf-idf