Функция, которая возвращает предсказанные пропущенные значения с оценкой предсказания.
Если вы занимаетесь традиционным машинным обучением, вы, вероятно, сталкиваетесь с продолжающейся битвой с пропущенными значениями (NaN) в ваших данных.
Это имеет место практически в каждом соревновании Kaggle, а также в большинстве наборов табличных данных. там.
Здесь я рассмотрю некоторые жизнеспособные подходы. Затем я попытаюсь коснуться аспектов, которые я разработал и которые я вижу отличными от других.
Спойлер: в этой статье я подробно расскажу о проблеме, но если вам просто нужно однострочное решение:
$ pip install verstack
Общая практика
Большинство практикующих специалистов по данным захотят быстро избавиться от недостающих значений и начать подгонку моделей для получения результата.
Следовательно, быстрое решение состоит в том, чтобы просто заполнить NaN определенными константами для каждого типа столбца с отсутствующими значениями:
numeric — среднее/медиана столбца:
df[col].fillna(df[col].mean(), inplace = True)
двоичный/категориальный (независимо от типа данных в столбце)
- самая распространенная категория:
most_common_category = df[col].value_counts().index[0] df[col].fillna(most_common_category, inplace = True)
- ввести новую категорию
Несмотря на простоту, этот подход жизнеспособен, поскольку отсутствующие данные могут появиться по определенной причине, и создание этой «причины» новой категории может привести к определенным знаниям
new_category = -999 # this can also be a string df[col].fillna(new_category, inplace = True)
text — постоянная строка
df[col].fillna('Missing_data', inplace = True)
Несмотря на то, что все эти варианты жизнеспособны и широко используются, последствия этого подхода добавляют к вашим данным необъективность.
Один из самых сложных моментов для меня здесь — это невозможность измерить, правильный процесс наполнения или нет. Например, я подумал, если бы мне пришлось заполнять столбец1, столбец2.. столбец (n) отдельно для каждого и какой из них я получил бы более точные результаты. Я разработал для этого функцию. Для будущей работы я хочу превратить его в пакет Python.
Набор данных
У нас есть 4 непрерывные и 1 бинарная переменная в наборе данных. Нам нужно обработать нулевые значения перед запуском ML для нашей двоичной переменной. Мы можем попробовать методы, которые я упомянул выше. Но если мы не можем это измерить, мы не можем этим управлять. Итак, я расскажу вам о своем подходе.
Мой подход
Первым шагом в моем подходе является выбор объектов для заполнения. Затем я создаю отдельную модель LightGBM для каждого заполняемого столбца. Каждая модель воспринимает другие столбцы как поезд и воспринимает заполняемый столбец как цель. Причина, по которой я использую LighGBM, заключается в том, что он такой быстрый. Потому что может быть слишком много столбцов для заполнения, и этот процесс может занять слишком много времени в других алгоритмах.
hyper_params = { 'boosting_type': 'gbdt', 'objective': 'regression', 'metric': 'l1', 'learning_rate': 0.005, "num_iterations": 800 } lgbm_dict = dict() colmns = ["feature_1","feature_2","feature_3","feature_4"] for col in colmns: lgbm_dict['y'+ str(col)] = df[df[[col]].notna().any(axis=1)][col] lgbm_dict['df_test'+ str(col)] = df[df[[col]].isna().any(axis=1)] df_train = df[df[[col]].notna().any(axis=1)] df_train.drop([col], axis=1, inplace=True) lgbm_dict['df_test'+ str(col)].drop([col], axis=1, inplace=True) lgbm_dict['X_train'+ str(col)], X_test, lgbm_dict['y_train'+ str(col)], lgbm_dict['y_test'+ str(col)] = train_test_split(df_train, lgbm_dict['y'+ str(col)], test_size=0.25, random_state=42) lgbm_dict['gbm'+ str(col)]= lgb.LGBMRegressor(**hyper_params) lgbm_dict['gbm'+ str(col)].fit(lgbm_dict['X_train'+ str(col)], lgbm_dict['y_train'+ str(col)], eval_set=[(X_test, lgbm_dict['y_test'+ str(col)])], eval_metric='l1', early_stopping_rounds=60,verbose=100)
Затем я создал каждую часть информации, которая появляется здесь, и записал ее в словарь.
lgbm_dict["gbmfeature_1"] Output: LGBMRegressor(learning_rate=0.005, metric='l1', num_iterations=800, objective='regression')
Оценка прогноза для каждого столбца
После этих операций я вычисляю баллы прогноза для каждого столбца.
colmns = ["feature_1","feature_2","feature_3","feature_4"] for col in colmns: lgbm_dict['y_pred'+ str(col)] = lgbm_dict['gbm'+ str(col)].predict(lgbm_dict['X_train'+ str(col)], num_iteration=lgbm_dict['gbm'+ str(col)].best_iteration_) print('The R2 Score of prediction of',col + str(":"), round(r2_score(lgbm_dict['y_train'+ str(col)], lgbm_dict['y_pred'+ str(col)]) ** 0.5, 5))
Выход:
The R2 Score of prediction of feature_1: 0.9024 The R2 Score of prediction of feature_2: 0.65733 The R2 Score of prediction of feature_3: 0.52101 The R2 Score of prediction of feature_4: 0.9136
Как видите, мои оценки прогнозов для feature2 и feature3 низкие. Я мог бы рассмотреть возможность применения других операций к этим функциям. Например, я могу попробовать другой алгоритм или, если оценка все еще слишком низкая, я могу напрямую удалить пустые строки.
Визуализации
Давайте оценим наши процессы до этого этапа.
1- Мы восполнили недостающие значения с помощью LightGBM. Мы выбрали его, потому что он быстрый.
2- После этого мы оценили результат. Мы оценили дальнейшие исследования для столбцов с низкими прогностическими показателями.
3- И, наконец, мы можем визуализировать отсутствующие значения для каждого столбца, чтобы увидеть, как они распределялись до и после их заполнения. Вы можете увидеть 2 примера ниже.
Подведение итогов / Будущая работа?
Я думаю, что это исследование может внести свой вклад в экосистему машинного обучения с точки зрения измерения и оценки. Поэтому я планирую сделать функцию пакетом Python. Я также хочу добавить к нему несколько модулей.
Спасибо за чтение.
Автор:
Что вы думаете об отсутствующих значениях и их влиянии на машинное обучение? Свяжитесь со мной на моем LinkedIn или прокомментируйте здесь ниже, чтобы обсудить!