gpt4 book ai didi

machine-learning - SciKit Learn 使用 RFECV 进行特征选择和交叉验证

转载 作者:行者123 更新时间:2023-11-30 08:51:38 36 4
gpt4 key购买 nike

我对机器学习还很陌生,并试图自己解决问题。我正在使用 SciKit learn 并拥有一个包含大约 20,000 个特征的推文数据集 (n_features=20,000)。到目前为止,我的准确率、召回率和 f1 分数都在 79% 左右。我想使用 RFECV 进行特征选择并提高模型的性能。我已阅读 SciKit 学习文档,但对如何使用 RFECV 仍然有点困惑。

这是我到目前为止的代码:

from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.naive_bayes import MultinomialNB
from sklearn.cross_validation import StratifiedShuffleSplit
from sklearn.cross_validation import cross_val_score
from sklearn.feature_selection import RFECV
from sklearn import metrics

# cross validation
sss = StratifiedShuffleSplit(y, 5, test_size=0.2, random_state=42)
for train_index, test_index in sss:
docs_train, docs_test = X[train_index], X[test_index]
y_train, y_test = y[train_index], y[test_index]

# feature extraction
count_vect = CountVectorizer(stop_words='English', min_df=3, max_df=0.90, ngram_range=(1,3))
X_CV = count_vect.fit_transform(docs_train)

tfidf_transformer = TfidfTransformer()
X_tfidf = tfidf_transformer.fit_transform(X_CV)

# Create the RFECV object
nb = MultinomialNB(alpha=0.5)

# The "accuracy" scoring is proportional to the number of correct classifications
rfecv = RFECV(estimator=nb, step=1, cv=2, scoring='accuracy')

rfecv.fit(X_tfidf, y_train)
X_rfecv=rfecv.transform(X_tfidf)

print("Optimal number of features : %d" % rfecv.n_features_)

# train classifier
clf = MultinomialNB(alpha=0.5).fit(X_rfecv, y_train)

# test clf on test data

X_test_CV = count_vect.transform(docs_test)
X_test_tfidf = tfidf_transformer.transform(X_test_CV)
X_test_rfecv = rfecv.transform(X_test_tfidf)

y_predicted = clf.predict(X_test_rfecv)

#print the mean accuracy on the given test data and labels

print ("Classifier score is: %s " % rfecv.score(X_test_rfecv,y_test))

三个问题:

1) 这是使用交叉验证和 RFECV 的正确方法吗?我特别想知道我是否面临过度拟合的风险。

2)我用上面的代码实现RFECV之前和之后的模型的准确性几乎相同(大约78-79%),这让我很困惑。我希望通过使用 RFECV 可以提高性能。我在这里可能错过了什么或者可以采取不同的措施来提高模型的性能吗?

3)您可以推荐我尝试哪些其他特征选择方法?到目前为止,我已经尝试过 RFE 和 SelectKBest,但它们都没有在模型准确性方面给我带来任何改进。

最佳答案

回答您的问题:

  1. RFECV 功能选择中内置了交叉验证(因此得名),因此您实际上不需要为此单个步骤进行额外的交叉验证。然而,由于我知道您正在运行多个测试,因此最好进行整体交叉验证,以确保您不会过度拟合特定的训练测试分割。我想在这里提两点:

    1. 我怀疑代码的行为是否与您想象的完全一样;)。

         # cross validation
      sss = StratifiedShuffleSplit(y, 5, test_size=0.2, random_state=42)
      for train_index, test_index in sss:
      docs_train, docs_test = X[train_index], X[test_index]
      y_train, y_test = y[train_index], y[test_index]
      # feature extraction
      count_vect = CountVectorizer(stop_words='English', min_df=3, max_df=0.90, ngram_range=(1,3))
      X_CV = count_vect.fit_transform(docs_train)

    这里我们首先执行 5 次迭代的循环(StratifiedShuffleSplit 中的 n_iter 参数)。然后我们跳出循环,只使用train_index、test_index的最后值运行所有代码。因此,这相当于您可能想要 5 个的单个训练测试分割。如果您希望它像“正确的”交叉验证一样运行,则应该将代码移回到循环中。

  2. 您担心过度拟合:确实,当“寻找最佳方法”时,存在这样的风险:我们将选择最有效的方法......仅在我们测试该方法的小样本上。< br/>这里的最佳实践是首先进行训练-测试分割,然后仅使用训练集执行交叉验证。当您认为自己找到了某些东西时,可以“谨慎”使用测试集,以确保获得的分数一致并且不会过度拟合。
    看起来您可能丢弃了 30% 的数据(您的测试集),但这绝对值得。
  • 看到特征选择没有那么大的影响可能会令人费解。要进一步反射(reflection),您可以研究分数随所选特征数量的演变(请参阅 the example from the docs )。
    话虽如此,我认为这不是 RFE 的正确用例。基本上,在您的代码中,您将逐一消除功能,这可能需要很长时间才能运行,并且当您拥有 20000 个功能时,这没有多大意义。

  • 其他特征选择方法:这里您提到了SelectKBest,但您没有告诉我们您使用哪种方法来对特征进行评分! SelectKBest 将根据评分函数选择 K 个最佳特征。我猜您使用的是默认值,这是可以的,但最好了解默认值的作用;)。

    我会尝试将 SelectPercentilechi2 作为评分函数。 SelectPercentile 可能比 SelectKBest 更方便,因为如果您的数据集增长百分比可能比硬编码的特征数量更有意义。
    Another example from the docs就可以做到这一点(以及更多)。

  • 附加说明:

    • 您可以使用 TfidfVectorizer 代替 CountVectorizer 后跟 TfidfTransformer。这是严格等价的。
    • 您可以使用 pipeline object将分类器的不同步骤打包到一个可以运行交叉验证的对象中(我鼓励您阅读文档,它非常有用)。

      from sklearn.feature_selection import chi2_sparse
      from sklearn.feature_selection import SelectPercentile
      from sklearn.pipeline import Pipeline
      from sklearn.feature_extraction.text import TfidfVectorizer

      pipeline = Pipeline(steps=[
      ("vectorizer", TfidfVectorizer(stop_words='English', min_df=3, max_df=0.90, ngram_range=(1,3))),
      ("selector", SelectPercentile(score_func=chi2, percentile=70)),
      ('NB', MultinomialNB(alpha=0.5))
      ])

    然后,您就可以对管道对象运行交叉验证,以找到 alpha 和百分位数的最佳组合,这对于使用单独的估算器来说要困难得多。

    希望这有帮助,快乐学习;)。

    关于machine-learning - SciKit Learn 使用 RFECV 进行特征选择和交叉验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32109810/

    36 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com