"Машинное обучение"

Обзор классификаций с несколькими ярлыками

Как мы можем классифицировать экземпляр как несколько классов?

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

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

Метрики

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

В зависимости от задачи существует 3 основных типа классов метрик:

а. Оценка разделов

б. Оценка рейтинга

c. Использование иерархии ярлыков

Перегородки

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

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

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

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

1. Метрики на основе примеров

  • Коэффициент точного соответствия: этот подход не считает частично правильным, считая их неправильными. Таким образом, он представляет прогноз с несколькими метками как прогнозы с одной меткой. Основная проблема в том, что он не различает частично правильные и полностью неправильные. В приведенном ниже уравнении Y - это фактический вектор меток, а Z - предсказанные метки для выборки «i», суммируя по всем «i» от 1 до n выборок. Он учитывается только в том случае, если и прогнозируемый, и фактический векторы меток полностью совпадают.
MR = np.all(y_pred == y_true, axis=1).mean()

  • 0–1 проигрыш: подход аналогичен коэффициенту точного совпадения и определяется выражением

1-точное соответствие

  • Точность: Обычно точность определяется как Точность = TP / (TP + FP + FN + TN). Для мультиэкрана определение дается как:

В уравнении Z - это прогнозируемый вектор метки, а Y - фактический вектор метки для образца i. Теперь, по определению, результат считается истинно положительным, если предсказанная метка и фактическая метка совпадают. Здесь мы берем пересечение двух векторов, поэтому результирующий вектор имеет только те метки, как 1, где и фактический, и прогнозируемый векторы были истинными или 1. Взяв значение Mod вектора, мы получаем числовое значение.

Скажем, (0,0,1,1,0) - ›Z - прогнозируемый вектор для выборки, а (0,1,1,1,0) -› Y - фактический вектор, So mod (Intersection (Y, Z)) = 2.

Для объединения mod (Union (Y, Z)) = 3. Общая частичная точность = = 0,67 для этого конкретного образца, потому что он правильно классифицировал 2 из 3 этикеток. Если он ошибочно предсказывает метку, также увеличивается объединение, т. Е. Знаменатель увеличивается, что снижает точность. Затем мы находим этот балл для каждого образца и усредняем его по всем образцам в наборе.

def Accuracy(y_true, y_pred):
temp = 0
for i in range(y_true.shape[0]):
temp += sum(np.logical_and(y_true[i], y_pred[i])) / sum(np.logical_or(y_true[i], y_pred[i]))
return temp / y_true.shape[0]
Accuracy(y_true, y_pred)
  • Точность. По определению, точность измеряет, сколько из выборок, оцененных как положительный класс, действительно положительны. Он определяется как TP / (TP + FP). Ложноположительные результаты - это образцы, которые ошибочно классифицируются как истинные модели. Оценка изменяется как:

В числителе метки равны 1, для которых истинны как прогнозируемые, так и фактические значения. Итак, истинные плюсы. Знаменатель дает всем меткам значение 1, прогнозируемые значения которого равны 1. Таким образом, он содержит как TP, так и FP. Таким образом, для конкретного образца мы получаем значение модуля упругости и усредняем его для всех образцов.

(0,0,1,1,0) - ›Z - прогнозируемый вектор для выборки, а (0,1,1,1,0) -› Y - фактический вектор, So mod (Intersection (Y, Z) ) = 2.

мод ((Z)) = 2.

Точность = 1 для образца, так как здесь нет ложных срабатываний.

def Precision(y_true, y_pred):
temp = 0
for i in range(y_true.shape[0]):
if sum(y_true[i]) == 0:
continue
temp+= sum(np.logical_and(y_true[i], y_pred[i]))/ sum(y_true[i])
return temp/ y_true.shape[0]
  • Отзыв: Согласно определению, отзыв задается как TP / TP + FN, то есть он определяет, сколько из выборок, которые были на самом деле истинными в наборе данных, предсказываются моделью как истинные. Он изменен как:

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

(0,0,1,1,0) - ›Z - прогнозируемый вектор для выборки, а (0,1,1,1,0) -› Y - фактический вектор, So mod (Intersection (Y, Z) ) = 2.

мод ((Y)) = 3.

Напомним, что для образца = 0,67, так как имеется 1 ложноотрицательный результат. Мы берем среднее значение по всем образцам.

def Recall(y_true, y_pred):
temp = 0
for i in range(y_true.shape[0]):
if sum(y_pred[i]) == 0:
continue
temp+= sum(np.logical_and(y_true[i], y_pred[i]))/ sum(y_pred[i])
return temp/ y_true.shape[0]
  • Оценка F1: дается как среднее гармоническое значение точности и полноты. Это можно представить как вычисление оценки F1 для образца и последующее усреднение его по всем образцам. Это дает:

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

Итак, здесь k - количество классов или меток для образца i. «I» - индикаторная функция. Во-первых, для образца «i» уравнение перебирает все метки «l» для l от 1 до k. Затем он пытается найти метку «l», для которой прогнозируемое значение не соответствует фактическому значению. Он суммирует все ошибки и делит их на количество меток.

(0,0,1,1,1) - ›Z - прогнозируемый вектор для выборки, а (0,1,1,1,0) -› Y - фактический вектор.

Для данного образца для класса меток с индексом 0 они совпадают, поэтому ошибка = 0, по второму индексу обнаруживается несоответствие, так как l для Y = 1 и l для Z = 0. Итак, логично и дает 1 за второе условие в уравнении. Итак, подытоживая, весь образец дает потерю хемминга, так как на 5 этикетках есть 2 несовпадения. Этот балл является средним по всем данным выборкам.

Потеря Хэмминга = 0 означает отсутствие ошибок.

def Hamming_Loss(y_true, y_pred):
temp=0
for i in range(y_true.shape[0]):
temp += np.size(y_true[i] == y_pred[i]) — np.count_nonzero(y_true[i] == y_pred[i])
return temp/(y_true.shape[0] * y_true.shape[1])
Hamming_Loss(y_true, y_pred)

2. Метрики на основе ярлыков

На основе меток измеряет все метки по отдельности. Если имеется k меток, он рассматривает оценку как оценку k различных результатов двоичной классификации. Таким образом, любые единицы или процедуры для измерения точности, прецизионности, отзыва, F1-балла могут использоваться без каких-либо изменений здесь для каждой метки. Затем мы берем среднее значение оценок по всем меткам. Есть два основных метода:

  • Макро-усредненные показатели. Это происходит в соответствии с приведенной выше логикой, то есть сначала рассчитываются показатели для каждой метки. Затем мы берем среднее значение по всем меткам. Это дает:

Для каждой метки рассчитываются точность, отзыв и F1-оценка, а затем мы берем среднее значение по всему количеству классов или меток (k).

  • Микро-усредненные показатели: он берет истинно положительный, ложноположительный, истинно отрицательный и ложноотрицательный для каждой метки отдельно, а затем вычисляет точность, отзывчивость и оценки F1. Это дает:

Здесь n - общее количество выборок. Существует k меток классов. Y представляет фактический набор выходных меток, а Z представляет собой предсказанный набор выходных меток. Разница здесь в том, что суммирование по всем меткам - это внешнее суммирование. Внутреннее суммирование суммирует по всем выборкам от 1 до n. YiZi - истинные положительные результаты для i-го образца для j-й метки и так далее.

Для 2 этикеток точность Micro определяется выражением: (TP1 + TP2) / (TP1 + TP2 + FP1 + FP2)

Для 2 этикеток Micro Recall определяется следующим образом: (TP1 + TP2) / (TP1 + TP2 + FN1 + FN2)

Свойства набора данных

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

  1. Определенный набор меток (DL): он определяется общим количеством различных комбинаций меток, наблюдаемых в наборе данных. Это объясняет распространение разных этикеток.
  2. Количество меток (LCard): среднее количество меток на пример. Он учитывает распространение образцов, а также этикеток.

Многопрофильное обучение

Существует два типа алгоритмов для обработки многозначной классификации:

  1. Простые методы преобразования проблемы
  2. Простые методы адаптации алгоритма

Методы трансформации проблемы:

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

  • Есть несколько простых методов преобразования. Давайте обсудим некоторые из них.

На данный момент мы игнорируем функции

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

  • Преобразование дублированной копии: Это похоже на преобразование копии, разница заключается в том, что наряду с метками также назначается вес.

Фактически веса равны 1 / (количество этикеток, имеющих значение 1 для образца).

  • Следующий метод выбирает одну метку из набора меток, которые имеют значение 1 для конкретного образца. Исходя из процесса выбора, есть 3 варианта
  1. Выберите Макс.
  2. Выберите Мин.
  3. Выбрать случайный
  • Игнорировать: игнорируются данные с несколькими ярлыками. Итак, здесь в окончательном наборе данных будет только пример 2.
  • Label Powerset (LP): он создает новые ярлыки для различных комбинаций ярлыков. Таким образом создается мультиклассовая классификация. Для нашего набора данных он изменен как:

Где l5 - это комбинация l2 и l3 и так далее. Верхняя граница количества меток, которые могут быть созданы, задается min (n, 2 ^ k), где n - количество примеров, а k - количество меток. 2 ^ k рассматривает все заданные комбинации, которые могут быть сформированы с использованием заданных основных k меток. Итак, это наихудший случай или n, то есть количество примеров, потому что у вас не может быть 2⁴ = 16 комбинаций, если у вас есть только 10 примеров.

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

Для решения этой проблемы используется Сокращенное преобразование задачи, которое принимает пользовательский порог, например, метка должна появляться не менее 4 раз в данном наборе примеров. Если метка не найдена 4 раза, она игнорируется.

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

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

  • Ранжирование путем попарного сравнения: он создает наборы данных kC2 (комбинированные) из k заданных меток. Таким образом, он выбирает метку Li и метку Lj, так что i ‹j‹ k объединяет их вместе, чтобы сформировать новую метку. В каждом наборе данных сохраняется пример из исходного набора, если пример принадлежит хотя бы к одному из них, но не к обоим.

Методы адаптации алгоритма

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

Функция потерь Log Loss или двоичная кросс-энтропия, которая является наиболее часто используемой функцией потерь для задач классификации, изменена на:

где, P (λj) = вероятность класса λj. Таким образом, он вычисляет потери для каждой метки, аналогично тому, как это делается для обычной двоичной классификации с одной меткой, а затем суммирует все потери для все ярлыки, чтобы дать окончательную потерю.

В основном есть три способа:

  1. Повышение на основе дерева. Алгоритм направлен на изменение алгоритма AdaBoost, используемого в повышении градиента деревьев, для получения результатов для данных с несколькими метками. Есть два типа модификаций: AdaBoost.MH, который пытается классифицировать, минимизируя потери на хемминге, и AdaBoost.MR.

Алгоритм Adaboost обычно работает по трем основным пунктам, которые отличаются от алгоритма случайного леса:

  • Алгоритм Adaboost работает с базовыми или слабыми учащимися дерева решений. У них один корень, то есть они могут использовать только одну из функций за раз для прогнозирования меток. Это не взрослые деревья, как мы используем в алгоритмах случайного леса.
  • В AdaBoost разным деревьям в лесу назначаются разные веса, то есть все деревья не имеют одинакового мнения или влияния на конечный результат или прогнозы, в отличие от случайных лесов, где все деревья имеют одинаковый вес для определения результатов.
  • Деревья в Adaboost учатся на ошибках предыдущих. Таким образом, они зависимы и зависят от порядка формирования деревьев, в отличие от случайных лесов, деревья не зависят друг от друга.

2. Ленивое обучение: Ленивое обучение основано на подходах ближайшего соседа. Они могут работать как над трансформацией проблемы, так и над подходами к алгоритмической адаптации. Для преобразования проблемы наиболее часто используемым подходом для ленивого обучения является BR-KNN. Это процедура, в которой бинарная релевантность используется для преобразования классификации с несколькими метками в классификацию с одной меткой, а затем применяется KNN.

3. Нейронные сети: алгоритмы обратного распространения нейронных сетей были изменены для решения задачи с несколькими метками. Функция потерь фактически изменена, чтобы учесть ошибки на нескольких этикетках. Такой подход называется BP-MLL.

4. Дискриминационные методы SVM: общий метод SVM использует метод двоичной релевантности для получения результата двоичной классификации каждой из k меток отдельно на первом этапе. Затем он расширяет набор данных на k дополнительных функций, которые фактически являются предсказаниями двоичных классификаторов на первом этапе. На следующем этапе «k» новых двоичных классификаторов, по одному для каждой k метки. Новые классификаторы обучаются на расширенных наборах данных, чтобы учитывать зависимости меток. Есть и другие подходы, например BandSVM.

Другие доступные методы

  1. Один против остальных. Этот подход очень похож на подход бинарной релевантности. Он рассматривает все k меток как взаимоисключающие и обучает другую модель с одинаковыми гиперпараметрами для каждой из k меток. Таким образом, модели обучаются независимо и не учитывают корреляции между разными ярлыками. Это создает проблемы независимой двоичной классификации.
  2. Цепочки классификаторов: они учитывают зависимость или корреляцию между k метками. Он создает k двоичных классификаторов для k меток. Первый двоичный классификатор принимает набор данных и предсказывает первую метку. Скажем, предсказание - С1. Для следующей классификационной метки используется второй двоичный классификатор. Для второго мы передаем набор функций плюс C1, то есть выходные данные классификатора для выходных данных первого классификатора. Скажем, дает C2. Для третьего классификатора этикеток мы подаем все признаки + C1 + C2. Итак, для классификации n-й метки мы расширяем набор функций на n-1 функции, которые на самом деле являются предсказанными метками предыдущих n-1 классов.

заявка

Теперь давайте посмотрим на применение вышеуказанных алгоритмов в Python.

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

Визуализация данных

При визуализации данные выглядят следующим образом:

Он имеет 6 классов, в которые должно быть отнесено каждое утверждение. Классы:

Index(['comment_text', 'toxic', 'severe_toxic', 'obscene', 'threat', 'insult',
       'identity_hate'],
      dtype='object')

Однако занятия не очень сбалансированы. «Токсичный» класс представлен с очень высокой долей по сравнению с другими.

Теперь обратите внимание на корреляцию шести ярлыков друг с другом.

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

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

Столбец comment_text будет нашим набором функций.

0    Explanation\nWhy the edits made under my usern...
1    D'aww! He matches this background colour I'm s...
2    Hey man, I'm really not trying to edit war. It...
3    "\nMore\nI can't make any real suggestions on ...
4    You, sir, are my hero. Any chance you remember...
Name: comment_text, dtype: object

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

import re
def remove_special_characters(text):
    text=text.lower()
    pattern=r'[^a-zA-Z0-9 ]'
    text = re.sub(r"what's", "what is ", text)
    text = re.sub(r"\'s", " ", text)
    text = re.sub(r"\'ve", " have ", text)
    text = re.sub(r"can't", "cannot ", text)
    text = re.sub(r"n't", " not ", text)
    text = re.sub(r"i'm", "i am ", text)
    text = re.sub(r"\'re", " are ", text)
    text = re.sub(r"\'d", " would ", text)
    text = re.sub(r"\'ll", " will ", text)
    text = re.sub(r"\'scuse", " excuse ", text)
    text = re.sub('\W', ' ', text)
    text = re.sub('\s+', ' ', text)
    text=re.sub(pattern,'',text)
    
    return text
def new_line_r(text):
    pattern=r'\n'
    text=re.sub(pattern,'',text)
    return text
import nltk
from nltk.tokenize import sent_tokenize, word_tokenize 
from nltk.corpus import stopwords
def remove_stop(text):
    stop_words = stopwords.words('english')
    cleaned=''
    words=word_tokenize(text) 
    for word in words:
        if word not in stop_words:
            cleaned=cleaned+word+' '
    return cleaned

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

0    explanation edits made username hardcore metal...
1    aww matches background colour seemingly stuck ...
2    hey man really trying edit war guy constantly ...
3    make real suggestions improvement wondered sec...
4                       sir hero chance remember page 
Name: cleaned_text, dtype: object

Наши очищенные тексты выглядят неплохо.

Затем мы векторизуем тексты и создаем обучающие и тестовые наборы для моделей.

X=df_final['cleaned_text']
Y=df_final.drop(['cleaned_text'],axis=1)
from sklearn.model_selection import train_test_split
X_train, X_test, Y_train, Y_test= train_test_split(X,Y, test_size=0.3)
from sklearn.feature_extraction.text import TfidfVectorizer
vectorizer=TfidfVectorizer(max_features=500,stop_words='english')
vectorizer.fit(X_train)
x_train=vectorizer.transform(X_train)
x_test=vectorizer.transform(X_test)

Фрагмент создает необходимые наборы.

Модели

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

from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
labels=Y_train.columns
log_reg=LogisticRegression()
for label in labels:
    y_train_f=Y_train[label]
    y_test_f=Y_test[label]
    log_reg.fit(x_train,y_train_f)
    y_pred=log_reg.predict(x_test)
    acc=accuracy_score(y_test_f,y_pred)
    print("For label {}: accuracy obtained: {}".format(label,acc))

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

For label toxic: accuracy obtained: 0.9416569184491979
For label severe_toxic: accuracy obtained: 0.9901403743315508
For label obscene: accuracy obtained: 0.9752882687165776
For label threat: accuracy obtained: 0.997033756684492
For label insult: accuracy obtained: 0.96563753342246
For label identity_hate: accuracy obtained: 0.991769719251337

Теперь перейдем к многозначной классификации.

Преобразование проблемы

Двоичная релевантность

from skmultilearn.problem_transform import BinaryRelevance
classifier = BinaryRelevance(
    classifier = LogisticRegression(),
)
classifier.fit(x_train, Y_train)
y_pred=classifier.predict(x_test)
acc=accuracy_score(Y_test,y_pred)

Модель дает оценку точности 91,11%.

Цепочки классификаторов

from skmultilearn.problem_transform import ClassifierChain
from sklearn.linear_model import LogisticRegression
chain_classifier = ClassifierChain(LogisticRegression())
chain_classifier.fit(x_train,Y_train)
y_pred = chain_classifier.predict(x_test)
acc=accuracy_score(Y_test, y_pred)

Цепи классификатора обеспечивают точность 91,26%.

Этикетка Powerset

from skmultilearn.problem_transform import LabelPowerset
pw_set_class = LabelPowerset(LogisticRegression())
pw_set_class.fit(x_train,Y_train)
y_pred=pw_set_class.predict(x_test)
acc=accuracy_score(Y_test, y_pred)

Точность: 91,28%

Адаптивные алгоритмы

В этом случае мы увидим, как применить Lazy Learning для решения проблем с несколькими ярлыками с применением классификатора Binary Relevance KNN.

from skmultilearn.adapt import BRkNNaClassifier
lazy_classifier=BRkNNaClassifier()
x_train_a=x_train.toarray()
from scipy.sparse import csr_matrix
y_train_a=csr_matrix(Y_train).toarray()
lazy_classifier.fit(x_train_a, y_train_a)
x_test_a=x_test.toarray()
y_pred=lazy_classifier.predict(x_test_a)

Заключение

В статье мы рассмотрели несколько подходов к классификации с несколькими метками.

Вот ссылка на Github.

Надеюсь, эта статья поможет.

использованная литература

Документ: https://pdfs.semanticscholar.org/b3c9/88366e6f80d1cfecbe7f4956e016ac2e498e.pdf

Документ: https://pdfs.semanticscholar.org/6b56/91db1e3a79af5e3c136d2dd322016a687a0b.pdf

Метрики: https://mmuratarat.github.io/2020-01-25/multilabel_classification_metrics.md

Https://arxiv.org/pdf/1912.13405.pdf