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')