Ordinal Encoding – порядковое кодирование используется в подготовке признаков для кодирования текстовых категориальных в числовые, как и прямое кодирование. Принимаем какой цифрой кодируется класс, после чего значение категориального признака заменяется на числовое.
Для удобства можно воспользоваться возможностями sklearn, sklearn.preprocessing.OrdinalEncoder. Основные методы объекта OrdinalEncoder:
– fit() – формирует категории, после применения этого метода можно обратиться к свойству categories_ объекта, что бы посмотреть, какие категории сформировались
– transform() – непосредственная трасформация
– fit_transform() – эквивалент вызова двух предыдущих методов fit(X).transform(X)
Предположим есть датасет, где в столбцах хранятся бал за контрольную и общий рейтинг по предмету, индексом служит идентификатор студента. Для подготовки признаков заменим текстовые значения категорий, на числовые.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
student_ids = [100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110] progress = pd.DataFrame({ 'grade': ['A', 'C', 'E/F', 'A', 'B', 'C', 'A', 'E/F', 'D', 'A', 'B'], 'global_rating': ['excellent', 'fair', 'fair', 'good', 'good', 'poor', 'excellent', 'bad', 'bad', 'good', 'fair']}, columns=['grade', 'global_rating'], index=student_ids) grade global_rating 100 A excellent 101 C fair 102 E/F fair 103 A good 104 B good 105 C poor 106 A excellent 107 E/F bad 108 D bad 109 A good 110 B fair |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
from sklearn.preprocessing import OrdinalEncoder # создаем объект кодироващика encoder = OrdinalEncoder() # устанавливаем порядковое кодирование encoder.fit(progress) transformed = encoder.transform(progress) print(transformed) [[0. 1.] [2. 2.] [4. 2.] [0. 3.] [1. 3.] [2. 4.] [0. 1.] [4. 0.] [3. 0.] [0. 3.] [1. 2.]] # или тоже самое делаем с помощью encoder.fit_transform(progress) print(encoder.fit_transform(progress)) # использование с датасетом progress_ordinal = pd.DataFrame(encoder.transform(progress), columns=progress.columns, index=student_ids) print(progress_ordinal) grade global_rating 100 0.0 1.0 101 2.0 2.0 102 4.0 2.0 103 0.0 3.0 104 1.0 3.0 105 2.0 4.0 106 0.0 1.0 107 4.0 0.0 108 3.0 0.0 109 0.0 3.0 110 1.0 2.0 |
В целом все прошло хорошо, но хотелось бы, что бы высшей оценке и рейтингу соответствовало наибольшее числовое значение или мы хотим какой-то особенный порядок присвоения числовых значений (по умолчанию они отсортированы в лексикографическом порядке). Для этого при инициализации объекта можно передать параметр categories. Рассмотрим на примере.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
progress = pd.DataFrame({ 'grade': ['A', 'C', 'E/F', 'A', 'B', 'C', 'A', 'E/F', 'D', 'A', 'B'], 'global_rating': ['excellent', 'fair', 'fair', 'good', 'good', 'poor', 'excellent', 'bad', 'bad', 'good', 'fair']}, columns=['grade', 'global_rating'], index=student_ids) encoder = OrdinalEncoder( categories=[['E/F', 'D', 'C', 'B', 'A'], ['bad', 'poor', 'fair', 'good', 'excellent']]) progress_ordinal = pd.DataFrame(encoder.fit_transform(progress), columns=progress.columns, index=student_ids) print(progress_ordinal) grade global_rating 100 4.0 4.0 101 2.0 2.0 102 0.0 2.0 103 4.0 3.0 104 3.0 3.0 105 2.0 1.0 106 4.0 4.0 107 0.0 0.0 108 1.0 0.0 109 4.0 3.0 110 3.0 2.0 |
В результате чего A и excellent кодируются наивысшими числовыми значениями, в данном случае 4.
В подобном примере порядковое кодирование подходит отлично, но есть и исключения, например, категориальный признака Питомец, может принимать значения: кошка, собака, попугай. Используя порядковое кодирование при вычислении, например среднего арифметического, мы можем получить закодированную собаку, тем самым дав возможность появиться неверной корреляции. Для таких случаев стоит воспользоваться прямым кодированием.