Перейти к содержанию
Публикация AiManual

Линейный дискриминантный анализ в практике: как LDA упрощает классификацию и помогает понять признаки

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

Коротко

Что будет в материале

  1. 01

    Что такое линейный дискриминантный анализ и что он дает на практике

  2. 02

    Как работает метод линейного дискриминантного анализа

  3. 03

    LDA и PCA: какую задачу решает каждый метод

  4. 04

    Практический пример LDA для классификации на табличном датасете в Python

Что такое линейный дискриминантный анализ и что он дает на практике

Линейный дискриминантный анализ, или LDA, это метод обучения с учителем, который использует метки классов и ищет линейные комбинации признаков с максимальным разделением категорий. Метод одновременно учитывает расстояние между центрами классов и разброс объектов внутри каждого класса.

В режиме классификатора LDA обучается на парах X и y, после чего возвращает класс через predict и вероятности через predict_proba. В режиме снижения размерности тот же обученный объект применяют через transform: он переводит исходные признаки в дискриминантные координаты, где классы должны разделяться заметнее.

LDA особенно полезен для табличных данных, когда классы уже известны, нужна компактная визуализация и требуется понять, какие направления признакового пространства связаны с границами между категориями. Для K классов метод может построить не больше K - 1 дискриминантных компонент. При двух классах остается одно направление, при трех доступны максимум две координаты.

LDA как метод снижения размерности и как классификатор

Эти два сценария часто смешивают, хотя задачи у них разные. Для классификации вызов fit(X_train, y_train) оценивает параметры распределений классов и границу решений. Затем predict(X_test) назначает каждому объекту категорию.

Для снижения размерности сначала выполняют тот же вызов fit, а потом передают данные в transform. LDA не сжимает признаки по общей дисперсии. Он строит координаты с учетом y, поэтому результат зависит от выбранной целевой переменной.

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

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

Переобучать LDA отдельно на тестовой выборке нельзя. Тестовые объекты нужно проецировать теми же параметрами, которые метод получил на обучающей части.

Когда LDA имеет практический смысл

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

  • Табличная классификация. Примерами могут быть медицинские измерения, характеристики товаров, параметры оборудования или числовые признаки документов.
  • Визуализация классов. При трех и более категориях две дискриминантные координаты позволяют построить информативный график.
  • Компактное представление. Число LDA-компонент ограничено количеством классов, поэтому размерность часто сокращается сильнее, чем при PCA.
  • Интерпретация. Коэффициенты и направления проекции дают отправную точку для анализа признаков.

LDA не гарантирует улучшение качества относительно деревьев, логистической регрессии или ансамблей. Если данные имеют сложную нелинейную структуру, метод лучше использовать как диагностический baseline.

Как работает метод линейного дискриминантного анализа

LDA ищет такой вектор весов w, чтобы после проекции z = w^T x центры классов оказались далеко друг от друга, а объекты внутри каждой категории оставались близко к своему центру. Хорошее направление одновременно увеличивает межклассовое рассеяние и уменьшает внутриклассовое.

Межклассовое и внутриклассовое рассеяние

Внутриклассовое рассеяние описывает разброс объектов вокруг среднего значения своего класса. Если признаки внутри категории сильно разбросаны, линейной границе сложнее отделить один класс от другого.

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

Математическая постановка LDA ищет направления, которые максимизируют отношение межклассового рассеяния к внутриклассовому. В матричной форме это приводит к обобщенной задаче на собственные значения для матриц S_B и S_W. Полный вывод нужен для реализации алгоритма с нуля, но для прикладной работы достаточно помнить критерий: разделить центры и сжать внутренний разброс.

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

Почему количество компонент ограничено числом классов

Средние значения K классов могут образовать не больше K - 1 независимых направлений различий. Поэтому LDA с тремя классами дает максимум две компоненты, с четырьмя классами, максимум три.

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

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

LDA и PCA: какую задачу решает каждый метод

LDA и PCA часто сравнивают, потому что оба метода переводят исходные признаки в новое пространство. Критерии у них разные: PCA ищет направления максимальной общей дисперсии, а LDA ищет направления максимальной разделимости известных классов.

Главное различие: дисперсия против разделимости классов

PCA работает без целевой переменной y. Он анализирует только структуру X и выбирает оси, на которых данные меняются сильнее всего. Направление с большой дисперсией может описывать шум, размер объекта или общий масштаб измерений, не помогая различать категории.

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

КритерийPCALDA
Нужны метки классовНетДа
ЦельСохранить общую дисперсиюУвеличить разделимость классов
Тип обученияБез учителяС учителем
Максимальное число компонентОграничено числом признаков и рангом данныхНе больше числа классов минус один
Типичная рольEDA, устранение избыточности, компактное представлениеКлассификация, supervised-визуализация, анализ границ

Представьте данные, где объекты двух классов вытянуты вдоль одной оси, но различаются по другой, менее дисперсионной координате. PCA выберет направление вытянутости, а LDA постарается найти ось, которая лучше отделяет категории.

Когда выбрать PCA, когда LDA, а когда сравнить оба подхода

PCA логичнее начать, если метки отсутствуют, сомнительны или нужно изучить общую структуру набора. Он помогает увидеть коррелированные признаки и уменьшить избыточность до обучения классификатора.

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

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

Практический пример LDA для классификации на табличном датасете в Python

Для примера подойдет встроенный набор Iris из scikit-learn. Он содержит 150 наблюдений, четыре числовых признака и три класса. Внешние файлы не нужны, поэтому пример можно воспроизвести в окружении с установленными scikit-learn и matplotlib.

Подготовка данных и разделение на train и test

Сначала разделите признаки и целевую переменную, после чего создайте стратифицированные обучающую и тестовую выборки. Параметр stratify=y сохраняет пропорции классов в обеих частях.

Масштабирование полезно, когда признаки измеряются в разных единицах. Его нужно обучать только на train. Поэтому StandardScaler помещают в Pipeline: конвейер сам применит преобразование к тесту с параметрами, полученными на обучении.

from sklearn.datasets import load_iris
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.metrics import accuracy_score, classification_report
from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
import matplotlib.pyplot as plt

iris = load_iris(as_frame=True)
X = iris.data
y = iris.target

X_train, X_test, y_train, y_test = train_test_split(
    X,
    y,
    test_size=0.25,
    random_state=42,
    stratify=y
)

model = Pipeline([
    ('scale', StandardScaler()),
    ('lda', LinearDiscriminantAnalysis())
])

В коде зафиксирован random_state, поэтому разбиение повторяется при следующих запусках. Это удобно для отладки и сравнения изменений в пайплайне.

Обучение LinearDiscriminantAnalysis и получение предсказаний

Метод fit получает только обучающую часть. После обучения доступны обычные предсказания классов, вероятности и отчет с precision, recall и F1 для каждой категории.

model.fit(X_train, y_train)

y_pred = model.predict(X_test)

print(f'Точность: {accuracy_score(y_test, y_pred):.3f}')
print(classification_report(
    y_test,
    y_pred,
    target_names=iris.target_names
))

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

predict_proba пригодится, если нужно получить вероятности классов или настроить порог принятия решения:

probabilities = model.predict_proba(X_test)
print(probabilities[:3])

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

Снижение размерности через transform

После обучения тот же объект переводит строки в дискриминантные координаты. Обучать отдельный LDA на тестовой части нельзя: в таком случае train и test получат разные оси, а оценка потеряет смысл.

X_train_lda = model.transform(X_train)
X_test_lda = model.transform(X_test)

y_test_array = y_test.to_numpy()

fig, ax = plt.subplots(figsize=(7, 5))
for label, name in enumerate(iris.target_names):
    mask = y_test_array == label
    ax.scatter(
        X_test_lda[mask, 0],
        X_test_lda[mask, 1],
        label=name,
        alpha=0.8
    )

ax.set_xlabel('LD1')
ax.set_ylabel('LD2')
ax.set_title('Проекция тестовой выборки в LDA')
ax.legend()
plt.tight_layout()
plt.show()

В Iris три класса, поэтому доступны две компоненты. Для бинарной задачи обращение к столбцу с индексом 1 вызовет ошибку: там нужно строить одномерный график по LD1.

Как LDA помогает визуализировать классы и понимать признаки

График дискриминантных компонент

Scatter plot по LD1 и LD2 показывает положение объектов после supervised-проекции. Цвет кодирует класс, а расстояние между облаками помогает оценить, насколько категории разделимы в найденном пространстве.

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

Знак дискриминантной компоненты произволен. Ось может развернуться, поэтому положительное значение LD1 в одном запуске способно соответствовать отрицательному значению в другом. Геометрия и относительные расстояния при таком отражении сохраняются.

Как читать коэффициенты и scalings_

У обученного объекта LDA есть несколько параметров с разным смыслом. Атрибут coef_ хранит коэффициенты линейных решающих функций для классов. Он помогает понять, как признаки участвуют в расчете оценок классификатора.

Атрибут scalings_ описывает линейное преобразование в дискриминантное пространство. Его столбцы соответствуют направлениям, которые используются при transform. В примере после стандартизации четыре строки соответствуют четырем исходным признакам, а две колонки, двум компонентам.

lda = model.named_steps['lda']

print('scalings_:')
print(lda.scalings_)

print('coef_:')
print(lda.coef_)

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

Коррелированные признаки усложняют интерпретацию. Они могут делить между собой одну и ту же информацию, из-за чего коэффициенты меняются при небольшом изменении выборки, хотя качество модели остается близким. Для solver, который поддерживает scalings_, набор доступных атрибутов зависит от реализации и версии scikit-learn, поэтому результат нужно сверять с фактическим объектом модели.

Почему вклад признака не равен причинному влиянию

Большой по модулю коэффициент означает, что признак участвует в линейном разделении при конкретных данных, масштабе и наборе остальных переменных. Он не доказывает, что признак вызывает принадлежность объекта к классу.

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

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

Предпосылки LDA и ситуации, где метод начинает ломаться

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

Реальные данные часто нарушают эти условия. Метод все еще может давать полезный baseline, но результат нужно подтверждать валидацией и сравнением с моделями, которые лучше описывают структуру конкретного набора.

Нелинейные границы и сложная структура классов

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

В такой ситуации сравните LDA с деревьями решений, ансамблями, kernel-методами или нелинейными преобразованиями признаков. Выбор альтернативы зависит от размера набора, требований к объяснимости и характера ошибок. Одна визуализация не заменяет метрики на отложенных данных.

Мультиколлинеарность, мало наблюдений и сингулярная ковариация

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

Перед обучением проверьте корреляции, удалите очевидные дубликаты и сократите избыточные признаки. Для регуляризации в scikit-learn доступны варианты shrinkage с solver lsqr или eigen. Например, для классификации можно проверить LinearDiscriminantAnalysis(solver='lsqr', shrinkage='auto'). Если требуется еще и transform, учитывайте ограничения выбранного solver и проверяйте поддержку проекции в своей версии библиотеки.

Регуляризация не исправляет плохую разметку и не превращает нелинейную задачу в линейную. Она снижает чувствительность оценки ковариации к шуму и ограниченному числу наблюдений.

Выбросы, дисбаланс классов и пропуски

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

Дисбаланс классов способен скрыть плохое качество на редкой категории. Используйте стратифицированное разбиение, смотрите recall и F1 по каждому классу, а для общего сравнения добавьте macro F1 или balanced accuracy.

Пропуски нужно обработать до LDA. Импутацию следует включить в Pipeline, чтобы статистики для заполнения вычислялись только на train-части. Так сохраняется граница между обучением и оценкой.

Как проверить, подходит ли LDA для вашей задачи

Минимальный протокол проверки

  1. Определите цель: нужен классификатор, компактное представление, визуализация или анализ признаков.
  2. Проверьте типы данных, пропуски, выбросы, дубликаты и баланс классов.
  3. Разделите выборку на train и test со стратификацией по целевой переменной.
  4. Соберите Pipeline с импутацией и масштабированием, если эти шаги нужны.
  5. Обучите LDA только на train-части.
  6. Оцените accuracy вместе с precision, recall, F1 и матрицей ошибок по классам.
  7. Проведите стратифицированную кросс-валидацию на обучающей части и подберите параметры только внутри этого контура.
  8. Сравните LDA с PCA-пайплайном и несколькими простыми классификаторами, например логистической регрессией и деревом решений.
  9. Проверьте устойчивость коэффициентов и дискриминантных направлений при разных разбиениях.

Такой протокол отделяет качество обобщения от красивой картинки. Проекция может хорошо разделять обучающие точки и при этом давать слабый результат на новых объектах.

Когда LDA стоит оставить в рабочем решении

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

Если качество уступает нелинейным моделям, коэффициенты нестабильны или классы сильно пересекаются, используйте LDA как baseline и инструмент диагностики. Основную модель выбирайте по качеству на новых данных, стоимости ошибок и требованиям к объяснимости.

Вывод: LDA полезен там, где классификацию нужно еще и объяснить

Линейный дискриминантный анализ использует метки классов, ищет направления с высокой разделимостью и может работать сразу в двух режимах: классификация через predict и снижение размерности через transform. Число дискриминантных компонент не превышает количества классов минус один.

Для табличных задач LDA дает компактный baseline, понятную визуализацию и параметры для первичного анализа признаков. PCA отвечает на другую задачу: сохраняет общую дисперсию без использования y.

Проверяйте LDA на стратифицированной валидации, учитывайте линейность границ, распределения внутри классов, ковариации, выбросы и баланс категорий. Коэффициенты помогают объяснить статистическую связь с решением модели, но не доказывают причинное влияние признаков.

Подписаться на канал