Во многих приложениях вы можете предпочитать относиться к классам в данных асимметрично. Например, данные могут иметь намного больше наблюдений одного класса, чем любой другой. Или неправильная классификация наблюдений одного класса имеет более серьезные последствия, чем неправильная классификация наблюдений другого класса. В таких ситуациях можно либо использовать алгоритм RUSBoost (указать 'Method'
как 'RUSBoost'
) или используйте аргумент пары "имя-значение" 'Prior'
или 'Cost'
из fitcensemble
.
Если некоторые классы недопредставлены или перепредставлены в вашем наборе обучающих данных, используйте 'Prior'
аргумент пары "имя-значение" или алгоритм RUSBoost. Например, предположим, что вы получаете свои обучающие данные путем симуляции. Из-за симуляции A
класса дороже, чем симуляция
B
класса, вы принимаете решение сгенерировать меньше наблюдений за
A
классов и больше наблюдений за
B классов
. Однако ожидается, что этот класс A
и классовые B
смешиваются в другой пропорции в реальных (нежимулированных) ситуациях. В этом случае используйте 'Prior'
чтобы задать предыдущие вероятности для A
классов и
B
приблизительно к значениям, которые вы ожидаете наблюдать в реальной ситуации. fitcensemble
функция нормирует предыдущие вероятности, чтобы они складывались в 1
. Умножение всех предыдущих вероятностей на один и тот же положительный коэффициент не влияет на результат классификации. Другой способ обработки несбалансированных данных - использовать RUSBoost
алгоритм (
). Вам не нужно корректировать предыдущие вероятности при использовании этого алгоритма. Для получения дополнительной информации смотрите Random Undersampling Boost and Classification with Imbalanced Data.'Method'
, 'RUSBoost'
Если классы адекватно представлены в обучающих данных, но вы хотите лечить их асимметрично, используйте 'Cost'
аргумент пары "имя-значение". Предположим, вы хотите классифицировать доброкачественные и злокачественные опухоли у больных раком. Отказ идентифицировать злокачественную опухоль (ложноотрицательная) имеет гораздо более серьезные последствия, чем неправильное определение доброкачественной функции как злокачественной (ложноположительная). Вы должны назначить высокую стоимость неправильного определения злокачественного заболевания как доброкачественного и низкой стоимости неправильного определения доброкачественного как злокачественного.
Вы должны передать затраты на неправильную классификацию как квадратную матрицу с неотрицательными элементами. Элементный C(i,j)
этой матрицы является стоимость классификации наблюдения в класс j
если класс true i
. Диагональные элементы C(i,i)
матрицы затрат должна быть 0
. В предыдущем примере можно выбрать злокачественную опухоль как класс 1 и доброкачественную опухоль как класс 2. Затем можно задать матрицу затрат равной
где c > 1 - стоимость неправильной идентификации злокачественной опухоли как доброкачественной. Затраты относительны - умножение всех затрат на один и тот же положительный фактор не влияет на результат классификации.
Если у вас только два класса, fitcensemble
корректирует их предыдущие вероятности используя для класса i = 1,2 и j ≠ i. Pi предыдущие вероятности переданы в fitcensemble
или вычисленных из частот классов в обучающих данных, и скорректированы предыдущие вероятности. Тогда fitcensemble
использует матрицу затрат по умолчанию
и эти скорректированные вероятности для обучения своих слабых учащихся. Манипулирование матрицей затрат, таким образом, эквивалентно манипулированию предыдущими вероятностями.
Если у вас есть три или более классов, fitcensemble
также преобразует входные затраты в скорректированные предыдущие вероятности. Это преобразование является более комплексным. Во-первых, fitcensemble
пытается решить матричное уравнение, описанное в Zhou и Liu [1]. Если он не может найти решение, fitcensemble
применяет корректировку «средней стоимости», описанную в Breiman et al. [2]. Для получения дополнительной информации см. Задрозный, Лэнгфорд и Абэ [3].
Этот пример показывает, как обучить ансамбль классификационных деревьев с неравными классификационными затратами. Этот пример использует данные о пациентах с гепатитом, чтобы увидеть, живут ли они или умирают в результате заболевания. Набор данных описан в UCI Машинное Обучение Data Repository.
Считайте набор данных о гепатите из репозитория UCI как символьный массив. Затем преобразуйте результат в массив ячеек из векторов символов с помощью textscan
. Задайте массив ячеек из векторов символов, содержащий имена переменных.
options = weboptions('ContentType','text'); hepatitis = textscan(webread(['http://archive.ics.uci.edu/ml/' ... 'machine-learning-databases/hepatitis/hepatitis.data'],options),... '%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f','Delimiter',',',... 'EndOfLine','\n','TreatAsEmpty','?'); size(hepatitis)
ans = 1×2
1 20
VarNames = {'dieOrLive' 'age' 'sex' 'steroid' 'antivirals' 'fatigue' ... 'malaise' 'anorexia' 'liverBig' 'liverFirm' 'spleen' ... 'spiders' 'ascites' 'varices' 'bilirubin' 'alkPhosphate' 'sgot' ... 'albumin' 'protime' 'histology'};
hepatitis
- массив ячеек 1 на 20 из векторов символов. Камеры соответствуют ответу (liveOrDie
) и 19 гетерогенных предикторов.
Задайте числовую матрицу, содержащую предикторы и вектор камеры, содержащий 'Die'
и 'Live'
, которые являются категориями отклика. Ответ содержит два значения: 1
указывает, что пациент умер, и 2
указывает, что пациент жил. Задайте массив ячеек из векторов символов для отклика, используя категории отклика. Первая переменная в hepatitis
содержит ответ.
X = cell2mat(hepatitis(2:end)); ClassNames = {'Die' 'Live'}; Y = ClassNames(hepatitis{:,1});
X
- числовая матрица, содержащая 19 предикторов. Y
- массив ячеек из векторов символов, содержащий ответ.
Проверьте данные на предмет отсутствующих значений.
figure barh(sum(isnan(X),1)/size(X,1)) h = gca; h.YTick = 1:numel(VarNames) - 1; h.YTickLabel = VarNames(2:end); ylabel('Predictor') xlabel('Fraction of missing values')
Большинство предикторов имеют отсутствующие значения, и один имеет почти 45% отсутствующих значений. Поэтому используйте деревья принятия решений с суррогатными расщеплениями для лучшей точности. Поскольку набор данных небольшой, время обучения с суррогатными разделениями должно быть допустимым.
Создайте шаблон дерева классификации, который использует суррогатные разделения.
rng(0,'twister') % For reproducibility t = templateTree('surrogate','all');
Исследуйте данные или описание данных, чтобы увидеть, какие предикторы категоричны.
X(1:5,:)
ans = 5×19
30.0000 2.0000 1.0000 2.0000 2.0000 2.0000 2.0000 1.0000 2.0000 2.0000 2.0000 2.0000 2.0000 1.0000 85.0000 18.0000 4.0000 NaN 1.0000
50.0000 1.0000 1.0000 2.0000 1.0000 2.0000 2.0000 1.0000 2.0000 2.0000 2.0000 2.0000 2.0000 0.9000 135.0000 42.0000 3.5000 NaN 1.0000
78.0000 1.0000 2.0000 2.0000 1.0000 2.0000 2.0000 2.0000 2.0000 2.0000 2.0000 2.0000 2.0000 0.7000 96.0000 32.0000 4.0000 NaN 1.0000
31.0000 1.0000 NaN 1.0000 2.0000 2.0000 2.0000 2.0000 2.0000 2.0000 2.0000 2.0000 2.0000 0.7000 46.0000 52.0000 4.0000 80.0000 1.0000
34.0000 1.0000 2.0000 2.0000 2.0000 2.0000 2.0000 2.0000 2.0000 2.0000 2.0000 2.0000 2.0000 1.0000 NaN 200.0000 4.0000 NaN 1.0000
Похоже, что предикторы с 2 по 13 категоричны, а также предиктор 19. Подтвердить это вывод можно с помощью описания набора данных в UCI Машинное Обучение Data Repository.
Перечислите категориальные переменные.
catIdx = [2:13,19];
Создайте перекрестно проверенный ансамбль, используя 150 учащихся и GentleBoost
алгоритм.
Ensemble = fitcensemble(X,Y,'Method','GentleBoost', ... 'NumLearningCycles',150,'Learners',t,'PredictorNames',VarNames(2:end), ... 'LearnRate',0.1,'CategoricalPredictors',catIdx,'KFold',5); figure plot(kfoldLoss(Ensemble,'Mode','cumulative','LossFun','exponential')) xlabel('Number of trees') ylabel('Cross-validated exponential loss')
Проверьте матрицу неточностей, чтобы увидеть, каких пациентов ансамбль предсказывает правильно.
[yFit,sFit] = kfoldPredict(Ensemble); confusionchart(Y,yFit)
Из 123 живущих пациентов ансамбль правильно предсказывает, что проживут 112. Но для 32 пациентов, которые умирают от гепатита, ансамбль только правильно предсказывает, что примерно половина умрет от гепатита.
Существует два типа ошибок в предсказаниях ансамбля:
Предсказание, что пациент живет, но пациент умирает
Предсказание, что пациент умирает, но пациент живет
Предположим, вы верите, что первая ошибка в пять раз хуже второй. Создайте новую матрицу классификационных затрат, которая отражает это убеждение.
cost.ClassNames = ClassNames; cost.ClassificationCosts = [0 5; 1 0];
Создайте новый перекрестно проверенный ансамбль с помощью cost
как стоимость неправильной классификации и просмотр полученной матрицы неточностей.
EnsembleCost = fitcensemble(X,Y,'Method','GentleBoost', ... 'NumLearningCycles',150,'Learners',t,'PredictorNames',VarNames(2:end), ... 'LearnRate',0.1,'CategoricalPredictors',catIdx,'KFold',5,'Cost',cost); [yFitCost,sFitCost] = kfoldPredict(EnsembleCost); confusionchart(Y,yFitCost)
Как ожидалось, новый ансамбль делает лучшую работу, классифицируя пациентов, которые умирают. Несколько удивительно, что новый ансамбль также делает лучшую работу классификации пациентов, которые живут, хотя результат статистически не значительно лучше. Результаты перекрестной валидации случайны, поэтому этот результат является просто статистическим колебанием. Результат, по-видимому, указывает на то, что классификация пациентов, которые живут, не очень чувствительна к стоимости.
[1] Чжоу, Z.-H. и X.-Y. Лю. «При многоклассовом учитывающем затраты обучении». Вычислительный интеллект. Том 26, Выпуск 3, 2010, стр. 232-257 CiteSeerX.
[2] Breiman, L., J. H. Friedman, R. A. Olshen, and C. J. Stone. Деревья классификации и регрессии. Бока Ратон, FL: Chapman & Hall, 1984.
[3] Задрозный, Б., Дж. Лэнгфорд, и Н. Абэ. «Экономичное обучение по пропорциональному по стоимости примеру». Третья Международная конференция IEEE по майнингу данных, 435-442. 2003.
confusionchart
| fitcensemble
| kfoldLoss
| kfoldPredict
| templateTree