exponenta event banner

Классификация

В этом примере показано, как выполнить классификацию с использованием дискриминантного анализа, наивных классификаторов Байеса и деревьев решений. Предположим, что у вас есть набор данных, содержащий наблюдения с измерениями различных переменных (называемых предикторами) и их известные метки классов. Если вы получите предикторные значения для новых наблюдений, можете ли вы определить, к каким классам, вероятно, относятся эти наблюдения? Это проблема классификации.

Данные Айрис Фишера

Данные Фишера состоят из измерений длины чашелистика, ширины чашелистика, длины лепестка и ширины лепестка для 150 экземпляров радужки. Существует по 50 экземпляров от каждого из трёх видов. Загрузите данные и посмотрите, как измерения чашелистики различаются между видами. Можно использовать два столбца, содержащие измерения чашелистиков.

load fisheriris
f = figure;
gscatter(meas(:,1), meas(:,2), species,'rgb','osd');
xlabel('Sepal length');
ylabel('Sepal width');
N = size(meas,1);

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

Линейный и квадратичный дискриминантный анализ

fitcdiscr функция может выполнять классификацию с использованием различных типов дискриминантного анализа. Сначала классифицируйте данные с помощью линейного дискриминантного анализа (LDA) по умолчанию.

lda = fitcdiscr(meas(:,1:2),species);
ldaClass = resubPredict(lda);

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

ldaResubErr = resubLoss(lda)
ldaResubErr =

    0.2000

Можно также вычислить матрицу путаницы на обучающем наборе. Матрица путаницы содержит информацию об известных метках классов и прогнозируемых метках классов. Вообще говоря, элемент (i, j) в матрице путаницы является числом выборок, чья известная метка класса является классом i и чей прогнозируемый класс является j. Диагональные элементы представляют корректно классифицированные наблюдения.

figure
ldaResubCM = confusionchart(species,ldaClass);

Из 150 обучающих наблюдений 20% или 30 наблюдений неправильно классифицируются линейной дискриминантной функцией. Вы можете увидеть, какие они, нарисовав X через неправильно классифицированные точки.

figure(f)
bad = ~strcmp(ldaClass,species);
hold on;
plot(meas(bad,1), meas(bad,2), 'kx');
hold off;

Функция разделила плоскость на области, разделенные линиями, и назначила различные области различным видам. Одним из способов визуализации этих областей является создание сетки из значений (x, y) и применение функции классификации к этой сетке.

[x,y] = meshgrid(4:.1:8,2:.1:4.5);
x = x(:);
y = y(:);
j = classify([x y],meas(:,1:2),species);
gscatter(x,y,j,'grb','sod')

Для некоторых наборов данных области для различных классов плохо разделены линиями. Когда это так, линейный дискриминантный анализ не подходит. Вместо этого вы можете попробовать квадратичный дискриминантный анализ (QDA) для наших данных.

Вычислите ошибку повторного замещения для квадратичного дискриминантного анализа.

qda = fitcdiscr(meas(:,1:2),species,'DiscrimType','quadratic');
qdaResubErr = resubLoss(qda)
qdaResubErr =

    0.2000

Вычислена ошибка повторного предоставления. Обычно людей больше интересует ошибка теста (также называемая ошибкой обобщения), которая является ожидаемой ошибкой прогнозирования на независимом аппарате. Фактически, ошибка повторного замещения, вероятно, будет недооценивать ошибку теста.

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

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

rng(0,'twister');

Первое использование cvpartition для создания 10 непересекающихся стратифицированных подмножеств.

cp = cvpartition(species,'KFold',10)
cp = 

K-fold cross validation partition
   NumObservations: 150
       NumTestSets: 10
         TrainSize: 135  135  135  135  135  135  135  135  135  135
          TestSize: 15  15  15  15  15  15  15  15  15  15

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

Оцените истинную ошибку теста для LDA, используя 10-кратную стратифицированную перекрестную проверку.

cvlda = crossval(lda,'CVPartition',cp);
ldaCVErr = kfoldLoss(cvlda)
ldaCVErr =

    0.2000

Ошибка перекрестной проверки LDA имеет то же значение, что и ошибка повторной выборки LDA для этих данных.

Оцените истинную ошибку теста для QDA, используя 10-кратную стратифицированную перекрестную проверку.

cvqda = crossval(qda,'CVPartition',cp);
qdaCVErr = kfoldLoss(cvqda)
qdaCVErr =

    0.2200

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

Наивные байесовские классификаторы

fitcdiscr имеет два других типа, «DiagLinear» и «DiagQuadratic». Они похожи на «линейные» и «квадратичные», но с оценками диагональной ковариационной матрицы. Эти диагональные варианты являются конкретными примерами наивного классификатора Байеса, поскольку они предполагают, что переменные условно независимы, учитывая метку класса. Наивные байесовские классификаторы входят в число наиболее популярных классификаторов. Хотя предположение об условной независимости класса между переменными в целом не верно, было обнаружено, что наивные классификаторы Байеса хорошо работают на практике во многих наборах данных.

fitcnb функция может использоваться для создания более общего типа наивного классификатора Байеса.

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

nbGau = fitcnb(meas(:,1:2), species);
nbGauResubErr = resubLoss(nbGau)
nbGauCV = crossval(nbGau, 'CVPartition',cp);
nbGauCVErr = kfoldLoss(nbGauCV)

labels = predict(nbGau, [x y]);
gscatter(x,y,labels,'grb','sod')
nbGauResubErr =

    0.2200


nbGauCVErr =

    0.2200

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

nbKD = fitcnb(meas(:,1:2), species, 'DistributionNames','kernel', 'Kernel','box');
nbKDResubErr = resubLoss(nbKD)
nbKDCV = crossval(nbKD, 'CVPartition',cp);
nbKDCVErr = kfoldLoss(nbKDCV)

labels = predict(nbKD, [x y]);
gscatter(x,y,labels,'rgb','osd')
nbKDResubErr =

    0.2067


nbKDCVErr =

    0.2133

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

Дерево решений

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

fitctree создает дерево решений. Создайте дерево решений для данных радужки и посмотрите, насколько хорошо она классифицирует ирисы по видам.

t = fitctree(meas(:,1:2), species,'PredictorNames',{'SL' 'SW' });

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

[grpname,node] = predict(t,[x y]);
gscatter(x,y,grpname,'grb','sod')

Другим способом визуализации дерева решений является построение диаграммы правила принятия решений и назначений классов.

view(t,'Mode','graph');

Это загроможденное дерево использует ряд правил вида «SL < 5,45» для классификации каждого образца в один из 19 конечных узлов. Чтобы определить назначение видов для наблюдения, начните с верхнего узла и примените правило. Если точка удовлетворяет правилу, вы выбираете левый путь, а если не правый путь. В конечном счете вы достигаете терминального узла, который назначает наблюдение одному из трех видов.

Вычислите ошибку повторной выборки и ошибку перекрестной проверки для дерева решений.

dtResubErr = resubLoss(t)

cvt = crossval(t,'CVPartition',cp);
dtCVErr = kfoldLoss(cvt)
dtResubErr =

    0.1333


dtCVErr =

    0.3000

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

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

resubcost = resubLoss(t,'Subtrees','all');
[cost,secost,ntermnodes,bestlevel] = cvloss(t,'Subtrees','all');
plot(ntermnodes,cost,'b-', ntermnodes,resubcost,'r--')
figure(gcf);
xlabel('Number of terminal nodes');
ylabel('Cost (misclassification error)')
legend('Cross-validation','Resubstitution')

Какое дерево выбрать? Простым правилом будет выбор дерева с наименьшей ошибкой перекрестной проверки. Хотя это может быть удовлетворительным, вы можете предпочесть использовать более простое дерево, если оно примерно так же хорошо, как и более сложное дерево. В этом примере рассмотрим простейшее дерево, которое находится в пределах одной стандартной ошибки минимума. Это правило по умолчанию, используемое cvloss способ ClassificationTree.

Это можно показать на графике путем вычисления значения отсечки, равного минимальной стоимости плюс одна стандартная ошибка. «Лучший» уровень, вычисленный cvloss метод является наименьшим деревом под этим отсечением. (Обратите внимание, что bestlevel= 0 соответствует невырезанному дереву, поэтому необходимо добавить 1, чтобы использовать его в качестве индекса в векторных выходах изcvloss.)

[mincost,minloc] = min(cost);
cutoff = mincost + secost(minloc);
hold on
plot([0 20], [cutoff cutoff], 'k:')
plot(ntermnodes(bestlevel+1), cost(bestlevel+1), 'mo')
legend('Cross-validation','Resubstitution','Min + 1 std. err.','Best choice')
hold off

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

pt = prune(t,'Level',bestlevel);
view(pt,'Mode','graph')

cost(bestlevel+1)
ans =

    0.2467

Заключения

В этом примере показано, как выполнять классификацию в MATLAB ® с использованием функций Toolbox™ статистики и машинного обучения.

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