GridSearchCV + StratifiedKfold 在 TFIDF 的情况下
GridSearchCV + StratifiedKfold in case of TFIDF
我正在处理 class化问题,我需要预测文本数据的 class。我需要为我正在考虑使用 GridSearchCV
的 class 化模型进行超参数调整。我也需要做 StratifiedKFold
因为我的数据不平衡。我知道如果我们有 multiclass classification,GridSearchCV
内部使用 StratifiedKFold
。
我读过 ,在 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())
我得到的 accuracy/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_train
、X_test
k 次,然后进行预测以提供最佳估算器。
在我的例子中,X 应该是什么?如果是在 fit_transform
之后生成的 X,那么在内部将 X 拆分为训练和测试时,测试数据已经进行了 fit_transform
,但理想情况下它应该只进行转换。
我担心的是,就我而言,在 GridSearchCV
内部,我如何能够控制 fit_transform
仅应用于训练数据,而转换应用于测试数据(验证数据)。
因为如果它在内部将 fit_transform 应用于整个数据,那么这不是一个好的做法。
这是一个确切的场景,您应该在 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
我正在处理 class化问题,我需要预测文本数据的 class。我需要为我正在考虑使用 GridSearchCV
的 class 化模型进行超参数调整。我也需要做 StratifiedKFold
因为我的数据不平衡。我知道如果我们有 multiclass classification,GridSearchCV
内部使用 StratifiedKFold
。
我读过 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())
我得到的 accuracy/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_train
、X_test
k 次,然后进行预测以提供最佳估算器。
在我的例子中,X 应该是什么?如果是在 fit_transform
之后生成的 X,那么在内部将 X 拆分为训练和测试时,测试数据已经进行了 fit_transform
,但理想情况下它应该只进行转换。
我担心的是,就我而言,在 GridSearchCV
内部,我如何能够控制 fit_transform
仅应用于训练数据,而转换应用于测试数据(验证数据)。
因为如果它在内部将 fit_transform 应用于整个数据,那么这不是一个好的做法。
这是一个确切的场景,您应该在 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