GoDaddy是現在進行的時序比賽,本文介紹GoDaddy賽題的基礎解決(jue) 方法,包括數據劃分、模型驗證和幾個(ge) 基礎的模型。
比賽地址:https://www.kaggle.com/competitions/godaddy-microbusiness-density-forecasting
步驟1:時序數據劃分
參考比賽數據劃分的邏輯,我們(men) 將數據集劃分為(wei) 訓練集、驗證集。當然隨著比賽逐漸進行,驗證的數據也會(hui) 發生改變。
HOLDOUT_SIZE = 4 test_set_dates = sorted(train["first_day_of_month"].unique())[-HOLDOUT_SIZE:] df_train = train[~train["first_day_of_month"].isin(test_set_dates)].copy() df_test = train[train["first_day_of_month"].isin(test_set_dates)].copy() df_test_public = df_test.loc[df_test["first_day_of_month"]==df_test["first_day_of_month"].unique()[0]].copy() if HOLDOUT_SIZE > 1: df_test_private = df_test.loc[df_test["first_day_of_month"].isin(df_test["first_day_of_month"].unique()[1:])].copy()
步驟2:定義(yi) 評價(jia) 指標
按照比賽評價(jia) 指標SMAPE,我們(men) 可以定義(yi) 評價(jia) 指標。
def SMAPE(y_true, y_pred): denominator = (y_true + np.abs(y_pred)) / 200.0 diff = np.abs(y_true - y_pred) / denominator diff[denominator == 0] = 0.0 return np.mean(diff)
步驟3:曆史均值預測
在對未來進行數據進行預測時,直接使用曆史均值是一個(ge) 不錯的方法。
y_pred_public = list() y_pred_private = list() for county in train['cfips'].unique(): county_avg = df_train.loc[df_train['cfips']==county, 'microbusiness_density'].mean() public_preds = [county_avg]*len(df_test_public[df_test_public['cfips']==county]) if HOLDOUT_SIZE > 1: private_preds = [county_avg]*len(df_test_private[df_test_private['cfips']==county]) y_pred_public += public_preds if HOLDOUT_SIZE > 1: y_pred_private += private_preds
驗證結果:
Leadboard estimate Public: 8.555 Private: 8.696
步驟4:最後點作為(wei) 預測
對於(yu) 時序任務,距離最近的點更加重要。因此可以直接考慮使用最後的一個(ge) 點作為(wei) 預測結果。
y_pred_public = list() y_pred_private = list() for county in train['cfips'].unique(): county_naive = df_train.loc[(df_train['cfips']==county), 'microbusiness_density'].values[-1] public_preds = [county_naive]*len(df_test_public[df_test_public['cfips']==county]) if HOLDOUT_SIZE > 1: private_preds = [county_naive]*len(df_test_private[df_test_private['cfips']==county]) y_pred_public += public_preds if HOLDOUT_SIZE > 1: y_pred_private += private_preds
驗證結果:
Leadboard estimate Public: 2.355 Private: 2.809
步驟5:按照季節進行預測
在對未來進行預測時,需要考慮季節因素。因此可以取上一年同月的值並用作預測。
y_pred_public = list() y_pred_private = list() for county in train['cfips'].unique(): county_public_naive_seasonal = df_train.loc[(df_train['cfips']==county) & (df_train['first_day_of_month'].dt.year == df_test_public['first_day_of_month'].dt.year.unique()[0]-1) & (df_train['first_day_of_month'].dt.month.isin(df_test_public['first_day_of_month'].dt.month)), 'microbusiness_density'].values if HOLDOUT_SIZE > 1: county_private_naive_seasonal = df_train.loc[(df_train['cfips']==county) & (df_train['first_day_of_month'].dt.year == df_test_private['first_day_of_month'].dt.year.unique()[0]-1) & (df_train['first_day_of_month'].dt.month.isin(df_test_private['first_day_of_month'].dt.month)), 'microbusiness_density'].values public_preds = list(county_public_naive_seasonal) private_preds = list(county_private_naive_seasonal) y_pred_public += public_preds y_pred_private += private_preds
驗證結果:
Leadboard estimate Public: 7.331 Private: 7.006
步驟6:均值漂移預測
允許預測值隨著時間的推移增大或減小,假定單位時間改變量(稱作 “漂移”)等於(yu) 曆史數據的平均改變量。
y_pred_public = list() y_pred_private = list() change_in_time = df_train['first_day_of_month'].nunique()-1 for county in train['cfips'].unique(): first_month = df_train['first_day_of_month'].unique()[0] last_month = df_train['first_day_of_month'].unique()[-1] first_value = df_train.loc[(df_train['cfips']==county) & (df_train['first_day_of_month']==first_month), 'microbusiness_density'].values[0] last_value = df_train.loc[(df_train['cfips']==county) & (df_train['first_day_of_month']==last_month), 'microbusiness_density'].values[0] slope = (last_value-first_value)/change_in_time public_preds = last_value + slope y_pred_public.append(public_preds) if HOLDOUT_SIZE > 1: for step in range(2,len(df_test_private['first_day_of_month'].unique())+2): private_preds = last_value + step*slope y_pred_private.append(private_preds)
驗證結果:
Leadboard estimate Public: 2.536 Private: 3.323
步驟7:線性回歸預測
將曆史時序數據作為(wei) 訓練數據,將月份作為(wei) 特征構建線性回歸模型。這裏建議對所有的地區的數據一起訓練。
def simple_lr_preprocess(df): days_conversion = list() for date in df["first_day_of_month"]: days_conversion.append((date - pd.to_datetime(date.today())).days) X = pd.concat([df['cfips'].reset_index(drop=True), pd.Series(days_conversion), df['microbusiness_density'].reset_index(drop=True)], axis=1) X.columns = ['cfips', 'days_since', 'microbusiness_density'] y = X.pop('microbusiness_density') return X, y
驗證結果:
Leadboard estimate Public: 6.279 Private: 7.212
如下是部分預測結果,可以看出模型預測結果與(yu) 驗證集差異不大。由於(yu) 數據集不複雜,建議嚐試其他簡單的模型。
本文源碼:https://www.kaggle.com/code/michaelbryantds/godaddy-simple-forecasting-methods
評論已經被關(guan) 閉。