Здравствуйте, друзья! Возможно, вы слышали, что модели, обученные на несбалансированных наборах данных, могут страдать от плохого обобщения и ограниченного обнаружения классов меньшинства. В следующих нескольких постах я приведу пример, показывающий, как несбалансированный набор данных влияет на производительность модели и как мы можем справиться с этой проблемой. В этом посте мы сначала загрузим данные и обработаем их для дальнейшего анализа.
Загрузить данные
Чтобы проиллюстрировать эту проблему несбалансированных наборов данных, мы будем использовать данные, извлеченные из базы данных Бюро переписи населения 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 тысяч или нет. Оставайтесь с нами 👀