Как сформировать исторические признаки для моделей машинного обучения
В этой статье я поделюсь простым приемом формирования исторических признаков на основании последовательных сведений.
Рассмотрим использованные в прошлой статье данные о заработках людей по месяцам:
Предположим, вы хотите предсказать доход человека в последующий месяц на основании предыдущих. Тогда данные следует перегруппировать таким образом, чтобы в строках находились сведения как о текущем, так и предыдущих месяцах.
Одним из простых путей добиться этого является объединение таблицы по месяцу и имени человека с ее же копией, сдвинутой на заданное количество месяцев вперед (в частности, для предыдущего - на один).
Это можно реализовать при помощи указанной ниже функции get_shift_data, принимающей в качестве параметра датафрейм, состоящий из колонки данных (заработок) и столбцов, по которым происходит объединение (ФИО человека и дата в нашем случае), наименований столбцов даты и данных, а также числа периодов, на которые целевой признак отстоит от текущего:
def get_shift_data(df, date_col, data_col, n): df_c = df.copy() cols_merge = list(df.columns) cols_merge.remove(data_col) df_c[date_col] = df_c[date_col].map(lambda x: x + n) df_f = pd.merge(df, df_c, on=cols_merge, suffixes=[None,f'_{n}']) return df_f
Рассмотрим ее применение на наших данных:
n_m_b = 3 df_hist = get_shift_data(data[['date_sh', 'names', 'income']],'date_sh','income', n_m_b) data[data['names']=='G H'] df_hist[df_hist['names']=='G H']
Функцию get_shift_data можно использовать для написания более продвинутой версии - get_shift_data_tilln, возвращающей все признаки раньше заданного (она принимает те же параметры):
def get_shift_data_tilln(df, date_col, data_col, n): cols_merge = list(df.columns) cols_merge.remove(data_col) df_f = get_shift_data(df, date_col, data_col, 1) if n>1: for i in range(2,n+1): df_f_t = get_shift_data(df, date_col, data_col, i) df_f = pd.merge(df_f, df_f_t[cols_merge+[data_col+f'_{i}']], on=cols_merge, suffixes=[None,f'_{n}']) return df_f
Рассмотрим ее работу на примере:
n_m_b = 3 df_hist_till = get_shift_data_tilln(data[['date_sh', 'names', 'income']] ,'date_sh','income', n_m_b) data[data['names']=='G H'] df_hist_till[df_hist_till['names']=='G H']
Или для другой длины окна, чтобы сохранить больше данных:
n_m_b = 2 df_hist_till = get_shift_data_tilln(df_nullplus[['date_sh', 'names', 'income']],'date_sh','income', n_m_b) data[data['names']=='G H'] df_hist_till[df_hist_till['names']=='G H']