学習する(8:標準化)

学習

時系列特徴量の標準化(平均0・分散1)を行い、シーケンス入力用に整形して保存する前処理

print("✅ スケーリング(高速版)")
TAIL = 3 

Xtr_main = X_train[:, :, : -TAIL]
Xtr_tail = X_train[:, :, -TAIL:]

Xtr_num = Xtr_main[:, :, keep_numeric_idx].reshape(-1, keep_numeric_idx.size)
means = Xtr_num.mean(axis=0)
stds  = Xtr_num.std(axis=0); stds[stds == 0] = 1.0
Xtr_view = Xtr_main[:, :, keep_numeric_idx]
Xtr_view -= means.reshape(1, 1, -1)
Xtr_view /= stds.reshape(1, 1, -1)

def scale_inplace(X, keep_idx, means, stds):
    X_main = X[:, :, : -TAIL]
    view   = X_main[:, :, keep_idx]
    view -= means.reshape(1, 1, -1)
    view /= stds.reshape(1, 1, -1)

scale_inplace(X_val,  keep_numeric_idx, means, stds)
scale_inplace(X_test, keep_numeric_idx, means, stds)

keep_for_seq = keep_numeric_idx.astype(np.int64)
def build_seq(X):
    X_main = X[:, :, : -TAIL]
    X_tail = X[:, :, -TAIL:]
    X_main_kept = np.take(X_main, keep_for_seq, axis=2) 
    return np.concatenate([X_main_kept, X_tail], axis=2).astype(np.float32)

X_train_seq = build_seq(X_train)
X_val_seq   = build_seq(X_val)
X_test_seq  = build_seq(X_test)

numeric_cols_final = [feature_columns[i] for i in keep_for_seq.tolist()] 
extra_cols = ["similarity_max", "history_len_norm_seq", "pad_flag"]
feature_names_seq = numeric_cols_final + extra_cols

with open("final_feature_names_seq.json", "w", encoding="utf-8") as f:
    json.dump(feature_names_seq, f, ensure_ascii=False, indent=2)
print("✅ final_feature_names_seq 保存済み")

scale_stats = {
    "keep_numeric_idx": keep_numeric_idx.tolist(),
    "means": means.astype(np.float32).tolist(),
    "stds": stds.astype(np.float32).tolist(),
    "TAIL": int(TAIL),
    "keep_for_seq": keep_for_seq.tolist(),
}
with open("scale_stats.json", "w", encoding="utf-8") as f:
    json.dump(scale_stats, f, ensure_ascii=False)
print("✅ scale_stats 保存済み")

このコードは、学習用の数値特徴をトレイン分布で標準化(スケーリング)し、推論時の再現性のために 統計量と最終特徴名を保存、さらに 埋め込み等の末尾3特徴(TAIL)を非スケールで保持したまま最終テンソルを組み立てる高速前処理です。構文の役割も併せて解説します。

  • TAIL=3(末尾3特徴は非スケール)
TAIL = 3
Xtr_main = X_train[:, :, : -TAIL]   # スケール対象(本体)
Xtr_tail = X_train[:, :, -TAIL:]    # 末尾3つ(類似度・履歴長・パディング等)

末尾3つ(類似度・履歴長・パディング等) 末尾3チャネルは そのままのスケールで保持 したい補助特徴の想定(例:similarity_max, history_len_norm_seq, pad_flag)。

  • トレインから平均・標準偏差を算出(分布リーク防止)
Xtr_num = Xtr_main[:, :, keep_numeric_idx].reshape(-1, keep_numeric_idx.size)
means = Xtr_num.mean(axis=0)
stds  = Xtr_num.std(axis=0); stds[stds == 0] = 1.0

keep_numeric_idx:数値列だけを選ぶインデックス(カテゴリ/埋め込み列は除外)。reshape(-1, d):時系列次元をフラット化して 全時点の分布 で平均・分散を推定。
std==0 を 1 に補正:定数列によるゼロ割りを防止。

  • ブロードキャストで高速インプレース標準化
Xtr_view = Xtr_main[:, :, keep_numeric_idx]
Xtr_view -= means.reshape(1, 1, -1)
Xtr_view /= stds.reshape(1, 1, -1)

reshape(1,1,-1)(N, S, Dnum) に自然に放送可能な形へ。
代入演算(-= /=)で ビューに直接反映 → 余分なコピーを避け高速。

  • 検証・テストにも同じ統計量を適用
def scale_inplace(X, keep_idx, means, stds): ...
scale_inplace(X_val,  keep_numeric_idx, means, stds)
scale_inplace(X_test, keep_numeric_idx, means, stds)

トレインで得た means/stds を固定して適用(将来情報の混入を回避)。
X[:, :, : -TAIL] のうち数値列のみを対象に標準化。

  • 最終シーケンスの組み立て(数値のみ+TAILを結合)
keep_for_seq = keep_numeric_idx.astype(np.int64)
def build_seq(X):
    X_main = X[:, :, : -TAIL]
    X_tail = X[:, :, -TAIL:]
    X_main_kept = np.take(X_main, keep_for_seq, axis=2)
    return np.concatenate([X_main_kept, X_tail], axis=2).astype(np.float32)

np.take(..., axis=2)チャネル軸で必要な数値特徴だけを抽出(順序を保持)。
スケール済み数値非スケールのTAIL を連結し、学習用テンソルを確定。

  • 最終特徴名と統計量の保存(再現性の担保)
numeric_cols_final = [feature_columns[i] for i in keep_for_seq.tolist()]
extra_cols = ["similarity_max", "history_len_norm_seq", "pad_flag"]
feature_names_seq = numeric_cols_final + extra_cols
# → final_feature_names_seq.json

scale_stats = {
    "keep_numeric_idx": ...,
    "means": ...,
    "stds": ...,
    "TAIL": 3,
    "keep_for_seq": ...
}
# → scale_stats.json

モデル入出力とログ解析で重要な 列順・列名final_feature_names_seq.json に保存。
インデックス・平均・標準偏差・TAIL などのメタscale_stats.json に保存し、推論・再学習で同一処理を再現可能に。

補足(細かな構文ポイント)

  • : -TAIL / -TAIL:末尾からのスライスでチャネルを二分。
  • インプレース演算 は一時配列の生成を避け、メモリ帯域の節約速度向上に寄与。
  • 標準化は 数値列だけ。カテゴリ(埋め込み用ID)はスケールせず、そのまま別経路で Embedding に入力する設計。
  • 結果の X_train_seq/X_val_seq/X_test_seqfloat32 で、「スケール済み数値 + 非スケールTAIL」 の構成になっています。

この手順により、リークのない標準化再現性のある特徴順効率的なテンソル構築が実現され、学習と推論の整合性が高まります。

コメント

タイトルとURLをコピーしました