Математика дискриминантного анализа Гаусса — с кодом.

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



Генеративные алгоритмы обучения

Алгоритмы обучения с учителем можно разделить на две категории:

  • Дискриминативные алгоритмы обучения
  • Алгоритмы генеративного обучения

а. Дискриминативные алгоритмы обучения

Эти алгоритмы пытаются изучить сопоставление между входным пространством, т. е. X, и метками y.
Примеры включают:

  • Линейная регрессия
  • Логистическая регрессия

б. Алгоритмы генеративного обучения

Эти алгоритмы пытаются смоделировать x при заданном y. т. е. они пытаются моделировать P(x|y) и P(y). Примеры включают:

  • Гауссовский дискриминантный анализ
  • Наивный байесовский

После моделирования 𝑝(𝑥|𝑦) и 𝑝(𝑦) наши алгоритмы используют правило Байеса для получения апостериорного распределения по y при заданном x:

Гауссовский дискриминантный анализ

Здесь X непрерывны, а y дискретны. Мы делаем предположение, что P(x|y), то есть X следуют за многомерное нормальное/гауссово распределение.

Импорт

import numpy as np
import pandas as pd

from scipy.stats import multivariate_normal #for calculating the pdf
from sklearn.metrics import accuracy_score #for measuring the accuracy

Данные

Я буду использовать знаменитый набор данных Iris. Он состоит из особенностей трех разных видов цветка ириса.

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

data = pd.read_csv("IRIS.csv")

Предварительная обработка

Здесь нам нужно закодировать столбец видов в дискретные значения. Эти значения будут представлять каждый класс.

def encode_num(x):
    value = None 
    if x == "Iris-setosa":
        value = 0
    if x == "Iris-versicolor":
        value = 1
    if x == "Iris-virginica":
        value = 2

    return value


data['species'] = data['species'].apply(encode_num

Расколоть

Нам нужно будет разделить данные на обучающий набор и тестовый набор. Мы будем использовать 80% данных для обучения и 20% данных для тестирования.

# shuffling the dataset
data = data.sample(frac=1).reset_index(drop=True)

# training set
train_size = int(0.8*len(data))
train_data = data.head(train_size)

# test set
test_size = int(0.2*len(data))
test_data = data.tail(test_size)   

x_train = np.array(train_data.drop("species",axis=1))
y_train = train_data["species"]

Модель

Во-первых, краткий обзор многомерного нормального распределения.

Многомерное нормальное/гауссово распределение

Это сокращенно как

где параметры:

Функция плотности (PDF) распределения определяется следующим образом:

Средний вектор и ковариационная матрица определяют форму PDF.

Моделирование

Модель может быть записана как:

Поскольку X непрерывны, а y дискретны, мы делаем предположение, что P(x|y), то есть X соответствует многомерному нормальному/гауссовскому распределению, а P (у)т.е. y подчиняются распределению Бернулли.

Следовательно, наши параметры равны 𝜙, Σ, µ0, µ1. Чтобы получить значение этих параметров, мы максимизируем логарифмическую вероятность.

логарифмическая вероятность

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

# we calculate the probability of occurence for each of the classes
priors = y_train.value_counts()/len(y_train)

# we calculate the mean values
mean = data.groupby('species').mean()

# we calculate the variance values
covariance = data.groupby('species').cov()

Чтобы сделать прогноз, мы суммируем журнал P (y) с журналом P (x | y) и выбираем класс, содержащий наибольший результат, в качестве прогнозируемого класса.

def predict(x_test, priors, mean , cov):
    
    labels = mean.shape[0]
    results = np.zeros((x_test.shape[0], labels))
    for label in range(labels):
        pdf = multivariate_normal(mean = mean.loc[label], cov = cov.loc[label])
        
        for i, data in enumerate(x_test):
            results[i, label] = np.log(priors[label]) + pdf.logpdf(data)
            
    predictions = np.argmax(results, axis=1)
    return predictions

Оценка

Модель работала достаточно хорошо с точностью 96,6667%, что на самом деле очень хорошо.

x_test = test_data[['sepal_length', 'sepal_width', 'petal_length', 'petal_width']]
y_test = test_data['species']

x_test = np.array(x_test)

preds = predict(x_test,priors,mean,covariance)

print(accuracy_score(y_test,preds) * 100)

Ознакомьтесь с полным кодом по ссылке ниже