English Deutsch 日本語
preview
Проблема разногласий: объяснимость и объяснители в ИИ

Проблема разногласий: объяснимость и объяснители в ИИ

MetaTrader 5Машинное обучение | 12 июля 2024, 13:11
114 1
Gamuchirai Zororo Ndawana
Gamuchirai Zororo Ndawana

Проблема разногласий

Разногласие является открытой сферой исследований в междисциплинарной области, известной как объяснимый искусственный интеллект (Explainable Artificial Intelligence, XAI). Объяснимый искусственный интеллект пытается помочь нам понять, как наши модели приходят к своим решениям. К сожалению, на практике все сложнее. 

Мы все знаем, что модели машинного обучения и доступные наборы данных становятся все больше и сложнее. На самом деле специалисты по данных, разрабатывающие алгоритмы машинного обучения, не могут точно объяснить поведение своих алгоритмов на всех возможных наборах данных. Объяснимый искусственный интеллект (XAI) должен помочь объяснить функциональность моделей и подтвердить, что модели готовы к практическому использованию. Как бы многообещающе это ни звучало, данная статья покажет читателю, почему мы не можем слепо доверять никаким объяснениям, которые мы можем получить от любого применения технологии объяснимого искусственного интеллекта. 

Содержание

  1. Введение
  2. Обзор методов объяснительного ИИ
  3. Глобальные и локальные объяснения
  4. Независимые от модели и специфичные для модели объяснения
  5. Определение проблемы разногласий и сопутствующих факторов
  6. Примеры
  7. Заключение
  8. ‌Рекомендации


Введение

Машинное обучение позволяет изучать отношения и взаимодействия, существующие в данных. Но как мы при этом можем изучить отношения и взаимодействия, существующие в самой модели? Лучший способ ответить на этот вопрос — использовать методы модельного объяснения. В этой статье мы с вами рассмотрим несколько различных методов объяснения. Методы модельного объяснения позволяют ответить на такие вопросы:

  • Какие признаки наша модель сочла наиболее информативными?
  • Если в нашем наборе данных 1000 признаков, как определить наиболее и наименее информативные?
  • Как меняется выходная информация нашей модели при изменении одного признака?
  • Какие признаки могут стоить дальнейшего проектирования?

Ответы на эти вопросы очень важны, но при этом существует серьезный барьер. Проблема в том, что иногда мы сталкиваемся с разногласиями между объяснениями, оценивающими одну и ту же модель. К сожалению, на момент написания не существует каких-либо всемирно признанных решений этой проблемы. Но сегодня мы попытаемся создать собственную систему, которая хоть как-то смягчит ее.

Существует глобальная тенденция, направленная на интеграцию искусственного интеллекта в более широкий спектр приложений. Однако чтобы доверять моделям, нужно быть в состоянии подробно объяснить сами модели, любые изученные ассоциации и процесс принятия решений. Это называется «объяснимостью». Объяснимый искусственный интеллект (Explainable Artificial Intelligence, XAI) умеет отслеживать то, как та или иная модель достигает своих прогнозов. Объяснимый ИИ появился как возможное решение проблемы: по мере того, как наши методы моделирования становятся более сложными, наша способность интерпретировать их постепенно уменьшается. 

Для начала рассмотрим простой пример, используя концепции, знакомые большинству читателей. Начнем с достаточно простой задачи, чтобы постепенно развить интуицию в отношении различных методов объяснения. После изучения этого примера мы должны быть готовы применить навыки к любой модели машинного обучения, обученной на реальных рыночных данных, которые мы получаем из терминала MetaTrader 5.

Простой пример, с которого мы начнем, представляет собой простую задачу оценки зарплаты спортсмена с учетом его физических способностей. Для нас очевидно, что по мере развития физических способностей спортсменов они могут рассчитывать на более высокую зарплату, но вопрос в том, какие физические способности оказывают наибольшее влияние на повышение зарплаты?

В нашем примере мы будем использовать выборку на данных, собранных титанами видеоигр Electronic Arts в рамках их серии видеоигр Madden NFL, в которой игроки могут моделировать матчи, играя за своего любимого профессионального американского футболиста. Набор данных содержит подробную статистику по профессиональным игрокам в американский футбол. Мы обучим четыре разные модели, чтобы прогнозировать зарплату игрока на основе таких характеристик игрока, как его возраст, скорость спринта и сила. После этого мы применим различные методы объяснения моделей и посмотрим, какую информацию мы можем узнать о взаимосвязи между характеристиками игрока и его зарплатой. Мы увидим, как интерпретируется каждый метод объяснения, а затем посмотрим, есть ли у нас какие-либо противоречивые объяснения. Мы выделим разногласия, попытаемся определить, что может способствовать разногласиям, и обсудим возможные решения. 


Серия видеоигр EA "Madden NFL"

Рис. 1. Видеоигра Madden NFL от Electronic Arts.


Обзор методов объяснительного ИИ

Вообще говоря, методы объяснимости можно классифицировать по-разному. Самый простой способ — разделить их на два класса: объяснители «белого ящика» и объяснители «черного ящика». В предыдущей статье мы обсуждали модели стеклянного ящика и модели черного ящика. Сегодня нас не интересуют прогнозные модели, поэтому черный ящик, о котором мы будем говорить, не является сложной и трудно интерпретируемой моделью машинного обучения. Сейчас имеется в виду алгоритмы объяснительности, которые помогают интерпретировать лежащую в основе модель.

Техника объяснения черного ящика предназначена для использования в моделях любого типа. Такой тип также называют модельно-агностическими объяснителями.

Техника объяснения белого ящика предназначена для использования структуры определенного типа базовой модели для предоставления объяснений, которые могут быть более точными для базовой модели.

Ожидаемо, разные методы объяснительности будут:

  • Придерживайтесь различных предположений о форме и структуре базовых данных.
  • Определять и оценивать различные показатели, чтобы понять модель.
  • Не справляться в определенных условиях.

Алгоритмы объяснимости также можно разделить по их методологии. Например, существуют методы объяснения, которые позволяют получить представление, корректируя входные данные каждого признака по одному и наблюдая за последующими изменениями в предсказаниях. Эти методы можно отнести к методам, основанным на возмущениях. С другой стороны, существуют некоторые алгоритмы объяснительности, которые стремятся понять, насколько чувствительна модель к изменениям характеристик. Эти методы можно классифицировать как методы, основанные на градиенте, поскольку они берут производную от выходных данных модели по ее характеристикам.

Сегодня мы рассмотрим лишь несколько различных типов объяснительных алгоритмов. Существует множество других методов объяснения, которые не покрывает наше обсуждение, и поэтому этот список не претендует на то, чтобы быть исчерпывающим.

Наконец, также важно управлять своими ожиданиями. Построение модели, способной прогнозировать цену ценной бумаги с точностью более 50%, необязательно гарантирует прибыльную торговлю. 


Глобальные и локальные объяснения

Если нужно узнать больше о важности функций и общем поведении нашей модели, необходимо использовать методы глобального объяснения. И наоборот, если мы хотим подробно понять, как наша модель пришла к одному конкретному прогнозу, нам потребуются локальные объяснения. 

Локальные объяснения позволяют понять взаимосвязь между признаками, на основе чего мы можем лучше доверять к предсказаниям нашей модели. Кроме того, мы также сможем лучше понять, какие признаки способствуют ложным прогнозам, и рассмотреть возможность разработки этих признаков, чтобы извлечь из них более полезную информацию.

Итак, вернемся к нашему простому примеру. Чтобы узнать, какие признаки важны для прогнозирования зарплаты спортсмена, нужно применить глобальные методы объяснения, такие как важность перестановок. Более того, если нужно более подробно понять прогноз одного конкретного спортсмена, понадобятся локальные методы объяснения, такие как LIME. 


На нашем примере разберемся для начала с глобальными объяснениями нашей модели.

Как всегда, начинаем с установки необходимых нам зависимостей.

Настраиваем:

  • Shap
  • eli5
  • Lime
  • Interpret
  • alibi

pip install alibi shap lime eli5 interpret

Далее загружаем наши обычные зависимости.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

Теперь мы можем прочитать набор данных.

csv = pd.read_csv("/add/your/path/here/to/the/madden/csv")

Давайте посмотрим на несколько строк и несколько столбцов из набора данных.

Набор данных Madden

Рис. 2. Пример набора данных. 

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

predictors = ["awareness_rating","throwPower_rating","kickReturn_rating",
              "leadBlock_rating","strength_rating","catchInTraffic_rating",
              "pursuit_rating", "catching_rating","acceleration_rating",
              "height","tackle_rating","yearsPro","throwUnderPressure_rating",
              "throwAccuracyDeep_rating","throwAccuracyShort_rating","speed_rating",
              "jumping_rating","toughness_rating","kickPower_rating",
              "kickAccuracy_rating","agility_rating","passBlock_rating","age"
             ]

csv[predictors].dtypes

awareness_rating            int64

throwPower_rating          int64

kickReturn_rating            int64

Теперь определим цель.

target = "totalSalary"

Теперь мы настроим модели, которые будем использовать.

from sklearn.linear_model import LinearRegression
from sklearn.neighbors import KNeighborsRegressor
from sklearn.ensemble import RandomForestRegressor
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.callbacks import EarlyStopping

После импорта нужных зависимостей и перед инициализацией наших моделей машинного обучения мы применили шаги предварительной обработки для масштабирования и стандартизации данных, а также чтобы разделить данные на обучение и тестирование. В описании статьи я опустил эти шаги, чтобы не перегружать излишними деталями. Разделили данные на обучающие и тестовые, получили переменные для обучающих данные x_train и y_train, переменные для проверочных данных x_valid и y_valid» и переменные для тестирования x_test и y_test.

Переходим к настройке каждой из моделей, с которыми сегодня будем работать.

lm = LinearRegression()
rf = RandomForestRegressor()
knn = KNeighborsRegressor(n_neighbors=10)
dnn = keras.Sequential([
    layers.Dense(units=30,activation="relu",input_shape=[scaled_data.shape[1]]),
    layers.Dense(units=20,activation="relu"),
    layers.Dropout(0.3),
    layers.Dense(units=10,activation="relu"),
    layers.Dense(units=1)
])

Затем обучаем каждую из моделей

#Fitting the linear regression
lm.fit(x_train,y_train)

#Fitting the k-nearest neighbor regressor
knn.fit(x_train,y_train)

#Fitting the random forest model
rf.fit(x_train,y_train)

#Fitting the deep neural network
early_stopping = EarlyStopping(
    min_delta=0.001,
    patience=20,
    restore_best_weights=True
)

dnn.compile(optimizer="adam",loss="mae")

dnn.fit(
    x_train,y_train,
    validation_data=(x_validation,y_validation),
    batch_size = 60,
    epochs=100,
    verbose=0,
    callbacks=[early_stopping]
)

Глобальные объяснения

Мы начнем с глобального объяснения нашей модели линейной регрессии. Техника, которую мы будем использовать, — важность перестановок. Это глобальный метод объяснения черного ящика.

import eli5
from sklearn.metrics import mean_squared_error
from eli5.sklearn import PermutationImportance
from eli5.permutation_importance import get_score_importances

Получим глобальные объяснения модели линейной регрессии

permutation = PermutationImportance(lm).fit(x_test,y_test)
eli5.show_weights(permutation,feature_names = predictors)

Глобальные объяснения для нашей модели линейной регрессии

Рис. 3. Глобальные объяснения нашей модели линейной регрессии.

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

В таблице выше важные признаки имеют положительные коэффициенты, а неважные — отрицательные. yearsPro — многолетний опыт спортсмена, имеет отрицательный коэффициент, но мы знаем, что на самом деле это имеет значение: обнаружила ли наша модель явление, о котором мы не знаем, или наш объяснитель не дает нам точного представления о правде? 

Важность перестановки может нереально перетасовать опыт спортсмена, потенциально делая его слишком молодым для своего уровня знаний или имеющим больше опыта, чем его общий возраст. Кроме того, этот метод игнорирует любые взаимодействия, которые могут присутствовать в наборе данных, и приписывает все изменения в ошибке модели только этому объекту. Следовательно, результаты могут быть потенциально нереалистичными. Это еще раз подчеркивает, как важно быть осторожными и хорошо понимать алгоритм, а не слепого применять его.

А вот длина пробежки может дать нам ценную информацию о наиболее важных признаках модели. В данном случае способность спортсмена ловить мяч и его ловкость являются одними из наиболее важных признаков. Это имеет смысл, потому что в футболе от вас ждут способности ловить широкие пасы от товарищей по команде, даже если вы находитесь под сильным давлением. Кроме того, после того, как вы поймаете мяч, нужно уйти от как можно большего количества соперников, не потеряв мяч, поэтому важность, придаваемая этим признакам, кажется правдивой.


Локальные объяснения

Как мы заявляли ранее, локальные объяснения помогают понять, как каждой признак влияет на каждый отдельный прогноз, который делает наша модель.

Мы получим местные объяснения ожиданий нашей глубокой нейронной сети относительно зарплаты Ришара ЛеКонта.


Ришар ЛеКонт

Рис. 4: Ричард ЛеКонтIII

Сначала импортируем LIME.

LIME — это аббревиатура от Locally Interpretable Model-Agnostic Explanations (локально интерпретируемые модельно-агностические объяснения). Метод объясняет, какие функции повлияли на выходные данные модели и повлияли ли эти факторы на выходные данные в лучшую или худшую сторону. 

import lime
from lime import lime_tabular
explainer = lime_tabular.LimeTabularExplainer(training_data = np.array(x_train),mode='regression',feature_names=predictors)
exp = explainer.explain_instance(data_row=scaled_data.iloc[test],predict_fn=lm.predict)
exp.show_in_notebook(show_table=True)



Объяснения глубокой сети от LIM

Рис. 5. Объяснения LIME для ожидаемой заработной платы нашей глубокой нейронной сети по игроку Ришару ЛеКонту


Графики содержат массу информации: прежде всего можно увидеть, какие физические способности ЛеКонта увеличивают его ожидаемую зарплату, а какие уменьшают. Наша нейросеть ожидала, что рейтинг стойкости ЛеКонта снизит его ожидаемую зарплату, и это имеет смысл, поскольку ЛеКонт имеет средний показатель стойкости. Более того, глубокая нейросеть правильно определила сильные стороны ЛеКонта и ожидала, что его зарплата увеличится за счет сильных сторон. Именно такое поведение мы и ожидали. Локальные объяснения позволяют проверить модель, а не слепо доверять ей.


Независимые от модели и специфичные для модели объяснения

В тех случаях, когда нам известна структура базовой модели, мы можем использовать методы объяснения, разработанные специально для этой архитектуры модели. Их обычно называют объяснителями белого ящика. На практике объяснители белого ящика могут быть более эффективными в вычислительном отношении, чем их аналоги черного ящика.

Объяснители черного ящика не зависят от модели, то есть могут интерпретировать и объяснить любую представленную им модель. Алгоритм LIME, который мы только что рассмотрели, является примером объяснителя черного ящика, о чем и говорится в названии: Locally Interpretable Model-Agnostic Explanations — локально интерпретируемое не зависящее от модели объяснение. 

Объяснители белого ящика можно использовать, когда мы точно знаем структуру базовой модели. При этом они позволяют получить более точные объяснения поведения нашей модели. При этом объяснители черного ящика часто привносят некоторый уровень предвзятости при объяснении наших моделей. Объяснители черного ящика делают некоторые упрощающие предположения о форме модели, с которой они имеют дело. И если эти предположения не оправдываются, мы получаем неверные объяснения.

Как правило, если вы точно знаете свойства модели, в лучше использовать объяснители белого ящика. 

Давайте посмотрим на объяснитель черного ящика в действии. В библиотеке SHAP есть реализации объяснителей черного ящика SHAP. Посмотрим на один из них. 

Импорт SHAP

Импорт SHAP

Расчет значений SHAP

explainer = shap.Explainer(xgb.predict,scaled_data.loc[test:test_end,predictors])
shap_values = explainer(scaled_data.loc[test:test_end,predictors])

Построение объяснения черного ящика

shap.plots.beeswarm(shap_values)


Объяснения черного ящика SHAP

Рис. 6. Объяснения черного ящика SHAP для нашей модели XGB


Ширина каждой строки определяется выбросами и не несет никакой информации о важности объекта. Мы оцениваем важность объекта, учитывая вертикальное расположение объекта на графике. Чем выше находится объект, тем более важным он воспринимается алгоритмом SHAP.

Кроме того, обратите внимание, что на некоторых объектах синие и розовые точки хорошо разделены, тогда как в других рядах они перемешаны. Когда точки перемешаны, это обычно является признаком эффекта взаимодействия между этим признаком и другим или набором признаков. И весь этот объем информации отображается на одном графике SHAP. 

Каждая точка представляет значение Шепли для каждой точки данных. Это позволяет быстро оценить, как каждая отдельная точка данных повлияла на прогноз модели на детальном уровне. Цвет точки представляет направление и величину влияния точки данных на прогноз нашей модели. Синий цвет указывает на снижение выхода модели, а розовый — на увеличение. Обратите внимание, что алгоритм SHAP предполагает, что объекты независимы, или, другими словами, он игнорирует любые взаимодействия в наборе данных. Если это предположение не оправдывается, алгоритм получается ненадежным. 

Теперь рассмотрим объяснитель белого ящика, предназначенный для древовидных моделей, таких как наша модель XGB. Мы используем специальный метод TreeExplainer(), предназначенный для объяснения древовидных моделей.

tree_explainer = shap.TreeExplainer(xgb)
tree_shap_values = explainer(x_test)

Далее можем построить объяснения белого ящика.

shap.plots.beeswarm(tree_shap_values)

Объяснение белого ящика SHAP

Рис. 7. Объяснения белого ящика SHAP для нашей модели XGB

Сравните 4 наиболее важные особенности объяснения SHAP для черного ящика и белого ящика. Видите проблему разногласий? 


Определение проблемы разногласий и сопутствующих факторов

Итак, мы с вами познакомились с объяснителями моделей. Далее перейдем непосредственно к проблеме разногласий. Начнем с рассмотрения того, что такое разногласие.
Давайте разберем, что представляет собой разногласие в области объяснений важности функций:
  • Перестановки функций. Первая форма разногласий — это когда перестановки функций различаются. Если определенный порядок важности функций имеет значение в вашем рабочем процессе, появление различных перестановок в объяснениях становится ключевым предметом конфликта. Это особенно важно, когда детальная последовательность функций имеет значение для анализа.
  • Наборы функций с лучшим рейтингом. Если копнуть глубже, разногласия распространяются и на наборы функций с лучшим рейтингом. Когда строгое соблюдение точной перестановки важности функций ослабляется, внимание переключается на набор главных функций. Несоответствие в первых 3, 5 или любых n характеристиках, определенных разными объяснителями для одной и той же модели, становится заметной точкой расхождения.
  • Колебание знака коэффициента. Показатели многих объяснителей зависят от коэффициентов, присвоенных признакам, указывающих их положительный или отрицательный вклад в желаемый результат. Иногда можно наблюдать изменение знака этого коэффициента между двумя объяснениями одной и той же модели. Такие изменения служат индикаторами разногласий. В таком случае нужно более внимательно изучить внутреннюю работу модели.
  • Относительное упорядочение интересующих особенностей. При более пристальном рассмотрении конкретных интересующих особенностей разногласия приобретают еще одно измерение. Если сосредоточиться на сопоставлении важности одной функции по сравнению с другой, изменения в порядке этих двух функций в разных объяснениях становятся причиной разногласий.

Что не является разногласием?

Важно учитывать, что не все различия означают разногласия. Рассмотрим такие случаи:

  • Расходящиеся значения важности. Бывает, что значения важности признаков, рассчитанные разными объяснителями, не совпадают точно. Это не является разногласием. Суть в том, что различные алгоритмы дают разные вычисления, что затрудняет прямое сравнение. Акцент при этом делается не на числовом равенстве значений важности, а на последовательных выводах, полученных в результате различных объяснений.
  • Последовательное понимание точных значений. Суть правильного анализа — стремление к последовательному пониманию, а не поиск точного числового равенства. Мы и не можем ожидать от объяснителей, что они дадут очень точную оценку с конкретными значениями. Здесь нужно взглянуть на вещи шире и понять, что объяснения, хотя и различаются численно, могут сходиться, например, в направлении.
  • Сложность модели и проблемы оценки. С увеличением сложности модели сложность точной оценки внутренней ее работы растет прямо пропорционально. Просто нужно признать эту внутреннюю сложность. Поэтому, когда мы имеем дело с очень сложными моделями, расхождение в значениях объяснителей становится скорее ожидаемой проблемой, чем поводом для тревоги. Эта точка зрения согласуется с развивающейся природой ИИ, где стремление к прозрачности сталкивается с растущими сложностями.

Почему объяснители не согласны друг с другом?
Есть много причин, по которым объяснители могут не соглашаться друг с другом, давайте вместе попробуем разобраться в нескольких случаях.

Сравнение глобальных и локальных объяснителей

Одна из причин, по которой мы можем наблюдать разногласия, заключается в том, что мы можем сравнивать глобальные и локальные объяснения. Хотя это очевидное объяснение, все равно хочется убедиться, что мы никогда не попадемся на эту ошибку. Глобальные и локальные объяснения нельзя просто напрямую сравнивать друг с другом. Если у вас нет детального понимания того, как алгоритмы реализованы под капотом, сравнивать глобальные и локальные объяснения нецелесообразно, поскольку это, вероятно, приведет к разным объяснениям.

Сравнение объяснителей черного и белого ящика

Более того, нельзя напрямую сравнивать объяснители черного ящика и белого ящика. Помните, что объяснители черного ящика пытаются показать полезность возможности объяснить любой алгоритм, поэтому они делают определенные упрощающие предположения о модели или ее поведении. Эти предположения позволяют объяснителям черного ящика работать в широком диапазоне обстоятельств, однако такие предположения не всегда оправдываются, а допущения могут быть слишком большими. Соответственно, объяснения черного и белого ящика будут различаться. 

Изменение порядка признаков

Неожиданным поводом для разногласий могут стать любые изменения порядка изложения признаков. Одни методы объяснения чувствительны к порядку входных данных модели, другие нет. Например, метод взаимной информации (Mutual Information) не чувствителен к порядку ввода, в отличие от SHAP. Следовательно, вполне возможно, что объяснитель SHAP не сможет прийти к согласию сам с собой после наблюдения идентичных моделей.  

Например, ниже показаны два объяснения SHAP, полученные от двух идентичных XGBRegressor. Единственная разница между двумя моделями — это порядок признаков, которые они принимают в качестве входных данных. При этом они обучаются на одном и том же наборе данных и имеют одну и ту же цель. 


Начальные значения SHAP

Рис. 8. Начальные значения SHAP


Перемешанные значения и SHAP

Рис. 9. Значения SHAP после изменения порядка элементов.

Изменив порядок отображения функций в модели, мы видим, что наши объяснения теперь не согласуются друг с другом. Признак высоты внезапно вырос, хотя новой информации у нас не было. Топ-3 остался неизменным, но большинство функций прыгали вверх и вниз и меняли позиции. Если вы планируете использовать методы бустрэппинга или другие формы повторной выборки или выбора подмножества, вы должны быть готовы к такому поведению. Это нормальное и ожидаемое явление. 


Более того, разные реализации одной и той же техники объяснения могут не согласовываться друг с другом из-за небольших различий в их расчетах. Например, реализация важности перестановок в eli5 чувствительна к порядку входных данных, а реализация той же техники в sklearn — нет. Потому что одна и та же техника объяснения может быть реализована разными способами. 

Чтобы продемонстрировать, что реализация важности перестановок в eli5 чувствительна к порядку входных данных, ниже я покажу два объяснения, полученные с использованием реализации важности перестановок в eli5. Мы получили результаты от двух идентичных XGBRegressor. Единственная разница между двумя моделями — это порядок признаков, которые они принимают в качестве входных данных. При этом они обучаются на одном и том же наборе данных и имеют одну и ту же цель. 


Начальная важность перестановки

Рис. 10. Начальная важность перестановки


Перемешанная важность перестановки

Рис. 11. Перемешанная важность перестановки


Обратите внимание, что параметр kickPower_rating изначально имел положительный коэффициент, но после изменения порядка функций имеет отрицательный коэффициент! Такие нестабильные колебания считаются сильными разногласиями. Изменились наиболее важные признаки, также изменился относительный порядок между признаками.

Наконец, одним из самых явных моментов будет методологическое расхождение. Оно порождает интересный феномен, когда объяснители не соглашаются друг с другом, хотя оба объясняют одну и ту же модель. Поскольку каждый объяснитель рассчитывает разные показатели модели, каждый из них может интерпретировать модель в разном свете.

К счастью, в XGB реализована функция, позволяющая оценить важность функций. Давайте воспользуемся этой функцией и посмотрим, какой метод объяснения дает достоверное представление истины. Я также сразу добавил сюда результаты предыдущих объяснений, чтобы вам не нужно было прокручивать вверх и вниз.


Истинные значения XGB

Рис. 12. Важность признаков XGB

Важность перестановки XGB

Рис. 13. Важность перестановки XGB


Объяснения белого ящика SHAP

Рис. 14: Объяснения белого ящика SHAP


Объяснения черного ящика SHAP

Рис. 15. Объяснения черного ящика SHAP


Explainable Boosting Machine (EBM)

Рис. 16. Важность функции модели на основе дерева, стеклянный ящик

Рейтинг осведомленности был самой важной особенностью модели, однако небольшой набор методов объяснения черного ящика не смог объяснить это, и вообще не справился с тремя основными признаками. Это еще одно напоминание о том, что объяснения — это всего лишь оценки важности признаков, а не абсолютная истина. Кроме того, обратите внимание, что yearsPro неоднократно занимал верхние позиции, но на самом деле это было не так важно. То есть не нужно полагаться на то, что признаки, которые несколько раз занимают высокие места в разных тестах, действительно по своей сути важны. 

Объяснитель черного ящика, который мы применили к нашей модели XGB, противоречит объяснителю белого ящика. Но в конечном итоге оба объяснителя оказались неправильными. Выяснять, какой объяснитель точнее, будет пустой тратой вашего времени, потому что ни один из них не приближает нас к истине.

Я также запустил ema на данных, чтобы посмотреть, можно ли использовать модель стеклянного ящика в качестве прокси для оценки важности признаков. И хотя ей удалось правильно определить наиболее важную особенность из набора данных, это не всегда подходящий вариант, особенно если ваша модель не основана на дереве. К сожалению, модель стеклянного ящика также обнаружила, что признак yearsPro информативен, хотя это не так. Это означает, что объяснители кроме прочего могут согласиться с ложной информацией!


Примеры

Теперь мы готовы начать работу с реальными рыночными данными. Сначала получим данные из терминала MetaTrader 5. Для эффективного извлечения и преобразования данных, разработаем скрипт на MQL5. Начнем с объявления глобальных переменных.
//---Our handlers for our indicators
int ma_handle;
int rsi_handle;
int cci_handle;
int ao_handle;
int bbands_handle;
int atr_handle;

Далее создадим массивы для хранения значений индикаторов. Здесь мы методично собираем и затем используем результаты индикаторов на протяжении всего выполнения скрипта. 

//---Data structures to store the readings from our indicators
double ma_reading[];
double rsi_reading[];
double cci_reading[];
double ao_reading[];
double bb_high_reading[];
double bb_low_reading[];
double bb_mid_reading[];
double atr_reading[];

Создадим CSV-файл. 

//---File name
string file_name = "The Dissagrement Problem Data.csv";

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

//---Amount of data requested
int size = 10000;
int size_fetch = size + 50;

Переходим к настройке обработчиков индикаторов. Чтобы настроить работу с индикатором, необходимо указать символ и таймфрейм, на которых мы будем его использовать. Далее, в зависимости от индикатора, может потребоваться указать период индикатора, параметр сдвига, метод сглаживания и тип цен для расчета. 

void OnStart()
  {
      //---Setup our technical indicators
      ma_handle = iMA(_Symbol,PERIOD_CURRENT,20,0,MODE_EMA,PRICE_CLOSE);
      rsi_handle = iRSI(_Symbol,PERIOD_CURRENT,60,PRICE_CLOSE);
      cci_handle = iCCI(_Symbol,PERIOD_CURRENT,10,PRICE_CLOSE);
      ao_handle = iAO(_Symbol,PERIOD_CURRENT);
      bbands_handle = iBands(_Symbol,PERIOD_CURRENT,120,0,0.2,PRICE_CLOSE);
      atr_handle = iATR(_Symbol,PERIOD_CURRENT,14);

Далее нужно перенести значения из хэндлов индикатора в структуры данных.

 //---Set the values as series
      CopyBuffer(ma_handle,0,0,size_fetch,ma_reading);
      ArraySetAsSeries(ma_reading,true);
      CopyBuffer(rsi_handle,0,0,size_fetch,rsi_reading);
      ArraySetAsSeries(rsi_reading,true);
      CopyBuffer(cci_handle,0,0,size_fetch,cci_reading);
      ArraySetAsSeries(cci_reading,true);
      CopyBuffer(ao_handle,0,0,size_fetch,ao_reading);
      ArraySetAsSeries(ao_reading,true);
      CopyBuffer(bbands_handle,0,0,size_fetch,bb_mid_reading);
      ArraySetAsSeries(bb_mid_reading,true);
      CopyBuffer(bbands_handle,1,0,size_fetch,bb_high_reading);
      ArraySetAsSeries(bb_high_reading,true);
      CopyBuffer(bbands_handle,2,0,size_fetch,bb_low_reading);
      ArraySetAsSeries(bb_low_reading,true);
      CopyBuffer(atr_handle,0,0,size_fetch,atr_reading);
      ArraySetAsSeries(atr_reading,true);

Прежде чем мы начнем процесс записи файла, обязательно в скрипт нужно включить обработчик файлов. Эти настройки позволят корректно создать выходной файл и работать с ним.

      //---Write to file
       int file_handle=FileOpen(file_name,FILE_WRITE|FILE_ANSI|FILE_CSV,",");

Далее важный этап в нашем скрипте: идем по массивам исторических цен и значений индикаторов, чтобы записать нужные данные в файл CSV.

for(int i=-1;i<=size;i++){
      if(i == -1){
            FileWrite(file_handle,"Time","Open","High","Low","Close","MA 20","RSI 60","CCI 10","AO","BBANDS 120 MID","BBANDS 120 HIGH","BBANDS 120 LOW","ATR 14");
      }
      
      else{
            FileWrite(file_handle,iTime(_Symbol,PERIOD_CURRENT,i),
                                 iOpen(_Symbol,PERIOD_CURRENT,i),
                                 iHigh(_Symbol,PERIOD_CURRENT,i),
                                 iLow(_Symbol,PERIOD_CURRENT,i),
                                 iClose(_Symbol,PERIOD_CURRENT,i),
                                 ma_reading[i],
                                 rsi_reading[i],
                                 cci_reading[i],
                                 ao_reading[i],
                                 bb_mid_reading[i],
                                 bb_high_reading[i],
                                 bb_low_reading[i],
                                 atr_reading[i]);
      }
    }
    FileClose(file_handle);
  }


Рыночные данные

Рис. 17. Рыночные данные из терминала MetaTrader 5.


Теперь мы готовы обработать данные и проверить то, что мы узнали из примера выборки. 

Импортируем зависимости.

#Import Dependencies
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import shap
import lime
from lime import lime_tabular
import eli5
from eli5.sklearn import PermutationImportance
from sklearn.feature_selection import mutual_info_regression

Загружаем зависимостей для IntepretML.

from interpret import set_visualize_provider
from interpret.provider import InlineProvider
set_visualize_provider(InlineProvider())
from interpret import show
from interpret.blackbox import MorrisSensitivity

Читаем csv.

csv = pd.read_csv("/enter/your/path/here")

Настроим цель.

csv["Target"] = csv["Close"].shift(-30)

Отбросить все строки с пропущенными значениями.

csv.dropna(axis=0,inplace=True)

Создадим список предикторов.

drop = ["Time","Target"]
predictors = csv.columns.tolist()
predictors = [col for col in predictors if col not in drop]
predictors

Масштабируем данные.

from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
print(scaler.fit(csv.loc[:,predictors]))
scaled_data =  pd.DataFrame(scaler.transform(csv.loc[:,predictors]), index = csv.index, columns = predictors)
scaled_data


Масштабированные рыночные данные

Рис. 18. Масштабированные рыночные данные

Настройка алгоритмов черного ящика

#Black box models
from xgboost import XGBRegressor
from sklearn.linear_model import LinearRegression
from xgboost import plot_importance
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.callbacks import EarlyStopping

Разделение данных на обучающую и тестовую выборку

train = 0
train_end = 5000
test = train_end + 40

Настройка линейной модели

lm = LinearRegression()
lm.fit(scaled_data.loc[train:train_end,predictors],csv.loc[train:train_end,"Target"])

Настройка модели XGB

#XGBModel
xgb = XGBRegressor()
xgb.fit(scaled_data.loc[train:train_end,predictors],csv.loc[train:train_end,"Target"])

Настройка модели глубокой нейросети

dnn = keras.Sequential([
    layers.Dense(units=30,activation="relu",input_shape=[scaled_data.shape[1]]),
    layers.Dense(units=20,activation="relu"),
    layers.Dropout(0.3),
    layers.Dense(units=10,activation="relu"),
    layers.Dense(units=1)
])
early_stopping = EarlyStopping(
    min_delta=0.001,
    patience=20,
    restore_best_weights=True
)
dnn.compile(optimizer="adam",loss="mae")
dnn.fit(
    scaled_data.loc[train:train_end,predictors],csv.loc[train:train_end,"Target"],
    validation_data=(csv.loc[validation:validation_end,predictors],csv.loc[validation:validation_end,"Target"]),
    batch_size = 60,
    epochs=100,
    verbose=0,
    callbacks=[early_stopping]
)


Получение глобальных объяснений для глубокой нейронной сети

Мы воспользуемся пакетом alibi, чтобы получить объяснения для нашей глубокой сети. В пакете alibi есть полезная реализация объяснительной техники "Накопленные локальные эффекты" (Accumulated Local Effects, ALE). Метод ALE достаточно надежен и может обрабатывать сильно коррелированные признаки. При этом в нем нет четких предположений о независимости признаков, его можно визуально интерпретировать, он эффективен в вычислительном отношении и, в отличие от некоторых других методов объяснения, ALE не полагается на предположения о линейности, что делает его хорошо подходящим для выявления сложных взаимосвязей в данных.   

Сначала рассчитываем значения ALE.

dnn_ale = ALE(dnn.predict, feature_names  = predictors,target_names=["Close 30 Steps"])

Затем мы преобразуем входные данные в формат NumPy, чтобы можно было построить графики ALE.

X = scaled_data.loc[train:train_end,predictors].to_numpy()
dnn_alibi =dnn_ale.explain(X)
plot_ale(dnn_alibi,n_cols=4, fig_kw={'figwidth': 20, 'figheight': 10}, sharey=None)

Графики ALE помогают интерпретировать, как изменения в каждом признаке влияют на выходные данные модели. Например, ниже показан график ALE для нашего Awesome Oscillator. Как видим, Awesome Oscillator может помочь нашей глубокой нейронной сети предвидеть, когда цена упадет. Мы наблюдаем нисходящий наклон на графике ALE по мере увеличения значения Awesome Oscillator.

ALE AO

Рис. 19. График ALE для Awesome Oscillator


Более того, неинформативные признаки будут иметь график ALE, напоминающий горизонтальную линию, а это означает, что изменения в этом признаке мало повлияют на цель. В нашем исследовании не был информативным индекс RSI. 

ALE RSI

Рис. 20. ALE RSI

Получение глобальных объяснений от независимого от модели объяснения SHAP

explainer = shap.Explainer(xgb.predict,scaled_data.loc[test:,predictors])
shap_values = explainer(scaled_data.loc[test:,predictors])
shap.plots.beeswarm(shap_values)


График Beeswarm черного ящика SHAP для нашей модели XGB

Рис. 21. График SHAP Black-box Beeswarm для XGB

Диаграмма beeswarm показывает, что Awesome Oscillator является наиболее важным признаком в этом наборе данных. Помните, что ширина каждой строки на графике не несет никакой информации. Кроме того, мы замечаем, что синие и розовые точки не перепутаны, а это означает, что в наборе данных может не быть сильных членов взаимодействия.

Важность признака в соответствии с взаимной информацией (Mutual Information, MI)

mi_scores = mutual_info_regression(scaled_data.loc[test:,predictors], csv.loc[test:,"Target"])
mi_scores = pd.Series(mi_scores, name="MI Scores", index=scaled_data.columns)
mi_scores = mi_scores.sort_values(ascending=False)
mi_scores

BBANDS 120 MID     1.739039

BBANDS 120 HIGH    1.731220

BBANDS 120 LOW     1.716019

MA 20                      1.525800

High                        1.172096

Open                       1.155583

Close                       1.143642

Low                         1.140613

ATR 14                     0.421772

AO                           0.232608

RSI 60                      0.181932

CCI 10                     0.016491

MI полностью противоречит нашему объяснению SHAP в том, что касается четырех основных признаков. Это только вызывает больше сомнений в нашем и без того запутанном деле. Хуже того, объяснитель SHAP был действительно прав в отношении того, что Awesome Oscillator является наиболее важной функцией в этом случае. Таким образом, использование нескольких объяснителей на самом деле является палкой о двух концах: с одной стороны, это защищает от предвзятости, унаследованной от любого используемого объяснения, но с другой стороны, создает большее пространство вероятности возникновения разногласий. Трудно сказать, какой случай эмпирически лучше, потому что все зависит от конкретного набора данных, конкретной модели и многих других переменных.

Наконец, рассмотрим анализ чувствительности Морриса (Morris Sensitivity Analysis)

msa = MorrisSensitivity(xgb, scaled_data.loc[train:train_end,predictors])
show(msa.explain_global())


Morris Sensitivity Analysis

Рис. 22: Morris Sensitivity Analysis

Фактические показатели важности из нашей модели XGB.

Истинные данные XGB

Рис. 23. Важность рыночных данных XGB

Скользящая средняя была самой важной функцией в выборке, за ней следовал Awesome Oscillator. В данном конкретном случае анализ чувствительности Морриса дал относительно лучшие объяснения, однако в большинстве случаев у нас нет доступа к истине, поэтому как выбрать, какому объяснению придать больший вес? Как быть уверенным в своем решении? Как проверить решения относительно важности функций, если нет доступа к таблицам истинной важности функций? 


Заключение

Как мы видим, здесь нет простых ответов. Слишком много составных частей. Необходимо учитывать форму и структуру данных, базовую модель, наличие условий взаимодействия в данных и, прежде всего, внутреннюю работу каждого объяснителя. Более того, в контролируемом примере видно, что все объяснители могут ошибаться, поэтому в такой ситуации попытка разрешить любые разногласия была бы бесполезной тратой времени. Таким образом, выгода, которую мы получаем от объяснительных методов, не всегда оправдывает сложность, которую они могут привнести. Будем надеяться, что со временем мы сможем реализовать более эффективные объяснительные методы и более совершенные алгоритмы.

Рекомендации

С учетом всего этого, возможно, лучшим решением проблемы разногласий может быть больше полагаться на модели машинного обучения, которые легче интерпретировать. Например, обобщенные аддитивные модели (GAM) или объяснимые повышающие машины (EBM). Они прекрасно заменяют собой необходимость объяснений. На сегодняшний день не существует общепризнанных решений для всех возможных случаев проблемы разногласий. Но, поскольку это известная проблема, возможно, однажды мы сможем уверенно объяснить любую модель машинного обучения, которую мы создаем. 

Перевод с английского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/en/articles/13729

Последние комментарии | Перейти к обсуждению на форуме трейдеров (1)
Maxim Dmitrievsky
Maxim Dmitrievsky | 13 июл. 2024 в 10:14
К сожалению, обьяснители работают только для стационарных зависимостей, когда важность предикторов не меняется со временем. Такие предикторы легко получить для цветков, по количеству лепестков и т.д., но сложно получить на фин. рынках. 
Кроме этого, современные модели способны самостоятельно занулять участие тех или иных признаков. 
Особенности написания Пользовательских Индикаторов Особенности написания Пользовательских Индикаторов
Написание пользовательских индикаторов в торговой системе MetaTrader 4
Разрабатываем мультивалютный советник (Часть 14): Адаптивное изменение объёмов в риск-менеджере Разрабатываем мультивалютный советник (Часть 14): Адаптивное изменение объёмов в риск-менеджере
Разработанный ранее риск-менеджер содержал только базовую функциональность. Попробуем рассмотреть возможные пути его развития, позволяющие повысить торговые результаты без вмешательства в логику торговых стратегий.
Особенности написания экспертов Особенности написания экспертов
Написание и тестирование экспертов в торговой системе MetaTrader 4.
Алгоритм искусственного электрического поля — Artificial Electric Field Algorithm (AEFA) Алгоритм искусственного электрического поля — Artificial Electric Field Algorithm (AEFA)
Статья представляет алгоритм искусственного электрического поля (AEFA), вдохновленный законом Кулона об электростатической силе. Алгоритм моделирует электрические явления для решения сложных задач оптимизации, используя заряженные частицы и их взаимодействие. AEFA демонстрирует уникальные свойства в контексте других алгоритмов, связанных с законами природы.