cross_val_score 和 StratifiedKFold 之间的 F-Score 差异
F-Score difference between cross_val_score and StratifiedKFold
我想对不平衡数据使用随机森林分类器,其中 X 是 np.array 代表特征,y 是 np.array 代表标签(标签有 90% 0 值,并且10% 1-值)。由于我不确定如何在交叉验证中进行分层,如果它有所不同,我还使用 StratifiedKFold 手动进行交叉验证。我希望得到不相同但有些相似的结果。由于情况并非如此,我想我错误地使用了一种方法,但我不明白是哪一种。这是代码
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import StratifiedKFold, cross_val_score, train_test_split
from sklearn.metrics import f1_score
rfc = RandomForestClassifier(n_estimators = 200,
criterion = "gini",
max_depth = None,
min_samples_leaf = 1,
max_features = "auto",
random_state = 42,
class_weight = "balanced")
X_train_val, X_test, y_train_val, y_test = train_test_split(X, y, test_size = 0.20, random_state = 42, stratify=y)
我还尝试了没有 class_weight 参数的分类器。从这里开始,我继续将这两种方法与 f1-score
进行比较
cv = cross_val_score(estimator=rfc,
X=X_train_val,
y=y_train_val,
cv=10,
scoring="f1")
print(cv)
交叉验证的 10 个 f1 分数都在 65% 左右。
现在 StratifiedKFold:
skf = StratifiedKFold(n_splits=10, shuffle=True, random_state=42)
for train_index, test_index in skf.split(X_train_val, y_train_val):
X_train, X_val = X_train_val[train_index], X_train_val[test_index]
y_train, y_val = y_train_val[train_index], y_train_val[test_index]
rfc.fit(X_train, y_train)
rfc_predictions = rfc.predict(X_val)
print("F1-Score: ", round(f1_score(y_val, rfc_predictions),3))
StratifiedKFold 的 10 个 f1-scores 让我获得了大约 90% 的价值。这是我感到困惑的地方,因为我不了解这两种方法之间的巨大差异。如果我只是将分类器拟合到训练数据并将其应用于测试数据,我也会得到大约 90% 的 f1 分数,这让我相信我应用 cross_val_score 的方式是不正确的。
造成差异的一个可能原因是 cross_val_score
使用带有默认 shuffle=False
参数的 StratifiedKFold
,而在使用 StratifiedKFold
的手动交叉验证中,您通过了shuffle=True
。因此,它可能只是你的数据排序方式的一个产物,即没有改组的交叉验证会产生更差的 F1 分数。
尝试在创建 skf
实例时传递 shuffle=False
以查看分数是否与 cross_val_score
匹配,然后如果您想在使用 cross_val_score
时使用随机播放在应用 cross_val_score
.
之前手动打乱训练数据
我想对不平衡数据使用随机森林分类器,其中 X 是 np.array 代表特征,y 是 np.array 代表标签(标签有 90% 0 值,并且10% 1-值)。由于我不确定如何在交叉验证中进行分层,如果它有所不同,我还使用 StratifiedKFold 手动进行交叉验证。我希望得到不相同但有些相似的结果。由于情况并非如此,我想我错误地使用了一种方法,但我不明白是哪一种。这是代码
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import StratifiedKFold, cross_val_score, train_test_split
from sklearn.metrics import f1_score
rfc = RandomForestClassifier(n_estimators = 200,
criterion = "gini",
max_depth = None,
min_samples_leaf = 1,
max_features = "auto",
random_state = 42,
class_weight = "balanced")
X_train_val, X_test, y_train_val, y_test = train_test_split(X, y, test_size = 0.20, random_state = 42, stratify=y)
我还尝试了没有 class_weight 参数的分类器。从这里开始,我继续将这两种方法与 f1-score
进行比较cv = cross_val_score(estimator=rfc,
X=X_train_val,
y=y_train_val,
cv=10,
scoring="f1")
print(cv)
交叉验证的 10 个 f1 分数都在 65% 左右。 现在 StratifiedKFold:
skf = StratifiedKFold(n_splits=10, shuffle=True, random_state=42)
for train_index, test_index in skf.split(X_train_val, y_train_val):
X_train, X_val = X_train_val[train_index], X_train_val[test_index]
y_train, y_val = y_train_val[train_index], y_train_val[test_index]
rfc.fit(X_train, y_train)
rfc_predictions = rfc.predict(X_val)
print("F1-Score: ", round(f1_score(y_val, rfc_predictions),3))
StratifiedKFold 的 10 个 f1-scores 让我获得了大约 90% 的价值。这是我感到困惑的地方,因为我不了解这两种方法之间的巨大差异。如果我只是将分类器拟合到训练数据并将其应用于测试数据,我也会得到大约 90% 的 f1 分数,这让我相信我应用 cross_val_score 的方式是不正确的。
造成差异的一个可能原因是 cross_val_score
使用带有默认 shuffle=False
参数的 StratifiedKFold
,而在使用 StratifiedKFold
的手动交叉验证中,您通过了shuffle=True
。因此,它可能只是你的数据排序方式的一个产物,即没有改组的交叉验证会产生更差的 F1 分数。
尝试在创建 skf
实例时传递 shuffle=False
以查看分数是否与 cross_val_score
匹配,然后如果您想在使用 cross_val_score
时使用随机播放在应用 cross_val_score
.