Подбор параметров для построения модели для различных видов переменных

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

Подбор признаков (Feature selection) - это процесс уменьшения количества входных параметров, используемых при построении моделей. Используя различные статистические подходы, мы можем определить взаимоотношение между признаками и целевой переменной, для определения тех переменных, которые имеют наиболее сильную связь. Однако, выбор статистических методов зависит как от создаваемой модели, так и от типов сравниваемых данных, а потому может представлять определённые трудности для разработчика. Числовые переменные Для начала рассмотрим методы, которые следует применять для работы с числовыми переменными. Если на выходе модели у нас формируется категориальная переменная (Номинальная, ординальная или класс, например), то правильным будет применять такие методы как ANOVA correlation coefficient или Kendall’s rank coefficient для линейной или нелинейной зависимости соответственно.

Пример программного кода для реализации данных алгоритмов:

from sklearn.feature_selection import SelectKBest from sklearn.feature_selection import f_classif import pandas as pd import numpy as np #%% Датасет для демонстрации df_africa = pd.read_csv(r"C:\Users\mmvik\Downloads\african_crises.csv") df_africa['banking_crisis'] = df_africa['banking_crisis'].map({'crisis': 1, 'no_crisis': 0}) #%% #для расчёта корреляции методом кендалла можно использовать библиотеку pandas corr = df_africa.corr(method='kendall') corr = corr['banking_crisis'] corr.drop('banking_crisis', inplace = True) #%% #Для использования ANOVA потребуется sklearn # f_classif используется для ANOVA feature_function = SelectKBest(score_func=f_classif, k=2) X = df_africa.drop('banking_crisis', axis = 1).copy() X = X.select_dtypes([np.number]) #оставляем только числовые поля y = df_africa['banking_crisis'].copy() feature_function.fit(X, y) X_selected = feature_function.transform(X) for i in range(len(feature_function.scores_)): print(corr.index[i], ': Anova: %f, Kendall: %f'% (feature_function.scores_[i],corr[i]))

Результат:

case : Anova: 0.591649, Kendall: -0.014954 year : Anova: 50.617197, Kendall: 0.200397 systemic_crisis : Anova: 2840.599138, Kendall: 0.853702 exch_usd : Anova: 30.991573, Kendall: 0.113212 domestic_debt_in_default : Anova: 56.785554, Kendall: 0.225797 sovereign_external_debt_default : Anova: 79.182398, Kendall: 0.263992 gdp_weighted_default : Anova: 0.745341, Kendall: 0.026736 inflation_annual_cpi : Anova: 10.432287, Kendall: 0.167179 independence : Anova: 27.634911, Kendall: 0.159620 currency_crises : Anova: 30.271703, Kendall: 0.167835 inflation_crises : Anova: 62.260056, Kendall: 0.235852

Видно, что максимальные и минимальные показатели совпадают, однако для некоторых параметров есть отличия, связанные со статическим распределением исходных параметров (currency_crises и exch_usd, например).

В случае, когда на выходе тоже получается числовая переменная, распространённо применяются коэффициенты Пирсона (Pearson's) или Спирмана (Spearman's), для линейных и нелинейных методов соответственно.

from sklearn.datasets import make_regression import pandas as pd import math # создаём датасет X_linear, y = make_regression(n_samples=1000, n_features=10, n_informative=2) df_samples = pd.DataFrame(X_linear) df_samples['y'] = y corr_pearson = df_samples.corr('pearson')['y'].drop('y') corr_spearman = df_samples.corr('spearman')['y'].drop('y') for i in range(len(corr_pearson)): print(corr_pearson.index[i], ': pearson: %f, spearman: %f'% (corr_pearson[i],corr_spearman[i])) print('Нелинейный пример:') X_nonlinear, y_nonlinear = make_regression(n_samples=1000, n_features=10, n_informative=2) for i in range(1000): for j in range(10): X_nonlinear[i][j] = math.log2(abs(X_nonlinear[i][j])) y_nonlinear = [abs(y) for y in y_nonlinear] df_samples_nonlinear = pd.DataFrame(X_nonlinear) df_samples_nonlinear['y'] = y_nonlinear corr_pearson = df_samples_nonlinear.corr('pearson')['y'].drop('y') corr_spearman = df_samples_nonlinear.corr('spearman')['y'].drop('y') for i in range(len(corr_pearson)): print(corr_pearson.index[i], ': pearson: %f, spearman: %f'% (corr_pearson[i],corr_spearman[i]))

Результат:

0 : pearson: 0.075557, spearman: 0.093597 1 : pearson: 0.384044, spearman: 0.374281 2 : pearson: -0.074026, spearman: -0.069885 3 : pearson: 0.007651, spearman: -0.013319 4 : pearson: -0.045287, spearman: -0.054908 5 : pearson: -0.034626, spearman: -0.038182 6 : pearson: -0.008276, spearman: 0.001085 7 : pearson: -0.012967, spearman: -0.005222 8 : pearson: 0.929335, spearman: 0.918733 9 : pearson: 0.000531, spearman: 0.015545 Нелинейный пример: 0 : pearson: 0.059650, spearman: 0.062185 1 : pearson: 0.010152, spearman: 0.013855 2 : pearson: -0.035513, spearman: -0.042905 3 : pearson: 0.044442, spearman: 0.022478 4 : pearson: 0.034085, spearman: 0.060602 5 : pearson: -0.005633, spearman: -0.018592 6 : pearson: -0.009302, spearman: -0.024156 7 : pearson: 0.340414, spearman: 0.376554 8 : pearson: 0.012585, spearman: 0.016479 9 : pearson: 0.327219, spearman: 0.364198

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

Категориальные переменные:

Случаи, когда у нас встречаются категориальные переменные, но при этом выходная переменная числовая можно рассматривать так же, как и в первом примере, случаи где у нас выходная переменная категориальная, а входные – числовые. Осталось рассмотреть пример для случая, когда у нас и входные и выходные переменные категориальные. И для этого можно использовать Chi-Squared test или Mutual Information.

Пример кода:

import pandas as pd import numpy as np from sklearn.feature_selection import SelectKBest from sklearn.preprocessing import OrdinalEncoder from sklearn.feature_selection import chi2 from sklearn.feature_selection import mutual_info_classif df_africa = pd.read_csv(r"C:\Users\mmvik\Downloads\african_crises.csv") X = df_africa[['case', 'country', 'year', 'systemic_crisis', 'domestic_debt_in_default','sovereign_external_debt_default','independence','currency_crises','inflation_crises']].copy() y = df_africa[['banking_crisis']].copy() X = X.astype(str) oe = OrdinalEncoder() oe.fit(y.to_numpy()) y_labeled = oe.transform(y.to_numpy()) oe.fit(X.to_numpy()) X_labeled = oe.transform(X.to_numpy()) feature_function_chi = SelectKBest(score_func=chi2, k='all') feature_function_mutual = SelectKBest(score_func=mutual_info_classif, k='all') feature_function_chi.fit(X_labeled, y_labeled) feature_function_mutual.fit(X_labeled, y_labeled) X_selected_chi = feature_function_chi.transform(X) X_selected_mutual = feature_function_chi.transform(X) for i in range(len(feature_function_chi.scores_)): print(str(i), ': chi: %f, mutual: %f'% (feature_function_chi.scores_[i],feature_function_mutual.scores_[i]))

Полученный в данном случае результат:

case: chi: 1.409371, mutual: 0.020210 country: chi: 0.549365, mutual: 0.024483 year: chi: 504.416057, mutual: 0.076050 systemic_crisis: chi: 712.044841, mutual: 0.194785 domestic_debt_in_default: chi: 51.851013, mutual: 0.013567 sovereign_external_debt_default: chi: 62.513388, mutual: 0.032492 independence: chi: 6.038413, mutual: 0.021688 currency_crises: chi: 27.271533, mutual: 0.005459 inflation_crises: chi: 51.287251, mutual: 0.023750

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

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

11
Начать дискуссию