This commit is contained in:
2026-04-24 13:43:00 +09:00
parent c4d8c8145a
commit be4c383b6f
23 changed files with 533 additions and 1833 deletions

67
script/train.py Normal file
View File

@@ -0,0 +1,67 @@
import pandas as pd
import json, os, sys, joblib
import numpy as np
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.model_selection import train_test_split
def train(script_dir, working_dir, data_dir, train_count, val_count, margin):
features = pd.read_json(os.path.join(working_dir, 'features.json'))
measures = pd.read_csv(os.path.join(data_dir, 'measure.csv'))
features['songno'] = features['songno'].astype(int)
measures['songno'] = measures['songno'].astype(int)
measures['diff'] = measures['diff'].replace('ura', 'edit')
df = pd.merge(features, measures, on=['songno', 'diff'])
with open(os.path.join(script_dir, 'factor.json'), 'r') as f:
weights = json.load(f)
for col in ['physical_density', 'stamina_requirement', 'pattern_complexity', 'rhythmic_complexity', 'reading_gimmick']:
df[col] = df[col] * weights.get(col, 1.0)
X_cols = ['physical_density', 'stamina_requirement', 'pattern_complexity', 'rhythmic_complexity', 'reading_gimmick']
model_path = os.path.join(working_dir, 'model.pkl')
model = joblib.load(model_path) if os.path.exists(model_path) else GradientBoostingRegressor(n_estimators=200, learning_rate=0.05, max_depth=3)
iteration = 1
while True:
# 3. 데이터 샘플링
df_sample = df.sample(n=int(train_count) + int(val_count))
train_df, val_df = train_test_split(df_sample, test_size=int(val_count))
X_train, y_train = train_df[X_cols], train_df['상수']
X_val, y_val = val_df[X_cols], val_df['상수']
# 4. 학습 (최대 10회)
for attempt in range(1, 11):
model.fit(X_train, y_train)
train_err = np.max(np.abs(np.clip(model.predict(X_train), 1.0, 12.0) - y_train))
print(f"Iteration {iteration} - Attempt {attempt} - Train Error: {train_err:.4f}")
if train_err <= float(margin): break
model.set_params(n_estimators=model.n_estimators + 50)
# 5. 검증
pred_val = np.clip(model.predict(X_val), 1.0, 12.0)
val_errors = np.abs(pred_val - y_val)
# 6. 검증 실패 시 재시도
if np.any(val_errors > float(margin)):
print(f"Validation failed (max error: {np.max(val_errors):.4f}). Retrying...")
iteration += 1
continue
val_result = pd.DataFrame({
'songno': val_df['songno'],
'difficulty': val_df['diff'],
'measure': y_val,
'predicted_measure': pred_val,
'error': val_errors
})
val_result.to_csv(os.path.join(working_dir, f'validate_result_{iteration}.csv'), index=False)
val_result.to_csv(os.path.join(working_dir, 'validate_result.csv'), index=False)
break
joblib.dump(model, model_path)
if __name__ == "__main__":
train(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], sys.argv[6])