Что такое ItakuraSaitoSelector?

Это селектор, основанный на расхождении Итакура-Сайто, который измеряет разницу между исходным спектром и его аппроксимацией. Спектр можно рассматривать как непрерывное распределение.

Поскольку в машинном обучении мы обычно имеем дело с наблюдаемыми данными, мы будем рассматривать дискретные распределения или конечные распределения.

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

Дивергенция Итакура-Сайто - это дивергенция Брегмана, порожденная минус-логарифмической функцией. Его можно рассчитать по следующей формуле:

где P и Q — распределения.

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

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

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

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

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

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

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

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

pip install kydavra

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

from kydavra import ItakuraSaitoSelector

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

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

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

df = df.select_dtypes('number')

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

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

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

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

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

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

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

Для расхождения между 1 и 2 получаем:

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

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

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

Вы можете найти набор данных здесь: 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 ItakuraSaitoSelector

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

itakura = ItakuraSaitoSelector(min_divergence=1, max_divergence=3)
cols = itakura.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.79
recall 0.90
AUC 0.79
selected columns: ['age', 'trestbps', 'chol', 'thalach', 'slope', 'thal']
With selector:
accuracy: 0.82
recall 0.86
AUC 0.81

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

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

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

https://www.facebook.com/sigmoidAI

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

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