【问题标题】:GridSearchCV + StratifiedKfold in case of TFIDFGridSearchCV + StratifiedKfold 在 TFIDF 的情况下
【发布时间】:2020-08-23 19:26:29
【问题描述】:

我正在研究一个分类问题,我需要预测文本数据的类别。我需要为我正在考虑使用GridSearchCV 的分类模型进行超参数调整。我也需要做StratifiedKFold,因为我的数据不平衡。我知道GridSearchCV 内部使用StratifiedKFold 如果我们有多类分类。

我读过here,在TfidfVectorizer 的情况下,我们将fit_transform 应用于训练数据并且仅转换为测试数据。

这就是我在下面使用StratifiedKFold 所做的。

skf = StratifiedKFold(n_splits=5, random_state=5)

for train_index, test_index in skf.split(X, y):
    iteration = iteration+1
    print(f"Iteration number {iteration}")
    X_train, y_train = X.iloc[train_index], y.iloc[train_index]
    X_test, y_test = X.iloc[test_index], y.iloc[test_index]

    train_tfid = tfidf_vectorizer.fit_transform(X_train.values.astype('U'))
    test_tfid = tfidf_vectorizer.transform(X_test.values.astype('U'))

    svc_model = linear_model.SGDClassifier()
    svc_model.fit(train_tfid, y_train.values.ravel())

我得到的准确率/f1 不好,所以想到使用 GridSearchCV 进行超参数调整。 在 GridSearchCV 中我们这样做

c_space = np.logspace(-5, 8, 15) 
param_grid = {'C': c_space} 

# Instantiating logistic regression classifier 
logreg = LogisticRegression() 

# Instantiating the GridSearchCV object 
logreg_cv = GridSearchCV(logreg, param_grid, cv = 5) 

logreg_cv.fit(X, y) 

据我说,logreg_cv.fit(X, y) 会在内部将 X 拆分为 X_trainX_test k 次,然后进行预测以提供最佳估算器。

在我的情况下,X 应该是什么?如果是在fit_transform之后生成的X,那么在内部将X拆分为训练和测试时,测试数据已经经历了fit_transform,但理想情况下它应该只经历变换。

我担心的是,在我的情况下,在 GridSearchCV 内部,我如何能够控制 fit_transform 仅应用于训练数据而转换应用于测试数据(验证数据)。

因为如果它在内部将 fit_transform 应用于整个数据,那么这不是一个好习惯。

【问题讨论】:

    标签: machine-learning scikit-learn cross-validation tf-idf grid-search


    【解决方案1】:

    这是一个确切的场景,您应该在 GridSearchCV 中使用 Pipeline。首先,创建一个包含数据预处理、特征选择和模型等所需步骤的管道。在此管道上调用 GridSearchCV 后,它将仅对训练折叠进行数据处理,然后与模型匹配。

    阅读here了解更多关于sklearn中模型选择模块的信息。

    from sklearn.datasets import fetch_20newsgroups
    from sklearn.feature_extraction.text import CountVectorizer
    from sklearn.pipeline import Pipeline
    from sklearn.ensemble import RandomForestClassifier
    from sklearn.linear_model import LogisticRegression
    from sklearn.model_selection import train_test_split, GridSearchCV
    import numpy as np
    
    cats = ['alt.atheism', 'sci.space']
    newsgroups_train = fetch_20newsgroups(subset='train',
                                          remove=('headers', 'footers', 'quotes'),
                                          categories=cats)
    X, y = newsgroups_train.data, newsgroups_train.target
    
    X_train, X_test, y_train, y_test = train_test_split(
        X, y, test_size=0.1, stratify=y)
    
    
    my_pipeline = Pipeline([
        ('vectorizer', CountVectorizer(stop_words='english')),
        ('clf', LogisticRegression())
    ])
    
    
    parameters = {'clf__C': np.logspace(-5, 8, 15)}
    
    grid_search = GridSearchCV(my_pipeline, param_grid=parameters,
                               cv=10, n_jobs=-1, scoring='accuracy')
    grid_search.fit(X_train, y_train)
    
    print(grid_search.best_params_)
    # {'clf__C': 0.4393970560760795}
    
    grid_search.score(X_test, y_test)
    # 0.8981481481481481
    

    【讨论】:

    • 我是否理解正确,在这种情况下,GridSearchCV 将矢量化,尝试拟合 Logistic 回归及其超参数,这对于 StratifiedKFold 拆分为 10,然后返回模型和超参数的最佳分数为那 10 折?
    猜你喜欢
    • 2020-05-13
    • 1970-01-01
    • 2017-03-08
    • 2016-02-08
    • 2015-06-12
    • 2021-01-23
    • 2016-10-04
    • 2018-07-28
    • 2016-01-07
    相关资源
    最近更新 更多