Thursday, June 16, 2022

Fisher's linear discriminant in Python

Линейный дискриминантный анализ Фишера — это алгоритм, используемый для классификации, уменьшения размерности, визуализации данных и разработки признаков. Алгоритм проецирует точки данных в новое пространство таким образом, что точки данных, принадлежащие определенному классу, собираются вместе с меньшей дисперсией внутри класса, а классы будут максимально разделены (максимальная дисперсия между классами). Когда классы будут отделены друг от друга, а точки данных, принадлежащие каждому классу, будут упакованы ближе, будет легко классифицировать точки данных. Критерий Фишера находит направление, в котором среднее значение между классами максимизируется, в то время как общая изменчивость минимизируется (общая изменчивость - это среднее значение ковариационных матриц внутри класса). И для каждых двух классов есть только одна такая линия. Вот почему, когда ваши данные имеют Х классов , LDA может предоставить вам не более Х-1 размерностей, независимо от исходной размерности данных. Если у вас есть только 2 класса A и B, вы получите одномерную проекцию, то есть линию. 

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

Обычно мы проецируем точки данных в пространстве измерения X-1, где X — количество классов.

FDA - это LDA с практической точки зрения, фактическое различие проистекает из теории, которая приводит к правилу классификатора, поскольку LDA предполагает распределение по Гауссу, а идея Фишера заключалась в том, чтобы проанализировать соотношение внутренних и внешних дисперсий класса.

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

===================================

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

Основная идея состоит в том, чтобы изучить набор параметров w ∈ R (d×d′), которые используются для проецирования заданных данных x ∈ R(d) на меньшее измерение d′. Ниже показана иллюстрация. Исходные данные имеют 2 измерения, d=2, и мы хотим спроецировать их на 1 измерение, d=1.







Если мы проецируем точки двумерных данных на линию (1-D) из всех таких линий, наша цель состоит в том, чтобы найти ту, которая максимизирует расстояние между средними значениями двух классов после проецирования. Если бы мы могли это сделать, мы могли бы добиться хорошего разделения между классами в 1-D. Это показано на рисунке слева и может быть отражено в идее максимизации «ковариации между классами». Однако, как мы видим, это вызывает много перекрытий между проецируемыми классами. Мы также хотим свести к минимуму это дублирование. Чтобы справиться с этим, LDA Фишера пытается минимизировать «внутриклассовую ковариацию» каждого класса. Минимизация этой ковариации приводит нас к проекции на рисунке справа, которая имеет минимальное перекрытие. Формализуя это, мы можем представить цель следующим образом.

==================================

Максимизация этого выражения = цель Fischer LDA

















где Xnk — n-й пример данных в k-м классе, Nk — количество примеров в k-м классе, m — общее среднее значение всех данных, а mk — среднее значение k-го класса. Теперь, используя дуальный Лагранж и условия ККТ, задачу максимизации J можно преобразовать в решение:







которая является проблемой собственных значений для матрицы inv(Sw).Sb . Таким образом, нашим окончательным решением для w будут собственные векторы приведенного выше уравнения, соответствующие наибольшим собственным значениям. Для приведения к d' измерениям мы берем d' самых больших собственных значений, так как они будут содержать больше всего информации. Также обратите внимание, что если у нас есть K классов, максимальное значение d′ может быть K−1.

Математические выкладки подробно выполнены в работе 

http://www.svcl.ucsd.edu/courses/ece271B-F09/handouts/Dimensionality2.pdf     (стр. 19-27)

Пример Пайтон кода

(.env) boris@boris-All-Series:~/VOTING$ cat specificFLDA.py

import matplotlib.pyplot as plt

import numpy as np

a = np.random.multivariate_normal((1.5, 3), [[0.5, 0], [0, .05]], 20)

b = np.random.multivariate_normal((4, 1.5), [[0.5, 0], [0, .05]], 20)

plt.plot(a[:,0], a[:,1], 'b.', b[:,0], b[:,1], 'r.')

mu_a, mu_b = a.mean(axis=0).reshape(-1,1), b.mean(axis=0).reshape(-1,1)

Sw = np.cov(a.T) + np.cov(b.T)

inv_S = np.linalg.inv(Sw)

res = inv_S.dot(mu_a-mu_b)  # the trick

plt.plot([-res[0], res[0]], [-res[1], res[1]]) # this is the solution

plt.plot(mu_a[0], mu_a[1], 'cx')

plt.plot(mu_b[0], mu_b[1], 'yx')

plt.gca().axis('square')

############################

# Project data point on it

############################

r = res.reshape(2,)

n2 = np.linalg.norm(r)**2

for pt in a:

    prj = r * r.dot(pt) / n2

    plt.plot([prj[0], pt[0]], [prj[1], pt[1]], 'b.:', alpha=0.2)

for pt in b:

    prj = r * r.dot(pt) / n2

    plt.plot([prj[0], pt[0]], [prj[1], pt[1]], 'r.:', alpha=0.2)

plt.show()

















No comments:

Post a Comment