Импутация - это процесс замены отсутствующих данных статистическими оценками отсутствующих значений. Цель любого метода вменения - создать полный набор данных, который можно использовать для обучения моделей машинного обучения.
Вменение режима состоит в замене всех вхождений пропущенных значений (NA) в переменной на режим, который, другими словами, относится к наиболее частому значению или наиболее частой категории .
Какие переменные можно вычислить с помощью наиболее частого / режима вменения?
Хотя режим или наиболее частое значение можно вычислить как для числовых, так и для категориальных переменных, на практике мы используем этот метод только для категориальных переменных. Причина в том, что для числовых переменных среднее значение или медиана, как правило, лучше представляют среднее значение для генеральной совокупности.
Когда использовать режим / наиболее частое вменение категорий?
Данные отсутствуют случайно.
Не более 5% переменной содержат отсутствующие данные.
Преимущества
Его легко реализовать.
Это быстрый способ получения полных наборов данных.
Его можно интегрировать в производственную среду (во время развертывания модели).
Ограничения
Это искажает связь наиболее часто встречающейся метки с другими переменными в наборе данных.
Это может привести к чрезмерному представлению наиболее часто встречающейся метки, если имеется большое количество NA.
Демонстрация приведения отсутствующих значений в режим.
Мы будем использовать набор данных о ценах на жилье, чтобы продемонстрировать, как выполнять условное исчисление в категориальных переменных.
Чтобы загрузить набор данных, обратитесь к: « Набор данных о ценах на жилье »
Импорт необходимых библиотек:
import pandas as pd import numpy as np import matplotlib.pyplot as plt # To split the datasets from sklearn.model_selection import train_test_split
Определение используемых столбцов:
BsmtQual: оценивает высоту подвала. (Категориальная переменная)
FireplaceQu: качество камина. (Категориальная переменная)
# Defining columns to use from the house price dataset cols_to_use = ['BsmtQual', 'FireplaceQu', 'SalePrice'] # Reading the dataset using pandas data = pd.read_csv('../houseprice.csv', usecols=cols_to_use) data.head()
Вывод:
У нас отсутствуют данные?
# let's inspect the percentage of missing values in each variable data.isnull().mean() BsmtQual 0.025342 FireplaceQu 0.472603 SalePrice 0.000000 dtype: float64
Переменная BsmtQual содержит только несколько наблюдений с NA (2,5%), поэтому замена этих наблюдений значением наиболее часто встречающейся категории - хороший подход.
С другой стороны, переменная FireplaceQu содержит недостающие данные почти в (47,26%) половине наблюдений. Следовательно, замена категорий наиболее часто встречающейся категорией, скорее всего, приведет к искажению связи наиболее часто встречающейся категории с продажной ценой.
Важное замечание:
Величина должна выполняться по обучающему набору, а затем распространяться на тестовый набор. Это означает, что из обучающего набора необходимо выбрать наиболее частую категорию и использовать ее для замены NA как в обучающей, так и в тестовой выборках.
Разделение на набор данных для обучения и тестирования:
# let's separate into training and testing set X_train, X_test, y_train, y_test = train_test_split( data, data['SalePrice'], # target test_size=0.3, # percentage of observations in the test set random_state=0)
BsmtQual (качество подвала):
Напомним процент пропущенных значений.
X_train['BsmtQual'].isnull().mean() 0.023483365949119372
Давайте проверим количество наблюдений для каждой категории в BsmtQual.
# value_counts() counts the amount of houses that show each of the labels in the variable indicated below X_train['BsmtQual'].value_counts().sort_values(ascending=False).plot.bar() plt.xlabel('BsmtQual') plt.ylabel('Number of houses')
Давайте найдем наиболее часто используемую категорию для BsmtQual.
X_train['BsmtQual'].mode() 0 TA dtype: object
Наблюдения. Наиболее частая категория в BsmtQual - это TA ( Среднее / Типичное ).
Построение распределений целевой переменной относительно BsmtQual.
fig = plt.figure() ax = fig.add_subplot(111) # select and plot houses with the most frequent label X_train[X_train[‘BsmtQual’]==’TA’][‘SalePrice’].plot(kind=’kde’, ax=ax) # select and plot houses with missing data in the variable X_train[X_train[‘BsmtQual’].isnull()][‘SalePrice’].plot(kind=’kde’, ax=ax, color=’red’) # add the legend lines, labels = ax.get_legend_handles_labels() labels = [‘Houses with TA’, ‘Houses with NA’] ax.legend(lines, labels, loc=’best’) # add figure title plt.title(‘BsmtQual’)
График выше показывает, что дома с отсутствующими данными стоят в целом меньше, чем дома с меткой TA. Следовательно, замена отсутствующих значений на TA может повлиять на общее распределение, если бы было много NA.
Давайте оставим исходное распределение SalePrice для наиболее часто встречающейся категории для дальнейшего использования.
# the use of tmp is common to name temporal variables tmp = X_train[X_train['BsmtQual']=='TA']['SalePrice']
Давайте заполним NA как для обучения, так и для тестирования с помощью категории часто используемых.
# inplace=True is used to replicate that in original dataframe X_train['BsmtQual'].fillna('TA', inplace=True) X_test['BsmtQual'].fillna('TA', inplace=True)
Оценка влияния на распределение категорий.
X_train['BsmtQual'].value_counts().sort_values(ascending=False).plot.bar() plt.xlabel('BsmtQual') plt.ylabel('Number of houses')
Из приведенного выше графика мы видим, что теперь есть еще несколько домов с меткой TA, которые раньше содержали NA, но общее влияние на распределение не является драматическим. График выглядит почти идентично тому, что было до вменения.
Изменилось ли распределение SalePrice для наиболее частой категории?
fig = plt.figure() ax = fig.add_subplot(111) # original distribution of salePrice for houses with most frequent label # remember I captured this a few cells up in the notebook tmp.plot(kind='kde', ax=ax) # distribution of the variable after imputation X_train[X_train['BsmtQual'] == 'TA']['SalePrice'].plot( kind='kde', ax=ax, color='red') # add the legend lines, labels = ax.get_legend_handles_labels() labels = ['Original variable', 'Imputed variable'] ax.legend(lines, labels, loc='best') # add title plt.title('BsmtQual')
Распределение цен на жилье между исходной и условно исчисленной переменной очень похоже, потому что количество отсутствующих данных было небольшим. Поэтому частое вменение категорий - хороший выбор для функции BsmtQual.
FirePlaceQu (качество камина):
Напомним процент пропущенных значений.
X_train['FireplaceQu'].isnull().mean() 0.46771037181996084
Давайте найдем наиболее часто используемую категорию для FirePlaceQu.
X_train['FireplaceQu'].mode() 0 Gd dtype: object
Наблюдения. Самая частая категория в FirePlaceQu - Gd (хорошо).
Построим график распределения целевого объекта для домов, которые показывают наиболее частую категорию, и тех, для которых данные отсутствуют.
fig = plt.figure() ax = fig.add_subplot(111) # houses with the most frequent label for FirePlaceQu X_train[X_train['FireplaceQu']=='Gd']['SalePrice'].plot(kind='kde', ax=ax) # houses with missing data in FirePlaceQu X_train[X_train['FireplaceQu'].isnull()]['SalePrice'].plot(kind='kde', ax=ax, color='red') # add the legend lines, labels = ax.get_legend_handles_labels() labels = ['Houses with Gd', 'Houses with NA'] ax.legend(lines, labels, loc='best') plt.title('FirePlaceQu')
Наблюдения:
Распределения совершенно разные: дома с отсутствующими данными стоят в целом меньше, чем дома с меткой Gd.
Давайте сохраним исходное распределение SalePrice, поскольку оно относится к наиболее частой категории для дальнейшего использования.
tmp = X_train[X_train['FireplaceQu']=='Gd']['SalePrice']
Давайте заполним NA как на тренировке, так и на тесте.
X_train['FireplaceQu'].fillna('Gd', inplace=True) X_test['FireplaceQu'].fillna('Gd', inplace=True)
Построим график распределения целевой переменной
и вмененной переменной.
fig = plt.figure() ax = fig.add_subplot(111) # original distribution of the variable tmp.plot(kind='kde', ax=ax) # distribution of the variable after imputation X_train[X_train['FireplaceQu'] == 'Gd']['SalePrice'].plot( kind='kde', ax=ax, color='red') # add the legend lines, labels = ax.get_legend_handles_labels() labels = ['Original variable', 'Imputed variable'] ax.legend(lines, labels, loc='best') plt.title('FirePlaceQu')
Наблюдения:
Средняя стоимость дома для наиболее часто встречающейся категории значительно снизилась после добавления значений стоимости дома в NA после изменения категории NA в качестве наиболее часто используемого ярлыка.
В подобных случаях, когда процент пропущенных значений очень высок (~ 50%), лучше создать новую категорию (Отсутствует), чтобы заключить наблюдения с NA.
Полный исходный код можно найти здесь:
Https://github.com/ku-nal/Feature-Engineering/tree/main/Frequent-Category-Imputation
Надеюсь, это была полезная статья. Если у вас есть комментарии, не стесняйтесь записывать их ниже. Вы можете подписаться на меня на medium, linkedin.