Что такое KullbackLeiblerSelector?
Это селектор функций, основанный на дивергенции Кульбака-Лейблера.
Дивергенция — это мера различия между двумя вероятностными распределениями. В случае машинного обучения мы можем рассмотреть распределения данных и рассчитать, насколько отличается определенный столбец признаков от целевого столбца.
Как это рассчитывается?
Дивергенция Кульбака-Лейблера, также называемая относительной энтропией в теории информации, рассчитывается по следующей формуле:
где P и Q — распределения, а X — пространство выборки. Это для дискретных дистрибутивов.
Использование KullbackLeiblerSelector
Конструктор KullbackLeiblerSelector имеет следующие параметры:
- EPS(с плавающей запятой, по умолчанию: 0,0001): небольшое значение, которое нужно добавить в столбец характеристик, чтобы избежать деления на ноль.
- min_divergence(int, по умолчанию: 0): минимально допустимое расхождение с целевым столбцом.
- max_divergence(int, по умолчанию: 1): максимально допустимое расхождение с целевым столбцом.
Метод select имеет следующие параметры:
- dataframe(pd.DataFrame): кадр данных, к которому применяется селектор.
- 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