PyCaret 3.4.0和 scikit-learn得到的结果不一致
我目前在使用PyCaret 3.4.0,因为4.0缺少一些对我情况有用的配置参数。
我尝试用scikit-learn来复现PyCaret的结果。
这是我的脚本,在运行PyCaret的 setup并获得转换后的数据后:
compare_models(include=['rf'],cross_validation=True)
scoring=['accuracy','precision','recall','f1','f1_macro','f1_weighted','f1_micro', 'roc_auc']
rfc = RandomForestClassifier(random_state=42, n_jobs=-1)
scores = cross_validate(rfc, xtrain_trans, ytrain_trans, scoring=scoring, cv=cv)
compare_models 返回这些结果:
Model Accuracy AUC Recall Prec. F1 Kappa MCC TT (Sec)
rf Random Forest Classifier 0.7164 0.7617 0.7164 0.7254 0.7137 0.4329 0.4416 0.25
但我从sklearn得到的结果如下:
- 准确率=0.6948717948717947
- AUC=0.7411665257819103
- 召回率=0.6908791208791208
- 精确率=0.7005056185644422
- F1=0.6867142420587947
- F1宏平均=0.6910345427878428
- F1加权平均=0.6911863570749788
- F1微平均=0.6948717948717947
为澄清一下,我在PyCaret和 sklearn上使用的交叉验证划分器完全相同。
cv = RepeatedStratifiedKFold(n_splits=5, n_repeats=10, random_state=42)
所使用的setup是:
setup(xtrain,
target = 'Group',
session_id=42,
test_data=xtest, #None default
imputation_type=None,
remove_multicollinearity=True,
multicollinearity_threshold=0.70,
remove_outliers=True,
transformation=True,
transformation_method='quantile',
normalize=True,
feature_selection=False,
fold_strategy=cv,
use_gpu=True)
我知道差异很小—but我想使用RFECV来减少特征数量。问题在于如果我执行RFECV,必须使用sklearn来完成,因为PyCaret中未实现RFECV,结果就不可比。在执行RFECV之后,我得到的最佳平均分(F1=0.70,特征数减少)低于PyCaret的平均分(F1=0.7137,全部特征),但高于sklearn的平均分(F1=0.6867)。所以现在我不确定该如何继续,是否应该使用降维后的集合。
可复现实例:
from sklearn.model_selection import RepeatedStratifiedKFold
from sklearn.model_selection import cross_validate
from sklearn.ensemble import RandomForestClassifier
cv = RepeatedStratifiedKFold(n_splits=5, n_repeats=10, random_state=42)
from sklearn.datasets import make_classification
X, y = make_classification(n_samples=100, n_features=5, n_informative=2, n_classes=2, flip_y=0.2, random_state=42)
dataset = pd.DataFrame(X)
dataset.columns = ['X1', 'X2', 'X3', 'X4', 'X5']
dataset['y'] = y
setup0 = setup(dataset,target = 'y',session_id=42,train_size=0.7,imputation_type=None,remove_multicollinearity=True,multicollinearity_threshold=0.70,remove_outliers=True,transformation=True,transformation_method='quantile',normalize=True,feature_selection=False,fold_strategy=cv,use_gpu=True)
# CV average results from PyCaret
compare_models(include=['rf'],sort='F1',errors='raise',cross_validation=True)
xtrain_trans = setup0.get_config('X_train_transformed')
ytrain_trans = setup0.get_config('y_train_transformed')
scoring=['accuracy', 'roc_auc', 'recall', 'precision', 'f1','f1_macro','f1_weighted','f1_micro']
rfc = RandomForestClassifier(random_state=42, n_jobs=-1)
scores = cross_validate(rfc, xtrain_trans, ytrain_trans, scoring=scoring, cv=cv)
scores=pd.DataFrame(scores)
scores=scores.mean().round(4)
# CV average results from sklearn
pd.DataFrame(scores).transpose()
解决方案
好吧,我觉得我找到了答案,但也并非百分之百确定。
我认为 PyCaret会在CV阶段的每个分割上运行一个管道。 在每个分割上,训练集会经过归一化和变换的预处理,然后测试集也会被转换。之后,模型会拟合,并使用经过转换的测试集进行预测。
如果我在PyCaet的设置中关闭所有预处理选项,那么来自 compare_models 和sklearn的平均CV结果将完全相同。
我在PyCaret的指南中找不到任何确认,而且由于4.0更新,GitHub最近也有变化,现在再研究这些脚本也不太容易。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。