Эта статья является продолжением статьи этого.

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

Пример: предположим, что на картинке у нас есть мяч, ручка и бита одновременно, проблема классификации заключается в том, есть ли эти 3 элемента на входном изображении или нет. Это означает, что вместо 1 метки (как в предыдущих типах классификации) у нас есть 3 метки для одной выборки данных.

мы можем временно создавать данные классификации с несколькими метками с помощью приведенного ниже кода.

X,y = make_multilabel_classification(sparse = False, n_samples = 100, n_labels = 4, allow_unlabeled = False)

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

Есть 3 способа построить модель для задачи классификации с несколькими метками.

  1. Трансформация проблемы
  2. Адаптированный алгоритм
  3. Ансамблевые подходы

Исследуем все способы…

  1. Трансформация проблемы. Это можно осуществить тремя способами.

а. Бинарная релевантность

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

в. Ярлык питания

Предположим, у нас есть входные данные X и данные меток [y1, y2, y3, y4]

A. Бинарная релевантность. В бинарной релевантности классификация с несколькими метками будет преобразована в классификацию с одним классом.

При преобразовании в одноклассовую классификацию пары будут формироваться вида (X, y1), (X, y2), (X, y3) и (X, y4).

Теперь модель будет рассматривать каждую пару и тренироваться с X и yi.

поэтому будет сгенерировано 4 выхода.

from sklearn.datasets import make_multilabel_classification
from skmultilearn.problem_transform import BinaryRelevance, ClassifierChain, LabelPowerset
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn import metrics
from scipy import sparse
X,y = make_multilabel_classification(sparse = False, n_samples = 100, n_labels = 4, allow_unlabeled = False)
X_train, X_test, y_train, y_test = train_test_split(X,y, test_size = 0.2)
tree_model = DecisionTreeClassifier()
meta_model = BinaryRelevance(tree_model)
meta_model.fit(X_train,y_train)
predictions = meta_model.predict(X_test)
print(metrics.accuracy_score(y_test, predictions))

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

Здесь тренировка будет такой,

(ввод, вывод)

X — — — y1

X, y1 — — y2

X, y1, y2 — — — y3

X, y1, y2, y3 — — — y4

Таким образом, будет произведено 4 выхода…

фрагмент кода:

from sklearn.datasets import make_multilabel_classification
from skmultilearn.problem_transform import BinaryRelevance, ClassifierChain, LabelPowerset
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn import metrics
from scipy import sparse
X,y = make_multilabel_classification(sparse = False, n_samples = 100, n_labels = 4, allow_unlabeled = False)
X_train, X_test, y_train, y_test = train_test_split(X,y, test_size = 0.2)
tree_model = DecisionTreeClassifier()
meta_model = ClassifierChain(tree_model)
meta_model.fit(X_train,y_train)
predictions = meta_model.predict(X_test)
print(metrics.accuracy_score(y_test, predictions))

C. Label Powerset: здесь для количества образцов данных, которые у нас есть, число будет присвоено различным комбинациям наборов меток. например,

в приведенных выше 6 выборках данных, как мы видим, x1 и x4 имеют одинаковый набор меток, а x3 и x6 имеют одинаковый набор меток. поэтому мы можем создать новый столбец в наборе данных, присвоить номера, как показано ниже, и удалить оставшийся набор меток.

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

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

Ансамблевые подходы такие же, как и традиционные ансамблевые подходы, и вы можете легко их понять (я не буду вдаваться в подробности, потому что эта статья посвящена только метрикам). приведенные ниже ссылки определенно помогут вам.

Ссылки:

  1. http://scikit.ml/api/skmultilearn.html
  2. https://github.com/scikit-multilearn/scikit-multilearn/blob/master/skmultilearn/adapt/mlknn.py

Просмотрите реализации scikit-multilearn на GitHub, чтобы вы тоже поняли код.

Теперь давайте перейдем к метрикам.

Теперь, что касается показателей,

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

Здесь я приведу некоторые существующие метрики для классификации с несколькими метками с кодом.

Метрики, которые мы собираемся обсудить,

  1. Точность @ К.
  2. Средняя точность @ K.
  3. Средняя средняя точность @ K.
  4. Образец F1-Score.

Точность @ K:

ydef patk(actual, pred, k):
 if k == 0:
  return 0
 k_pred = pred[:k]
 actual_set = set(actual)
 pred_set = set(k_pred)
 common_values = actual_set.intersection(pred_set)
 return len(common_values)/len(pred[:k])
y_true = [1 ,2, 0]
y_pred = [1, 1, 0]
if __name__ == "__main__":
    print(patk(y_true, y_pred,3))

Не путайтесь с определением точности, которое мы обсуждали ранее, с этой точностью в точности @k. Согласно моим предыдущим блогам, точность — это не что иное, как «насколько точно значения +ve были предсказаны в фактических значениях +ve». но здесь точность — это «насколько (или сколько) правильно сделано каждое предсказание» (вы поймете это на примере ниже). Таким образом, Precision@K — это не что иное, как оценка того, насколько правильно сделан прогноз, учитывающая только верхние K элементов в списке элементов метки для конкретной выборки.

В приведенном выше коде мы рассмотрели значение 3 для K, а длина y_true, y_pred также равна 3, поэтому мы рассматриваем все элементы в метке.

В Precision @ K мы вычисляем точность только для одного образца, представьте себе, что есть фотография, на которой есть летучая мышь, мяч и ручка, давайте присвоим ей значение, например, летучая мышь = 1, мяч = 2, ручка = 0.

Итак, теперь в приведенном выше коде даны y_true = [1,2, 0] и y_pred = [1, 1, 0]. Это означает, что на самом деле на фотографии мяч, бита и ручка есть, но согласно к нашей модели 2 биты и ручка есть.

теперь, как мы видим, 2 из 3 элементов верны, поэтому 66,666% предсказания сделано правильно, поэтому точность @ K будет равна 0,6666666.

Обычно мы можем использовать точность @ K для одной выборки.

Примечание.Обычно мы используем среднюю среднюю точность @k, так как она представляет собой оптимальную точность общих данных. обе (точность @k, средняя точность @k) приведут к средней средней точности @K. Я просто объясняю это (точность, средняя точность), чтобы мы знали, каковы компоненты (точность, средняя точность) среднего средняя точность.

Среднее значение @ K:

Теперь здесь мы будем работать с номером N. образцов с N›1,

Рассмотрим следующие данные:

y_true = [[1,2,0,1], [0,4], [3], [1,2]] # здесь у нас 4 метки

у_пред = [[1,1,0,1], [1,4], [2], [1,3]]

Теперь здесь мы вычисляем точность для каждой метки (набора элементов) для разных значений K (от 0 до K) и усредняем все эти точности, называемые средней точностью при K.

import numpy as np
def patk(actual, pred, k):
 if k == 0:
  return 0
k_pred = pred[:k]
actual_set = set(actual)
pred_set = set(k_pred)
common_values = actual_set.intersection(pred_set)
return len(common_values)/len(pred[:k])
 
def apatk(acutal, pred, k):
precision_ = []
 for i in range(1, k+1):
precision_.append(patk(acutal, pred, i))
if len(precision_) == 0:
  return 0
return np.mean(precision_)
y_true = [[1,2,0,1], [0,4], [3], [1,2]]
y_pred = [[1,1,0,1], [1,4], [2], [1,3]]
if __name__ == "__main__":
 for i in range(len(y_true)):
  for j in range(1, 4):
   print("for K = "+str(j)+"average precision is "+str(apatk(y_true[i], y_pred[i], k=j)))

Средняя средняя точность @ K:

Средняя средняя точность @ K — это не что иное, как усреднение средней точности каждой метки, которая представляет точную метрику для реальных данных.

import numpy as np
def patk(actual, pred, k):
 if k == 0:
  return 0
k_pred = pred[:k]
actual_set = set(actual)
pred_set = set(k_pred)
common_values = actual_set.intersection(pred_set)
return len(common_values)/len(pred[:k])
 
def apatk(acutal, pred, k):
precision_ = []
 for i in range(1, k+1):
precision_.append(patk(acutal, pred, i))
if len(precision_) == 0:
  return 0
return np.mean(precision_)
y_true = [[1,2,0,1], [0,4], [3], [1,2]]
y_pred = [[1,1,0,1], [1,4], [2], [1,3]]
def mapk(acutal, pred, k):
#creating a list for storing the Average Precision Values
 average_precision = []
 #interating through the whole data and calculating the apk for each 
 for i in range(len(acutal)):
  average_precision.append(apatk(acutal[i], pred[i], k))
#returning the mean of all the data
 return np.mean(average_precision)
if __name__ == "__main__":
    print(mapk(y_true, y_pred,3))

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

Журнал потерь:

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

Это также известно как Средняя потеря журнала по столбцам. мы можем реализовать это легко. Если вам нужна реализация, пройдитесь по моему GitHub здесь.

Оценка F1:

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

from sklearn.metrics import f1_score
from sklearn.preprocessing import MultiLabelBinarizer
def f1_sampled(actual, pred):
   mlb = MultiLabelBinarizer()
   actual = mlb.fit_transform(actual)
   pred = mlb.fit_transform(pred)
   f1 = f1_score(actual, pred, average = "samples")
   return f1
y_true = [[1,2,0,1], [0,4], [3], [1,2]]
y_pred = [[1,1,0,1], [1,4], [2], [1,3]]
if __name__ == "__main__":
   print(f1_sampled(y_true, y_pred))

Теперь вы можете с уверенностью сказать: «Я знаю метрики классификации с несколькими ярлыками😊»

Вывод:

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

___________________________________________________________________

Вы, ребята, можете отправить мне свою любимую тему на LinkedIn и подписаться на мой GitHub здесь.

Следуйте за мной на Medium:- https://iamvishnu-varapally.medium.com/

Удачного обучения✌!!