実際に利用した例を使ってまとめます。
状況
競馬データで、単勝予測の機械学習システムを構築しようと思いました。しかし、最低でも5頭、最大で20頭近くで行われることもある競馬のレースデータでは、単純に(一位orその他)で分けただけのデータを使うと、ラベルに大きな偏りが生まれて学習がうまくいきません。なので、(一位orその他)のデータの比率を1:1にアンダーサンプリングしました。
サンプルコード
undersampling.py
def under_sampling(data: pd.DataFrame):
#order_of_finish = 着順
low_frequency_data_sample = data[data["order_of_finish"] == 1]
low_frequency_data_size = len(low_frequency_data_sample)
# 高頻度データの行ラベル
high_frequency_data = data[data["order_of_finish"] == 0].index
# 高頻度データの行ラベルから、低頻度のデータと同じ数をランダムで抽出
random_indices = np.random.choice(high_frequency_data, low_frequency_data_size, replace=False)
# 抽出した行ラベルを使って、該当するデータを取得
high_frequency_data_sample = data.loc[random_indices]
pd.DataFrame(high_frequency_data_sample)
# データをマージする。 concatは結合API
merged_data = pd.concat([high_frequency_data_sample, low_frequency_data_sample], ignore_index=True)
balanced_data = pd.DataFrame(merged_data)
return balanced_data