TL; DR;

HandySpark - это пакет Python, предназначенный для улучшения взаимодействия с пользователем PySpark, особенно когда дело доходит до исследовательского анализа данных, включая визуализацию возможности, а теперь и расширенные показатели оценки для двоичных классификаторов.

Попробуйте сами с помощью Google Colab:



Google Colaboratory
Изучение Титаника с помощью HandySpark colab.research.google.com



Проверить репозиторий:



Вступление

В моем предыдущем сообщении я представил HandySpark, пакет для PySpark, который я разработал, чтобы помочь сократить разрыв между pandas и Spark. фреймы данных.

Сегодня я рад объявить о выпуске новой версии, которая не только решает некоторые проблемы с производительностью с помощью стратифицированных операций (которые теперь должны быть в несколько раз быстрее!) , но также значительно упрощает оценку двоичных классификаторов.

Задача двоичной классификации

Мы воспользуемся простой задачей двоичной классификации, чтобы проиллюстрировать расширенные возможности оценки, предоставляемые HandySpark: еще раз прогнозировать выживаемость пассажиров с использованием набора данных Титаник.

Давайте сначала настроим все и загрузим наши данные:

Чтобы оценить модель, нам нужно сначала ее обучить. Чтобы обучить модель, нам нужно сначала очистить набор данных. Итак, начнем с этого!

Очистка данных с помощью HandySpark

Мы знаем, что для Age, Cabin и Embarked отсутствуют значения. Вы можете легко убедиться в этом, используя метод isnull.

Чтобы наша модель и конвейер были как можно более простыми, давайте остановимся на числовых только переменных, например Age, Fare, SibSp и Parch.

Для вменения пропущенных значений для Age мы могли бы просто использовать простое среднее для каждого пропущенного значения, верно? Но действительно ли вы думаете, что возраст мужчин и женщин первого, второго и третьего классов был одинаковым?

Давайте проверим это с помощью операции thestratify, примерно так:

hdf.stratify(['Pclass', 'Sex']).cols['Age'].mean()
Pclass  Sex   
1       female    34.611765
        male      41.281386
2       female    28.722973
        male      30.740707
3       female    21.750000
        male      26.507589
Name: Age, dtype: float64

Разница явно есть ... женщины были моложе мужчин и чем ниже класс, тем моложе пассажиры. Неудивительно, я бы сказал ...

А как насчет выбросов? Мы можем использовать метод заборов Тьюки, чтобы определить, а затем значения заборов, которые считаются экстремальными. Сколько у нас выбросов для Fare?

hdf.cols['Fare'].outliers(k=3)
Fare    53
Name: outliers, dtype: int64

Имейте в виду, что заборы Тьюки довольно чувствительны: они предполагают, что все, выше k раз межквартильного диапазона (IQR), является крайними значениями. В нашем случае это привело к 53 выбросам! Однако вы можете попробовать другие значения для k, чтобы откалибровать его…

Итак, давайте воспользуемся тем, что мы узнали о данных, чтобы очистить их. Сначала мы заполняем отсутствующие Age значения в соответствии с их средними значениями для заданных Pclass и Sex. Затем мы ограждаем Fare значения с помощью метода Тьюки:

Построение модели

Получив чистый набор данных, мы можем построить простой классификатор, чтобы предсказать, выжил ли пассажир в катастрофе Титаника или нет. Давайте воспользуемся для этой задачи RandomForestClassifier Spark.

Но помните, что алгоритмам Spark ML необходимо, чтобы все функции были аккуратно собраны в вектор функций. Более того, этот вектор признаков не принимает отсутствующие значения.

Как с этим справиться? Мы можем просто использовать методы imputer и fencer HandySpark для создания соответствующих преобразователей для заполнения отсутствующих значений и ограждения выбросов. Затем мы добавляем эти трансформаторы в наш конвейер, и все готово!

Как выглядят наши прогнозы? Давайте сделаем DataFrame HandyFrame и посмотрим на наши ярлыки и прогнозы, созданные классификатором:

predictions.toHandy().cols[['probability', 'prediction', 'Survived']][:5]

Столбец вероятность содержит вектор с вероятностями, связанными с классами 0 и 1 соответственно. Для целей оценки нам нужна вероятность быть положительным случаем, поэтому мы должны смотреть на второй элемент вектора вероятности. Столбец прогноз показывает нам соответствующий класс при пороге 0,5.

Оценка модели

Насколько хороша наша модель? Мы могли бы просто вычислить долю строк с совпадающим прогнозом и оставшимися столбцами, что и будет нашей точностью. Однако оказывается, что точность не такой уж хороший показатель для оценки двоичного классификатора.

Чтобы точно определить, насколько хороша наша модель, нам нужны другие показатели, такие как истинно положительный рейтинг (TPR, также известный как отзыв), частота ложных срабатываний (FPR) и точность, которые различаются в зависимости от порог мы выбираем, чтобы превратить предсказанные вероятности в предсказанные классы (0 или 1).

Если мы превысим все возможные пороговые значения и вычислим эти показатели, мы сможем построить как Рабочие характеристики приемника (ROC) кривая и кривая Precision-Recall (PR) для данной модели.

Возникает другой вопрос: как сравнить две модели, используя эти кривые? Они могут пересекаться друг с другом в разных точках, верно? Один из способов решения этой проблемы - посмотреть на область под кривой: чем больше площадь, тем лучше модель, грубо говоря. Таким образом, мы можем вычислить площадь под кривой ROC (AUROC, ROC AUC или иногда просто AUC) и Площадь под кривой PR (PR AUC).

Если вы хотите узнать больше обо всех этих показателях, ознакомьтесь с этими статьями: Смущает матрица неточностей, Демистифицированы кривые рабочих характеристик приемника, Понимание AUC - кривой ROC и Понимание кривых ROC (интерактивно).

Оценка модели с помощью PySpark

У нас есть и хорошие, и некоторые плохие новости ... хорошие новости: PySpark дает нам и то, и другое ROC AUC и PR AUC. Плохие новости: PySpark дает нам ТОЛЬКО то :-(

Что, если мы хотим поэкспериментировать с разными порогами? HandySpark нам на помощь :-)

Оценка модели с помощью HandySpark

HandySpark расширяет PySpark BinaryClassificationMetrics, поскольку его Java-аналог уже имеет несколько методов для получения показателей и пороговых значений, которые теперь доступны в HandySpark. Но есть и недавно реализованные методы.

HandySpark также позволяет использовать DataFrame, содержащий прогнозируемые вероятности и метки в качестве аргумента, как показано в сущности ниже:

Давайте рассмотрим все эти новые возможности оценки модели.

Построение кривых

Изображение стоит тысячи слов! Итак, давайте начнем с графиков обеих кривых, используя методы plot_roc_curve и plot_pr_curve. Это так просто:

fig, axs = plt.subplots(1, 2, figsize=(12, 4))
bcm.plot_roc_curve(ax=axs[0])
bcm.plot_pr_curve(ax=axs[1])

Вуаля! Теперь мы можем сказать, что, если мы согласны принять ложноположительную ставку в 20%, мы получим истинно положительную оценку выше 60%. Достаточно хорошо? Прохладный!

Вы спросите, какой порог мы должны использовать для этого?

Пороги и показатели

Мы можем получить все пороговые значения и соответствующие показатели с помощью метода getMetricsByThreshold. Он возвращает Spark DataFrame, который мы затем можем отфильтровать по интересующей нас метрике (в нашем случае FPR от 19% до 21%):

bcm.getMetricsByThreshold().filter('fpr between 0.19 and 0.21').toPandas()

Нам нужно, чтобы вероятность ложных срабатываний составляла не более 20%, поэтому соответствующий порог равен 0,415856. Это даст нам True Positive Rate (Отзыв) 68,1% и точность 68,3%.

Мы также могли бы взглянуть на матрицу путаницы, построенную с использованием этого конкретного порога, которая дает только что полученные нами показатели.

Матрица путаницы

Матрицы путаницы могут быть, э ... запутанными! ;-) Чтобы попытаться свести к минимуму любую неверную интерпретацию, которая могла возникнуть в результате его чтения, я пометил как столбцы, так и строки, поэтому вам не нужно угадывать, какой класс на первом месте и какие из них являются прогнозируемыми и фактическими значениями.

Просто вызовите print_confusion_matrix с выбранным вами порогом, и все, вот так:

bcm.print_confusion_matrix(.415856)

Последние мысли

Моя цель - улучшить взаимодействие с пользователем PySpark, упростив очистку данных и оценку модели . Излишне говорить, что это работа, и я уже запланировал еще много улучшений.

Если вы специалист по данным, использующий PySpark, я надеюсь, что вы попробуете HandySpark и поделитесь со мной своими мыслями по этому поводу :-)



Если у вас есть мысли, комментарии или вопросы, оставьте комментарий ниже или свяжитесь со мной в Twitter.