Диаграмма важности функций в нейронной сети с использованием Keras в Python
Я использую Python(3,6) Анаконда (64 бит) Spyder (3.1.2). Я уже установил модель нейронной сети, используя keras (2.0.6) для задачи регрессии (один ответ, 10 переменных). Мне было интересно, как я могу сгенерировать диаграмму важности функций следующим образом:
def base_model():
model = Sequential()
model.add(Dense(200, input_dim=10, kernel_initializer='normal', activation='relu'))
model.add(Dense(1, kernel_initializer='normal'))
model.compile(loss='mean_squared_error', optimizer = 'adam')
return model
clf = KerasRegressor(build_fn=base_model, epochs=100, batch_size=5,verbose=0)
clf.fit(X_train,Y_train)
4 ответа
Недавно я искал ответ на этот вопрос и нашел кое-что, что было бы полезно для того, что я делал, и подумал, что было бы полезно поделиться. В итоге я использовал модуль важности перестановок из пакета eli5. Это наиболее легко работает с моделью scikit-learn. К счастью, Keras предоставляет упаковку для последовательных моделей. Как показано в коде ниже, использовать его очень просто.
from keras.wrappers.scikit_learn import KerasClassifier, KerasRegressor
import eli5
from eli5.sklearn import PermutationImportance
def base_model():
model = Sequential()
...
return model
X = ...
y = ...
my_model = KerasRegressor(build_fn=basemodel, **sk_params)
my_model.fit(X,y)
perm = PermutationImportance(my_model, random_state=1).fit(X,y)
eli5.show_weights(perm, feature_names = X.columns.tolist())
Это относительно старый пост с относительно старыми ответами, поэтому я хотел бы предложить еще одно предложение по использованию SHAP
чтобы определить важность функций для ваших моделей Keras. SHAP
предлагает поддержку как двумерных, так и трехмерных массивов по сравнению с eli5
который в настоящее время поддерживает только 2d-массивы (поэтому, если ваша модель использует слои, требующие ввода 3d, например LSTM
или GRU
, eli5
не будет работать).
Вот ссылка на пример того, какSHAP
может определить важность функции для вашего Keras
моделей, но на случай, если он когда-либо станет сломан, ниже также приведены примеры кода и графики (взяты из указанной ссылки):
import shap
# load your data here, e.g. X and y
# create and fit your model here
# load JS visualization code to notebook
shap.initjs()
# explain the model's predictions using SHAP
# (same syntax works for LightGBM, CatBoost, scikit-learn and spark models)
explainer = shap.TreeExplainer(model)
shap_values = explainer.shap_values(X)
# visualize the first prediction's explanation (use matplotlib=True to avoid Javascript)
shap.force_plot(explainer.expected_value, shap_values[0,:], X.iloc[0,:])
shap.summary_plot(shap_values, X, plot_type="bar")
В настоящее время Keras не предоставляет никаких функций для извлечения важности функции.
Вы можете проверить этот предыдущий вопрос: Keras: Есть ли способ получить значение переменной?
или связанная GoogleGroup: важность функции
Спойлер: В GoogleGroup кто-то объявил проект с открытым исходным кодом, чтобы решить эту проблему..
Неудобный способ — получить веса для каждого нейрона в каждом слое и показать/сложить их вместе.
feature_df = pd.DataFrame(columns=['feature','layer','neuron','weight','abs_weight'])
for i,layer in enumerate(model.layers[:-1]):
w = layer.get_weights()
w = np.array(w[0])
n = 0
for neuron in w.T:
for f,name in zip(neuron,X.columns):
feature_df.loc[len(feature_df)] = [name,i,n,f,abs(f)]
n+=1
feature_df = feature_df.sort_values(by=['abs_weight'])
feature_df.reset_index(inplace=True)
feature_df = feature_df.drop(['index'], axis=1)
fig = px.bar(feature_df,x='feature',y='abs_weight',template='simple_white')
fig.show()
Это дает что-то вроде этого: ось X — это ваши функции: