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

Как определить соответствующие функции?

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

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

Первое, что мне нужно сделать, это очистить набор данных

Вот количество отсутствующих/нулевых значений на атрибут

import pandas as pd
df = pd.read_csv("train.csv")
df.isnull().sum()

Здесь атрибут возраста является числовым атрибутом, и мы можем заменить отсутствующие/нулевые значения средним значением, как показано ниже:

df.Age.fillna(math.floor(df.Age.mean()),inplace=True)
df.isnull().sum()

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

df.drop(["Cabin"],axis=1,inplace=True)
df.isnull().sum()

Теперь только атрибут Embarked имеет отсутствующие/нулевые значения, Embarked является категориальным атрибутом, поэтому нам нужно сначала преобразовать его в числовой атрибут. Мы можем использовать LabelEncoder для этой цели

from sklearn.preprocessing import LabelEncoder
le_embarked = LabelEncoder()
df.Embarked = le_embarked.fit_transform(df.Embarked)
df.Embarked.head()

Теперь мы можем заменить отсутствующие значения, используя среднее значение Embarked, как показано ниже:

df.Embarked.fillna(df.Embarked.median(),inplace=True)
df.isnull().sum()

Теперь, если вы заметили, что у нас есть некоторые числовые атрибуты (например, возраст), NominalAttributes (например, пол), а также некоторые нечисловые атрибуты, которые не являются категориальными (например, имя)

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

df.drop(["PassengerId","Name"],axis=1,inplace=True)
df

Мы можем преобразовать пол в числовые значения, используя LabelEncoder, как показано ниже.

le_sex = LabelEncoder()
df.Sex = le_sex.fit_transform(df.Sex)
df

Мы можем отказаться от Билетов, так как это приведет к нестабильности нашего Дерева решений, поскольку оно имеет много уникальных значений, которые могут не повлиять на результат (Выживание)

df.drop(["Ticket"],axis=1,inplace=True)
df

Мы можем преобразовать Age и Fare в порядковые атрибуты, как показано ниже.

Возраст›0 и Возраст‹26 =› Молодой

Возраст≥26 и возраст‹50 => средний возраст

Возраст≥50 и возраст‹100 => Старый

Тариф ≥0 и тариф‹170 => Низкий

Тариф ≥170 и тариф ‹340=> Средний

Тариф ≥340 и тариф ‹513=> Высокий

df.Age = pd.cut(df['Age'],bins=[0,25,50,100],labels=["Young","MiddleAge","Old"])
df.Fare = pd.cut(df['Fare'],bins=[-1,170,340,513],labels=["Low","Medium","High"])
df

Теперь нам просто нужно преобразовать порядковые значения (возраст, стоимость проезда) в числовое значение, как показано ниже:

le_Age = LabelEncoder()
df.Age = le_Age.fit_transform(df.Age)
le_Fare = LabelEncoder()
df.Fare = le_Fare.fit_transform(df.Fare)
df

Теперь мы готовы построить модель дерева решений с использованием Sklearn, как показано ниже:

model = tree.DecisionTreeClassifier()
x = df.drop(["Survived"],axis=1)
y = df.Survived
dt.fit(x,y)
dt.score(x,y)

Теперь попробуем определить нерелевантные атрибуты для повышения производительности.

1. Удаление атрибутов низкой дисперсии

Дисперсия относится к изменчивости Атрибутов, как часто они меняют свое значение. Деревья решений подвержены дисперсии, поскольку это модель с низким смещением и высокой дисперсией. Мы можем использовать метод VarianceThreshould от Sklearn, чтобы удалить атрибуты, имеющие дисперсию ниже порогового значения (имеющие одинаковое значение для всех экземпляров для заданного порогового значения).

Дисперсия может быть рассчитана как Var = p*(1-p)

где p = вероятность

dfTest = df
from sklearn.feature_selection import VarianceThreshold
variance = VarianceThreshold(0.8*(1-0.8))
variance.fit_transform(dfTest)[0]
cols = [ j for i,j in enumerate(dfTest.columns) if not variance.get_support()[i]]
dfTest = dfTest.drop(cols,axis=1)
dfTest

Здесь у Fare была самая низкая дисперсия около 0,12, поэтому она исключается из нашего рассмотрения.

2. Использование одномерного выбора признаков

from sklearn.feature_selection import SelectKBest,chi2
best_features = SelectKBest(score_func=chi2,k="all")
best_features.fit(df.drop(["Survived"],axis=1),df.Survived)
pd.DataFrame(best_features.scores_,df.drop(["Survived"],axis=1).columns)

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

Здесь я использовал метод SelectKBest Sklearn, но вы можете использовать и другие.

SelectPercentile: будет выбрано указанное пользователем свойство с наивысшим процентом оценки.

GenericUnivariateSelect: это позволит вам выбирать функции с настраиваемой стратегией. Здесь вы также можете указать оценщик поиска гиперпараметров

Входная функция score_func принимает входные данные как функцию оценки и возвращает одномерную оценку и p-значения. Доступны различные функции оценки.

  • Для регрессии: r_regression, f_regression, mutual_info_regression
  • Для классификации: chi2, f_classif, mutual_info_classif

3. Использование выбора объектов на основе дерева

from sklearn.ensemble import ExtraTreesClassifier
model1 = ExtraTreesClassifier()
model1.fit(df.drop(["Survived"],axis=1),df.Survived)
imp = pd.Series(model1.feature_importances_,index=df.drop(["Survived"],axis=1).columns)
imp.plot(kind="barh")
plt.show()

Здесь также вы обнаружите, что Fare имеет наименьшее значение в нашем наборе данных. Так что скорее всего сбросят.

Примечание. Вы всегда можете использовать метод SelectFromModel Sklearn для извлечения важных функций, как показано ниже.

Здесь я взял пример из ExtraTreeClassifier, но вы можете применить его и к любым другим методам.

from sklearn.ensemble import ExtraTreesClassifier
from sklearn.feature_selection import SelectFromModel
model1 = ExtraTreesClassifier()
model1.fit(df.drop(["Survived"],axis=1),df.Survived)
selectModel = SelectFromModel(model1,prefit=True)
newX = selectModel.transform(df.drop(["Survived"],axis=1))
cols = [ j for i,j in enumerate(dfTest.columns) if selectModel.get_support()[i]]
pd.DataFrame(newX,columns=cols)

Конечный результат будет зависеть от того, какой метод вы использовали.

4. Конвейер для выбора функций

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

from sklearn.pipeline import Pipeline
from sklearn.tree import DecisionTreeClassifier
model1 = Pipeline([('feature_selection',SelectFromModel(ExtraTreesClassifier())),('classification',DecisionTreeClassifier())])
model1.fit(df.drop(["Survived"],axis=1),df.Survived)
model1.score(df.drop(["Survived"],axis=1),df.Survived)

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

Если вы найдете это полезным, пожалуйста, поделитесь им с другими.

- Спасибо.