如何有效地比较所有模型的准确性
Posted
技术标签:
【中文标题】如何有效地比较所有模型的准确性【英文标题】:How to effectively compare all models accuracy [closed] 【发布时间】:2019-07-09 17:14:01 【问题描述】:我已经拆分了训练数据并初始化了 11 个我现在想要比较的分类器模型。
我在 Ubuntu 18.04 上运行 VS Code。
我试过了:
# Prepare lists
models = [ran, knn, log, xgb, gbc, svc, ext, ada, gnb, gpc, bag]
scores = []
# Sequentially fit and cross validate all models
for mod in models:
mod.fit(X_train, y_train)
acc = cross_val_score(mod, X_train, y_train, scoring =
"accuracy", cv = 10)
scores.append(acc.mean())
# Creating a table of results, ranked highest to lowest
results = pd.DataFrame(
'Model': ['Random Forest', 'K Nearest Neighbour', 'Logistic
Regression', 'XGBoost', 'Gradient Boosting', 'SVC', 'Extra
Trees', 'AdaBoost', 'Gaussian Naive Bayes', 'Gaussian Process',
'Bagging Classifier'],
'Score': scores)
在最后一部分返回:
ValueError: 数组的长度必须相同
我数了 2 倍,确实有 11 个模型。
我错过了什么?
【问题讨论】:
究竟在哪里弹出错误?请包含完整的错误跟踪... @desertnaut 熊猫数据框返回错误。 您是否检查了下面的答案(即将scores.append()
与for
循环的其余部分内联)?
欢迎来到 SO;如果其中一个答案解决了您的问题,请接受(请参阅What should I do when someone answers my question?)
没有一个好到可以接受的答案?
【参考方案1】:
您的代码中似乎存在缩进错误,请参阅下面的编辑代码。在您的代码中,如果您执行len(scores)
,您将获得1
,因为只有最后一个值被添加,因为在循环外调用了追加。
# Prepare lists
models = [ran, knn, log, xgb, gbc, svc, ext, ada, gnb, gpc, bag]
scores = []
# Sequentially fit and cross validate all models
for mod in models:
mod.fit(X_train, y_train)
acc = cross_val_score(mod, X_train, y_train, scoring =
"accuracy", cv = 10)
scores.append(acc.mean())
【讨论】:
不,这不是问题。代码的最后一部分 pandas 数据帧返回错误。 @StanislavJirak 这并不意味着答案是错误的;正如您的代码一样,scores
原来是一个单元素列表(即,您只附加了 for 循环中的最后一个 acc.mean()
),这确实会产生您在下游报告的错误;请包含完整的错误跟踪...
@StanislavJirak,您可以在您的代码中查看scores
的长度,即1
。您正在尝试创建一个数据框,其中一列中包含 11
条目,另一列中包含 1
条目,这会引发错误。 Pandas 抛出错误,该错误的发生是因为列的长度不正确。
我现在明白了。但是如何创建一个有 11 列的空数组呢?我试过代码。
什么意思?为什么要创建任何空数组?此处建议的补救措施可以解决您的问题,另请参阅我的佐证答案...,【参考方案2】:
已经对上一个答案投了赞成票,我继续证明该错误确实是由于您的score.append()
在您的for
循环之外:
我们不需要实际拟合任何模型;我们可以通过对您的代码进行以下修改来模拟这种情况,这不会改变问题的本质:
import numpy as np
import pandas as pd
models = ['ran', 'knn', 'log', 'xgb', 'gbc', 'svc', 'ext', 'ada', 'gnb', 'gpc', 'bag']
scores = []
cv=10
# Sequentially fit and cross validate all models
for mod in models:
acc = np.array([np.random.rand() for i in range(cv)]) # simulate your accuracy here
scores.append(acc.mean()) # as in your code, i.e outside the for loop
# Create a dataframe of results
results = pd.DataFrame(
'Model': ['Random Forest', 'K Nearest Neighbour', 'Logistic Regression', 'XGBoost', 'Gradient Boosting',
'SVC', 'Extra Trees', 'AdaBoost', 'Gaussian Naive Bayes', 'Gaussian Process', 'Bagging Classifier'],
'Score': scores)
不出所料,这基本上复制了您的错误:
ValueError: arrays must all be same length
因为,正如在另一个答案中已经讨论过的,您的 scores
列表只有一个元素,即仅来自循环的 last 迭代的 acc.mean()
:
len(scores)
# 1
scores
# [0.47317491043203785]
因此 pandas 抱怨,因为它无法填充 11 行数据框...
在for
循环内移动scores.append()
,正如另一个答案中已经建议的那样,解决了这个问题:
for mod in models:
acc = np.array([np.random.rand() for i in range(cv)])
scores.append(acc.mean()) # moved inside the loop
# Create a dataframe of results
results = pd.DataFrame(
'Model': ['Random Forest', 'K Nearest Neighbour', 'Logistic Regression', 'XGBoost', 'Gradient Boosting',
'SVC', 'Extra Trees', 'AdaBoost', 'Gaussian Naive Bayes', 'Gaussian Process', 'Bagging Classifier'],
'Score': scores)
print(results)
# output:
Model Score
0 Random Forest 0.492364
1 K Nearest Neighbour 0.624068
2 Logistic Regression 0.613653
3 XGBoost 0.536488
4 Gradient Boosting 0.484195
5 SVC 0.381556
6 Extra Trees 0.274922
7 AdaBoost 0.509297
8 Gaussian Naive Bayes 0.362866
9 Gaussian Process 0.606538
10 Bagging Classifier 0.393950
您可能还需要记住,您的代码中不需要 model.fit()
部分 - cross_val_score
会自行完成所有必要的拟合...
【讨论】:
很好的解释。 @StanislavJirak 希望您了解您的代码有什么问题。以上是关于如何有效地比较所有模型的准确性的主要内容,如果未能解决你的问题,请参考以下文章