DataWhale AI サマー キャンプ - 機械学習
学習記録その1
環境が構成され、ベースラインが実行され、これに基づいてデータの簡単な分析が実行されました。
1. 外れ値分析
トレーニングセット内の欠損値と外れ値を分析する
train_data.info()
train_data.describe()
データに欠損値や外れ値がないことを確認しますtrain_dataset['下部温度9'] == -32768.000000]
。欠損値を削除します。
train_dataset.drop(train_dataset[train_dataset['下部温度9'] == -32768.000000].index).reset_index(drop=True)
2. 単変量箱ひげ図の視覚化
トレーニング セットとテスト セットの流量、上限設定温度、下限設定温度のデータ分布を箱ひげ図として視覚化すると、設定温度の上限と下限のデータにいくつかの外れ値があることが観察されました
。データでは2023/1/7、2023/1/8、2023/1/9の3日間データ。
ベースライン (6.29551) に基づいて 2 つの変更が加えられました。
- データ内の誤った値を削除しました (6.72811)
- 2023/1/7、2023/1/8、2023/1/9のデータを削除 (6.73844)
3. 機能の重要性分析
次に、単一の予測変数に対する効率的な固有解析を分析する試みが行われました。
- 相関行列を計算する
df = pd.concat([X, y.iloc[:,0]], axis = 1) # X是处理后的训练数据,y是标签
corr_matrix = df.corr()
corr_matrix['上部温度1'].sort_values(ascending=False)
lightgbm
機能の重要性
feature_importance = model.feature_importance()
sorted_features = sorted(zip(X.columns, feature_importance), key=lambda x: x[1], reverse=True)
# 打印按照feature_importance值降序排列的特征列表
for feature, importance in sorted_features:
print(f"{
feature}: {
importance}")
相関行列は線形相関を計算するため、観察される結果は lightgbm の特徴重要度の結果とは多少異なります。
次のステップでは、さまざまな特徴を構築し、各予測出力の結果に対して特徴スクリーニングを実行します。
学習記録2(2023.07.27更新)
ここ数日は主に Baseline との格闘でしたが、その後すべて失敗しました。データレベル、特徴エンジニアリング、データ分割方法、後処理などの試みが行われてきました。
1. データプレーン
前回見つかったデータには欠損値(0)や外れ値があり、検索により除外・修正されます。最近では、視覚化により、ほぼすべての特徴に異常値が存在するようになりました。特に交通特性に反映されます。
上の図は、トレーニング データ内の 17 個の交通特徴を折れ線グラフで示したものですが、依然として大きな変動があることがわかります。
スライディング ウィンドウ フィルタリングに中央値を使用して得られた結果。赤い曲線はテスト セットのフィルタリングの結果です。
フィルタリングに使用されるコード:
def smooth_t(df, cols):
df = df.copy()
window_size = 5
for col in cols:
df[f'smoothed_{
col}'] = df[col].rolling(window=window_size, center=True).median()
outlier_threshold = 5.0
df['absolute_diff'] = abs(df[col] - df[f'smoothed_{
col}'])
outliers = df['absolute_diff'] > outlier_threshold
df.loc[outliers, col] = df.loc[outliers, f'smoothed_{
col}']
df.drop(columns=[f'smoothed_{
col}', 'absolute_diff'], inplace=True)
return df
結果: フィルタリングされたデータでは、テスト セットの MAE は減少しません。
2. 特徴量エンジニアリング
主に次の 3 つの側面からです。
- トラフィック特性: 一定の時間範囲 (1 日) 内の分散、平均、変動係数が構築されます。その中で、変動係数は良好なパフォーマンスを示し、ツリー モデルの特徴重要度のスコアは元の交通特徴のスコアよりも高かったが、この特徴でトレーニングした後のテスト セットのパフォーマンスは良くなかった。機能の保持と削除はまだやや混乱していました。
- 温度設定特徴量:これらの特徴量は、相関相関において対象と強い線形相関を持ちますが、ツリーモデルの特徴量重要度評価では性能が悪く、値が比較的安定しているため、派生特徴量を構築するのは容易ではありません。すべての値を最も多い n 個の値に置き換え、1、0、-1 を使用してその前後の変更を構築して、それを個別の特徴に構築しようとしました。しかし、これらの機能のパフォーマンスはあまり良くありません。
- そこで全自動特徴量生成ツールopenFEを使ってみました。効果も平均的です。
from openfe import OpenFE, transform, tree_to_formula
ofe = OpenFE()
features = ofe.fit(data = train_x, label = train_y, n_jobs=12) # n_jobs:指定CPU内核数
train_x_feature, test_dataset_feture = transform(train_x, test_x, features[:20], n_jobs = 12)
# 查看前20个高分特征
for feature in ofe.new_features_list[:20]:
print(tree_to_formula(feature))
3. データ分割方法
時系列データであるため、train_test_split
そのまま使用するとタイムトラベルが発生するため、時系列データを使用する効果は非常に低く、パフォーマンスはTimeSeriesSplit
使用するKFold
ほど良くありませんtrain_test_split
。
4. 後処理
- Hillclimbing ライブラリ - モデル フュージョン用
モデル フュージョン用のライブラリを見つけましたが、現在 lightgbm しか使用していないため、まだ試していません。
!pip install hillclimbers
from hillclimbers import climb, partial
def climb_hill(
train=None,
oof_pred_df=None,
test_pred_df=None,
target=None,
objective=None,
eval_metric=None,
negative_weights=False,
precision=0.01,
plot_hill=True,
plot_hist=False
) -> np.ndarray: # Returns test predictions resulting from hill climbing
- 後処理技術
興味深い処理技術を見つけましたが、このデータセットには適用できませんでしたが、このアイデアを使用して温度設定特徴の離散エンコーディングを構築しましたが、効果も非常に低かったです。
# 1. 存储target唯一值
unique_targets = np.unique(trian['yield'])
# 2. 完成对训练和测试数据的预测
off_preds = model.prdict(X_val[features])
test_preds += model.predict(test[features]) / n_splits
# 四舍五入到最接近的唯一目标值
off_preds = [min(unique_targets, key = lambda x: abs(x-pred)) for pred in oof_preds]
test_preds = [min(unique_targets, key = lambda x: abs(x-pred)) for pred in test_preds]
学習記録3(2023.07.30更新)
以前は特徴の選択に多くの時間を費やしていましたが、構築された特徴の量が特徴の選択の量とは程遠いことに後で気づきました。また、スコアが上がらない場合はデータ分析から始めましょう。そこで、この 2 日間でデータを注意深く分析したところ、新たな発見が得られました。
まず、トレーニング セット上のから2022-11-06 09:00:00
までの2023-03-01 04:00:00
時間ごとのデータの記録を数えました。
データの例は次のとおりです。
2022-11-06 09:00:00,40
2022-11-06 10:00:00,47
2022-11-06 11:00:00,46
2022-11-06 12:00:00,47
2022-11-06 13:00:00,47
2022-11-06 14:00:00,48
2022-11-06 15:00:00,47
......
トレーニング セットは、各時間のデータのサンプリング頻度に応じて 5 つの部分に分割されます。たとえば、2022-11-7
とのデータ2022-11-8
は 1 時間あたり約 48 回サンプリングされ、その後データが 4 つのステップで 4 つの部分に分割されるため、1 時間あたり約 12 個のサンプルが得られます。同様の操作がトレーニング セットの残りの部分に対して実行されるため、データ全体が 1 時間あたり約 12 サンプルに保たれます。
この目的は、テスト セットがすべて 1 時間あたり 11 回または 12 回のサンプリング頻度を維持するためです。
このような処理の後、トレーニング セットとテスト セットで等しい時間ステップが達成されます。これは、その後のタイミング機能の構築に便利です。
さらに、トレーニング セットを分割することにより、空き時間の影響も効果的に回避できます。
さらに、検証セットを手動で選択すると、検証セットとテスト セットの配布の一貫性が確保され、オンラインおよびオフラインでのフィッティングが向上します。
次に、同じ時間ステップで処理されたデータを使用して、以前の試みからの時系列相関特徴が再構築されました。簡単な検証にはベースライン方法を使用します。今回はより高速なマシンに変更しましたが、最終的に MAE は7.52
さらに悪化しました。その後、ベースラインを再度実行すると、今回はベースラインが変更され8.51
、前のベースラインのスコアは同じままであることがわかりました6.29
。
まとめ: この 2 日間、データ処理に時間がかかりすぎて、プログラムの品質を評価するのは簡単ではありません。結果はさまざまな要因に影響され、変数を制御するのは簡単ではないと感じています。プログラミング全体プロセスも混沌としており、後で練習して強化する必要があります。ユラオの生放送で学んだアイデアの中にはまだ実践していないものもあるので、ここ数日でもう一度試してみたいと思います。