LightGBM обрабатывает Pandas Категориалов, основанных на имени или значении cat_code? - PullRequest
0 голосов
/ 12 февраля 2020

LightGBM предоставляет возможность обрабатывать категориальные переменные без необходимости одноразового кодирования набора данных.

Один из способов использовать эту функцию (из интерфейса Python) - указать имена столбцов категориальных признаков в виде списка с использованием categorical_feature -аргумента. Этот подход требует, чтобы категории были закодированы в виде целых чисел.

Но альтернативой является предоставление LightGBM Pandas DataFrame, где столбцы, которые по своей природе являются категориями, имеют тип Категориальный dtype, а LightGBM будет выяснить, какие столбцы следует рассматривать как категориальные.

Но базовые интергерские коды, используемые в категориях, задаются Pandas и, вероятно, не будут согласованы в сеансах Python. Не приведут ли смешанные коды cat_codes к неверному истолкованию записей LightGBM в категориях?

По категориям Pandas я ссылаюсь на набор функций как df['Some_categorical_feature'] = df['Some_categorical_feature'].astype('category').

1 Ответ

0 голосов
/ 16 февраля 2020

Pandas назначает категориальные коды путем сортировки ключей (категорий) перед назначением кодов, и LightGBM использует Pandas для правильного назначения категориальных кодов. Введение ранее невидимой категории нарушит порядок упорядочения категорий и, следовательно, сместит коды категорий.

Источник: https://github.com/microsoft/LightGBM/issues/2761#issuecomment -586722068

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

#!/usr/bin/env python
# -*- coding: utf8 -*-

import pandas as pd
import lightgbm as lgb

X_train = pd.Series(['D', 'A', 'C', 'C', 'E', 'E', 'A'],
                    name='X', dtype='category').to_frame()
X_deploy = pd.Series(['B', 'E', 'A', 'C', 'D', 'E', 'F'],
                     name='X', dtype='category').to_frame()

X_train_transformed = lgb.basic._data_from_pandas(X_train, None, None, None)
X_deploy_transformed = lgb.basic._data_from_pandas(X_deploy, None, None, None)

print("X_train", X_train, sep=':\n', end='\n\n')
# X_train:
#    X
# 0  D
# 1  A
# 2  C
# 3  C
# 4  E
# 5  E
# 6  A

print("X_deploy", X_deploy, sep=':\n', end='\n\n')
# X_deploy:
#    X
# 0  B
# 1  E
# 2  A
# 3  C
# 4  D
# 5  E
# 6  F


print('X_train_transformed', X_train_transformed, sep=':\n', end='\n\n')
# X_train_transformed:
# (array([[2.],
#        [0.],
#        [1.],
#        [1.],
#        [3.],
#        [3.],
#        [0.]], dtype=float32), None, None, [['A', 'C', 'D', 'E']])

print('X_deploy_transformed', X_deploy_transformed, sep=':\n', end='\n\n')
# X_deploy_transformed:
# (array([[1.],
#        [4.],
#        [0.],
#        [2.],
#        [3.],
#        [4.],
#        [5.]], dtype=float32), None, None, [['A', 'B', 'C', 'D', 'E', 'F']])

print('X_train LGB-transformed codes and original Series')
# X_train LGB-transformed codes and original Series

print(*list(zip(X_train_transformed[0], X_train.X.to_list())), sep='\n', end='\n\n')
# (array([2.], dtype=float32), 'D')
# (array([0.], dtype=float32), 'A')
# (array([1.], dtype=float32), 'C')
# (array([1.], dtype=float32), 'C')
# (array([3.], dtype=float32), 'E')
# (array([3.], dtype=float32), 'E')
# (array([0.], dtype=float32), 'A')

print('X_deploy LGB-transformed codes and original Series')
# X_deploy LGB-transformed codes and original Series

print(*list(zip(X_deploy_transformed[0], X_deploy.X.to_list())), sep='\n', end='\n\n')
# (array([1.], dtype=float32), 'B')
# (array([4.], dtype=float32), 'E')
# (array([0.], dtype=float32), 'A')
# (array([2.], dtype=float32), 'C')
# (array([3.], dtype=float32), 'D')
# (array([4.], dtype=float32), 'E')
# (array([5.], dtype=float32), 'F')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...