将 ROC AUC 分数与 Logistic 回归和 Iris 数据集结合使用
Using ROC AUC score with Logistic Regression and Iris Dataset
我需要的是:
- 应用逻辑回归 classifier
- 使用 AUC 报告每个 class ROC。
- 利用逻辑回归的估计概率来指导ROC的构建。
- 训练模型的 5 倍交叉验证。
为此,我的方法是使用 this 非常好的教程:
根据他的想法和方法,我只是改变了我获取原始数据的方式,我得到的是这样的:
df = pd.read_csv(
filepath_or_buffer='https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data',
header=None,
sep=',')
df.columns=['sepal_len', 'sepal_wid', 'petal_len', 'petal_wid', 'class']
df.dropna(how="all", inplace=True) # drops the empty line at file-end
df.tail()
# split data table into data X and class labels y
X = df.iloc[:,0:4].values
Y = df.iloc[:,4].values
他们我只是运行代码。如果我尝试 运行 用于 accuracy
或
等指标
balanced_accuracy
一切正常(即使有许多其他指标)。我的问题是,当我尝试使用指标 roc_auc
运行 时,出现错误:
"ValueError: Only one class present in y_true. ROC AUC score is not
defined in that case."
已讨论此错误 here1, here2, , and here4。但是,我无法使用他们提供的任何 "solution"/解决方法来解决我的问题。
我的全部代码是:
import warnings
warnings.simplefilter(action='ignore', category=FutureWarning)
import pandas as pd
import numpy as np
import plotly.graph_objs as go
from plotly.offline import init_notebook_mode
from sklearn.preprocessing import StandardScaler
from IPython import get_ipython
get_ipython().run_line_magic('matplotlib', 'qt')
import matplotlib.pyplot as plt
import pandas as pd
from sklearn import model_selection
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.naive_bayes import GaussianNB
from sklearn.ensemble import RandomForestClassifier
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split
df = pd.read_csv(
filepath_or_buffer='https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data',
header=None,
sep=',')
df.columns=['sepal_len', 'sepal_wid', 'petal_len', 'petal_wid', 'class']
df.dropna(how="all", inplace=True) # drops the empty line at file-end
df.tail()
# split data table into data X and class labels y
X = df.iloc[:,0:4].values
Y = df.iloc[:,4].values
#print(X)
#print(Y)
seed = 7
# prepare models
models = []
models.append(('LR', LogisticRegression()))
# evaluate each model in turn
results = []
names = []
scoring = 'roc_auc'
for name, model in models:
kfold = model_selection.KFold(n_splits=5, random_state=seed)
cv_results = model_selection.cross_val_score(model, X, Y, cv=kfold, scoring=scoring)
results.append(cv_results)
names.append(name)
msg = "%s: %f (%f)" % (name, cv_results.mean(), cv_results.std())
print(msg)
# boxplot algorithm comparison
fig = plt.figure()
fig.suptitle('Algorithm Comparison')
ax = fig.add_subplot(111)
plt.boxplot(results)
ax.set_xticklabels(names)
plt.show()
鸢尾花数据集通常根据 classes 排序。因此,当您在不进行洗牌的情况下进行拆分时,测试数据集可能只会得到一个 class。
一个简单的解决方案是使用 shuffle
参数。
kfold = model_selection.KFold(n_splits=10, shuffle=True, random_state=seed)
即便如此 roc_auc
也不直接支持 multi-class 格式(iris - 数据集有三个 classes)。
通过 this link 了解更多关于如何在多 class 情况下使用 roc_auc
的信息。
理想情况下,对于 classification 任务,使用分层 k 折迭代来保持 classes 在训练和测试折叠中的平衡。
在 scikit-learn cross_val_score
中,交叉验证的默认行为取决于任务。文档说:-
cv : int, cross-validation generator or an iterable, optional
Determines the cross-validation splitting strategy. Possible inputs for cv are:
- None, to use the default 3-fold cross validation,
- integer, to specify the number of folds in a (Stratified)KFold,
CV splitter,
An iterable yielding (train, test) splits as arrays of indices.
For integer/None inputs, if the estimator is a classifier and y is either binary or multiclass, StratifiedKFold is used. In all other cases, KFold is used.
现在鸢尾花数据集是一组 150 个样本,按 classes(Iris setosa、Iris virginica 和 Iris versicolor)排序。因此,使用一个简单的 5 折 K 折迭代器将处理训练集中的前 120 个样本和测试集中的后 30 个样本。最后 30 个样本属于单一的 Iris versicolor class.
因此,如果您没有任何特定理由使用 KFold
,那么您可以这样做:
cv_results = model_selection.cross_val_score(model, X, Y, cv=5, scoring=scoring)
但是现在scoring
的问题来了。您使用的 'roc_auc'
仅为二进制 class 化任务定义。因此,要么选择一个不同的指标来代替 roc_auc
,要么指定要将哪个 class 视为阳性,将哪些其他 class 视为阴性。
我需要的是:
- 应用逻辑回归 classifier
- 使用 AUC 报告每个 class ROC。
- 利用逻辑回归的估计概率来指导ROC的构建。
- 训练模型的 5 倍交叉验证。
为此,我的方法是使用 this 非常好的教程:
根据他的想法和方法,我只是改变了我获取原始数据的方式,我得到的是这样的:
df = pd.read_csv(
filepath_or_buffer='https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data',
header=None,
sep=',')
df.columns=['sepal_len', 'sepal_wid', 'petal_len', 'petal_wid', 'class']
df.dropna(how="all", inplace=True) # drops the empty line at file-end
df.tail()
# split data table into data X and class labels y
X = df.iloc[:,0:4].values
Y = df.iloc[:,4].values
他们我只是运行代码。如果我尝试 运行 用于 accuracy
或
等指标
balanced_accuracy
一切正常(即使有许多其他指标)。我的问题是,当我尝试使用指标 roc_auc
运行 时,出现错误:
"ValueError: Only one class present in y_true. ROC AUC score is not defined in that case."
已讨论此错误 here1, here2,
我的全部代码是:
import warnings
warnings.simplefilter(action='ignore', category=FutureWarning)
import pandas as pd
import numpy as np
import plotly.graph_objs as go
from plotly.offline import init_notebook_mode
from sklearn.preprocessing import StandardScaler
from IPython import get_ipython
get_ipython().run_line_magic('matplotlib', 'qt')
import matplotlib.pyplot as plt
import pandas as pd
from sklearn import model_selection
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.naive_bayes import GaussianNB
from sklearn.ensemble import RandomForestClassifier
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split
df = pd.read_csv(
filepath_or_buffer='https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data',
header=None,
sep=',')
df.columns=['sepal_len', 'sepal_wid', 'petal_len', 'petal_wid', 'class']
df.dropna(how="all", inplace=True) # drops the empty line at file-end
df.tail()
# split data table into data X and class labels y
X = df.iloc[:,0:4].values
Y = df.iloc[:,4].values
#print(X)
#print(Y)
seed = 7
# prepare models
models = []
models.append(('LR', LogisticRegression()))
# evaluate each model in turn
results = []
names = []
scoring = 'roc_auc'
for name, model in models:
kfold = model_selection.KFold(n_splits=5, random_state=seed)
cv_results = model_selection.cross_val_score(model, X, Y, cv=kfold, scoring=scoring)
results.append(cv_results)
names.append(name)
msg = "%s: %f (%f)" % (name, cv_results.mean(), cv_results.std())
print(msg)
# boxplot algorithm comparison
fig = plt.figure()
fig.suptitle('Algorithm Comparison')
ax = fig.add_subplot(111)
plt.boxplot(results)
ax.set_xticklabels(names)
plt.show()
鸢尾花数据集通常根据 classes 排序。因此,当您在不进行洗牌的情况下进行拆分时,测试数据集可能只会得到一个 class。
一个简单的解决方案是使用 shuffle
参数。
kfold = model_selection.KFold(n_splits=10, shuffle=True, random_state=seed)
即便如此 roc_auc
也不直接支持 multi-class 格式(iris - 数据集有三个 classes)。
通过 this link 了解更多关于如何在多 class 情况下使用 roc_auc
的信息。
理想情况下,对于 classification 任务,使用分层 k 折迭代来保持 classes 在训练和测试折叠中的平衡。
在 scikit-learn cross_val_score
中,交叉验证的默认行为取决于任务。文档说:-
cv : int, cross-validation generator or an iterable, optional Determines the cross-validation splitting strategy. Possible inputs for cv are:
- None, to use the default 3-fold cross validation,
- integer, to specify the number of folds in a (Stratified)KFold, CV splitter,
An iterable yielding (train, test) splits as arrays of indices.
For integer/None inputs, if the estimator is a classifier and y is either binary or multiclass, StratifiedKFold is used. In all other cases, KFold is used.
现在鸢尾花数据集是一组 150 个样本,按 classes(Iris setosa、Iris virginica 和 Iris versicolor)排序。因此,使用一个简单的 5 折 K 折迭代器将处理训练集中的前 120 个样本和测试集中的后 30 个样本。最后 30 个样本属于单一的 Iris versicolor class.
因此,如果您没有任何特定理由使用 KFold
,那么您可以这样做:
cv_results = model_selection.cross_val_score(model, X, Y, cv=5, scoring=scoring)
但是现在scoring
的问题来了。您使用的 'roc_auc'
仅为二进制 class 化任务定义。因此,要么选择一个不同的指标来代替 roc_auc
,要么指定要将哪个 class 视为阳性,将哪些其他 class 视为阴性。