如何使用 weka 的 ADTrees 分类器作为装袋 scikitlearn 模型的基础?

How to use the ADTrees classifier from weka as base of a bagging scikitlearn model?

我的目的是使用 scikit-learn 和其他库重新创建一个在 weka 上完成的大模型。

我用 pyweka 完成了这个基础模型。

base_model_1 = Classifier(classname="weka.classifiers.trees.ADTree", 
                  options=["-B", "10", "-E", "-3", "-S", "1"])

base_model_1.build_classifier(train_model_1)
base_model_1

但是当我尝试像这样将它用作基础刺激器时:

model = BaggingClassifier(base_estimator= base_model_1, n_estimators = 100, n_jobs = 1, random_state = 1)

并尝试像这样评估模型:

cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
AUC_scores = cross_val_score(model, X_data_train, y_data_train, scoring='roc_auc', cv=cv, n_jobs=-1)
F1_scores = cross_val_score(model, X_data_train, y_data_train, scoring='f1', cv=cv, n_jobs=-1)
Precision_scores = cross_val_score(model, X_data_train, y_data_train, scoring='precision', cv=cv, n_jobs=-1)
Recall_scores = cross_val_score(model, X_data_train, y_data_train, scoring='recall', cv=cv, n_jobs=-1)
Accuracy_scores = cross_val_score(model, X_data_train, y_data_train, scoring='accuracy', cv=cv, n_jobs=-1)
print("-------------------------------------------------------")
print(AUC_scores)
print("-------------------------------------------------------")
print(F1_scores)
print("-------------------------------------------------------")
print(Precision_scores)
print("-------------------------------------------------------")
print(Recall_scores)
print("-------------------------------------------------------")
print(Accuracy_scores)
print("-------------------------------------------------------")
print('Mean ROC AUC: %.3f' % mean(AUC_scores))
print('Mean F1: %.3f' % mean(F1_scores))
print('Mean Precision: %.3f' % mean(Precision_scores))
print('Mean Recall: %.3f' % mean(Recall_scores))
print('Mean Accuracy: %.3f' % mean(Accuracy_scores))

我刚收到 NaN:


Distribución Variable Clase Desbalanceada
0    161
1     34
Name: Soft-Tissue_injury_≥4days, dtype: int64
-------------------------------------------------------
[nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
 nan nan nan nan nan nan nan nan nan nan nan nan]
-------------------------------------------------------
[nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
 nan nan nan nan nan nan nan nan nan nan nan nan]
-------------------------------------------------------
[nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
 nan nan nan nan nan nan nan nan nan nan nan nan]
-------------------------------------------------------
[nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
 nan nan nan nan nan nan nan nan nan nan nan nan]
-------------------------------------------------------
[nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
 nan nan nan nan nan nan nan nan nan nan nan nan]
-------------------------------------------------------
Mean ROC AUC: nan
Mean F1: nan
Mean Precision: nan
Mean Recall: nan
Mean Accuracy: nan

所以我认为我错误地使用了 ADTree 分类器作为装袋基础。

有什么方法可以正确做到这一点吗?

我刚刚发布了 sklearn-weka-plugin 的 0.0.5 版本,您可以使用它执行以下操作:

import os
from statistics import mean

from sklearn.ensemble import BaggingClassifier
from sklearn.model_selection import RepeatedStratifiedKFold
from sklearn.model_selection import cross_val_score

import sklweka.jvm as jvm
from sklweka.classifiers import WekaEstimator
from sklweka.dataset import load_arff

jvm.start(packages=True)

# adjust the path to your dataset
# the example assumes all attributes and class to be nominal
data_file = "/some/where/vote.arff"
X, y, meta = load_arff(data_file, class_index="last")

base_model_1 = WekaEstimator(classname="weka.classifiers.trees.ADTree",
                             options=["-B", "10", "-E", "-3", "-S", "1"],
                             nominal_input_vars="first-last",  # which attributes need to be treated as nominal
                             nominal_output_var=True)          # class is nominal as well
model = BaggingClassifier(base_estimator=base_model_1, n_estimators=100, n_jobs=1, random_state=1)

cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
accuracy_scores = cross_val_score(model, X, y, scoring='accuracy', cv=cv, n_jobs=None)  # single process!
print("-------------------------------------------------------")
print(accuracy_scores)
print("-------------------------------------------------------")
print('Mean Accuracy: %.3f' % mean(accuracy_scores))

jvm.stop()

这会生成以下输出:

-------------------------------------------------------
[0.97727273 0.95454545 0.95454545 0.95454545 0.97727273 0.90697674
 1.         0.90697674 0.95348837 0.95348837 0.97727273 0.95454545
 0.90909091 0.88636364 0.97727273 0.97674419 0.97674419 0.97674419
 0.97674419 0.97674419 0.93181818 0.97727273 0.93181818 0.90909091
 1.         1.         1.         0.90697674 0.97674419 0.95348837]
-------------------------------------------------------
Mean Accuracy: 0.957

请注意,您在尝试生成其他指标时可能会遇到类似 object has no attribute 'decision_function' 的异常。 This article 可能会有所帮助。

最后,由于在后台使用 JVM 和 python-javabridge 造成的限制是您无法在核心 (n_jobs=None) 之间分叉进程和分配作业。