Предсказать() и предсказать_проба() в API scikit-learn для прогнозирования в машинном обучении.

В течение долгого времени меня сбивали с толку два метода в библиотеке sklearn, используемые в задачах классификации. Это методы predict() и predict_proba().

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

Классификация и предсказание класса

Классификация — это подмножество контролируемого машинного обучения, которое представляет собой процесс обучения модели таким образом, чтобы она сопоставляла входные функции с выходными функциями. Тот факт, что функция вывода содержит метки классов, противоречит другому подмножеству машинного обучения с учителем — регрессии, которая имеет числовые функции вывода. Таким образом, проблемы классификации основаны на предсказании меток классов, таких как класс 0 и класс 1 (это бинарная классификация только с двумя метками классов, но может быть и несколько меток классов, и в этом случае проблема известная как классификация с несколькими выходами), тогда как задачи регрессии основаны на прогнозировании непрерывных по своей природе значений, таких как 7,5, 87,9 и т. д.

При обучении моделей (точнее, контролируемых моделей) с помощью Sci-kit learn нам иногда нужно предсказать фактический класс, а в некоторых других случаях нам может понадобиться предсказать вероятности класса. Я объясню подробнее, что мы подразумеваем под предсказанием вероятностей класса. Мы обсудим, как использовать методы predict и predict_proba в игрушечном наборе данных для выполнения прогнозов. Кроме того, мы также рассмотрим, когда один используется над другим.

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

## Importing necessary libraries
import os
import pandas as pd, numpy as np
from sklearn.datasets import make_blobs
from sklearn.neighbors import KNeighborsClassifier
##Mute the warnings
import warnings as w
w.filterwarnings(“always”)
w.filterwarnings(“ignore”,category=DeprecationWarning)
## Create your data set
x, y = make_blobs(n_samples=100, centers=2, n_features=4, random_state=42)
##convert to a data frame
x_df = pd.DataFrame(x,columns=‘feature_1’,’feature_2',’feature_3',’feature_4'])
y_df = pd.DataFrame(y,columns=[‘target’])
df = pd.concat([x_df,y_df],axis=1)
# df.rename(columns={‘0’:’feature_1',’1':’feature_2',’2':’feature_3',’3':’feature_4',’0':’target’})
df.head()

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

from sklearn.model_selection import train_test_split
##Splitting the data set
x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.2,random_state=1765)
## Training the classifier
kn = KNeighborsClassifier(algorithm=’ball_tree’,n_jobs=-1)
kn.fit(x_train,y_train)

Теперь мы обучили нашу модель и готовы делать прогнозы для невидимых экземпляров данных, таких как набор тестовых данных, который мы сохранили из нашего игрушечного набора данных. Обратите внимание, что это проблема бинарной классификации, т.е. у нас есть только два класса для прогнозирования — класс 0 и класс 1. Более того, набор данных составлен таким образом, что он сбалансирован т.е. количество экземпляров данных в обоих классах равно 50, как показано в выходных данных, приведенных ниже. (Когда доля одного ярлыка класса превышает число ярлыков другого класса, это называется несбалансированным набором данных).

Метод прогнозирования ()

Когда нам нужно сделать прогнозы фактических меток классов, мы используем метод predict().

Этот метод прогнозирует фактические метки классов для новых данных, которые вводятся с функциями, на которых модель уже обучена. Модель, основанная на ее обучении, предсказывает фактические метки классов для невидимых данных (т. е. данных, не используемых в процессе обучения — в данном случае x_test). Следовательно, этот метод даст либо 0, либо 1, соответствующие двум классам в нашем наборе данных.

Обратите внимание, что мы обучили модель только на 80% наших данных, а 20% были оставлены для целей тестирования.

predictions = kn.predict(x_test)
pred_df = pd.concat([pd.DataFrame(x_test),pd.DataFrame(y_test),pd.DataFrame(predictions)],axis=1,
 ignore_index=True)
pred_df.rename(columns={0:’feature_1',1:’feature_2',2:’feature_3',3:’feature_4',4:’Actual labels’,5:’Predicted labels’},
 inplace=True)
pred_df.head(10)

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

Метод pred_proba()

Когда мы намерены получить вероятности каждого из наших классов, мы используем метод predict_proba().

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

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

predictions_prob = kn.predict_proba(x_test)
for i in range(3):
 print(“X = %s |***| actual labels = %s |***| predicted labels = %s” % (x_test[i],y_test[i],predictions_prob[i]))

Интерпретация

Как мы интерпретируем результаты здесь, глядя на массивы предсказанных вероятностей; в первой точке данных массив имеет 1 по первому индексу и 0 по другому индексу, что означает, что вероятность того, что точка данных принадлежит классу 0, равна 1, а вероятность того, что точка данных принадлежит классу 1, равна 0. Следовательно, у нас есть наш окончательный прогноз как 0. Все прогнозы сделаны на основе меток классов, имеющих самые высокие вероятности, а затем эти прогнозы сравниваются с фактическими значениями, чтобы установить точность, т.е. сколько прогнозов было действительно правильным, а сколько было нет!

Заключение

› Обратите внимание, что вероятности в массиве могут быть любыми непрерывными значениями от 0 до 1 и не обязательно принимать только целочисленные значения от 0 до 1. Подобные вероятности могут быть [0,6,0,4], и в этом случае у нас будет класс 0 только как наш окончательный прогноз, поскольку этот класс имеет более высокую вероятность.

› Законы вероятности останутся неизменными, т. е. сумма вероятностей всегда будет равна единице.

Надеюсь, это прольет свет на методы и прояснит ваши опасения, если таковые имеются.

Не стесняйтесь связаться со мной и ознакомиться с моими проектами в области Data science/ML. Спасибо за ваше время!

Github: https://github.com/keyush06

LinkedIn: https://www.linkedin.com/in/keyush-shah-3a1b32184/