df = pd.read_excel("data\shop_quit.xlsx")
pd.concat([df.head(), df.tail()])
sex | experience | wd | salary | quit | |
---|---|---|---|---|---|
0 | female | 184.500 | 39.000 | 3738 | 0 |
1 | female | 34.500 | 47.000 | 3079 | 0 |
2 | female | 79.400 | 42.500 | 2887 | 0 |
3 | male | 4.700 | 47.500 | 2742 | 0 |
4 | female | 56.300 | 64.000 | 3483 | 0 |
116 | male | 28.100 | 26.000 | 2651 | 0 |
117 | female | 19.000 | 63.000 | 3177 | 0 |
118 | female | 18.900 | 49.000 | 2239 | 0 |
119 | male | 46.600 | 4.000 | 4731 | 0 |
120 | female | 21.500 | 17.500 | 2163 | 0 |
#Перекодируем пол
from sklearn.preprocessing import LabelEncoder
df.sample(5)
df.sex=class_le.fit_transform(df.sex.values)
sex | experience | wd | salary | quit | |
---|---|---|---|---|---|
61 | 0 | 42.300 | 51.500 | 3324 | 0 |
2 | 0 | 79.400 | 42.500 | 2887 | 0 |
76 | 1 | 1.600 | 13.500 | 1649 | 0 |
75 | 0 | 1.500 | 34.000 | 2806 | 0 |
73 | 0 | 64.700 | 51.000 | 2594 | 0 |
plt.figure(figsize=(15, 5))
plt.subplot(131)
sns.boxplot(x="quit", y="wd", data=df)
plt.subplot(132)
sns.boxplot(x="quit", y="salary", data=df)
plt.subplot(133)
sns.boxplot(x="quit", y="experience", data=df)
Показатели уволившихся ниже, но это следовало ожидать. Посмотрим на средние показатели по группам
df_group = df.groupby('quit')
df_group.agg(np.mean)
sex | experience | wd | salary | |
---|---|---|---|---|
quit | ||||
0 | 0.272 | 33.731 | 38.053 | 3,021.495 |
1 | 0.556 | 17.233 | 24.694 | 2,392.000 |
#Выделяем признаки и метки кластеров
labels_col = "quit"
features = df.drop(labels_col, axis=1)
labels = df[labels_col]
#Выделяем название признаков
features_names=features.columns
features_names
Index(['sex', 'experience', 'wd', 'salary'], dtype='object')
Теперь переходим непосредственно к нашей задаче - отбора признаков.
Существует три типа методов отбора признаков: фильтрующие, циклические
и вложенные.
Фильтрующие методы отбирают наилучшие признаки, изучая их статистические
свойства. Циклические (wrapper) методы для поиска подмножества признаков, которые
создают модели с предсказаниями лучшего качества, используют метод проб и ошибок. Наконец, вложенные (embedded) методы отбирают наилучшее подмножество
признаков как часть или как продолжение процесса тренировки
обучающегося алгоритма
Методы фильтрации
Методы фильтрации включают применение статистической меры для оценки различных признаков. Эта оценка позволяет ранжировать признаки и это ранжирование
используется для определения того, какие признаки следует сохранить, а какие можно
удалить из данных. Как правило, каждый признак рассматривается отдельно
(т. е. однофакторный тест).Одним из простейших методов алгоритмического выбора признаков является измерение их дисперсии. Формально этот метод известен как определение порога отклонения,
который реализован в библиотеке scikit-learn с помощью селектора VarianceThreshold.
Он удаляет все признаки, дисперсия которых не соответствует некоторому порогу.
По умолчанию он удаляет все признаки с нулевой дисперсией, то есть признаки,
которые имеют одинаковое значение во всех выборках, при этом значение дисперсий
можно получить из атрибута variances_.from sklearn.feature_selection import VarianceThreshold
# Создаем обработчик
vt = VarianceThreshold()
# Рассчитываем и выводим дисперсии признаков c сортировкой
vt.fit_transform(features)
feature_variances = vt.variances_
for var, name in sorted(zip(vt.variances_, features_names), key=lambda x: x[0], reverse=True):
print(f'{name:>10} variance = {var:.5f}')
salary variance = 4848.00000 experience variance = 184.20000 wd variance = 67.50000 sex variance = 0.21542#Отмасштабируем признаки от нуля до единицы и заново посмотрим
#на результатfrom sklearn.preprocessing import MinMaxScaler
features_ss = MinMaxScaler().fit_transform(features)
vt.fit_transform(features_ss)
for var, name in sorted(zip(vt.variances_, features_names), key=lambda x: x[0], reverse=True):
print(f'{name:>10} variance = {var:.3f}')sex variance = 0.215 wd variance = 0.048 salary variance = 0.039 experience variance = 0.038Как видно, такой анализ не дает оснований, для удаления какого-нибудь признака,
т.к. нет показателя с низкой дисперсией. Переходим к другим, более
"продвинутым" одномерным статистическим методам фильтрации. С помощью
одномерных статистик мы определяем наличие статистически значимой взаимосвязи
между каждым признаком и зависимой переменной. Затем отбираем признаки, сильнее
всего связанные с зависимой переменной (имеющие уровень значимости, не
превышающий заданного порогового значения). В случае классификации эта
процедура известна как дисперсионный анализ (ANOVA). Ключевым свойством этих
тестов является то, что они являются одномерными, то есть они рассматривают
каждую характеристику по отдельности. Чтобы осуществить одномерный отбор
признаков в scikit-learn, вам нужно выбрать тест, обычно либо f_classif (по
умолчанию) для классификации или f_regression для регрессии. f_classif
используется для вычисления статистического показателя F дисперсионного
анализа (ANOVA) с каждым признаком и вектором целей. Оценочные значения F
проверяют, различаются ли значимо средние значения для каждой группы, когда мы
группируем этот числовой признак по вектору целей.Все методы исключения параметров используют пороговое значение,
чтобы исключить все признаки со слишком высоким р-значением (высокое p-значение
указывает на то, что признак вряд ли связан с зависимой переменной). Методы
отличаются способами вычисления этого порогового значения, самым простым из
которых являются SelectKB, выбирающий фиксированное число k признаков, и
SelectPercentile,выбирающий фиксированный процент признаков.Продемонстрируем эти методы на нашем наборе данных. Используем метод SelectKBest для вычисления оценок для всех признаков и используем функцию оценки по умолчанию f_classif. Задаем, что все признаки должны быть сохранены, установив k='all', чтобы можно было вывести оценки всех показателей. Если установить k равным n, то будут сохранены только лучшие n признаков.
from sklearn.feature_selection import SelectKBest
skb = SelectKBest(k='all')
skb.fit(features, labels)
for var, name in sorted(zip(skb.scores_, features_names), key=lambda x: x[0], reverse=True):
print(f'{name:>18} score = {var:.3f}')wd score = 13.869 salary score = 6.846 sex score = 5.910 experience score = 3.284В следующем примере мы меняем score_func на mutual_info_classif, что определяет
количественную зависимость между признакам и меткой. Когда две функции
независимы, эта статистика стремится к нулю, и по мере увеличения зависимости
статистика также увеличивается.from sklearn.feature_selection import mutual_info_classif skb = SelectKBest(mutual_info_classif, k='all') skb.fit(features, labels)for var, name in sorted(zip(skb.scores_, features_names), key=lambda x: x[0],
reverse=True):print(f'{name:>18} score = {var:.3f}')wd score = 0.129 experience score = 0.075 sex score = 0.011 salary score = 0.008Циклические методы
Эти методы рассматривают выбор набора признаков как задачу поиска, где
оцениваются и сравниваются различные наборы признаков с другими наборами.
Оценки присваиваются на основе точности модели. Поскольку мы должны обучать
модель для каждой комбинации признаков, этот подход намного дороже,
чем метод фильтрации.Одним из популярных методов-оболочек является алгоритм
рекурсивного исключения признаков. Рекурсивное устранение признаков (RFE)
работает путем рекурсивного удаления признаков и построения модели из
оставшихся. Точность модели используется для определения признаков , которые
предоставляемая библиотекой scikit-learn, находится в модуле feature_selection.
больше всего способствуют прогнозированию целевого признака. Реализация RFE,Есть два ключевых аргумента для создания селектора RFE:
estimator : оценщик контролируемого обучения с методом подгонки, который
представляет информацию о важности функции либо через атрибут coef_, либо
через атрибут feature_importances_. n_features_to_select : int или None
(по умолчанию = None), количество признаков для выбора. Если None,
будет выбрана половина признаков.Рассмотрим применение метода для наших данных. Для отбора используем метод опорных векторов. Устанавливаем n_features_to_select равным 1, чтобы результат этой операции идентифицировал наиболее важную функцию, но мы по-прежнему можем получить ранги всех признаков через атрибут ранжирования ranking_.
from sklearn.svm import LinearSVC from sklearn.feature_selection import RFE # Создаем и обучаем классификатор svc = LinearSVC(random_state=23) rfe = RFE(estimator=svc, n_features_to_select=1) rfe.fit(features, labels) # Выводим отсортированные ранги признаков for var, name in sorted(zip(rfe.ranking_, features_names), key=lambda x: x[0]): print(f'{name:>18} rank = {var}')
sex rank = 1 wd rank = 2 experience rank = 3 salary rank = 4Используем в RFE модель случайного леса ,в этом случае отбор займет несколько большее время, в особенности если набор большой
from sklearn.ensemble import RandomForestClassifier
rfc = RandomForestClassifier(random_state=23)
# Создаем модель RFE
rfe = RFE(estimator=rfc, n_features_to_select=1)
rfe.fit(features, labels)
# Выводим рассчитанные ранги признаков
for var, name in sorted(zip(rfe.ranking_, features_names), key=lambda x: x[0]):
print(f'{name:>18} rank = {var}')wd rank = 1 salary rank = 2 experience rank = 3 sex rank = 4Встроенные методы
Встроенные методы выполняют выбор признаков непосредственно при построении модели. Некоторые алгоритмы, такие как дерево решений и ансамблевые методы, основанные на дереве решений, обеспечивают доступ к показателям важности признаков. Эта дополнительная информация может использоваться для ранжирования признаков для использования с этими моделями. Например, классификатор случайного леса (RFC) в качестве ансамблевого метода строит модели путем случайного выбора признаков при построении каждого дерева. В этом процессе RFC вычисляет общую важность каждого признака при построении окончательной модели. Извлекая важность признаков из окончательной модели, мы получаем их ранжированный порядок, используемых для построения модели.
Применяем классификатор случайного леса к нашему набору данных и затем отображаем важность функции каждого набора данных с атрибутом модели feature_importances_.
from sklearn.ensemble import RandomForestClassifier # Строим модель rfc = RandomForestClassifier(random_state=23) rfc.fit(features, labels) print(f'{"Label":18s}: Importance') print(26*'-') for val, name in sorted(zip(rfc.feature_importances_, features_names),key=lambda x: x[0], reverse=True): print(f'{name:>18}: {val:.2%}')
abel : Importance -------------------------- wd: 43.21% salary: 26.90% experience: 23.44% sex: 6.45%
Как видим, по важности на первом месте с большим отрывом количество
отработанных смен, далее с почто одинаковой важностью идут среднесменная
заработная плата и стаж, наименее важен пол работника.
Комментариев нет:
Отправить комментарий