Использование показателя ROC AUC с помощью логистической регрессии и набора данных Iris - PullRequest
6 голосов
/ 02 мая 2019

Мне нужно:

  • Применить классификатор логистической регрессии
  • Сообщить о ROC для каждого класса с помощью AUC.
  • Используйте оценочные вероятности логистической регрессии для руководства построением РПЦ.
  • 5-кратная перекрестная проверка для обучения вашей модели.

Для этого мой подход заключался в использовании этого действительно хорошего учебника:

ИзЕго идею и метод я просто изменил, как я получаю необработанные данные, которые я получаю так:

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: в y_true присутствует только один класс. В этом случае не определен счет ROC AUC».

Эта ошибка обсуждалась здесь1 , здесь2 , здесь3 и здесь4 .Однако я не смог использовать ни одно из предоставленных ими «решений» / обходных путей, чтобы решить мою проблему.

Весь мой код:

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()

Ответы [ 2 ]

5 голосов
/ 03 мая 2019

Набор данных iris обычно упорядочен по классам. Следовательно, при разделении без перемешивания тестовый набор данных может получить только один класс.

Одним из простых решений было бы использование параметра shuffle.

kfold = model_selection.KFold(n_splits=10, shuffle=True, random_state=seed)

Даже тогда roc_auc не поддерживает напрямую мультиклассовый формат (iris - набор данных имеет три класса).

Перейдите по этой ссылке , чтобы узнать больше информации о том, как использовать roc_auc для ситуации с несколькими классами.

0 голосов
/ 03 мая 2019

В идеале для задач классификации используется итерация со стратифицированным k-кратным смещением, которая сохраняет баланс классов в обучающих и тестовых сгибах.

В 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:
  • Нет, чтобы использовать 3-кратную перекрестную проверку по умолчанию,
  • целое число, чтобы указать количество сгибов в (Стратифицированный) KFold, CV-сплиттер,
  • Итеративный выход (тренировка, тест) разделяется на массивы индексов.

  • Для целочисленных / нулевых входов,если оценщик является классификатором, а y является двоичным или мультиклассовым, используется StratifiedKFold.Во всех остальных случаях используется KFold.

Теперь набор данных iris представляет собой набор из 150 образцов, упорядоченных по классам (Iris setosa, Iris virginica и Irisлишай).Таким образом, использование простого итератора с K-кратным сгибом в 5 сгибов будет обрабатывать первые 120 образцов в обучающем наборе и последние 30 образцов в наборе испытаний.Последние 30 образцов относятся к одному классу Iris versicolor.

Так что если у вас нет особых причин использовать KFold, тогда вы можете сделать это:

cv_results = model_selection.cross_val_score(model, X, Y, cv=5, scoring=scoring)

Но теперь приходитвыпуск scoring.Вы используете 'roc_auc', который определен только для задач двоичной классификации.Поэтому вместо roc_auc выберите другую метрику или укажите, какой класс вы хотите считать положительным, а какие - отрицательным.

...