Вопрос или проблема
У меня есть набор данных с закупками организации, в которой я работаю. Цель состоит в том, чтобы найти наиболее важные характеристики, которые объясняют, почему некоторые процессы закупок успешны, а другие – нет.
Для решения этой задачи я использую классификатор деревьев решений.
Сначала я конвертирую булевые столбцы в целочисленные.
for col in ['flag_prequalification', 'flag_procurement_category_strategy']:
data.loc[:, col] = data.loc[:, col].astype(int)
Затем конвертирую объекты типа в строку. Это необходимо для кодирования меток.
for cat_feature in categorical_features:
data.loc[:, cat_feature] = data.loc[:, cat_feature].fillna('unknown').astype(str)
%%time
encoder = defaultdict(LabelEncoder)
data.loc[:, categorical_features] = (
data
.loc[:, categorical_features]
.apply(lambda x: encoder[x.name].fit_transform(x), axis=0)
)
После этого давайте используем логарифм суммы вместо суммы.
for col in ['sum_tru_no_nds (lot)', 'price (lot)', 'count (lot)']:
data[col] = (data[col] + 1).apply(np.log)
И, в конце, нарисуем дерево:
from sklearn.externals.six import StringIO
from IPython.display import Image
from sklearn.tree import export_graphviz
import pydotplus
import graphviz
# DOT данные
dot_data = tree.export_graphviz(clf, out_file=None,
feature_names=None,
class_names=target_col,
filled=True)
# Рисуем граф
graph = graphviz.Source(dot_data, format="png")
graph
Вопрос в том, как я могу объяснить это дерево другим, более точно, как я могу декодировать эти метки в дереве?
Во-первых, установка feature_names
заменит все X[2]
и тому подобное. Использование feature_names=data.columns
имеет смысл, при условии, что ваши имена признаков не слишком длинные для удобного отображения.
Теперь вы все равно будете сравнивать с кодировками меток. Сохранив объекты кодировщика меток (ваш словарь encoder
), вы можете узнать, какие уровни соответствуют целочисленным меткам (с атрибутом classes_
или, возможно, методом inverse_transform
). Если у ваших признаков много уровней, вероятно, вы не захотите отображать все уровни в каждом разбиении, и лучше просто предоставить их где-то сбоку. Если у ваших признаков немного уровней, возможно, стоит подкорректировать полученный код DOT; смотрите этот связанный ответ от меня, который касается переменных с одноразовым кодированием.
Поскольку вы уже используете scikit-learn для обучения дерева решений, вам следует использовать scikit-learn для кодирования признаков. Например, OneHotEncoder от scikit-learn имеет атрибут get_feature_names
, который возвращает имена признаков для выходных признаков.
Ответ или решение
Чтобы объяснить дерево решений другим и декодировать закодированные метки, вам следует учесть несколько ключевых аспектов, которые помогут сделать вашу презентацию понятной и доступной.
1. Установка имен признаков
Когда вы создаете граф дерева решений и вызываете export_graphviz
, очень важно правильно указать параметр feature_names
. Это заменит индексы вроде X[2]
на реальные имена признаков, присвоенные вашим данным. Подходящим вариантом будет установить feature_names=data.columns
, однако убедитесь, что ваши названия не слишком длинные для удобного отображения.
2. Использование кодировщика для декодирования меток
Проблема заключается в том, что после применения кодировщика LabelEncoder
к категориальным признакам, вы остаетесь с целыми числами, представляющими каждую категорию. Чтобы декодировать эти метки обратно в исходные значения, сохраните объекты кодировщика в вашем словаре encoder
. Таким образом, вы сможете получить соответствие между уровнями и их целочисленными метками при помощи атрибута classes_
или метода inverse_transform
. Это позволит вам легко преобразовать закодированные метки обратно в оригинальные категории.
3. Обработка множества уровней
Если у ваших категориальных признаков много уровней, то показывать их все в каждом разделе дерева может быть нецелесообразно. В таком случае, лучше держать эти уровни отдельно и представлять их в сжатом виде, например, в таблице под вашим деревом решений. Если же уровней немного, то вы можете отредактировать сгенерированный код DOT, чтобы напрямую заменить закодированные метки на их оригинальные наименования.
4. Использование OneHotEncoder
Вместо применения LabelEncoder
для категориальных переменных вы можете также рассмотреть использование OneHotEncoder
из библиотеки scikit-learn. Этот подход будет полезен, если ваши категориальные переменные являются номинальными (без порядка). Один из плюсов OneHotEncoder
в том, что он предоставляет метод get_feature_names
, который возвращает имена выходных признаков, что упрощает анализ и интерпретацию.
5. Визуализация дерева решений
После выполнения всех вышеупомянутых шагов, перепечатывайте ваш граф дерева решений, но теперь уже с правильно декодированными метками. Это сделает ваш граф более читабельным и понятным для аудитории.
Заключение
Ваша способность эффективно декодировать и объяснить дерево решений будет зависеть от того, как хорошо вы сможете представить свою модель и обеспечить понимание взаимосвязи между признаками и целевыми переменными. Кроме того, использование инструментов визуализации поможет значительно повысить уровень понимания и вовлечённости вашей аудитории. Не забывайте добывать отзывы и задавать вопросы, чтобы убедиться, что все аспекты были чётко объяснены.