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

Загрузить данные

Чтобы проиллюстрировать эту проблему несбалансированных наборов данных, мы будем использовать данные, извлеченные из базы данных Бюро переписи населения 1994 года Ронни Кохави и Барри Беккер (Data Mining and Visualization, Silicon Graphics). Задача прогнозирования состоит в том, чтобы определить, зарабатывает ли человек более 50 тысяч долларов в год или нет. Вы можете скачать набор данных по следующей ссылке:



Предварительно обработать данные

# Load the data the check first lines 
import pandas as pd
df = pd.read_csv("adult.csv")
df.head()

Затем мы отбросим недостающие значения и значения, которые не нужны для нашего анализа.

# Drop missing values 
import numpy as np
df[df=='?']=np.nan
new_df=df.dropna(axis=0)

# Drop the fnlwgt column which is useless for later analysis
new_df = new_df.drop('fnlwgt', axis=1)

Мы также заменим значение дохода на 0 (≤50 тыс.) и 1 (>50 тыс.).

new_df['income'].replace({'<=50K':0,'>50K':1},inplace=True)

# Examine if there are missing value
new_df.info()

Одно горячее кодирование

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

# One-hot encode the 'features_log_minmax_transform' data using sklearn.OneHotEncoder

# Categorical columns' names
cat_feats = new_df.dtypes[new_df.dtypes=='object'].index.tolist()
cat_idx = [new_df.columns.get_loc(col) for col in cat_feats]

# Create the encoder
from sklearn.preprocessing import OneHotEncoder
encoder = OneHotEncoder(handle_unknown="ignore", sparse=False)

# Fit and transform the encoder on categorical features
encoded_cat_feats = encoder.fit_transform(new_df.loc[:, cat_feats])

# Get the unique values for each category in the original columns
unique_values = [new_df[col].unique() for col in cat_feats]

# Generate the feature names for the encoded categorical features
encoded_cat_feats_name = []
for i, col in enumerate(cat_feats):
    for value in unique_values[i]:
        encoded_cat_feats_name.append(f"{col}_{value}")

# Create the encoded categorical features dataframe
encoded_cat_feats_df = pd.DataFrame(encoded_cat_feats, columns=encoded_cat_feats_name)

encoded_cat_feats_df.head()

# Define the list of numerical column names
num_col = [col for col in new_df.columns if col not in cat_feats]

# Extract the dataframe with only numerical features
num_feats_df = new_df[num_col].reset_index()

# Concatenate numerical and encoded categorical features together
df_encoding = pd.merge(num_feats_df, encoded_cat_feats_df, left_index=True, right_index=True).drop('index', axis=1)

df_encoding.head()

Чтобы показать, насколько искажен набор данных, мы можем запустить следующий код:

income_1_count = df_encoding[df_encoding['income'] == 1].shape[0]
print("Number of data points with income = 1:", income_1_count)

income_0_count = df_encoding[df_encoding['income'] == 0].shape[0]
print("Number of data points with income = 0:", income_0_count)

--> Result: 
Number of data points with income = 1: 7508
Number of data points with income = 0: 22654

Наконец, мы сохраняем закодированные данные в новый файл CSV.

df_encoding.to_csv('encoded_data.csv', index=False)

Обзор:

Что мы сделали до сих пор, так это подготовили наш набор данных для задач классификации. Далее мы будем использовать многослойный персептрон (MLP), чтобы классифицировать, зарабатывает ли человек больше 50 тысяч или нет. Оставайтесь с нами 👀