Что такое KullbackLeiblerSelector?

Это селектор функций, основанный на дивергенции Кульбака-Лейблера.

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

Как это рассчитывается?

Дивергенция Кульбака-Лейблера, также называемая относительной энтропией в теории информации, рассчитывается по следующей формуле:

где P и Q — распределения, а X — пространство выборки. Это для дискретных дистрибутивов.

Использование KullbackLeiblerSelector

Конструктор KullbackLeiblerSelector имеет следующие параметры:

  1. EPS(с плавающей запятой, по умолчанию: 0,0001): небольшое значение, которое нужно добавить в столбец характеристик, чтобы избежать деления на ноль.
  2. min_divergence(int, по умолчанию: 0): минимально допустимое расхождение с целевым столбцом.
  3. max_divergence(int, по умолчанию: 1): максимально допустимое расхождение с целевым столбцом.

Метод select имеет следующие параметры:

  1. dataframe(pd.DataFrame): кадр данных, к которому применяется селектор.
  2. target(str): имя столбца, с которым будут сравниваться столбцы характеристик.

Этот метод возвращает список имен столбцов, выбранных из фрейма данных.

Пример использования KullbackLeiblerSelector

Прежде всего, вам следует установить kydavra, если у вас его еще нет:

pip install kydavra

Теперь вы можете импортировать селектор:

from kydavra import KullbackLeiblerSelector

Импортируйте набор данных и создайте из него кадр данных:

import pandas as pd
df = pd.read_csv('./heart.csv')

Поскольку наш селектор ожидает числовые значения, давайте выберем столбцы с числовым типом данных:

df = df.select_dtypes('number')

Давайте создадим экземпляр нашего селектора и выберем функции по сравнению с «целевым» столбцом:

cols = KullbackLeiblerSelector().select(df, 'target')

Селектор возвращает список имен столбцов функций, которые имеют расхождение с выбранным столбцом между min_divergence и max_divergence.

В этом примере с набором данных heart.csv селектор возвращает следующие столбцы:

['age', 'cp', 'trestbps', 'chol', 'thalach', 'slope', 'thal']

Если мы ограничим расхождение выбранных столбцов между 1 и 3 относительно целевого столбца, мы получим следующее:

['sex', 'restecg', 'oldpeak']

Вариант использования

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

Вы можете найти набор данных здесь: https://www.kaggle.com/ronitf/heart-disease-uci.

Фактически мы создадим две модели. Один будет обучен без выбора функций, а другой — с выбранными функциями из нашего селектора.

Давайте сначала импортируем набор данных:

import pandas as pd
df = pd.read_csv('./heart.csv')
X = df.drop(columns=['target'])
y = df['target']

Теперь давайте создадим модель без селектора:

from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y)
clf = LogisticRegression().fit(X_train, y_train)

Теперь давайте добавим несколько метрик, чтобы можно было сравнить две модели:

from sklearn.metrics import accuracy_score, recall_score, roc_auc_score
print('Without selector:')
print(f'accuracy: {accuracy_score(y_test, clf.predict(X_test)):.2f}')
print(f'recall {recall_score(y_test, clf.predict(X_test)):.2f}')
print(f'AUC {roc_auc_score(y_test, clf.predict(X_test)):.2f}')

Отлично. Проделаем то же самое для второй модели. Но теперь мы применим наш селектор. Сначала импортируйте его:

from kydavra import KullbackLeiblerSelector

Мы будем использовать столбцы, которые имеют расхождение от 1 до 3 относительно целевого столбца (который в этом наборе данных для удобства назван «целевой»):

kullback = KullbackLeiblerSelector(min_divergence=1, max_divergence=3)
cols = kullback.select(df, 'target')
print(f'\nselected columns: {cols}')

Теперь давайте выберем эти столбцы из DataFrame. Целевой столбец остается прежним:

X = df[cols]
y = df['target']

Продолжайте создавать модель и распечатывать метрики:

X_train, X_test, y_train, y_test = train_test_split(X, y)
clf_with_selector = LogisticRegression().fit(X_train, y_train)
print('\nWith selector:')
print(f'accuracy: {accuracy_score(y_test, clf_with_selector.predict(X_test)):.2f}')
print(f'recall {recall_score(y_test, clf_with_selector.predict(X_test)):.2f}')
print(f'AUC {roc_auc_score(y_test, clf_with_selector.predict(X_test)):.2f}')

Вот что мы получаем на выходе:

Without selector:
accuracy: 0.82
recall 0.76
AUC 0.82
selected columns: ['sex', 'restecg', 'oldpeak']
With selector:
accuracy: 0.80
recall 0.88
AUC 0.80

Мы видим, что показатели Accuray и AUC ROC немного ухудшились. Вместо этого отзыв значительно улучшился. В разных случаях результаты могут отличаться. Хотя экспериментирование с параметрами селектора может привести к разнице в результате. Кроме того, не забывайте учитывать другие факторы, такие как набор данных или используемая модель.

Сделано с помощью ❤ от Sigmoid.

Подпишитесь на нас в Facebook, Instagram и LinkedIn:

https://www.facebook.com/sigmoidAI

https://www.instagram.com/sigmo.ai/

https://www.linkedin.com/company/sigmoid/