This commit is contained in:
2026-04-25 16:51:07 +09:00
parent 4f6ce49704
commit 956c53ba23
24 changed files with 312 additions and 99952 deletions

View File

@@ -6,6 +6,9 @@ import os
import random
import joblib
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from xgboost import XGBRegressor
from sklearn.preprocessing import StandardScaler
@@ -177,7 +180,9 @@ def train_model(
dataset.append((
features,
measure
measure,
songno,
diff
))
# =====================================================
@@ -205,25 +210,29 @@ def train_model(
]
X_train = np.array(
[x for x, _ in train_dataset],
[x for x, _, _, _ in train_dataset],
dtype=np.float32
)
y_train = np.array(
[y for _, y in train_dataset],
[y for _, y, _, _ in train_dataset],
dtype=np.float32
)
X_valid = np.array(
[x for x, _ in valid_dataset],
[x for x, _, _, _ in valid_dataset],
dtype=np.float32
)
y_valid = np.array(
[y for _, y in valid_dataset],
[y for _, y, _, _ in valid_dataset],
dtype=np.float32
)
valid_info = [
(s, d) for _, _, s, d in valid_dataset
]
print(f"Train Size: {len(X_train)}")
print(f"Valid Size: {len(X_valid)}")
print(f"Feature Count: {len(feature_names)}")
@@ -314,6 +323,73 @@ def train_model(
for name, score in pairs:
print(f"{name:25} {score:.6f}")
# =====================================================
# save validate.json
# =====================================================
validate_details = []
for i in range(len(y_valid)):
actual = float(y_valid[i])
predicted = float(pred[i])
songno, diff = valid_info[i]
validate_details.append({
"songno": songno,
"diff": diff,
"actual": actual,
"predicted": predicted,
"error": actual - predicted
})
# 에러 절댓값 기준 정렬
validate_details.sort(key=lambda x: abs(x["error"]), reverse=True)
validate_result = {
"summary": {
"total_compared": len(y_valid),
"average_absolute_error": float(mae),
"accuracy": float(accuracy),
"timestamp": "now",
"script_used": "train/train_xgboost.py"
},
"details": validate_details
}
validate_path = os.path.join(working_dir, "validate.json")
with open(validate_path, "w", encoding="utf-8") as f:
json.dump(validate_result, f, indent=2, ensure_ascii=False)
print(f"Validation result saved: {validate_path}")
# =====================================================
# save validate.png
# =====================================================
try:
plt.switch_backend('Agg') # GUI 없는 환경 대응
df_plot = pd.DataFrame(validate_details)
df_plot['abs_error'] = df_plot['error'].abs()
df_plot = df_plot.sort_values('abs_error', ascending=False).reset_index(drop=True)
plt.figure(figsize=(12, 6))
sns.scatterplot(data=df_plot, x=df_plot.index, y='abs_error', alpha=0.6, s=20, color='darkorange')
plt.axhline(0.2, color='green', linestyle='--', linewidth=0.8, alpha=0.5, label='Target (0.2)')
plt.axhline(0.5, color='blue', linestyle='--', linewidth=0.8, alpha=0.5)
plt.axhline(1.0, color='red', linestyle='--', linewidth=0.8, alpha=0.5)
plt.ylim(0, max(3.5, df_plot['abs_error'].max() + 0.5))
plt.title(f'Validation Absolute Error - {os.path.basename(working_dir)}', fontsize=14)
plt.xlabel('Samples (Sorted by Error Magnitude)', fontsize=12)
plt.ylabel('Absolute Error', fontsize=12)
plt.grid(True, axis='y', alpha=0.3)
plot_path = os.path.join(working_dir, "validate.png")
plt.savefig(plot_path)
plt.close()
print(f"Validation plot saved: {plot_path}")
except Exception as e:
print(f"[WARN] Failed to create validation plot: {e}")
# =====================================================
# save
# =====================================================
@@ -366,4 +442,4 @@ if __name__ == "__main__":
train_model(
args.workingDir,
args.dataDir
)
)