首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何将SelectKBest集成到SKlearn管道中

如何将SelectKBest集成到SKlearn管道中
EN

Stack Overflow用户
提问于 2020-06-12 11:02:05
回答 1查看 1.1K关注 0票数 0

我试着用滑雪板构建一个文本分类器。其想法是:

  1. 基于TfidfVectorizer的训练语料库矢量化
  2. 使用SelectKBest选择结果最多的20,000个特性(如果结果数低于20k,则使用所有特性)
  3. 将这些特性输入到Logistic回归分类器

我已经成功地设置了如下所示:

代码语言:javascript
运行
复制
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.feature_selection import SelectKBest, f_classif
from sklearn.linear_model import LogisticRegression

vectorizer = TfidfVectorizer()
x_train = vectorizer.fit_transform(df_train["input"])
selector = SelectKBest(f_classif, k=min(20000, x_train.shape[1]))
selector.fit(x_train, df_train["label"].values)
x_train = selector.transform(x_train)
classifier = LogisticRegression()
classifier.fit(x_train, df_train["label"])

现在,我想将所有这些都打包到一个管道中,并共享这个管道,以便其他人可以使用它来处理自己的文本数据。然而,我不知道如何让SelectKBest实现与上面相同的行为,即接受min(20000,来自向量器输出的n_features )为k。如果我简单地将其保留为k=20000,则当向新的语料库配置少于20k矢量化功能时,管道就不能工作(抛出一个错误)。

代码语言:javascript
运行
复制
pipe = Pipeline([
            ("vect",TfidfVectorizer()),
            ("selector",SelectKBest(f_classif, k=20000)),
            ("clf",LogisticRegression())])
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-06-13 08:23:47

正如@vivek所指出的,您需要重写SelectKBestSelectKBest方法,并将您的逻辑添加到其中,如下所示:

代码语言:javascript
运行
复制
class MySelectKBest(SelectKBest):
    def _check_params(self, X, y):
        if (self.k >= X.shape[1]):
            warnings.warn("Less than %d number of features found, so setting k as %d" % (self.k, X.shape[1]),
                      UserWarning)
            self.k = X.shape[1]
        if not (self.k == "all" or 0 <= self.k):
            raise ValueError("k should be >=0, <= n_features = %d; got %r. "
                             "Use k='all' to return all features."
                             % (X.shape[1], self.k)) 

我还设置了一个警告,以防发现的功能数量少于阈值设置。现在,让我们看一个相同的工作示例:

代码语言:javascript
运行
复制
from sklearn.datasets import fetch_20newsgroups
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.feature_selection import SelectKBest, f_classif
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline
import warnings

categories = ['alt.atheism', 'comp.graphics',
              'comp.sys.ibm.pc.hardware', 'comp.sys.mac.hardware',
              'comp.windows.x', 'misc.forsale', 'rec.autos']
newsgroups = fetch_20newsgroups(categories=categories)
y_true = newsgroups.target

# newsgroups result in 47K odd features after performing TFIDF vectorizer

# Case 1: When K < No. of features - the regular case
pipe = Pipeline([
            ("vect",TfidfVectorizer()),
            ("selector",MySelectKBest(f_classif, k=30000)),
            ("clf",LogisticRegression())])

pipe.fit(newsgroups.data, y_true)
pipe.score(newsgroups.data, y_true)
#0.968

#Case 2: When K > No. of cases - the one with an issue

pipe = Pipeline([
            ("vect",TfidfVectorizer()),
            ("selector",MySelectKBest(f_classif, k=50000)),
            ("clf",LogisticRegression())])

pipe.fit(newsgroups.data, y_true)
UserWarning: Less than 50000 number of features found, so setting k as 47407

pipe.score(newsgroups.data, y_true)
#0.9792
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62342923

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档