понимать влияние избыточности функций и мер обнаружения

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

Чем больше, тем веселее, правда?

Я понимаю, как здорово объединить в своей модели как можно больше функций. Я помню, как мне нравилось смотреть на размер моего тренировочного CSV-файла и представлять, насколько хороша будет модель. Однако это не всегда так. Вот почему:

1. Избыточные функции замедляют процесс обучения

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

Наличие коррелированных признаков в обучающей выборке делает картину потерь плохо обусловленной (определение будет позже). Например, в задаче двумерной линейной регрессии контурные графики потерь должны быть почти круговыми, если обе функции стандартизированы (см. Другой мой пост о стандартизации данных).

# two features 
X1 = np.random.randn(1000,1)
X1 = (X1 -np.mean(X1))/np.std(X1)
X2 = np.random.randn(1000,1)
X2 = (X2 - np.mean(X2))/np.std(X2)
Y = 2.3*X1-0.8*X2 + 0.3*np.random.rand(1000,1)

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

# two features 
X1 = np.random.randn(1000,1)
X1 = (X1 -np.mean(X1))/np.std(X1)
X2 = X1 + 0.5* np.random.randn(1000,1)
X2 = (X2 - np.mean(X2))/np.std(X2)
Y = 2.3*X1-0.8*X2 + 0.3*np.random.rand(1000,1)

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

X1 = np.random.randn(1000,1)
X1 = (X1 -np.mean(X1))/np.std(X1)
X2 = X1 + 0.02*np.random.randn(1000,1)
X2 = (X2 - np.mean(X2))/np.std(X2)
Y = 2.3*X1 - 0.8*X2 + 0.3*np.random.rand(1000,1)

Как видите, градиентный спуск затруднен в плохо обусловленных ландшафтах потерь и требует гораздо большего количества итераций (даже 18 000 итераций недостаточно!) Для достижения разумных потерь. Модели, основанные на сильно коррелированных функциях, требуют большего количества итераций и, следовательно, требуют больше времени для обучения.

2. Сниженная способность к оценке

Теперь мы знаем, что модели, основанные на сильно коррелированных функциях, нуждаются в гораздо большем количестве итераций для обучения. Следовательно, если вы используете номер итерации, который является разумным в других проектах, например 6000 или 10000 (в большинстве случаев вполне достаточно), алгоритм может завершиться слишком рано, что вредит производительности модели (см. Таблицу потерь выше).

Есть и другая причина: в следующей модели полилинейной регрессии

наилучшая оценка в теории:

Если X имеет избыточность (коллинеарность или мультиколлинеарность), ранг X не является полным. Следовательно, мы не можем получить наилучшую оценку, поскольку обратного к X ^ T * X не существует. ("дальнейшее чтение" )

3. Трудно интерпретировать вашу модель

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

Когда в наборе данных существует коллинеарность, t-баллы этих функций обычно малы, потому что веса коррелированных функций имеют большую дисперсию. Другими словами, модели, основанные на разных разделах, могут иметь очень разные параметры функций. Например:

X1 = np.random.randn(1000,1)
X1 = (X1 -np.mean(X1))/np.std(X1)
X2 = X1 
Y = 0*X1 + 6*X2 + 0.3*np.random.rand(1000,1)
#essentially 0*X1(X2) + 6*X1(X2) + 0.3*np.random.rand(1000,1)

Поскольку где-нибудь на синей линии успешно минимизирует MSE, w1 и w2 могут сильно различаться, пока w1 + w2 = 6. Если мы проводим тест на значимость с нулевой гипотезой о том, что X1 не имеет значения, очень вероятно, что мы не сможем отклонить нулевую гипотезу, поскольку стандартная ошибка огромна. Например:

import statsmodels.api as sma
X1 = np.random.randn(1000,1)
X1 = (X1 -np.mean(X1))/np.std(X1)
X2 = X1 + 0.01*np.random.randn(1000,1)
X2 = (X2 - np.mean(X2))/np.std(X2)
X = np.concatenate((X1,X2), axis=1)
Y = 0.5*X1 + X2 + 0.3*np.random.rand(1000,1)
# we know both X1 and X2 contribute to the outcome
mod = sma.OLS(Y,X)
res= mod.fit()
print(res.summary()

Коэффициенты как X1, так и X2 имеют небольшой t-балл (и, следовательно, большое значение P). Таким образом, мы ошибочно приходим к выводу, что ни X1, ни X2 не актуальны (интерпретировать значения P). Избыточность функций приводит к большим стандартным ошибкам коэффициентов и скрывает истинную роль функции в регрессии.

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

Как определить избыточность функций?

Обнаружение коррелированных функций: номер условия

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

По заданной матрице (входные данные X) найдите корреляционную матрицу X Corr (X):

Если корреляционная матрица X имеет большое число обусловленности, это указывает на серьезную коллинеарность.

Вот небольшой пример, который поможет вам понять, как работает номер условия:

Обнаружение нерелевантных функций

Суть обнаружения нерелевантных функций состоит в том, чтобы определить, влияет ли данная функция на результат. В зависимости от типа вывода (непрерывный или категориальный) и особенностей 1 можно использовать несколько математических методов. Категориальный признак Категориальный ответ - тест хи-квадрат

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

Я создал простой искусственный набор данных, чтобы вы лучше понимали, почему полезен хи-квадрат.

import pandas as pd
import scipy.stats as sst
X = np.random.randint(5,size=1000)
Y = np.ones(X.shape)
index = X<=2 
Y[index] =0 # when X <=2, Y = 0. Therefore X influences Y
crosstab = pd.crosstab(X,Y) 
chi2, p,_,_ = sst.chi2_contingency(crosstab)
###P value =  3.569412779777166e-215-> reject the null hypothesis   ->feature is relevant
X = np.random.randint(5,size=1000)
Y = np.random.randint(2, size = 1000) # no relatinoship
crosstab = pd.crosstab(X,Y)
chi2, p,_,_ = sst.chi2_contingency(crosstab)
###P value =  0.5244308199595783-> large P value, relationship is statistically insignificant

2. Непрерывный ответ категориального признака - ANOVA

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

Пример:

X = np.random.randint(3,size=1000)
Y = np.random.rand(1000) # no relationship 
one = Y[X==1]
two = Y[X==2]
zero = Y[X==0]
sst.f_oneway(one,two,zero)
###statistic=0.07592457518151591, pvalue=0.9268914727618249-> large P value-> relationship is insignificant
X = np.random.randint(3,size=1000)
Y = np.random.rand(1000) + 0.1*X # X is part of Y
one = Y[X==1]
two = Y[X==2]
zero = Y[X==0]
sst.f_oneway(one,two,zero)
### F_onewayResult(statistic=38.076396290550555, pvalue=1.1607768540773696e-16)-> reject the null hypothesis-> feature is relevant

3. Непрерывный признак Непрерывный ответ - корреляция или хи-квадрат / ANOVA

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

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

Альтернативный способ - дискретизация обеих переменных и использование теста хи-квадрат, который, как вы можете видеть, успешно определяет немонотонную взаимосвязь:

X = 10*np.random.rand(1000)
Y = np.sin(X)
X_ca = pd.qcut(X,10, labels=False) # discretize into 10 classes
Y_ca = pd.qcut(Y,10, labels=False)
crosstab = pd.crosstab(X_ca,Y_ca)
chi2, p,_,_ = sst.chi2_contingency(crosstab)
print ('P value = ', p)
### P value =  0.0-> a strong relationship

4. Непрерывный категориальный ответ функции - критерий хи-квадрат

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

Резюме

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