3

В чем преимущество бинарного кодирования перед простой нумерацией категорий?

Создается впечатление, что оно не несет никакой дополнительной информации.

Пример. Пусть есть континенты Европа, Африка, Америка, Австралия. Они получат номера 0,1,2,3 соответственно, что соответствует бинарному кодированию 00, 01, 10, 11. Каждый бит записан в своей колонке

  • День добрый. У нас принято задавать вопросы на русском (: – Suvitruf - Andrei Apanasik Mar 09 '19 at 20:00
  • 1
    Не совсем понимаю что именно вы под этим понимаете и в чем суть вопроса. Если речь о том, что бы небольшое количество категорий кодировать отдельными битами при условии что один объект может входить в несколько категорий одновременно, то есть несколько плюсов: 1. компактность (в 4х байтах int можно уместить 32 категории). 2. простота сравнения сразу набора бинарными операторами (в основном &) – Mike Mar 09 '19 at 20:44

1 Answers1

2

Представьте себе категориальный признак, например некоторое название/наименование.

          region  val  region_id
0         Europe  940          2
1  North America  605          3
2         Africa  423          0
3         Europe  398          2
4  South America  504          4
5  South America  538          4
6           Asia  337          1
7         Africa  474          0
8           Asia  662          1
9         Europe  834          2

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

0 < 1 < 2 < 3 < 4

т.е. для примера выше:

Africa < Asia < Europe < North America < South America

что не имеет ничего общего с реальной выборкой.

Если найти среднее для нашей выборки:

In [51]: df['region_id'].mean()
Out[51]: 1.9

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

Использование One Hot Encoding устраняет данные недостатки.

          region  val  Africa  Asia  Europe  North America  South America
0         Europe  940       0     0       1              0              0
1  North America  605       0     0       0              1              0
2         Africa  423       1     0       0              0              0
3         Europe  398       0     0       1              0              0
4  South America  504       0     0       0              0              1
5  South America  538       0     0       0              0              1
6           Asia  337       0     1       0              0              0
7         Africa  474       1     0       0              0              0
8           Asia  662       0     1       0              0              0
9         Europe  834       0     0       1              0              0

теперь если посчитать среднее значение, то мы получим:

In [63]: df.drop(['region','val'],1).mean()
Out[63]:
Africa           0.2
Asia             0.2
Europe           0.3
North America    0.1
South America    0.2
dtype: float64

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

Еще одно преимущество уже указал @Mike в комментарии - если объект может содержать несколько признаков одновременно, то One Hot Encoding учитывает данную особенность а нумерация категорий здесь никак не поможет.


Код на Python для примера:

import numpy as np
import pandas as pd
from sklearn.preprocessing import LabelEncoder

l = ['Asia', 'Africa', 'Europe', 'North America', 'South America']
le = LabelEncoder()

np.random.seed(3)
reg = np.random.choice(l, size=10, p=[0.2, 0.15, 0.3, 0.2, 0.15])
df = pd.DataFrame({'region':reg, 'val':np.random.randint(1000, size=10)})
df['region_id'] = le.fit_transform(df['region'])
print(df)
print(df['region_id'].mean())


del df['region_id']
df = df.join(pd.get_dummies(df['region']))
print(df)
print(df.drop(['region','val'],1).mean())
MaxU - stand with Ukraine
  • 149,321
  • 12
  • 59
  • 132