Za darmo

Машинное обучение доступным языком

Tekst
Oznacz jako przeczytane
Czcionka:Mniejsze АаWiększe Aa

df[numeric_columns] = imputer.fit_transform(df[numeric_columns].values)

Обнаружение аномалий

(anomaly detection) Мир не идеален, и в данных бывают ошибки. Некоторые из них мы можем массово исправить с помощью доменных знаний (domain knowledge), то есть специфических сведений об исследуемой области. В мире банкинга люди старше 70 с кредитами – аномалия5! Их доля не столь велика, и такие записи все же вычищают.

Самый легкий способ обнаружить выбросы (outlier) – визуальный. Мы построим разновидность графика "ящик с усами" (boxplot) для одной из числовых переменных "Возраст":


Скучковавшиеся шарики-точки в верхней части изображения – и есть аномалии. От них, как правило, избавляются с помощью квантили 99%. Это означает, что мы соберем все возрасты в виртуальный список, сортируем от малого к большому, а затем уберем 1% самых больших значений.

q = df["Возраст"].quantile(0.99)

df[df["Возраст"] < q]

Аналогичным способом определяем, что для числовых переменных пропуски обозначаются числом 999 или пустой ячейкой.

Одномерный анализ

(univariate analysis)

Прежде чем применять те или иные методы обучения, нам необходимо удостовериться, что они вообще применимы к текущему датасету. Хоть данные и ценны, к ним все равно есть требования. С этим нам поможет замечательная библиотека pandas-profiling.

Описательная статистика

Запустим профайлер и передадим наш датафрейм в качестве аргумента:

profile = ProfileReport(df)

profile

Профайлер высчитает основные статистические метрики для каждой переменной и датасета в целом:



Основные характеристики фактора “Возраст” – число уникальных значений (Distinct), пропуски (Missing), число сильно отстоящих значений (Infinite) – способ обнаружения пропусков, среднее арифметическое (Mean), минимум (Minimum), максимум (Maximum), число нулей (Zeros), занимаемая память (Memory size).

График справа помогает оценить нормальное распределение (normal distribution). Без нее множество статистических методов к признаку просто не применить, и некоторые модели не построить. Но к счастью, не везде.

Отдельный интерес для нас представляет раздел корреляций (‘Correlations’). Чем ярче (краснее / синее) ячейка, тем сильнее выражена взаимосвязь между парой факторов. Диагональные ячейки игнорируются, поскольку являются результатом расчета коэффициента между переменной и ее копией.



Признаки важно именовать лаконично. Здесь пришлось ввести сокращения, чтобы pandas не обрезал слишком длинные названия:

• КУБ: Колебания уровня безработицы

• ИПЦ: Индекс потребительских цен

• ИПУ: Индекс потребительской уверенности

• ЕМС: Европейская межбанковская ставка

• КС: Количество сотрудников [в компании]

"Колебание уровня безработицы" и "Европейская межбанковская ставка" сильно коррелируют друг с другом, но являются второстепенными факторами. В дальнейшем их можно объединить на этапе инжиниринга признаков (feature engineering). Еще чаще корреляцию из датасета вообще устраняют. Группа сильно коррелирующих признаков не принесет много дополнительной информации, но усложнит алгоритм и повысит риск ошибки.

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

(feature importance)

Прежде чем произвести инжиниринг признаков и сократить объем входных данных, стоит определить, какие признаки имеют первостепенную значимость, и в этом нам помогут scikit-learn и критерий Хи-квадрат (Chi-squared test). Метрика сравнивает размер любых расхождений между ожидаемыми и фактическими результатами, учитывая размер выборки и количество переменных. Он работает только с числовыми переменными. Мы закладываем такие в переменную X. В y с помощью слайсинга отправляем целевой признак.

Scikit-learn экономит время и использует одинаковые по названию методы6. Мы обучаем экземпляр класса SelectKBest (“выбрать K самых важных признаков”) с помощью fit() и не ограничиваем число факторов. Для построения рейтинга фичей мы “загоняем” очки важности в датафрейм dfScores, а названия столбцов – в dfColumns.

X = df[['Возраст', 'Длительность', 'Кампания', 'День', 'Предыдущий контакт', 'Индекс потребительских цен', 'Европейская межбанковская ставка', 'Количество сотрудников в компании']]

y = df.iloc[:, -1]

bestFeatures = SelectKBest(score_func = chi2, k = 'all')

fit = bestFeatures.fit(X, y)

dfScores = pd.DataFrame(fit.scores_)

dfColumns = pd.DataFrame(X.columns)

Посмотрим на 10 самых важных признаков:

featureScores = pd.concat([dfColumns, dfScores], axis = 1)

featureScores.columns = ['Фича', 'Очков важности']

print(featureScores.nlargest(10, 'Очков важности'))

Неожиданно, но в топе оказалась “кампания”, то есть число звонков в рамках текущей рекламной кампании. Похоже, мы недооценивали силу упорства!



Многомерный анализ

(multivariate analysis) Чего только не создаст комьюнити в науке о данных!

Парные особенности

Для нужд разведочного анализа крайне кстати будут парные графики. Здесь на помощь приходит другой великолепный класс – seaborn.pairplot(). Каждая из переменных ляжет в основу одной из осей двумерного точечного графика. Изменим еще раз названия длинных переменных, чтобы уместить их на скромном отведенном пространстве.

df.rename(columns = {

'Предыдущий контакт': 'ПК',

'Колебание уровня безработицы': 'КУБ',

'Индекс потребительских цен': 'ИПЦ',

'Индекс потребительской уверенности': 'ИПУ',

'Европейская межбанковская ставка': 'ЕМС',

'Количество сотрудников в компании': 'КС'

}, inplace = True)

sns.pairplot(df, hue = 'y')

Полную версию парного графика со всеми признаками, можно найти в ноутбуке.

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

При сопоставлении возраста и количества сотрудников в компании данные быстро собрались в группы-линии:



Это означает, что вторая фича скорее относится к категориальным признакам. Ее значения – ограниченный ряд чисел: 5200, 5175, 5100, 5075 и так далее.

Мы сопоставили кампании (то есть число звонков в рамках текущей рекламной кампании) и длительности звонка:



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

Понижение размерности

(dimensionality reduction) Некоторые из признаков могут быть “слиты” в один с помощью специальной техники – Анализа главных компонент (PCA – principal component analysis). Давайте создадим с его помощью такой агрегирующий столбец. Он в равной мере представит исходные признаки.

Выделим список признаков, подлежащих “сокращению”. Среди них целевого быть не должно.

features = ['Колебание уровня безработицы', 'Индекс потребительских цен', 'Индекс потребительской уверенности', 'Европейская межбанковская ставка']

x = df.loc[:, features].values

y = df.loc[:,['y']].values

5Сейчас картина постепенно меняется: у пожилых людей в России, например, в среднем более высокий кредитный рейтинг, и потому некоторые банки целиком таргетируют свои кредитные продукты на пенсионеров.
6К примеру, обучение модели и определение важности признаков оба производятся методами fit(), predict().