Compare commits
7 Commits
be4c383b6f
...
4f6ce49704
| Author | SHA1 | Date | |
|---|---|---|---|
| 4f6ce49704 | |||
| df82515a33 | |||
| da4201fb20 | |||
| 8a8c0c9713 | |||
| 52aaa4d1f6 | |||
| 0fe1e355a7 | |||
| cd38fd49e2 |
@@ -1,21 +1,20 @@
|
||||
# fumen-analyze 최종 진행 리포트 (Final)
|
||||
# fumen-analyze 프로젝트 상태 보고 (Current)
|
||||
|
||||
## 1. 모델 성능 요약
|
||||
- **최종 MAE**: **0.1758**
|
||||
- **모델 유형**: `GradientBoostingRegressor` (Warm Start + Precision Tuning)
|
||||
- **최종 Estimators**: 1,600개
|
||||
- **성과**: 30개 이상의 피처를 기반으로 채보의 미세한 난이도 차이를 성공적으로 학습. 이상치(에러 > 1.0)를 배제한 정밀 튜닝으로 안정성 확보.
|
||||
## 1. 모델 아키텍처 전환
|
||||
- **이전**: `GradientBoostingRegressor` (scikit-learn)
|
||||
- **현재**: `XGBRegressor` (XGBoost)
|
||||
- **변경 사유**: 대규모 데이터셋에 대한 학습 속도 향상 및 하이퍼파라미터 튜닝의 유연성 확보.
|
||||
|
||||
## 2. 핵심 피처 가중치 (추정)
|
||||
- **밀도**: Global NPS, Peak NPS (1s/2s)
|
||||
- **리듬**: 엇박 비율(Triplets), 리듬 표준편차, 가속도
|
||||
- **패턴**: 손 배치 전환(Hand-switching), 3노트 단위 패턴 복잡도
|
||||
- **기믹**: SV/BPM 변화 빈도 및 변동성
|
||||
## 2. 성능 지표 (목표치)
|
||||
- **목표 MAE**: **0.15 이하** (현재 약 0.17~0.18 추정)
|
||||
- **허용 오차 범위**: ±0.1 (상수 단위 기준)
|
||||
- **성과**: 리듬 복잡도 및 순간 밀도 피처를 도입하여 10성급 고난이도 채보 간의 미세한 서열(상수 11.0~12.0)을 유의미하게 구분 중.
|
||||
|
||||
## 3. 사용 안내
|
||||
- **학습 업데이트**: `./run_pipeline.sh` (현재 정밀 튜닝 모드 설정됨)
|
||||
- **상수 예측**: `./run_predict.sh <TJA_Path> [diff]`
|
||||
- **문서 참조**: `GUIDE.md`
|
||||
## 3. 핵심 업데이트 사항
|
||||
- **BPM/Scroll 변화 감지**: `#BPMCHANGE` 뿐만 아니라 `#SCROLL` 변화를 결합한 시각적 속도 변화 피처 추가.
|
||||
- **색상 복잡도 가중치**: 노트 간 간격이 좁을수록 더 높은 난이도 가중치를 부여하는 $1/\Delta t^2$ 로직 적용.
|
||||
- **지속 학습 지원**: `CONTINUE_TRAINING` 옵션을 통해 기존 모델에 추가 데이터를 점진적으로 학습 가능.
|
||||
|
||||
## 4. 최종 결론
|
||||
현재 모델은 10성급 고난이도 곡들 사이의 미세한 '상수' 서열을 0.1~0.2 오차 범위 내에서 예측할 수 있는 수준에 도달했습니다. 추가 데이터 확보 시 0.1 미만으로의 진입이 충분히 가능합니다.
|
||||
## 4. 향후 과제
|
||||
- `rhythm_complexity` 로직의 정교화 (비정형 박자 감지 강화).
|
||||
- `measure.csv` 데이터셋 확충을 통한 과적합 방지 및 일반화 성능 향상.
|
||||
|
||||
@@ -1,36 +1,23 @@
|
||||
# TJA 난이도 산정 핵심 요소 (Technical Factors)
|
||||
# TJA 난이도 산정 피처 (Features)
|
||||
|
||||
'상수' 산출을 위해 채보에서 추출해야 하는 5개 핵심 차원과 세부 지표입니다.
|
||||
`preprocess/featurize.ts`에서 추출되는 8가지 핵심 피처입니다.
|
||||
|
||||
## 1. 물리적 밀도 (Physical Density)
|
||||
물리적인 타격 속도와 관련된 지표입니다.
|
||||
- **Global NPS**: `총 노트 수 / 총 연주 시간`. 곡의 전반적인 속도 체급.
|
||||
- **Peak NPS (Sliding Window)**: 1초~2초 단위 윈도우에서 추출한 최대 NPS. 순간 폭타의 한계치.
|
||||
- **Density Variance**: NPS의 표준 편차. 곡이 얼마나 균일한지 또는 급격한지 측정.
|
||||
## 1. 양적 지표
|
||||
- **note_count**: 총 노트 수. 곡의 길이에 따른 절대적인 노트 양.
|
||||
|
||||
## 2. 지구력 요구량 (Stamina Requirement)
|
||||
지치지 않고 집중력을 유지해야 하는 정도입니다.
|
||||
- **Longest Stream Count**: 쉼표(예: 8분음표 이상의 간격) 없이 이어지는 최대 노트 개수.
|
||||
- **Stream Density Ratio**: 전체 곡 시간 대비 스트림(연타) 구간이 차지하는 비중.
|
||||
- **Rest Interval Analysis**: 회복 가능한 구간의 배치와 빈도.
|
||||
## 2. 밀도 지표
|
||||
- **density_avg**: 평균 NPS. `(총 노트 수 / 곡의 총 소요 시간) * 1000`.
|
||||
- **density_peak**: 순간 최대 밀도. 임의의 노트를 기준으로 1초 이내에 포함된 최대 노트 수.
|
||||
|
||||
## 3. 배치 복잡도 (Pattern Complexity)
|
||||
인지적 부하와 손 배치(Hand-switching)의 어려움입니다.
|
||||
- **Color Transition Ratio**: `색상 전환(d↔k) 횟수 / 총 노트 수`. 전환이 많을수록 인지 부하 증가.
|
||||
- **Hand-Switching Index**: 홀수(3, 5, 7) 및 짝수(2, 4) 연타의 혼합도. 기준 손이 강제로 바뀌는 빈도.
|
||||
- **Complex Pattern Detection**: 비정형 패턴(예: ddkdk, kkkdk 등)의 출현 빈도.
|
||||
## 3. 속도 변화 지표
|
||||
- **bpm_avg**: 노트별 BPM의 단순 산술 평균.
|
||||
- **bpm_change**: BPM 변동 횟수. 인접한 두 노트 간 BPM 차이가 1.5 이상일 때 카운트.
|
||||
- **scroll_change**: 시각적 속도(`BPM * Scroll`) 변동 횟수. 차이가 1.5 이상일 때 카운트.
|
||||
|
||||
## 4. 리듬 복잡도 (Rhythmic Complexity)
|
||||
정확도(98%) 달성을 방해하는 타이밍 요소입니다.
|
||||
- **Quantization Diversity**: 사용된 음표 단위(1/16, 1/12, 1/24, 1/48 등)의 종류와 혼합 빈도.
|
||||
- **Off-beat Ratio**: 정박(1/4, 1/8)을 벗어난 엇박 노지의 비율.
|
||||
- **Rhythmic Entropy**: 노트 간 시간 간격의 불규칙성 정도.
|
||||
## 4. 구조적 복잡도
|
||||
- **rhythm_complexity**: 리듬의 정규성. 인접한 노트 간 시간 간격의 비율이 2의 거듭제곱(1, 0.5, 2 등)에 가까운 횟수를 카운트.
|
||||
- *참고: 현재 코드는 정규 리듬일 때 증가하며, 문서와 실제 로직의 방향성이 반대일 수 있음.*
|
||||
- **color_complexity**: 색상 배치 복잡도. 인접 노트의 색상(Don/Ka)이 바뀔 때, 그 간격의 제곱의 역수($1/\Delta t^2$)를 누적. 간격이 좁을수록 수치가 급격히 상승.
|
||||
|
||||
## 5. 가독성 및 기믹 (Reading & Gimmicks)
|
||||
시각적인 반응 속도와 암기 요소를 측정합니다.
|
||||
- **Scroll Velocity (SV) Variance**: `#SCROLL` 변화의 진폭과 빈도.
|
||||
- **BPM Fluctuation**: `#BPMCHANGE`를 통한 급격한 속도 변화 및 정지(#DELAY).
|
||||
- **Visual Overlap**: 저속 구간에서의 노트 겹침이나 고속 구간의 반응 한계.
|
||||
|
||||
## 상수 추정 가중치 (Proposed)
|
||||
`Constant ∝ (Peak_NPS * 0.4) + (Complexity * 0.3) + (Stamina * 0.2) + (Reading * 0.1)`
|
||||
## 주의사항
|
||||
- `color_complexity`는 수치의 범위가 매우 클 수 있으므로 학습 시 `StandardScaler`를 통한 정규화가 필수적입니다.
|
||||
|
||||
@@ -2,16 +2,20 @@
|
||||
|
||||
## Technical Stack
|
||||
- **Runtime**: [Bun](https://bun.sh/)
|
||||
- **Language**: TypeScript
|
||||
- **Library**: [tja](https://www.npmjs.com/package/tja) (TJA parser)
|
||||
- **Language**: TypeScript (Preprocessing), Python (Machine Learning)
|
||||
- **ML Library**: [XGBoost](https://xgboost.readthedocs.io/), [scikit-learn](https://scikit-learn.org/)
|
||||
- **TJA Parser**: [tja-parser](https://www.npmjs.com/package/tja-parser)
|
||||
|
||||
## Key Documents
|
||||
- `.gemini/tja-spec.md`: Rigorous TJA format specification.
|
||||
- `tja-format.mediawiki`: Original source document.
|
||||
- `measure.csv`: Dataset with columns `상수`, `songno`, `diff`.
|
||||
## Key Directories
|
||||
- `preprocess/`: TJA 파싱 및 피처 추출 로직 (TypeScript)
|
||||
- `script/`: 전처리, 학습 제어 스크립트
|
||||
- `train/`: XGBoost 학습 엔진 (Python)
|
||||
- `predict/`: 추론 엔진 (Python)
|
||||
- `datas/tja/`: 원본 TJA 데이터셋
|
||||
- `datas/measure.csv`: 정답지 (상수 데이터)
|
||||
- `test/`: 학습 결과물 (model.pkl, scaler.pkl, features.json)
|
||||
|
||||
## Models (model/)
|
||||
- `constant_predictor.py`: DNN 기반 상수 예측 모델.
|
||||
|
||||
## Library Usage (tja)
|
||||
...
|
||||
## Data Flow
|
||||
1. `datas/tja/*.tja` → `script/preprocess.ts` → `test/features.json`
|
||||
2. `test/features.json` + `datas/measure.csv` → `train/train_xgboost.py` → `test/model.pkl`
|
||||
3. `test/model.pkl` + `test/features.json` → `predict/predict_xgboost.py` → Result
|
||||
|
||||
@@ -1,13 +1,35 @@
|
||||
# 파이프라인 실행 규칙
|
||||
# 파이프라인 실행 가이드
|
||||
|
||||
모든 경로는 실행 시점에 인자로 지정하여 관리합니다.
|
||||
모든 실행은 프로젝트 루트 디렉토리에서 수행합니다.
|
||||
|
||||
## 1. 학습 파이프라인 (`run_train.sh`)
|
||||
- **인자 1 (TJA_DIR)**: 학습용 TJA 채보가 저장된 폴더 (예: `sample/training`)
|
||||
- **인자 2 (MODEL_PATH)**: 모델이 저장될 경로 (예: `output/model/v2_constant`)
|
||||
- **인자 3 (DATASET_DIR)**: 데이터셋이 저장될 폴더 (예: `output/dataset`)
|
||||
## 1. 전처리 (Feature Extraction)
|
||||
TJA 파일들로부터 피처를 추출하여 `features.json`을 생성합니다.
|
||||
```bash
|
||||
bun run script/preprocess.ts --workingDir ./test --dataDir ./datas
|
||||
```
|
||||
- **--workingDir**: 결과물(`features.json`)이 저장될 폴더.
|
||||
- **--dataDir**: 원본 데이터(`tja/` 폴더)가 위치한 폴더.
|
||||
|
||||
## 2. 예측 파이프라인 (`run_predict.sh`)
|
||||
- **인자 1 (MODEL_PATH)**: 추론에 사용할 모델 경로
|
||||
- **인자 2 (TJA_DIR)**: 예측할 TJA 채보가 모여있는 폴더
|
||||
- **인자 3 (OUTPUT_DIR)**: 결과가 저장될 폴더
|
||||
## 2. 모델 학습 (Training)
|
||||
추출된 피처와 상수 데이터를 사용하여 XGBoost 모델을 학습시킵니다.
|
||||
```bash
|
||||
python3 train/train_xgboost.py \
|
||||
--workingDir ./test \
|
||||
--dataDir ./datas \
|
||||
--trainSize 1000 \
|
||||
--validSize 200
|
||||
```
|
||||
- **--trainSize / --validSize**: 학습 및 검증에 사용할 데이터 수.
|
||||
|
||||
## 3. 난이도 예측 (Inference)
|
||||
특정 곡 번호(`songno`)에 대한 난이도 상수를 예측합니다.
|
||||
```bash
|
||||
python3 predict/predict_xgboost.py --workingDir ./test --songno 1000
|
||||
```
|
||||
- **--songno**: 예측할 곡의 번호 (파일명 기준).
|
||||
|
||||
## 주요 산출물 (in `workingDir`)
|
||||
- `features.json`: 추출된 피처 데이터셋.
|
||||
- `model.pkl`: 학습된 XGBoost 모델 파일.
|
||||
- `scaler.pkl`: 피처 정규화를 위한 Scaler 객체.
|
||||
- `features.txt`: 학습에 사용된 피처 이름 목록.
|
||||
|
||||
37
.old/compare.ts
Normal file
37
.old/compare.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import path from 'node:path';
|
||||
import measure from './datas/measure.json';
|
||||
import predict from './result.json';
|
||||
import { writeFile, writeFileSync } from 'node:fs';
|
||||
|
||||
const ob: any[] = [];
|
||||
|
||||
let max = 0;
|
||||
let min = Infinity;
|
||||
predict.forEach((p) => {
|
||||
const songno = path.basename(p.filename, '.tja')
|
||||
const m = measure.find((m) => m.songno.toString() === songno && (
|
||||
p.difficulty_type === "oni" ? m.diff === "oni" :
|
||||
m.diff === "ura"
|
||||
));
|
||||
|
||||
if(m){
|
||||
if(max < p.predicted_measure){
|
||||
max = p.predicted_measure
|
||||
}
|
||||
if(min > p.predicted_measure){
|
||||
min = p.predicted_measure;
|
||||
}
|
||||
ob.push({
|
||||
songno,
|
||||
diff: m.diff,
|
||||
predicted: p.predicted_measure,
|
||||
measure: m.상수,
|
||||
error: p.predicted_measure - m.상수,
|
||||
errorAbs: Math.abs(p.predicted_measure - m.상수)
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
ob.forEach((v) => v.calibrated = ((v.predicted - min) * 11 / (max - min) + 1))
|
||||
|
||||
writeFileSync('./compare.json', JSON.stringify(ob, null, 2))
|
||||
@@ -1,16 +1,23 @@
|
||||
import { parseTja } from './parse';
|
||||
import { factorize } from './factorize';
|
||||
import { readdirSync, readFileSync, writeFileSync, existsSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
import { readdirSync, readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
|
||||
import { join, dirname } from 'path';
|
||||
import iconv from 'iconv-lite';
|
||||
|
||||
const [,, workingDir, dataDir] = process.argv;
|
||||
|
||||
if (existsSync(join(workingDir, 'features.json'))) {
|
||||
console.log('features.json already exists. Skipping extraction.');
|
||||
const featurePath = join(workingDir, 'factors.json');
|
||||
|
||||
if (existsSync(featurePath)) {
|
||||
console.log('factors.json already exists. Skipping extraction.');
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
// 작업 디렉토리 존재 확인 및 생성
|
||||
if (!existsSync(workingDir)) {
|
||||
mkdirSync(workingDir, { recursive: true });
|
||||
}
|
||||
|
||||
const tjaDir = join(dataDir, 'tja');
|
||||
const results: any[] = [];
|
||||
|
||||
@@ -38,5 +45,5 @@ for (const file of readdirSync(tjaDir)) {
|
||||
results.push({ songno, diff: diff === 'oni' ? 'oni' : 'ura', ...factors });
|
||||
}
|
||||
}
|
||||
writeFileSync(join(workingDir, 'features.json'), JSON.stringify(results, null, 2));
|
||||
console.log(`Features extracted to ${workingDir}/features.json`);
|
||||
writeFileSync(featurePath, JSON.stringify(results, null, 2));
|
||||
console.log(`Features extracted to ${featurePath}`);
|
||||
71
.old/predict-all.ts
Normal file
71
.old/predict-all.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
import { readdirSync, writeFileSync, existsSync } from 'fs';
|
||||
import { join, extname, dirname } from 'path';
|
||||
import { execSync } from 'child_process';
|
||||
|
||||
async function predictAll() {
|
||||
const args = process.argv.slice(2);
|
||||
if (args.length < 3) {
|
||||
console.log("Usage: bun script/predict-all.ts <workingDir> <tjaDir> <outputPath>");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const workingDir = args[0];
|
||||
const tjaDir = args[1];
|
||||
const outputPath = args[2];
|
||||
const targetDifficulties = ['oni', 'edit'];
|
||||
|
||||
if (!existsSync(tjaDir)) {
|
||||
console.error(`❌ Directory not found: ${tjaDir}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const files = readdirSync(tjaDir).filter(file => extname(file).toLowerCase() === '.tja');
|
||||
console.log(`📂 Found ${files.length} TJA files. Processing Oni & Edit...`);
|
||||
|
||||
const finalResults: any[] = [];
|
||||
|
||||
let i = 0;
|
||||
for (const file of files) {
|
||||
const fullPath = join(tjaDir, file);
|
||||
|
||||
for (const diff of targetDifficulties) {
|
||||
try {
|
||||
// 개별 예측 실행
|
||||
const cmd = `bun script/predict.ts "${workingDir}" "${fullPath}" "${diff}"`;
|
||||
const output = execSync(cmd, { stdio: ['pipe', 'pipe', 'ignore'] }).toString();
|
||||
|
||||
const match = output.match(/(?:Prediction|Predicted Difficulty):\s*(\d+\.\d+)/);
|
||||
|
||||
if (match) {
|
||||
const value = parseFloat(match[1]);
|
||||
console.log(`✅ [${file}] ${diff.toUpperCase()}: ${value}`);
|
||||
finalResults.push({
|
||||
filename: file,
|
||||
difficulty_type: diff,
|
||||
predicted_measure: value
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
// 해당 난이도가 없는 경우 조용히 넘어감
|
||||
}
|
||||
}
|
||||
i++;
|
||||
console.log(`${i}/${files.length}`)
|
||||
}
|
||||
|
||||
// 결과 저장 (확장자에 따라 분기)
|
||||
if (outputPath.endsWith('.json')) {
|
||||
writeFileSync(outputPath, JSON.stringify(finalResults, null, 2));
|
||||
} else {
|
||||
// CSV 저장 (기본값)
|
||||
const csvContent = [
|
||||
"filename,difficulty,predicted_measure",
|
||||
...finalResults.map(r => `"${r.filename}",${r.difficulty_type},${r.predicted_measure}`)
|
||||
].join('\n');
|
||||
writeFileSync(outputPath, csvContent);
|
||||
}
|
||||
|
||||
console.log(`\n✨ Prediction complete! Results saved to: ${outputPath}`);
|
||||
}
|
||||
|
||||
predictAll();
|
||||
15
.old/predict.sh
Executable file
15
.old/predict.sh
Executable file
@@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Arguments: working_dir tja_path difficulty
|
||||
WORKING_DIR=${1:-"."}
|
||||
TJA_PATH=${2}
|
||||
DIFFICULTY=${3:-"oni"}
|
||||
|
||||
if [ -z "$TJA_PATH" ]; then
|
||||
echo "Usage: ./predict.sh <working_dir> <tja_path> [difficulty: oni|edit]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Running prediction for $TJA_PATH..."
|
||||
# script_dir 인자가 사라졌으므로, 예측 스크립트 실행 시 인자 순서에 맞춰 실행
|
||||
bun script/predict.ts "$WORKING_DIR" "$TJA_PATH" "$DIFFICULTY"
|
||||
97
.old/predict.ts
Normal file
97
.old/predict.ts
Normal file
@@ -0,0 +1,97 @@
|
||||
import { parseTja } from './parse';
|
||||
import { factorize } from './factorize';
|
||||
import { join } from 'path';
|
||||
import { readFileSync, writeFileSync, unlinkSync, existsSync } from 'fs';
|
||||
import { execSync } from 'child_process';
|
||||
|
||||
/**
|
||||
* 예측 엔진: 모델 실행을 위해 Python 환경을 호출
|
||||
*/
|
||||
function runInference(workingDir: string, factors: Record<string, number>): number {
|
||||
const tempFactorPath = join(workingDir, `temp_feat_${Date.now()}.json`);
|
||||
writeFileSync(tempFactorPath, JSON.stringify(factors));
|
||||
|
||||
const pythonScript = `
|
||||
import json, torch, sys
|
||||
import numpy as np
|
||||
import torch.nn as nn
|
||||
|
||||
# 모델 정의 (학습된 구조와 동일해야 함)
|
||||
class DifficultyNet(nn.Module):
|
||||
def __init__(self, input_dim):
|
||||
super().__init__()
|
||||
self.net = nn.Sequential(
|
||||
nn.Linear(input_dim, 128),
|
||||
nn.BatchNorm1d(128),
|
||||
nn.ReLU(),
|
||||
nn.Dropout(0.4),
|
||||
nn.Linear(128, 64),
|
||||
nn.ReLU(),
|
||||
nn.Dropout(0.3),
|
||||
nn.Linear(64, 32),
|
||||
nn.ReLU(),
|
||||
nn.Linear(32, 1),
|
||||
nn.Sigmoid()
|
||||
)
|
||||
def forward(self, x): return self.net(x)
|
||||
|
||||
def predict():
|
||||
try:
|
||||
with open('${tempFactorPath}', 'r') as f: factors = json.load(f)
|
||||
with open('${join(workingDir, 'scaler.json')}', 'r') as f: s = json.load(f)
|
||||
|
||||
X = np.array([[factors[col] for col in s['cols']]], dtype=np.float32)
|
||||
|
||||
# 정규화 (Robust/Standard 지원)
|
||||
if 'center' in s: X_scaled = (X - np.array(s['center'])) / np.array(s['scale'])
|
||||
else: X_scaled = (X - np.array(s.get('mean', 0))) / np.array(s.get('std', s.get('scale', 1)))
|
||||
|
||||
model = DifficultyNet(len(s['cols']))
|
||||
model.load_state_dict(torch.load('${join(workingDir, 'model.pth')}', map_location='cpu'))
|
||||
model.eval()
|
||||
|
||||
with torch.no_grad():
|
||||
input_tensor = torch.from_numpy(X_scaled).float()
|
||||
pred = model(input_tensor) * 12 + 0.5
|
||||
print(float(pred.item()))
|
||||
except Exception as e:
|
||||
print(f"ERROR: {e}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__": predict()
|
||||
`;
|
||||
|
||||
const tempPyPath = join(workingDir, `inference_${Date.now()}.py`);
|
||||
writeFileSync(tempPyPath, pythonScript);
|
||||
|
||||
try {
|
||||
const result = execSync(`python3 ${tempPyPath}`).toString().trim();
|
||||
return parseFloat(result);
|
||||
} finally {
|
||||
if (existsSync(tempFactorPath)) unlinkSync(tempFactorPath);
|
||||
if (existsSync(tempPyPath)) unlinkSync(tempPyPath);
|
||||
}
|
||||
}
|
||||
|
||||
function main() {
|
||||
const [workingDir, tjaPath, difficulty = 'oni'] = process.argv.slice(2);
|
||||
|
||||
if (!workingDir || !tjaPath) {
|
||||
console.log("Usage: bun run script/predict.ts <workingDir> <tjaPath> [difficulty]");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const tjaContent = readFileSync(tjaPath, 'utf-8');
|
||||
const parsed = parseTja(tjaContent);
|
||||
const chart = parsed[difficulty.toLowerCase() as 'oni' | 'edit'];
|
||||
|
||||
if (!chart) {
|
||||
console.error(`Error: Difficulty '${difficulty}' not found.`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const score = runInference(workingDir, factorize(chart));
|
||||
console.log(`\n🎯 Predicted Difficulty: ${score.toFixed(2)}`);
|
||||
}
|
||||
|
||||
main();
|
||||
70
.old/spec.md
Normal file
70
.old/spec.md
Normal file
@@ -0,0 +1,70 @@
|
||||
# 학습
|
||||
## CLI
|
||||
- cli로 학습할 수 있는 쉘 스크립트를 작성한다.
|
||||
- argument
|
||||
- script_dir
|
||||
- working_dir
|
||||
- data_dir
|
||||
- train_data_count = 100
|
||||
- validate_data_count = 20
|
||||
- margin = 0.5
|
||||
- validate_iterations = 5
|
||||
|
||||
## 학습 모델
|
||||
- **추천:** PyTorch 기반의 **Deep MLP** (Dropout 및 Weight Decay 필수 적용)
|
||||
- **과적합 방지 전략:**
|
||||
- **Dropout (0.3 ~ 0.5):** 학습 시 뉴런을 의도적으로 꺼서 특정 데이터 암기를 방지한다.
|
||||
- **L2 Regularization (Weight Decay):** 가중치가 비정상적으로 커지는 것을 막는다.
|
||||
- **Output Mapping:** 최종 출력에 `Sigmoid`를 걸고 (y * 11) + 1을 적용해 [1, 12] 범위를 강제한다.
|
||||
|
||||
## 학습 과정
|
||||
1. `{data_dir}/tja`의 tja를 파싱한다. (`{script_dir}/parse.ts`)
|
||||
2. `oni`와 `edit` course를 factorize하여 `{working_dir}/factors.json`에 저장한다.
|
||||
- 이미 존재하면 생략하되, Factor 로직 수정 시 삭제 후 재실행한다.
|
||||
3. 데이터 표준화(Standardization)를 위한 스케일링 파라미터를 계산하고 `{working_dir}/scaler.json`에 저장한다.
|
||||
4. **학습 단계:** 전체 데이터 중 `train_data_count`만큼 데이터를 랜덤하게 추출하여 학습을 진행한다.
|
||||
- `edit` 코스는 `ura`와 매칭하여 오차를 계산한다.
|
||||
- 모델이 충분히 수렴할 때까지 학습을 수행하며, 기존 모델 존재 시 가중치를 로드하여 업데이트한다.
|
||||
5. **검증 단계:** 학습이 완료된 모델을 대상으로 아래 과정을 수행한다.
|
||||
- `validate_data_count`만큼의 데이터를 랜덤하게 추출하여 오차를 계산하고 `validate_result_{n}.csv`에 저장한다.
|
||||
- 이 과정을 `validate_iterations` 횟수만큼 반복한다.
|
||||
- **재시도 조건:** 검증 루프 도중 단 한 번이라도 Mean Absolute Error(MAE)가 `margin`보다 크다면, 즉시 검증을 중단하고 4번(학습 단계)으로 돌아가 데이터를 새로 샘플링하여 재학습한다.
|
||||
6. **성공 및 종료:** 모든 `validate_iterations` 회차에서 MAE가 `margin` 이하일 경우에만 학습 성공으로 간주하고 최종 모델 파일을 저장한다.
|
||||
|
||||
### 유의 사항
|
||||
- 모든 데이터는 `working_dir`에 저장한다.
|
||||
- Apple Silicon 환경에서 `mps` 디바이스를 할당하여 GPU 가속을 사용한다.
|
||||
|
||||
# 예측
|
||||
## CLI
|
||||
- argument: `working_dir`, `tja`, `difficulty` (oni | edit)
|
||||
|
||||
## 예측 과정
|
||||
- 로드된 모델과 학습 시 사용했던 스케일링 파라미터(Mean, Std)를 동일하게 적용하여 예측을 진행한다.
|
||||
|
||||
# Factor
|
||||
## 추천 Factor 세트 (난이도 결정 핵심 지표)
|
||||
1. **density_avg**: 평균 노트 밀도 (총 노트 수 / 곡 길이)
|
||||
2. **density_peak**: 1초당 최대 밀도 (가장 촘촘한 구간의 노트 수)
|
||||
3. **bpm_avg**: 곡의 평균 BPM
|
||||
4. **bpm_change**: BPM 변화율 (BPM 변속의 다양성)
|
||||
5. **note_count**: 총 노트 수
|
||||
6. **complexity**: 동캇 꼬임
|
||||
|
||||
## Factor 계산 로직
|
||||
- **밀도 계열**:
|
||||
- 노트 간 시간 간격을 `delta`라고 할 때, `1 / delta`로 순시 밀도를 구한 뒤 최대값(`peak`)과 평균값(`avg`)을 도출합니다.
|
||||
- **패턴 계열**:
|
||||
- 노트 타입을 배열로 매핑(예: 0=none, 1=don, 2=ka, 3=big_don, 4=big_ka)합니다.
|
||||
- 슬라이딩 윈도우(예: 4~8개 노트)를 사용하여 인접한 노트의 타입 변화가 잦은 구간을 복합 패턴으로 판정(`complex_ratio`)합니다.
|
||||
- **연타 계열**:
|
||||
- `#ROLL` 명령 혹은 특정 시간 내에 입력이 몰려있는 노트를 연타로 간주하여 카운트합니다.
|
||||
|
||||
## 구현 가이드
|
||||
- `factorize.ts`에서 각 곡의 `Course` 데이터를 순회하며 위 지표들을 계산합니다.
|
||||
- 계산된 값은 `Record<string, number>` 형태로 반환하여 학습기에 입력합니다.
|
||||
- 모든 Factor는 이상치(Outlier) 처리를 위해 학습 단계에서 `StandardScaler` 또는 `RobustScaler`를 반드시 거쳐야 합니다.
|
||||
|
||||
# Scripts
|
||||
- `parse.ts`: TJA 문자열을 `Course` 객체로 변환.
|
||||
- `factorize.ts`: `Course`를 입력받아 확장된 `Factor` 세트를 반환.
|
||||
6
.old/t.sh
Executable file
6
.old/t.sh
Executable file
@@ -0,0 +1,6 @@
|
||||
for val in 0.5 0.45 0.4 0.35 0.3 0.25 0.2; do
|
||||
echo "🚀 현재 학습 파라미터: $val (50회 반복 중)"
|
||||
for i in {1..50}; do
|
||||
./train.sh script test datas 1000 200 $val 10
|
||||
done
|
||||
done
|
||||
12620
.old/test/compare.json
Normal file
12620
.old/test/compare.json
Normal file
File diff suppressed because it is too large
Load Diff
16128
.old/test/factors.json
Normal file
16128
.old/test/factors.json
Normal file
File diff suppressed because it is too large
Load Diff
BIN
.old/test/model.pth
Normal file
BIN
.old/test/model.pth
Normal file
Binary file not shown.
7332
.old/test/result.json
Normal file
7332
.old/test/result.json
Normal file
File diff suppressed because it is too large
Load Diff
1
.old/test/scaler.json
Normal file
1
.old/test/scaler.json
Normal file
@@ -0,0 +1 @@
|
||||
{"mean": [630.3327571305099, 5.390975807838123, 11.292999135695766, 173.114216056683, 2.808124459809853, 0.011057130071469854, 4.286084701815039], "std": [211.64659003608378, 1.4301422132137462, 3.1270522447781857, 42.402697977620676, 7.900275348859312, 0.002796230062876389, 15.234164907711529], "cols": ["note_count", "density_avg", "density_peak", "bpm_avg", "bpm_change", "complexity", "scroll_change"]}
|
||||
201
.old/test/validate_result_1.csv
Normal file
201
.old/test/validate_result_1.csv
Normal file
@@ -0,0 +1,201 @@
|
||||
songno,diff,상수,predicted_measure,error
|
||||
828,oni,4.1,4.206385,0.10638513565063512
|
||||
63,oni,6.1,4.832204,1.2677961349487301
|
||||
1216,oni,10.0,9.5192,0.48079967498779297
|
||||
243,oni,11.0,9.915412,1.0845880508422852
|
||||
999,oni,10.8,9.808392,0.9916084289550788
|
||||
32,oni,6.8,6.970789,0.17078895568847674
|
||||
1012,oni,9.7,9.215172,0.48482818603515554
|
||||
959,oni,7.0,7.0853252,0.08532524108886719
|
||||
224,oni,6.8,7.196848,0.39684791564941424
|
||||
349,oni,6.8,6.479022,0.3209779739379881
|
||||
397,oni,7.9,7.942276,0.042276000976562145
|
||||
539,oni,6.0,5.876666,0.12333393096923828
|
||||
1100,oni,3.9,3.809228,0.09077205657958975
|
||||
1269,oni,3.2,2.7388601,0.4611398696899416
|
||||
1214,oni,6.0,6.4056187,0.40561866760253906
|
||||
161,oni,3.0,2.962341,0.0376589298248291
|
||||
193,oni,4.4,4.2237315,0.1762684822082523
|
||||
1002,oni,4.9,4.9559927,0.05599269866943324
|
||||
117,oni,8.0,8.2179575,0.2179574966430664
|
||||
625,oni,5.5,5.444084,0.05591583251953125
|
||||
567,oni,7.1,7.0908155,0.009184455871581676
|
||||
122,oni,1.9,2.9562376,1.056237554550171
|
||||
519,oni,7.3,7.4535465,0.15354652404785174
|
||||
559,oni,5.4,5.4344945,0.03449449539184535
|
||||
417,oni,3.3,3.3136492,0.013649177551269709
|
||||
60,oni,7.9,7.9494324,0.049432373046874645
|
||||
629,oni,7.3,6.906698,0.3933017730712889
|
||||
990,oni,10.9,9.670632,1.2293676376342777
|
||||
91,oni,3.8,3.716854,0.08314590454101545
|
||||
604,oni,1.0,1.1668034,0.16680335998535156
|
||||
166,oni,6.0,5.829277,0.17072296142578125
|
||||
388,oni,9.0,9.137562,0.13756179809570312
|
||||
1073,oni,2.3,2.394328,0.09432811737060565
|
||||
1175,oni,4.5,4.54766,0.047659873962402344
|
||||
1208,oni,4.3,4.2226963,0.07730369567871076
|
||||
367,oni,5.8,6.021642,0.2216422080993654
|
||||
223,oni,8.1,7.3584685,0.7415314674377438
|
||||
308,oni,5.2,4.990783,0.20921678543090838
|
||||
613,oni,3.0,2.9797726,0.020227432250976562
|
||||
1402,oni,5.8,5.8168125,0.01681251525878924
|
||||
1335,oni,4.0,3.8683329,0.1316671371459961
|
||||
882,oni,1.9,1.8341815,0.06581845283508292
|
||||
933,oni,7.1,7.331907,0.23190679550170934
|
||||
1422,oni,5.6,5.7453094,0.14530935287475621
|
||||
430,oni,1.5,1.7298045,0.22980451583862305
|
||||
454,oni,7.7,7.780956,0.0809557914733885
|
||||
887,oni,7.2,7.051265,0.1487352371215822
|
||||
894,oni,1.7,1.6517099,0.04829008579254146
|
||||
719,oni,9.9,9.321081,0.5789188385009769
|
||||
660,oni,6.6,6.25142,0.34857997894287074
|
||||
560,oni,6.0,5.845188,0.15481185913085938
|
||||
1421,oni,8.1,8.032013,0.06798706054687464
|
||||
434,oni,4.1,4.1712093,0.07120933532714879
|
||||
1356,oni,9.4,9.225898,0.1741022109985355
|
||||
262,oni,6.8,6.8975925,0.09759254455566424
|
||||
918,oni,6.4,6.2478523,0.15214767456054723
|
||||
1240,oni,4.2,4.3363075,0.13630752563476545
|
||||
1164,oni,5.4,5.845188,0.44518814086914027
|
||||
962,oni,2.6,3.1786516,0.5786515712738036
|
||||
304,oni,5.6,5.4814534,0.11854658126831019
|
||||
1255,oni,10.4,9.691372,0.708628082275391
|
||||
126,oni,4.6,4.485203,0.11479721069335902
|
||||
842,oni,2.1,1.9751469,0.12485311031341562
|
||||
930,oni,7.1,7.913493,0.8134931564331058
|
||||
775,oni,10.6,9.802061,0.7979389190673825
|
||||
1359,oni,2.2,2.4671395,0.26713948249816877
|
||||
1219,oni,4.4,4.62963,0.229630088806152
|
||||
42,oni,1.1,2.9574435,1.8574434757232665
|
||||
993,oni,10.0,9.799214,0.20078563690185547
|
||||
1059,oni,5.6,5.5380435,0.06195650100707972
|
||||
504,oni,6.1,5.845188,0.254811859130859
|
||||
1282,oni,3.8,4.334233,0.534232807159424
|
||||
1285,oni,2.4,2.4647148,0.06471476554870614
|
||||
720,oni,9.6,9.387812,0.21218833923339808
|
||||
66,oni,5.9,5.845188,0.05481185913085973
|
||||
1377,oni,4.9,4.9466968,0.04669675827026332
|
||||
74,oni,4.5,4.536579,0.036579132080078125
|
||||
85,oni,7.4,7.427013,0.027012920379638317
|
||||
51,oni,3.2,2.998054,0.20194597244262713
|
||||
487,oni,3.5,3.6010914,0.10109138488769531
|
||||
137,oni,6.1,6.0426464,0.05735359191894496
|
||||
649,oni,7.6,7.212104,0.3878961563110348
|
||||
1295,oni,1.3,1.133282,0.16671805381774907
|
||||
257,oni,6.3,6.122114,0.17788581848144513
|
||||
1015,oni,8.7,8.804349,0.10434894561767649
|
||||
127,oni,5.9,5.9468956,0.04689559936523402
|
||||
927,oni,8.9,8.5859165,0.3140834808349613
|
||||
654,oni,4.5,4.328125,0.171875
|
||||
96,oni,8.8,8.476414,0.3235862731933601
|
||||
366,oni,1.5,2.3543668,0.8543667793273926
|
||||
98,oni,3.1,3.4718246,0.37182464599609366
|
||||
1319,oni,8.8,8.910327,0.11032695770263601
|
||||
1330,oni,1.6,2.3295865,0.7295865058898925
|
||||
1369,oni,11.8,11.984631,0.18463058471679616
|
||||
273,oni,3.3,3.53368,0.2336799621582033
|
||||
465,oni,6.9,6.837492,0.06250801086425817
|
||||
1107,oni,6.5,6.6370926,0.13709259033203125
|
||||
431,oni,7.6,7.6814866,0.08148660659790075
|
||||
568,oni,7.5,7.328082,0.17191791534423828
|
||||
738,oni,7.9,7.6613083,0.2386917114257816
|
||||
307,oni,4.1,3.9636607,0.1363392829895016
|
||||
1280,oni,3.9,4.2937455,0.393745517730713
|
||||
1457,oni,5.4,5.485291,0.08529100418090785
|
||||
1314,oni,4.4,4.248893,0.151107215881348
|
||||
1109,oni,6.8,6.6508837,0.1491163253784178
|
||||
1233,oni,4.1,3.903399,0.19660100936889613
|
||||
1234,oni,6.6,6.50439,0.09561023712158168
|
||||
1366,oni,4.7,4.8216677,0.1216676712036131
|
||||
115,oni,2.3,2.2282612,0.07173876762390119
|
||||
947,oni,5.2,5.7635384,0.563538360595703
|
||||
261,oni,7.4,7.6588984,0.2588983535766598
|
||||
458,oni,6.3,6.2306204,0.06937961578369123
|
||||
319,oni,4.4,4.567095,0.16709480285644496
|
||||
1349,oni,6.3,5.845188,0.4548118591308592
|
||||
730,oni,5.1,4.697263,0.40273723602294886
|
||||
226,oni,6.7,6.548712,0.15128822326660174
|
||||
998,oni,5.0,5.098602,0.0986018180847168
|
||||
816,oni,8.2,8.676427,0.47642688751220774
|
||||
1034,oni,5.9,5.8499846,0.050015354156494496
|
||||
1049,oni,9.5,9.412386,0.08761405944824219
|
||||
12,oni,7.5,7.4275417,0.07245826721191406
|
||||
1407,oni,2.8,2.7094536,0.09054641723632795
|
||||
432,oni,6.6,6.7569847,0.15698471069335973
|
||||
406,oni,7.7,7.693886,0.006114196777343928
|
||||
68,oni,9.2,8.833591,0.36640853881835866
|
||||
1000,oni,8.0,8.003995,0.003994941711425781
|
||||
757,oni,10.5,10.120777,0.3792228698730469
|
||||
274,oni,4.3,4.3155355,0.015535545349121271
|
||||
1077,oni,3.9,3.902987,0.0029870033264161044
|
||||
447,oni,4.0,4.0462713,0.046271324157714844
|
||||
577,oni,9.8,9.342824,0.4571760177612312
|
||||
518,oni,11.4,11.650173,0.250173187255859
|
||||
1147,oni,9.1,8.942031,0.15796909332275355
|
||||
614,oni,6.4,5.970553,0.42944707870483434
|
||||
148,oni,9.7,9.349513,0.3504869461059563
|
||||
739,oni,7.1,7.3886776,0.2886775970458988
|
||||
335,oni,9.4,9.030155,0.36984481811523473
|
||||
220,oni,9.3,9.154587,0.1454132080078132
|
||||
566,oni,7.6,7.663207,0.06320705413818395
|
||||
110,oni,10.9,10.075016,0.8249839782714847
|
||||
694,oni,3.5,4.001005,0.5010051727294922
|
||||
1351,oni,9.3,9.762559,0.4625589370727532
|
||||
256,oni,4.9,4.7010565,0.1989435195922855
|
||||
822,oni,7.2,7.1134377,0.08656234741210955
|
||||
1136,oni,2.7,3.2574682,0.5574682235717772
|
||||
898,oni,3.8,4.029142,0.22914190292358416
|
||||
167,oni,7.1,7.137214,0.0372141838073734
|
||||
352,oni,2.5,2.549781,0.049781084060668945
|
||||
675,oni,5.2,5.875123,0.6751230239868162
|
||||
483,oni,7.1,7.3588047,0.2588047027587894
|
||||
626,oni,6.3,6.4142413,0.11424131393432635
|
||||
1036,oni,6.5,6.2653823,0.2346177101135254
|
||||
672,oni,2.4,2.623148,0.22314796447753915
|
||||
1252,oni,4.9,5.0239687,0.12396869659423793
|
||||
639,oni,7.0,6.931817,0.06818294525146484
|
||||
610,oni,6.0,5.80618,0.19381999969482422
|
||||
350,oni,5.5,5.536312,0.036312103271484375
|
||||
906,oni,9.1,9.289001,0.18900146484375036
|
||||
1048,oni,9.4,9.316141,0.08385887145996129
|
||||
310,oni,6.2,6.251908,0.051907825469970525
|
||||
415,oni,1.8,2.84784,1.0478400707244873
|
||||
1354,oni,7.0,7.4809437,0.4809436798095703
|
||||
831,oni,1.2,1.2000558,5.5837631225630346e-05
|
||||
322,oni,7.0,7.011821,0.011820793151855469
|
||||
1196,oni,6.6,6.2691593,0.3308406829833981
|
||||
482,oni,1.8,1.6762199,0.12378005981445317
|
||||
687,oni,4.3,4.1856074,0.11439256668090803
|
||||
1080,oni,8.0,8.098514,0.09851360321044922
|
||||
391,oni,7.4,6.5624576,0.8375424385070804
|
||||
402,oni,6.5,6.452997,0.04700279235839844
|
||||
1218,oni,1.4,1.6566312,0.2566312313079835
|
||||
1110,oni,1.7,2.0302389,0.3302388668060303
|
||||
1304,oni,4.7,4.2533813,0.4466187477111818
|
||||
340,oni,5.2,5.115123,0.08487720489501971
|
||||
1124,oni,2.8,2.4958134,0.30418663024902326
|
||||
1451,oni,5.1,5.1919827,0.09198274612426793
|
||||
1322,oni,7.9,7.850716,0.0492838859558109
|
||||
1382,oni,3.2,3.5220692,0.32206921577453596
|
||||
819,oni,8.6,8.7340145,0.1340145111083988
|
||||
1174,oni,6.2,6.517852,0.3178518295288084
|
||||
1256,oni,6.2,6.084713,0.1152870178222658
|
||||
321,oni,6.3,6.2436576,0.05634241104125959
|
||||
1424,oni,6.4,6.2954216,0.10457839965820348
|
||||
26,oni,4.1,5.500279,1.4002789497375492
|
||||
43,oni,8.1,8.08124,0.018760299682616832
|
||||
480,oni,3.2,3.3859277,0.18592767715454084
|
||||
13,oni,7.2,7.3293734,0.1293733596801756
|
||||
968,oni,7.0,6.966305,0.033695220947265625
|
||||
558,oni,8.5,8.246681,0.25331878662109375
|
||||
795,oni,2.6,2.3113527,0.2886472702026368
|
||||
469,oni,4.5,4.6131096,0.11310958862304688
|
||||
593,oni,10.6,9.9727,0.627299880981445
|
||||
551,oni,4.5,4.616651,0.11665105819702148
|
||||
797,oni,8.8,7.9628973,0.8371026992797859
|
||||
1133,oni,5.7,5.578541,0.12145919799804705
|
||||
929,oni,8.3,8.203068,0.09693222045898509
|
||||
1232,oni,7.2,6.9321103,0.2678896903991701
|
||||
686,oni,8.7,8.237562,0.4624378204345696
|
||||
732,oni,2.4,2.3426375,0.0573624610900878
|
||||
651,oni,7.1,6.437669,0.6623311996459957
|
||||
|
201
.old/test/validate_result_10.csv
Normal file
201
.old/test/validate_result_10.csv
Normal file
@@ -0,0 +1,201 @@
|
||||
songno,diff,상수,predicted_measure,error
|
||||
897,oni,4.5,4.108138,0.3918619155883789
|
||||
1338,oni,10.0,9.66922,0.330780029296875
|
||||
116,oni,2.8,2.8755562,0.07555623054504412
|
||||
1357,oni,8.1,8.198347,0.09834709167480504
|
||||
927,oni,8.9,8.5859165,0.3140834808349613
|
||||
1073,oni,2.3,2.394328,0.09432811737060565
|
||||
1150,oni,4.1,3.2386503,0.8613496780395504
|
||||
1354,oni,7.0,7.4809437,0.4809436798095703
|
||||
477,oni,9.3,9.341164,0.04116363525390554
|
||||
1309,oni,6.5,6.507756,0.007756233215332031
|
||||
495,oni,10.1,9.74755,0.3524499893188473
|
||||
616,oni,5.8,5.77202,0.027980136871337713
|
||||
542,oni,4.2,4.0955725,0.10442752838134783
|
||||
360,oni,9.2,9.504893,0.3048933029174812
|
||||
1076,oni,2.1,2.0889874,0.011012649536132901
|
||||
922,oni,5.7,5.6340675,0.06593246459960955
|
||||
1331,oni,2.2,2.7129545,0.512954521179199
|
||||
89,oni,7.6,7.661222,0.06122198104858434
|
||||
1180,oni,6.5,6.422063,0.07793712615966797
|
||||
22,oni,5.5,5.295011,0.20498895645141602
|
||||
925,oni,5.2,4.9190726,0.28092737197875994
|
||||
1308,oni,8.4,8.65023,0.2502304077148434
|
||||
782,oni,2.7,2.7994647,0.099464702606201
|
||||
630,oni,9.3,8.637385,0.6626146316528327
|
||||
1205,oni,6.1,6.03403,0.06597003936767543
|
||||
797,oni,8.8,7.9628973,0.8371026992797859
|
||||
200,oni,2.3,2.223773,0.0762269973754881
|
||||
279,oni,4.7,4.948142,0.24814205169677717
|
||||
1125,oni,3.6,3.4895444,0.11045560836792001
|
||||
861,oni,4.2,4.4093747,0.2093747138977049
|
||||
469,oni,4.5,4.6131096,0.11310958862304688
|
||||
375,oni,8.7,8.550151,0.14984912872314382
|
||||
949,oni,5.1,4.900959,0.19904098510742152
|
||||
150,oni,6.3,6.2841473,0.015852737426757635
|
||||
971,oni,10.3,9.681194,0.6188056945800788
|
||||
938,oni,5.3,5.209937,0.09006290435790998
|
||||
140,oni,3.3,3.0745137,0.2254863262176512
|
||||
1097,oni,5.1,5.135783,0.035783195495605824
|
||||
483,oni,7.1,7.3588047,0.2588047027587894
|
||||
1426,oni,6.2,5.8172493,0.38275070190429705
|
||||
513,oni,8.4,8.350839,0.0491613388061527
|
||||
107,oni,4.6,4.2985578,0.3014422416687008
|
||||
1327,oni,3.7,4.1225753,0.42257528305053693
|
||||
1342,oni,2.2,2.297284,0.097283887863159
|
||||
1,oni,9.0,9.170969,0.17096900939941406
|
||||
1023,oni,3.4,3.542378,0.14237794876098642
|
||||
438,oni,7.7,7.6389027,0.061097335815429865
|
||||
343,oni,6.4,5.75634,0.6436599731445316
|
||||
1363,oni,4.4,4.349381,0.05061902999877965
|
||||
1425,oni,7.9,7.9018764,0.0018764495849605822
|
||||
1037,oni,9.2,8.873722,0.32627792358398366
|
||||
990,oni,10.9,9.670632,1.2293676376342777
|
||||
774,oni,9.0,9.228863,0.22886276245117188
|
||||
1279,oni,8.4,8.668176,0.2681756973266598
|
||||
1208,oni,4.3,4.2226963,0.07730369567871076
|
||||
924,oni,2.8,2.7967556,0.003244447708129705
|
||||
864,oni,8.1,8.247111,0.14711132049560582
|
||||
1412,oni,6.2,6.3555965,0.15559654235839826
|
||||
608,oni,3.5,3.7859712,0.28597116470336914
|
||||
587,oni,5.2,5.1716547,0.02834529876709002
|
||||
852,oni,6.6,6.5446224,0.05537757873535121
|
||||
1172,oni,11.9,11.048339,0.8516611099243168
|
||||
976,oni,8.7,8.713133,0.013132858276367898
|
||||
1165,oni,7.9,7.9121323,0.012132263183593395
|
||||
3,oni,3.6,2.7672272,0.8327728271484376
|
||||
1295,oni,1.3,1.133282,0.16671805381774907
|
||||
1422,oni,5.6,5.7453094,0.14530935287475621
|
||||
471,oni,7.2,7.574646,0.3746459960937498
|
||||
383,oni,6.1,6.0199423,0.08005771636962855
|
||||
48,oni,5.6,5.4978957,0.10210428237915004
|
||||
381,oni,2.3,2.3997626,0.09976263046264666
|
||||
707,oni,6.4,6.3381214,0.06187858581543004
|
||||
221,oni,6.7,6.725834,0.025833892822265447
|
||||
1181,oni,3.3,3.7384562,0.4384562492370607
|
||||
257,oni,6.3,6.122114,0.17788581848144513
|
||||
445,oni,7.1,7.3118544,0.21185436248779332
|
||||
432,oni,6.6,6.7569847,0.15698471069335973
|
||||
462,oni,7.3,6.9185348,0.3814652442932127
|
||||
595,oni,9.5,9.133109,0.36689090728759766
|
||||
524,oni,8.9,9.106796,0.20679626464843714
|
||||
1001,oni,3.6,3.725905,0.1259049415588378
|
||||
392,oni,9.0,8.880889,0.1191110610961914
|
||||
741,oni,3.5,4.1137867,0.6137866973876953
|
||||
1012,oni,9.7,9.215172,0.48482818603515554
|
||||
1435,oni,5.2,5.0266085,0.1733915328979494
|
||||
36,oni,1.6,1.8594168,0.25941684246063224
|
||||
1024,oni,3.3,3.3856637,0.08566374778747576
|
||||
152,oni,7.9,7.8858066,0.014193439483642933
|
||||
1085,oni,10.0,9.612744,0.3872556686401367
|
||||
397,oni,7.9,7.942276,0.042276000976562145
|
||||
204,oni,2.4,2.719502,0.3195019721984864
|
||||
736,oni,3.5,3.618028,0.11802792549133301
|
||||
644,oni,4.4,4.3509674,0.049032592773437855
|
||||
1349,oni,6.3,5.845188,0.4548118591308592
|
||||
1056,oni,4.7,4.598622,0.10137815475463885
|
||||
727,oni,6.7,6.5126877,0.18731231689453143
|
||||
738,oni,7.9,7.6613083,0.2386917114257816
|
||||
163,oni,5.8,5.5594893,0.24051074981689435
|
||||
11,oni,1.5,2.3513732,0.8513731956481934
|
||||
1374,oni,1.6,2.4462283,0.846228265762329
|
||||
1137,oni,7.1,7.197917,0.09791698455810582
|
||||
284,oni,3.8,3.552865,0.24713497161865217
|
||||
926,oni,3.7,3.3538485,0.3461515426635744
|
||||
931,oni,7.7,7.59026,0.10973997116088885
|
||||
851,oni,10.1,9.837338,0.26266155242919886
|
||||
1274,oni,4.8,4.9417405,0.14174051284790057
|
||||
157,oni,3.3,3.1216764,0.1783235549926756
|
||||
889,oni,4.2,4.020527,0.17947311401367205
|
||||
1029,oni,1.6,1.3594662,0.24053380489349374
|
||||
1061,oni,3.9,3.5892773,0.3107227325439452
|
||||
352,oni,2.5,2.549781,0.049781084060668945
|
||||
141,oni,4.6,4.4628506,0.1371494293212887
|
||||
601,oni,3.5,3.6112447,0.11124467849731445
|
||||
1433,oni,5.5,5.6608744,0.1608743667602539
|
||||
114,oni,7.0,6.7927685,0.2072315216064453
|
||||
198,oni,2.4,2.7392402,0.3392401695251466
|
||||
882,oni,1.9,1.8341815,0.06581845283508292
|
||||
1120,oni,8.2,8.383063,0.18306331634521555
|
||||
1090,oni,4.2,4.540201,0.3402011871337889
|
||||
1282,oni,3.8,4.334233,0.534232807159424
|
||||
1148,oni,3.4,3.4094017,0.009401655197143644
|
||||
1297,oni,9.4,9.196398,0.20360221862793004
|
||||
808,oni,6.2,6.37263,0.1726301193237303
|
||||
345,oni,4.5,3.4398248,1.0601751804351807
|
||||
184,oni,5.2,4.5262094,0.6737906455993654
|
||||
243,oni,11.0,9.915412,1.0845880508422852
|
||||
1020,oni,5.0,5.0843077,0.08430767059326172
|
||||
1188,oni,3.9,4.303166,0.4031659126281739
|
||||
333,oni,1.1,1.4720416,0.3720416069030761
|
||||
94,oni,9.9,9.473127,0.42687263488769567
|
||||
1280,oni,3.9,4.2937455,0.393745517730713
|
||||
1104,oni,9.7,9.212923,0.4870769500732415
|
||||
539,oni,6.0,5.876666,0.12333393096923828
|
||||
928,oni,10.3,9.718238,0.5817621231079109
|
||||
1098,oni,5.9,5.3342714,0.5657285690307621
|
||||
179,oni,10.2,9.583749,0.6162511825561516
|
||||
1134,oni,9.6,9.668004,0.06800403594970739
|
||||
1418,oni,8.0,7.8037148,0.19628524780273438
|
||||
72,oni,7.4,7.6135597,0.21355972290039027
|
||||
83,oni,6.0,6.248336,0.2483358383178711
|
||||
406,oni,7.7,7.693886,0.006114196777343928
|
||||
626,oni,6.3,6.4142413,0.11424131393432635
|
||||
455,oni,5.7,5.487079,0.21292085647583026
|
||||
583,oni,2.9,2.784802,0.11519804000854483
|
||||
500,oni,4.5,4.253699,0.24630117416381836
|
||||
672,oni,2.4,2.623148,0.22314796447753915
|
||||
1216,oni,10.0,9.5192,0.48079967498779297
|
||||
1057,oni,6.4,6.3955936,0.004406356811523793
|
||||
686,oni,8.7,8.237562,0.4624378204345696
|
||||
1369,oni,11.8,11.984631,0.18463058471679616
|
||||
1380,oni,6.9,6.8520164,0.04798355102539098
|
||||
1403,oni,5.0,4.905402,0.09459781646728516
|
||||
496,oni,6.1,6.430355,0.33035507202148473
|
||||
771,oni,3.3,3.3331902,0.03319020271301287
|
||||
571,oni,9.1,9.056726,0.04327354431152308
|
||||
815,oni,8.9,8.579678,0.320322418212891
|
||||
596,oni,6.8,6.777798,0.022201824188232244
|
||||
458,oni,6.3,6.2306204,0.06937961578369123
|
||||
755,oni,6.9,7.2296677,0.3296676635742184
|
||||
277,oni,3.2,2.558311,0.6416890144348146
|
||||
637,oni,6.6,6.266298,0.33370218276977504
|
||||
1146,oni,7.5,7.736816,0.2368159294128418
|
||||
224,oni,6.8,7.196848,0.39684791564941424
|
||||
869,oni,10.9,10.199179,0.7008213043212894
|
||||
428,oni,6.5,6.475257,0.024743080139160156
|
||||
514,oni,7.7,7.8003054,0.1003053665161131
|
||||
340,oni,5.2,5.115123,0.08487720489501971
|
||||
1256,oni,6.2,6.084713,0.1152870178222658
|
||||
8,oni,2.2,2.6536784,0.45367841720581037
|
||||
1405,oni,10.3,9.282177,1.0178230285644538
|
||||
1154,oni,8.9,9.2293825,0.3293825149536129
|
||||
1140,oni,5.6,5.3424892,0.2575107574462887
|
||||
846,oni,8.5,8.355557,0.14444255828857422
|
||||
555,oni,11.3,10.049599,1.2504013061523445
|
||||
1036,oni,6.5,6.2653823,0.2346177101135254
|
||||
1173,oni,9.2,8.834013,0.3659870147705071
|
||||
977,oni,8.8,8.352481,0.4475191116333015
|
||||
1419,oni,9.8,9.345617,0.4543827056884773
|
||||
429,oni,4.7,4.3966427,0.30335731506347674
|
||||
935,oni,9.5,8.687765,0.8122348785400391
|
||||
534,oni,4.0,3.9437454,0.05625462532043457
|
||||
552,oni,6.5,6.4038367,0.09616327285766602
|
||||
193,oni,4.4,4.2237315,0.1762684822082523
|
||||
560,oni,6.0,5.845188,0.15481185913085938
|
||||
386,oni,7.0,7.1123323,0.11233234405517578
|
||||
1039,oni,9.2,9.421019,0.2210186004638679
|
||||
1312,oni,2.9,3.1262274,0.22622737884521493
|
||||
1278,oni,11.7,11.715541,0.01554088592529368
|
||||
1396,oni,4.6,3.8423722,0.7576278209686276
|
||||
1367,oni,11.6,11.049116,0.550883865356445
|
||||
1242,oni,5.8,5.7851844,0.014815616607665838
|
||||
160,oni,5.3,5.2640634,0.03593664169311506
|
||||
283,oni,8.5,8.440965,0.059035301208496094
|
||||
199,oni,3.1,2.4848018,0.6151982307434083
|
||||
1347,oni,6.9,6.590419,0.3095811843872074
|
||||
350,oni,5.5,5.536312,0.036312103271484375
|
||||
64,oni,6.3,6.4002404,0.1002404212951662
|
||||
750,oni,8.8,9.02407,0.22406978607177663
|
||||
740,oni,8.8,8.772017,0.027983474731446023
|
||||
1391,oni,7.8,7.8338575,0.033857536315918146
|
||||
|
201
.old/test/validate_result_2.csv
Normal file
201
.old/test/validate_result_2.csv
Normal file
@@ -0,0 +1,201 @@
|
||||
songno,diff,상수,predicted_measure,error
|
||||
430,oni,1.5,1.7298045,0.22980451583862305
|
||||
401,oni,11.3,10.439279,0.860721397399903
|
||||
51,oni,3.2,2.998054,0.20194597244262713
|
||||
1268,oni,6.3,6.229351,0.07064895629882795
|
||||
676,oni,2.6,2.7677126,0.1677125930786132
|
||||
1260,oni,8.8,9.02407,0.22406978607177663
|
||||
83,oni,6.0,6.248336,0.2483358383178711
|
||||
621,oni,8.2,8.37565,0.17565040588378977
|
||||
304,oni,5.6,5.4814534,0.11854658126831019
|
||||
138,oni,7.7,7.8239584,0.12395839691162092
|
||||
207,oni,4.2,4.2350945,0.03509454727172834
|
||||
380,oni,4.6,4.6236706,0.023670578002930043
|
||||
680,oni,7.9,7.9497805,0.049780464172362926
|
||||
38,oni,5.7,5.6291122,0.07088775634765643
|
||||
938,oni,5.3,5.209937,0.09006290435790998
|
||||
689,oni,4.3,4.1817994,0.11820058822631818
|
||||
396,oni,5.8,6.0741944,0.2741944313049318
|
||||
1438,oni,7.4,7.79311,0.39310989379882777
|
||||
502,oni,8.8,8.9434595,0.14345951080322195
|
||||
610,oni,6.0,5.80618,0.19381999969482422
|
||||
1021,oni,7.0,6.821661,0.17833900451660156
|
||||
917,oni,6.7,5.3931637,1.3068363189697267
|
||||
907,oni,7.9,8.020189,0.12018928527831996
|
||||
209,oni,3.1,3.3612163,0.2612163066864013
|
||||
982,oni,9.9,9.456101,0.44389858245849645
|
||||
887,oni,7.2,7.051265,0.1487352371215822
|
||||
1031,oni,4.7,5.2932096,0.5932095527648924
|
||||
422,oni,3.0,3.2640421,0.2640421390533447
|
||||
1457,oni,5.4,5.485291,0.08529100418090785
|
||||
434,oni,4.1,4.1712093,0.07120933532714879
|
||||
1400,oni,1.6,2.1304216,0.5304216384887694
|
||||
974,oni,1.5,2.088167,0.5881669521331787
|
||||
611,oni,3.8,3.8965096,0.09650964736938494
|
||||
111,oni,4.7,4.5066733,0.19332666397094744
|
||||
266,oni,6.3,6.4265485,0.126548480987549
|
||||
302,oni,6.1,5.975836,0.12416419982910121
|
||||
1057,oni,6.4,6.3955936,0.004406356811523793
|
||||
843,oni,10.0,9.909245,0.09075546264648438
|
||||
1080,oni,8.0,8.098514,0.09851360321044922
|
||||
1380,oni,6.9,6.8520164,0.04798355102539098
|
||||
794,oni,7.6,6.201171,1.398829078674316
|
||||
356,oni,8.1,8.2789545,0.1789545059204105
|
||||
1408,oni,4.5,4.593335,0.09333515167236328
|
||||
34,oni,6.3,6.27956,0.020439910888671697
|
||||
734,oni,8.6,8.177258,0.42274246215820277
|
||||
1035,oni,5.4,5.1531134,0.2468866348266605
|
||||
310,oni,6.2,6.251908,0.051907825469970525
|
||||
1079,oni,5.6,5.3822875,0.21771249771118129
|
||||
344,oni,5.2,5.2222204,0.022220420837402166
|
||||
1241,oni,5.0,4.6463585,0.3536415100097656
|
||||
1251,oni,4.5,4.1223273,0.3776726722717285
|
||||
1302,oni,1.4,1.5472724,0.1472724437713624
|
||||
1234,oni,6.6,6.50439,0.09561023712158168
|
||||
492,oni,1.9,2.398783,0.49878296852111825
|
||||
915,oni,5.7,5.4805393,0.21946067810058612
|
||||
1218,oni,1.4,1.6566312,0.2566312313079835
|
||||
1054,oni,3.9,3.99446,0.09446010589599618
|
||||
450,oni,9.0,8.956529,0.043471336364746094
|
||||
578,oni,6.5,6.2173667,0.28263330459594727
|
||||
932,oni,7.5,7.25756,0.24244022369384766
|
||||
541,oni,5.6,5.419343,0.18065700531005824
|
||||
484,oni,5.3,5.3123913,0.012391281127929865
|
||||
951,oni,4.2,4.1377635,0.06223649978637713
|
||||
1346,oni,8.8,8.989751,0.18975086212158132
|
||||
1235,oni,7.8,7.8989544,0.09895439147949237
|
||||
1247,oni,10.0,9.550696,0.44930362701416016
|
||||
1092,oni,4.7,4.495435,0.2045647621154787
|
||||
770,oni,6.9,6.8700523,0.02994766235351598
|
||||
323,oni,4.3,4.327031,0.02703113555908221
|
||||
525,oni,6.6,6.3501854,0.24981460571289027
|
||||
1349,oni,6.3,5.845188,0.4548118591308592
|
||||
1406,oni,11.4,10.735728,0.6642717361450199
|
||||
452,oni,8.5,8.498182,0.0018177032470703125
|
||||
1236,oni,11.2,11.153378,0.046622467041014914
|
||||
1381,oni,7.3,7.888981,0.5889808654785158
|
||||
1125,oni,3.6,3.4895444,0.11045560836792001
|
||||
410,oni,6.6,6.6413183,0.0413183212280277
|
||||
775,oni,10.6,9.802061,0.7979389190673825
|
||||
716,oni,6.8,6.8853464,0.08534641265869158
|
||||
1136,oni,2.7,3.2574682,0.5574682235717772
|
||||
956,oni,2.1,2.52589,0.4258901119232177
|
||||
1040,oni,11.6,10.210405,1.3895946502685543
|
||||
1170,oni,6.9,7.0019712,0.10197124481201136
|
||||
1321,oni,5.8,5.845188,0.0451881408691408
|
||||
1292,oni,4.4,4.468697,0.0686970710754391
|
||||
1029,oni,1.6,1.3594662,0.24053380489349374
|
||||
1026,oni,4.1,3.8297968,0.2702032089233395
|
||||
556,oni,4.4,4.3982005,0.0017994880676273084
|
||||
1177,oni,3.4,3.871611,0.4716111183166505
|
||||
759,oni,9.0,8.656189,0.34381103515625
|
||||
537,oni,6.9,6.9082613,0.008261299133300426
|
||||
738,oni,7.9,7.6613083,0.2386917114257816
|
||||
905,oni,10.1,9.582528,0.517471885681152
|
||||
681,oni,7.0,7.2444925,0.2444925308227539
|
||||
36,oni,1.6,1.8594168,0.25941684246063224
|
||||
473,oni,5.4,5.588812,0.18881187438964808
|
||||
777,oni,10.8,9.979303,0.8206966400146491
|
||||
758,oni,10.8,9.948399,0.8516014099121101
|
||||
294,oni,4.3,4.851549,0.5515491485595705
|
||||
1355,oni,9.0,9.127055,0.12705516815185547
|
||||
751,oni,7.7,7.925638,0.22563819885253888
|
||||
713,oni,8.3,8.379393,0.07939262390136648
|
||||
976,oni,8.7,8.713133,0.013132858276367898
|
||||
723,oni,9.9,9.376441,0.5235589981079105
|
||||
100,oni,5.3,5.1635313,0.1364686965942381
|
||||
429,oni,4.7,4.3966427,0.30335731506347674
|
||||
341,oni,3.3,4.5935755,1.2935754776000978
|
||||
755,oni,6.9,7.2296677,0.3296676635742184
|
||||
823,oni,5.8,5.9487357,0.1487357139587404
|
||||
654,oni,4.5,4.328125,0.171875
|
||||
510,oni,5.3,5.2113357,0.08866434097290021
|
||||
1297,oni,9.4,9.196398,0.20360221862793004
|
||||
93,oni,5.9,6.05892,0.15891990661621058
|
||||
608,oni,3.5,3.7859712,0.28597116470336914
|
||||
183,oni,7.0,7.051115,0.05111503601074219
|
||||
1328,oni,9.9,9.375269,0.5247310638427738
|
||||
395,oni,7.7,7.528426,0.17157382965087908
|
||||
208,oni,4.5,4.484102,0.01589822769165039
|
||||
81,oni,4.4,5.829715,1.4297147750854489
|
||||
26,oni,4.1,5.500279,1.4002789497375492
|
||||
941,oni,4.6,4.5694156,0.030584430694579723
|
||||
970,oni,7.2,7.0208073,0.17919273376464862
|
||||
601,oni,3.5,3.6112447,0.11124467849731445
|
||||
1293,oni,3.8,4.05702,0.25702018737792987
|
||||
316,oni,7.1,6.120003,0.9799967765808102
|
||||
459,oni,5.6,5.5550127,0.044987297058105113
|
||||
968,oni,7.0,6.966305,0.033695220947265625
|
||||
1153,oni,1.8,2.1704838,0.37048382759094234
|
||||
375,oni,8.7,8.550151,0.14984912872314382
|
||||
39,oni,5.6,5.4114456,0.1885543823242184
|
||||
365,oni,10.0,8.945875,1.0541248321533203
|
||||
149,oni,4.8,5.013694,0.21369380950927752
|
||||
952,oni,10.0,9.769096,0.23090362548828125
|
||||
204,oni,2.4,2.719502,0.3195019721984864
|
||||
1197,oni,4.5,4.3139343,0.186065673828125
|
||||
945,oni,5.0,4.583455,0.41654491424560547
|
||||
1257,oni,9.0,8.956529,0.043471336364746094
|
||||
156,oni,5.8,5.7743926,0.025607395172118963
|
||||
470,oni,5.0,4.7149334,0.2850666046142578
|
||||
127,oni,5.9,5.9468956,0.04689559936523402
|
||||
1274,oni,4.8,4.9417405,0.14174051284790057
|
||||
552,oni,6.5,6.4038367,0.09616327285766602
|
||||
1422,oni,5.6,5.7453094,0.14530935287475621
|
||||
824,oni,1.3,1.4652954,0.16529543399810787
|
||||
154,oni,7.7,7.9209757,0.22097568511962873
|
||||
735,oni,6.4,6.3566375,0.043362522125244496
|
||||
164,oni,8.0,7.877853,0.1221470832824707
|
||||
139,oni,4.8,4.6042676,0.1957324028015135
|
||||
90,oni,5.6,5.5476413,0.05235872268676722
|
||||
368,oni,1.8,2.6962068,0.8962068080902099
|
||||
1048,oni,9.4,9.316141,0.08385887145996129
|
||||
615,oni,9.0,8.879463,0.12053680419921875
|
||||
994,oni,8.3,8.048112,0.2518880844116218
|
||||
576,oni,8.0,8.001074,0.0010738372802734375
|
||||
479,oni,4.9,4.708866,0.19113388061523473
|
||||
762,oni,10.3,9.964611,0.33538894653320384
|
||||
1111,oni,4.0,4.145422,0.14542198181152344
|
||||
719,oni,9.9,9.321081,0.5789188385009769
|
||||
1384,oni,9.3,9.402317,0.10231704711913991
|
||||
808,oni,6.2,6.37263,0.1726301193237303
|
||||
70,oni,6.1,5.9111953,0.18880472183227504
|
||||
571,oni,9.1,9.056726,0.04327354431152308
|
||||
488,oni,5.7,5.5653105,0.13468952178955096
|
||||
855,oni,5.7,4.9179006,0.7820994377136232
|
||||
491,oni,8.2,8.159609,0.04039115905761648
|
||||
498,oni,6.7,5.881829,0.8181712150573732
|
||||
79,oni,3.2,3.9292216,0.7292216300964354
|
||||
487,oni,3.5,3.6010914,0.10109138488769531
|
||||
922,oni,5.7,5.6340675,0.06593246459960955
|
||||
496,oni,6.1,6.430355,0.33035507202148473
|
||||
1249,oni,8.3,8.288431,0.011568832397461648
|
||||
846,oni,8.5,8.355557,0.14444255828857422
|
||||
700,oni,9.6,9.639939,0.03993930816650426
|
||||
103,oni,8.2,8.3685665,0.16856651306152415
|
||||
74,oni,4.5,4.536579,0.036579132080078125
|
||||
345,oni,4.5,3.4398248,1.0601751804351807
|
||||
404,oni,8.5,8.037392,0.46260833740234375
|
||||
1137,oni,7.1,7.197917,0.09791698455810582
|
||||
94,oni,9.9,9.473127,0.42687263488769567
|
||||
1412,oni,6.2,6.3555965,0.15559654235839826
|
||||
1300,oni,2.0,2.610785,0.6107850074768066
|
||||
315,oni,3.2,3.581308,0.3813078880310057
|
||||
364,oni,5.2,5.120959,0.07904119491577166
|
||||
1254,oni,5.9,5.639204,0.26079597473144567
|
||||
926,oni,3.7,3.3538485,0.3461515426635744
|
||||
732,oni,2.4,2.3426375,0.0573624610900878
|
||||
523,oni,5.1,4.688936,0.41106376647949183
|
||||
1425,oni,7.9,7.9018764,0.0018764495849605822
|
||||
1058,oni,6.4,6.4812675,0.08126745223998988
|
||||
543,oni,5.5,5.6081347,0.10813474655151367
|
||||
150,oni,6.3,6.2841473,0.015852737426757635
|
||||
471,oni,7.2,7.574646,0.3746459960937498
|
||||
666,oni,6.7,6.532254,0.1677457809448244
|
||||
833,oni,9.6,9.165459,0.4345413208007809
|
||||
765,oni,11.9,11.395069,0.5049308776855472
|
||||
166,oni,6.0,5.829277,0.17072296142578125
|
||||
1411,oni,9.1,8.809523,0.29047737121581996
|
||||
53,oni,6.4,6.430334,0.030334091186523082
|
||||
1176,oni,4.0,3.6295004,0.3704996109008789
|
||||
1098,oni,5.9,5.3342714,0.5657285690307621
|
||||
|
201
.old/test/validate_result_3.csv
Normal file
201
.old/test/validate_result_3.csv
Normal file
@@ -0,0 +1,201 @@
|
||||
songno,diff,상수,predicted_measure,error
|
||||
1349,oni,6.3,5.845188,0.4548118591308592
|
||||
1407,oni,2.8,2.7094536,0.09054641723632795
|
||||
1133,oni,5.7,5.578541,0.12145919799804705
|
||||
204,oni,2.4,2.719502,0.3195019721984864
|
||||
694,oni,3.5,4.001005,0.5010051727294922
|
||||
148,oni,9.7,9.349513,0.3504869461059563
|
||||
1332,oni,1.5,2.2710903,0.7710902690887451
|
||||
305,oni,3.7,3.7643456,0.06434564590454084
|
||||
1138,oni,4.1,4.1449833,0.04498329162597692
|
||||
437,oni,2.6,2.7578714,0.157871389389038
|
||||
1383,oni,9.3,9.224361,0.07563858032226634
|
||||
239,oni,7.6,9.329233,1.7292331695556644
|
||||
758,oni,10.8,9.948399,0.8516014099121101
|
||||
202,oni,7.9,8.050922,0.15092239379882777
|
||||
737,oni,9.9,9.715982,0.1840175628662113
|
||||
565,oni,4.7,4.9257283,0.22572832107543928
|
||||
820,oni,10.7,10.07424,0.6257602691650384
|
||||
851,oni,10.1,9.837338,0.26266155242919886
|
||||
1353,oni,2.8,3.3464475,0.5464474678039553
|
||||
15,oni,5.4,5.427866,0.027865982055663707
|
||||
198,oni,2.4,2.7392402,0.3392401695251466
|
||||
1418,oni,8.0,7.8037148,0.19628524780273438
|
||||
739,oni,7.1,7.3886776,0.2886775970458988
|
||||
396,oni,5.8,6.0741944,0.2741944313049318
|
||||
880,oni,5.0,5.18964,0.18964004516601562
|
||||
1327,oni,3.7,4.1225753,0.42257528305053693
|
||||
417,oni,3.3,3.3136492,0.013649177551269709
|
||||
661,oni,2.9,2.848915,0.05108489990234366
|
||||
933,oni,7.1,7.331907,0.23190679550170934
|
||||
230,oni,7.4,7.2959986,0.1040014266967777
|
||||
898,oni,3.8,4.029142,0.22914190292358416
|
||||
935,oni,9.5,8.687765,0.8122348785400391
|
||||
954,oni,9.7,9.612374,0.08762569427490163
|
||||
1237,oni,4.5,4.42432,0.07567977905273438
|
||||
1124,oni,2.8,2.4958134,0.30418663024902326
|
||||
926,oni,3.7,3.3538485,0.3461515426635744
|
||||
1227,oni,10.8,10.015021,0.7849786758422859
|
||||
287,oni,2.8,3.2971406,0.4971405982971193
|
||||
214,oni,7.8,7.899379,0.09937877655029315
|
||||
408,oni,3.6,3.389768,0.2102321147918702
|
||||
776,oni,7.7,7.219965,0.4800350189208986
|
||||
261,oni,7.4,7.6588984,0.2588983535766598
|
||||
60,oni,7.9,7.9494324,0.049432373046874645
|
||||
1052,oni,8.1,7.9752064,0.12479362487792933
|
||||
824,oni,1.3,1.4652954,0.16529543399810787
|
||||
982,oni,9.9,9.456101,0.44389858245849645
|
||||
161,oni,3.0,2.962341,0.0376589298248291
|
||||
1084,oni,2.6,3.0994637,0.49946370124816886
|
||||
1233,oni,4.1,3.903399,0.19660100936889613
|
||||
194,oni,9.4,9.450678,0.05067787170410121
|
||||
666,oni,6.7,6.532254,0.1677457809448244
|
||||
445,oni,7.1,7.3118544,0.21185436248779332
|
||||
315,oni,3.2,3.581308,0.3813078880310057
|
||||
1412,oni,6.2,6.3555965,0.15559654235839826
|
||||
1236,oni,11.2,11.153378,0.046622467041014914
|
||||
1055,oni,1.8,2.166351,0.36635107994079585
|
||||
1096,oni,5.1,3.3114526,1.7885473728179928
|
||||
1181,oni,3.3,3.7384562,0.4384562492370607
|
||||
608,oni,3.5,3.7859712,0.28597116470336914
|
||||
1312,oni,2.9,3.1262274,0.22622737884521493
|
||||
90,oni,5.6,5.5476413,0.05235872268676722
|
||||
861,oni,4.2,4.4093747,0.2093747138977049
|
||||
626,oni,6.3,6.4142413,0.11424131393432635
|
||||
469,oni,4.5,4.6131096,0.11310958862304688
|
||||
181,oni,8.5,8.829673,0.32967281341552734
|
||||
466,oni,3.0,4.420792,1.4207921028137207
|
||||
16,oni,8.3,8.095219,0.20478134155273509
|
||||
1067,oni,9.2,9.369811,0.1698110580444343
|
||||
111,oni,4.7,4.5066733,0.19332666397094744
|
||||
817,oni,8.0,8.014091,0.014090538024902344
|
||||
472,oni,5.9,6.009906,0.10990581512451136
|
||||
255,oni,5.5,5.6039057,0.10390567779541016
|
||||
1339,oni,4.5,4.5587,0.0587000846862793
|
||||
180,oni,7.3,7.391402,0.09140176773071307
|
||||
542,oni,4.2,4.0955725,0.10442752838134783
|
||||
483,oni,7.1,7.3588047,0.2588047027587894
|
||||
1320,oni,8.0,7.8748026,0.1251974105834961
|
||||
1370,oni,8.6,8.680969,0.08096923828125036
|
||||
1308,oni,8.4,8.65023,0.2502304077148434
|
||||
67,oni,7.6,7.61247,0.01247014999389684
|
||||
770,oni,6.9,6.8700523,0.02994766235351598
|
||||
1243,oni,1.1,1.061276,0.03872404098510751
|
||||
568,oni,7.5,7.328082,0.17191791534423828
|
||||
435,oni,5.7,5.4369884,0.26301164627075213
|
||||
947,oni,5.2,5.7635384,0.563538360595703
|
||||
358,oni,7.5,7.3555374,0.14446258544921875
|
||||
348,oni,3.9,3.733858,0.1661418914794921
|
||||
930,oni,7.1,7.913493,0.8134931564331058
|
||||
997,oni,4.0,4.2168503,0.21685028076171875
|
||||
1279,oni,8.4,8.668176,0.2681756973266598
|
||||
1013,oni,8.3,8.191456,0.10854415893554759
|
||||
1311,oni,6.7,6.815501,0.11550121307373029
|
||||
753,oni,5.3,5.040696,0.2593038558959959
|
||||
951,oni,4.2,4.1377635,0.06223649978637713
|
||||
157,oni,3.3,3.1216764,0.1783235549926756
|
||||
751,oni,7.7,7.925638,0.22563819885253888
|
||||
775,oni,10.6,9.802061,0.7979389190673825
|
||||
74,oni,4.5,4.536579,0.036579132080078125
|
||||
317,oni,2.9,3.59739,0.6973899364471436
|
||||
728,oni,4.9,4.727743,0.17225685119628942
|
||||
1382,oni,3.2,3.5220692,0.32206921577453596
|
||||
572,oni,8.3,8.527885,0.22788543701171804
|
||||
1452,oni,8.1,8.237134,0.13713397979736364
|
||||
1301,oni,2.0,2.1946142,0.19461417198181152
|
||||
39,oni,5.6,5.4114456,0.1885543823242184
|
||||
1450,oni,2.9,2.7411995,0.1588005065917968
|
||||
1034,oni,5.9,5.8499846,0.050015354156494496
|
||||
97,oni,7.5,7.3623753,0.13762474060058594
|
||||
1285,oni,2.4,2.4647148,0.06471476554870614
|
||||
390,oni,4.8,4.1861615,0.613838481903076
|
||||
952,oni,10.0,9.769096,0.23090362548828125
|
||||
208,oni,4.5,4.484102,0.01589822769165039
|
||||
193,oni,4.4,4.2237315,0.1762684822082523
|
||||
1116,oni,4.2,4.2934246,0.09342460632324201
|
||||
1315,oni,5.9,6.147772,0.24777183532714808
|
||||
233,oni,3.1,3.4442387,0.3442386627197265
|
||||
403,oni,5.3,5.125764,0.17423610687255842
|
||||
1277,oni,5.0,5.122813,0.12281322479248047
|
||||
639,oni,7.0,6.931817,0.06818294525146484
|
||||
498,oni,6.7,5.881829,0.8181712150573732
|
||||
179,oni,10.2,9.583749,0.6162511825561516
|
||||
793,oni,3.1,3.1706154,0.07061543464660636
|
||||
1160,oni,6.3,6.065338,0.23466186523437482
|
||||
1276,oni,9.2,9.156151,0.04384918212890554
|
||||
561,oni,5.5,5.413027,0.08697319030761719
|
||||
278,oni,3.8,4.709072,0.9090721130371096
|
||||
1083,oni,7.5,5.1249447,2.3750553131103516
|
||||
1019,oni,5.5,5.5518045,0.051804542541503906
|
||||
108,oni,6.8,6.9671035,0.1671034812927248
|
||||
929,oni,8.3,8.203068,0.09693222045898509
|
||||
988,oni,5.3,5.2196455,0.08035449981689435
|
||||
1154,oni,8.9,9.2293825,0.3293825149536129
|
||||
1401,oni,7.4,7.3951006,0.004899406433105824
|
||||
906,oni,9.1,9.289001,0.18900146484375036
|
||||
1368,oni,7.5,7.64944,0.14943981170654297
|
||||
1027,oni,3.9,4.020381,0.12038097381591806
|
||||
865,oni,5.6,5.53293,0.06707010269165004
|
||||
397,oni,7.9,7.942276,0.042276000976562145
|
||||
310,oni,6.2,6.251908,0.051907825469970525
|
||||
1110,oni,1.7,2.0302389,0.3302388668060303
|
||||
42,oni,1.1,2.9574435,1.8574434757232665
|
||||
431,oni,7.6,7.6814866,0.08148660659790075
|
||||
1381,oni,7.3,7.888981,0.5889808654785158
|
||||
395,oni,7.7,7.528426,0.17157382965087908
|
||||
514,oni,7.7,7.8003054,0.1003053665161131
|
||||
1362,oni,6.1,5.8406997,0.25930032730102504
|
||||
1305,oni,7.8,7.7893615,0.010638523101806463
|
||||
741,oni,3.5,4.1137867,0.6137866973876953
|
||||
958,oni,8.4,8.552175,0.15217456817626918
|
||||
1228,oni,4.1,3.8578901,0.24210987091064418
|
||||
203,oni,4.4,4.3201413,0.07985868453979528
|
||||
308,oni,5.2,4.990783,0.20921678543090838
|
||||
1266,oni,6.9,6.620808,0.279191875457764
|
||||
984,oni,4.2,4.5411806,0.3411806106567381
|
||||
764,oni,11.2,10.063731,1.1362688064575188
|
||||
702,oni,10.6,10.179897,0.42010269165039027
|
||||
418,oni,8.2,8.12527,0.07473011016845632
|
||||
1115,oni,3.8,3.9233134,0.1233133792877199
|
||||
534,oni,4.0,3.9437454,0.05625462532043457
|
||||
293,oni,3.9,4.5801744,0.6801744461059571
|
||||
1213,oni,5.3,5.074323,0.22567682266235334
|
||||
224,oni,6.8,7.196848,0.39684791564941424
|
||||
387,oni,4.9,4.804673,0.09532680511474645
|
||||
644,oni,4.4,4.3509674,0.049032592773437855
|
||||
1029,oni,1.6,1.3594662,0.24053380489349374
|
||||
1325,oni,8.2,8.245262,0.04526214599609446
|
||||
49,oni,4.4,4.6545525,0.2545524597167965
|
||||
1172,oni,11.9,11.048339,0.8516611099243168
|
||||
783,oni,6.0,5.882972,0.11702823638916016
|
||||
341,oni,3.3,4.5935755,1.2935754776000978
|
||||
527,oni,7.3,7.4277773,0.12777729034423846
|
||||
118,oni,3.0,2.7463155,0.25368452072143555
|
||||
448,oni,5.5,5.4255238,0.07447624206542969
|
||||
288,oni,8.2,8.141322,0.05867786407470632
|
||||
672,oni,2.4,2.623148,0.22314796447753915
|
||||
973,oni,4.0,3.9920924,0.007907629013061523
|
||||
1108,oni,10.4,9.689839,0.7101606369018558
|
||||
442,oni,10.3,9.434371,0.8656290054321296
|
||||
981,oni,3.3,3.3986528,0.09865279197692889
|
||||
319,oni,4.4,4.567095,0.16709480285644496
|
||||
1211,oni,6.0,5.586297,0.41370296478271484
|
||||
8,oni,2.2,2.6536784,0.45367841720581037
|
||||
750,oni,8.8,9.02407,0.22406978607177663
|
||||
1259,oni,6.1,6.0426464,0.05735359191894496
|
||||
992,oni,10.1,9.259041,0.8409591674804684
|
||||
507,oni,5.8,5.805967,0.005966854095459162
|
||||
1432,oni,10.0,9.590779,0.40922069549560547
|
||||
574,oni,8.6,8.241462,0.3585382461547848
|
||||
416,oni,6.0,5.845188,0.15481185913085938
|
||||
1114,oni,2.0,2.5233107,0.523310661315918
|
||||
1076,oni,2.1,2.0889874,0.011012649536132901
|
||||
63,oni,6.1,4.832204,1.2677961349487301
|
||||
31,oni,8.1,8.09505,0.004950141906737926
|
||||
115,oni,2.3,2.2282612,0.07173876762390119
|
||||
112,oni,6.5,6.330585,0.16941499710083008
|
||||
1044,oni,5.3,5.208531,0.091469097137451
|
||||
9,oni,2.0,2.2515485,0.25154852867126465
|
||||
1421,oni,8.1,8.032013,0.06798706054687464
|
||||
1218,oni,1.4,1.6566312,0.2566312313079835
|
||||
151,oni,4.8,4.623654,0.17634611129760724
|
||||
|
201
.old/test/validate_result_4.csv
Normal file
201
.old/test/validate_result_4.csv
Normal file
@@ -0,0 +1,201 @@
|
||||
songno,diff,상수,predicted_measure,error
|
||||
1200,oni,2.4,2.7606864,0.3606863975524903
|
||||
1420,oni,3.7,3.7231805,0.02318053245544416
|
||||
852,oni,6.6,6.5446224,0.05537757873535121
|
||||
406,oni,7.7,7.693886,0.006114196777343928
|
||||
112,oni,6.5,6.330585,0.16941499710083008
|
||||
37,oni,5.3,5.221942,0.0780580520629881
|
||||
187,oni,7.4,7.523672,0.12367210388183558
|
||||
1342,oni,2.2,2.297284,0.097283887863159
|
||||
1051,oni,8.7,8.919339,0.2193391799926765
|
||||
593,oni,10.6,9.9727,0.627299880981445
|
||||
242,oni,2.9,2.8971946,0.0028053760528563565
|
||||
1269,oni,3.2,2.7388601,0.4611398696899416
|
||||
663,oni,4.1,3.8161051,0.2838948726654049
|
||||
914,oni,8.7,8.76552,0.06552009582519602
|
||||
113,oni,5.7,5.845188,0.14518814086914045
|
||||
484,oni,5.3,5.3123913,0.012391281127929865
|
||||
469,oni,4.5,4.6131096,0.11310958862304688
|
||||
783,oni,6.0,5.882972,0.11702823638916016
|
||||
1188,oni,3.9,4.303166,0.4031659126281739
|
||||
1411,oni,9.1,8.809523,0.29047737121581996
|
||||
1043,oni,9.8,9.788532,0.011467742919922586
|
||||
32,oni,6.8,6.970789,0.17078895568847674
|
||||
47,oni,5.1,5.0852995,0.014700508117675426
|
||||
465,oni,6.9,6.837492,0.06250801086425817
|
||||
207,oni,4.2,4.2350945,0.03509454727172834
|
||||
824,oni,1.3,1.4652954,0.16529543399810787
|
||||
499,oni,8.8,8.752506,0.047493743896485086
|
||||
661,oni,2.9,2.848915,0.05108489990234366
|
||||
1379,oni,9.5,9.345877,0.15412330627441406
|
||||
662,oni,7.4,7.6551266,0.2551265716552731
|
||||
211,oni,7.8,7.7671843,0.032815742492675604
|
||||
794,oni,7.6,6.201171,1.398829078674316
|
||||
1173,oni,9.2,8.834013,0.3659870147705071
|
||||
1034,oni,5.9,5.8499846,0.050015354156494496
|
||||
1199,oni,4.3,4.3580647,0.05806465148925799
|
||||
450,oni,9.0,8.956529,0.043471336364746094
|
||||
1026,oni,4.1,3.8297968,0.2702032089233395
|
||||
539,oni,6.0,5.876666,0.12333393096923828
|
||||
1410,oni,3.0,2.8184204,0.18157958984375
|
||||
1412,oni,6.2,6.3555965,0.15559654235839826
|
||||
877,oni,1.3,1.7480694,0.44806940555572505
|
||||
808,oni,6.2,6.37263,0.1726301193237303
|
||||
623,oni,5.0,4.8877587,0.11224126815795898
|
||||
617,oni,5.6,6.084587,0.4845870971679691
|
||||
675,oni,5.2,5.875123,0.6751230239868162
|
||||
1209,oni,4.1,4.285281,0.18528118133544957
|
||||
462,oni,7.3,6.9185348,0.3814652442932127
|
||||
1191,oni,5.4,5.603399,0.20339879989623988
|
||||
418,oni,8.2,8.12527,0.07473011016845632
|
||||
1280,oni,3.9,4.2937455,0.393745517730713
|
||||
177,oni,2.0,2.734377,0.7343769073486328
|
||||
467,oni,2.9,2.862545,0.037454986572265536
|
||||
1071,oni,9.6,9.450291,0.14970932006835902
|
||||
471,oni,7.2,7.574646,0.3746459960937498
|
||||
220,oni,9.3,9.154587,0.1454132080078132
|
||||
1334,oni,4.0,4.209813,0.20981311798095703
|
||||
506,oni,5.6,3.9512367,1.648763275146484
|
||||
511,oni,2.3,2.8341331,0.5341331481933596
|
||||
1292,oni,4.4,4.468697,0.0686970710754391
|
||||
887,oni,7.2,7.051265,0.1487352371215822
|
||||
1145,oni,7.2,7.3018465,0.1018465042114256
|
||||
1332,oni,1.5,2.2710903,0.7710902690887451
|
||||
951,oni,4.2,4.1377635,0.06223649978637713
|
||||
1406,oni,11.4,10.735728,0.6642717361450199
|
||||
51,oni,3.2,2.998054,0.20194597244262713
|
||||
758,oni,10.8,9.948399,0.8516014099121101
|
||||
1422,oni,5.6,5.7453094,0.14530935287475621
|
||||
88,oni,8.1,7.868636,0.23136386871337855
|
||||
1073,oni,2.3,2.394328,0.09432811737060565
|
||||
549,oni,8.3,7.9438715,0.35612850189209055
|
||||
248,oni,6.2,6.27658,0.07657985687255842
|
||||
171,oni,9.6,9.666423,0.06642284393310582
|
||||
1258,oni,4.6,4.4628506,0.1371494293212887
|
||||
536,oni,6.7,6.679579,0.02042121887207049
|
||||
302,oni,6.1,5.975836,0.12416419982910121
|
||||
702,oni,10.6,10.179897,0.42010269165039027
|
||||
1415,oni,3.6,3.5990567,0.0009432792663575107
|
||||
981,oni,3.3,3.3986528,0.09865279197692889
|
||||
1169,oni,3.6,4.2148876,0.6148876190185546
|
||||
445,oni,7.1,7.3118544,0.21185436248779332
|
||||
858,oni,11.1,10.486108,0.6138921737670895
|
||||
1098,oni,5.9,5.3342714,0.5657285690307621
|
||||
1324,oni,9.3,9.130554,0.1694458007812507
|
||||
1226,oni,3.5,3.291145,0.20885491371154785
|
||||
1086,oni,10.6,10.089752,0.5102478027343746
|
||||
546,oni,6.8,6.8765535,0.07655353546142596
|
||||
1164,oni,5.4,5.845188,0.44518814086914027
|
||||
596,oni,6.8,6.777798,0.022201824188232244
|
||||
945,oni,5.0,4.583455,0.41654491424560547
|
||||
1184,oni,6.4,6.7978306,0.3978305816650387
|
||||
534,oni,4.0,3.9437454,0.05625462532043457
|
||||
1450,oni,2.9,2.7411995,0.1588005065917968
|
||||
1157,oni,4.6,4.355861,0.24413881301879847
|
||||
157,oni,3.3,3.1216764,0.1783235549926756
|
||||
1295,oni,1.3,1.133282,0.16671805381774907
|
||||
1107,oni,6.5,6.6370926,0.13709259033203125
|
||||
1196,oni,6.6,6.2691593,0.3308406829833981
|
||||
1070,oni,3.5,3.736236,0.2362360954284668
|
||||
1045,oni,8.0,7.8687744,0.1312255859375
|
||||
579,oni,7.2,7.204522,0.004522132873534979
|
||||
785,oni,8.5,8.505435,0.005434989929199219
|
||||
73,oni,8.5,8.4226885,0.07731151580810547
|
||||
879,oni,8.5,8.33581,0.16419029235839844
|
||||
869,oni,10.9,10.199179,0.7008213043212894
|
||||
340,oni,5.2,5.115123,0.08487720489501971
|
||||
401,oni,11.3,10.439279,0.860721397399903
|
||||
1306,oni,4.9,4.731516,0.1684841156005863
|
||||
297,oni,6.0,5.7628894,0.23711061477661133
|
||||
765,oni,11.9,11.395069,0.5049308776855472
|
||||
1248,oni,6.6,6.713462,0.1134618759155277
|
||||
384,oni,2.1,2.4554389,0.3554388523101806
|
||||
753,oni,5.3,5.040696,0.2593038558959959
|
||||
687,oni,4.3,4.1856074,0.11439256668090803
|
||||
505,oni,3.0,3.9480019,0.9480018615722656
|
||||
241,oni,2.6,2.7528176,0.15281763076782218
|
||||
110,oni,10.9,10.075016,0.8249839782714847
|
||||
881,oni,7.7,7.814657,0.11465721130371076
|
||||
544,oni,5.9,6.0155296,0.11552963256835902
|
||||
999,oni,10.8,9.808392,0.9916084289550788
|
||||
994,oni,8.3,8.048112,0.2518880844116218
|
||||
1099,oni,11.0,9.8232155,1.1767845153808594
|
||||
920,oni,4.9,4.69801,0.20199003219604528
|
||||
275,oni,3.5,3.5875602,0.08756017684936523
|
||||
1313,oni,5.3,5.4312534,0.13125343322753924
|
||||
1144,oni,2.7,2.792343,0.09234290122985822
|
||||
1172,oni,11.9,11.048339,0.8516611099243168
|
||||
266,oni,6.3,6.4265485,0.126548480987549
|
||||
14,oni,3.7,3.3840866,0.3159133911132814
|
||||
101,oni,1.4,1.6238686,0.22386858463287362
|
||||
115,oni,2.3,2.2282612,0.07173876762390119
|
||||
1354,oni,7.0,7.4809437,0.4809436798095703
|
||||
52,oni,5.2,5.161411,0.038589191436767756
|
||||
1418,oni,8.0,7.8037148,0.19628524780273438
|
||||
843,oni,10.0,9.909245,0.09075546264648438
|
||||
612,oni,6.7,6.813999,0.11399917602539045
|
||||
1323,oni,6.8,6.8110046,0.011004638671875178
|
||||
844,oni,8.1,8.043919,0.05608139038085902
|
||||
87,oni,5.6,5.726159,0.1261590957641605
|
||||
1090,oni,4.2,4.540201,0.3402011871337889
|
||||
111,oni,4.7,4.5066733,0.19332666397094744
|
||||
339,oni,6.8,6.780081,0.019919204711913885
|
||||
1198,oni,7.0,7.4989223,0.49892234802246094
|
||||
154,oni,7.7,7.9209757,0.22097568511962873
|
||||
291,oni,5.9,5.845188,0.05481185913085973
|
||||
739,oni,7.1,7.3886776,0.2886775970458988
|
||||
1137,oni,7.1,7.197917,0.09791698455810582
|
||||
725,oni,4.4,4.192197,0.20780315399169957
|
||||
1382,oni,3.2,3.5220692,0.32206921577453596
|
||||
253,oni,5.0,5.038617,0.03861713409423828
|
||||
1163,oni,8.3,8.122807,0.17719345092773509
|
||||
948,oni,8.3,8.308329,0.008328628540038352
|
||||
991,oni,6.3,6.262135,0.037864971160888494
|
||||
415,oni,1.8,2.84784,1.0478400707244873
|
||||
452,oni,8.5,8.498182,0.0018177032470703125
|
||||
503,oni,11.3,10.671308,0.6286924362182624
|
||||
1394,oni,10.3,10.036249,0.26375083923339915
|
||||
169,oni,3.7,3.7415326,0.04153256416320783
|
||||
1240,oni,4.2,4.3363075,0.13630752563476545
|
||||
515,oni,3.5,3.4623504,0.03764963150024414
|
||||
1106,oni,9.1,9.420722,0.3207220077514652
|
||||
685,oni,10.4,9.864383,0.5356172561645511
|
||||
412,oni,7.0,7.036152,0.036151885986328125
|
||||
453,oni,6.5,6.6112123,0.11121225357055664
|
||||
977,oni,8.8,8.352481,0.4475191116333015
|
||||
828,oni,4.1,4.206385,0.10638513565063512
|
||||
492,oni,1.9,2.398783,0.49878296852111825
|
||||
388,oni,9.0,9.137562,0.13756179809570312
|
||||
1131,oni,3.6,3.4794557,0.12054429054260263
|
||||
640,oni,8.5,8.225748,0.27425193786621094
|
||||
1122,oni,7.8,7.899935,0.09993476867675799
|
||||
888,oni,6.1,5.907568,0.1924320220947262
|
||||
1317,oni,11.2,10.480424,0.7195760726928704
|
||||
748,oni,10.8,9.854418,0.9455821990966804
|
||||
1147,oni,9.1,8.942031,0.15796909332275355
|
||||
666,oni,6.7,6.532254,0.1677457809448244
|
||||
489,oni,4.7,4.4432297,0.2567703247070314
|
||||
434,oni,4.1,4.1712093,0.07120933532714879
|
||||
706,oni,3.3,3.252023,0.047977018356323065
|
||||
1214,oni,6.0,6.4056187,0.40561866760253906
|
||||
80,oni,8.4,8.461607,0.06160697937011683
|
||||
897,oni,4.5,4.108138,0.3918619155883789
|
||||
565,oni,4.7,4.9257283,0.22572832107543928
|
||||
1377,oni,4.9,4.9466968,0.04669675827026332
|
||||
389,oni,6.2,5.975665,0.22433490753173846
|
||||
867,oni,9.0,9.131069,0.13106918334960938
|
||||
428,oni,6.5,6.475257,0.024743080139160156
|
||||
935,oni,9.5,8.687765,0.8122348785400391
|
||||
358,oni,7.5,7.3555374,0.14446258544921875
|
||||
279,oni,4.7,4.948142,0.24814205169677717
|
||||
954,oni,9.7,9.612374,0.08762569427490163
|
||||
703,oni,5.1,5.1526203,0.05262031555175817
|
||||
1059,oni,5.6,5.5380435,0.06195650100707972
|
||||
574,oni,8.6,8.241462,0.3585382461547848
|
||||
1309,oni,6.5,6.507756,0.007756233215332031
|
||||
998,oni,5.0,5.098602,0.0986018180847168
|
||||
124,oni,5.5,5.4560986,0.04390144348144531
|
||||
572,oni,8.3,8.527885,0.22788543701171804
|
||||
1134,oni,9.6,9.668004,0.06800403594970739
|
||||
738,oni,7.9,7.6613083,0.2386917114257816
|
||||
775,oni,10.6,9.802061,0.7979389190673825
|
||||
|
201
.old/test/validate_result_5.csv
Normal file
201
.old/test/validate_result_5.csv
Normal file
@@ -0,0 +1,201 @@
|
||||
songno,diff,상수,predicted_measure,error
|
||||
173,oni,6.0,5.917573,0.0824270248413086
|
||||
1061,oni,3.9,3.5892773,0.3107227325439452
|
||||
1104,oni,9.7,9.212923,0.4870769500732415
|
||||
424,oni,6.3,6.343747,0.04374713897705096
|
||||
339,oni,6.8,6.780081,0.019919204711913885
|
||||
730,oni,5.1,4.697263,0.40273723602294886
|
||||
1412,oni,6.2,6.3555965,0.15559654235839826
|
||||
1282,oni,3.8,4.334233,0.534232807159424
|
||||
109,oni,4.6,4.4378033,0.16219673156738246
|
||||
441,oni,10.7,10.057486,0.6425144195556634
|
||||
771,oni,3.3,3.3331902,0.03319020271301287
|
||||
180,oni,7.3,7.391402,0.09140176773071307
|
||||
140,oni,3.3,3.0745137,0.2254863262176512
|
||||
1233,oni,4.1,3.903399,0.19660100936889613
|
||||
1295,oni,1.3,1.133282,0.16671805381774907
|
||||
71,oni,6.0,5.845188,0.15481185913085938
|
||||
1012,oni,9.7,9.215172,0.48482818603515554
|
||||
623,oni,5.0,4.8877587,0.11224126815795898
|
||||
361,oni,8.0,8.176176,0.1761760711669922
|
||||
1304,oni,4.7,4.2533813,0.4466187477111818
|
||||
644,oni,4.4,4.3509674,0.049032592773437855
|
||||
1323,oni,6.8,6.8110046,0.011004638671875178
|
||||
491,oni,8.2,8.159609,0.04039115905761648
|
||||
1391,oni,7.8,7.8338575,0.033857536315918146
|
||||
267,oni,3.6,3.689395,0.08939495086669913
|
||||
1324,oni,9.3,9.130554,0.1694458007812507
|
||||
1379,oni,9.5,9.345877,0.15412330627441406
|
||||
846,oni,8.5,8.355557,0.14444255828857422
|
||||
1267,oni,4.7,4.7183113,0.018311309814452947
|
||||
1105,oni,5.5,4.235367,1.2646331787109375
|
||||
880,oni,5.0,5.18964,0.18964004516601562
|
||||
103,oni,8.2,8.3685665,0.16856651306152415
|
||||
1226,oni,3.5,3.291145,0.20885491371154785
|
||||
911,oni,4.7,4.432701,0.2672988891601564
|
||||
1403,oni,5.0,4.905402,0.09459781646728516
|
||||
106,oni,5.1,4.919034,0.18096599578857386
|
||||
250,oni,3.0,3.369525,0.3695249557495117
|
||||
1018,oni,4.9,4.7685223,0.13147773742675817
|
||||
545,oni,4.8,4.993164,0.19316406250000018
|
||||
386,oni,7.0,7.1123323,0.11233234405517578
|
||||
184,oni,5.2,4.5262094,0.6737906455993654
|
||||
790,oni,2.5,2.8459394,0.34593939781188965
|
||||
1056,oni,4.7,4.598622,0.10137815475463885
|
||||
459,oni,5.6,5.5550127,0.044987297058105113
|
||||
1200,oni,2.4,2.7606864,0.3606863975524903
|
||||
804,oni,5.7,5.78445,0.084450054168701
|
||||
345,oni,4.5,3.4398248,1.0601751804351807
|
||||
1276,oni,9.2,9.156151,0.04384918212890554
|
||||
1455,oni,4.6,4.585906,0.014093971252441051
|
||||
961,oni,10.2,9.469546,0.7304536819458001
|
||||
26,oni,4.1,5.500279,1.4002789497375492
|
||||
640,oni,8.5,8.225748,0.27425193786621094
|
||||
1420,oni,3.7,3.7231805,0.02318053245544416
|
||||
126,oni,4.6,4.485203,0.11479721069335902
|
||||
1117,oni,2.9,3.0611537,0.16115365028381357
|
||||
570,oni,9.0,8.652149,0.3478507995605469
|
||||
1083,oni,7.5,5.1249447,2.3750553131103516
|
||||
1428,oni,5.0,4.738045,0.26195478439331055
|
||||
190,oni,7.7,7.912362,0.21236209869384748
|
||||
1465,oni,6.8,7.052265,0.2522651672363283
|
||||
967,oni,8.8,7.3483477,1.4516523361206062
|
||||
1397,oni,3.3,3.8423722,0.5423721790313722
|
||||
1062,oni,5.0,4.9341946,0.06580543518066406
|
||||
713,oni,8.3,8.379393,0.07939262390136648
|
||||
524,oni,8.9,9.106796,0.20679626464843714
|
||||
627,oni,11.5,10.365782,1.1342182159423828
|
||||
1092,oni,4.7,4.495435,0.2045647621154787
|
||||
1037,oni,9.2,8.873722,0.32627792358398366
|
||||
1287,oni,3.2,3.1268172,0.07318277359008807
|
||||
454,oni,7.7,7.780956,0.0809557914733885
|
||||
63,oni,6.1,4.832204,1.2677961349487301
|
||||
474,oni,5.3,5.03934,0.2606599807739256
|
||||
724,oni,8.5,8.412328,0.08767223358154297
|
||||
689,oni,4.3,4.1817994,0.11820058822631818
|
||||
1386,oni,5.4,5.1236534,0.276346588134766
|
||||
115,oni,2.3,2.2282612,0.07173876762390119
|
||||
1438,oni,7.4,7.79311,0.39310989379882777
|
||||
753,oni,5.3,5.040696,0.2593038558959959
|
||||
266,oni,6.3,6.4265485,0.126548480987549
|
||||
1313,oni,5.3,5.4312534,0.13125343322753924
|
||||
1370,oni,8.6,8.680969,0.08096923828125036
|
||||
1122,oni,7.8,7.899935,0.09993476867675799
|
||||
1345,oni,4.5,4.4040623,0.09593772888183594
|
||||
167,oni,7.1,7.137214,0.0372141838073734
|
||||
828,oni,4.1,4.206385,0.10638513565063512
|
||||
358,oni,7.5,7.3555374,0.14446258544921875
|
||||
107,oni,4.6,4.2985578,0.3014422416687008
|
||||
1230,oni,3.4,3.2455196,0.15448036193847647
|
||||
1072,oni,9.8,9.565875,0.234124946594239
|
||||
917,oni,6.7,5.3931637,1.3068363189697267
|
||||
293,oni,3.9,4.5801744,0.6801744461059571
|
||||
11,oni,1.5,2.3513732,0.8513731956481934
|
||||
1351,oni,9.3,9.762559,0.4625589370727532
|
||||
1393,oni,5.2,4.9068255,0.293174457550049
|
||||
1302,oni,1.4,1.5472724,0.1472724437713624
|
||||
122,oni,1.9,2.9562376,1.056237554550171
|
||||
1109,oni,6.8,6.6508837,0.1491163253784178
|
||||
604,oni,1.0,1.1668034,0.16680335998535156
|
||||
960,oni,10.1,9.670273,0.42972717285156214
|
||||
349,oni,6.8,6.479022,0.3209779739379881
|
||||
778,oni,11.0,10.150578,0.8494224548339844
|
||||
1188,oni,3.9,4.303166,0.4031659126281739
|
||||
1010,oni,4.8,5.020252,0.2202522277832033
|
||||
763,oni,10.8,9.695452,1.1045482635498054
|
||||
1332,oni,1.5,2.2710903,0.7710902690887451
|
||||
541,oni,5.6,5.419343,0.18065700531005824
|
||||
314,oni,1.3,1.4790187,0.17901868820190425
|
||||
218,oni,7.7,7.211827,0.48817319869995135
|
||||
1280,oni,3.9,4.2937455,0.393745517730713
|
||||
751,oni,7.7,7.925638,0.22563819885253888
|
||||
952,oni,10.0,9.769096,0.23090362548828125
|
||||
131,oni,8.2,8.129029,0.07097072601318288
|
||||
277,oni,3.2,2.558311,0.6416890144348146
|
||||
1014,oni,5.3,5.1404095,0.15959053039550763
|
||||
700,oni,9.6,9.639939,0.03993930816650426
|
||||
348,oni,3.9,3.733858,0.1661418914794921
|
||||
408,oni,3.6,3.389768,0.2102321147918702
|
||||
819,oni,8.6,8.7340145,0.1340145111083988
|
||||
121,oni,9.3,8.394699,0.9053009033203132
|
||||
401,oni,11.3,10.439279,0.860721397399903
|
||||
1377,oni,4.9,4.9466968,0.04669675827026332
|
||||
360,oni,9.2,9.504893,0.3048933029174812
|
||||
365,oni,10.0,8.945875,1.0541248321533203
|
||||
487,oni,3.5,3.6010914,0.10109138488769531
|
||||
461,oni,7.1,7.155115,0.05511512756347692
|
||||
792,oni,3.7,4.1929874,0.4929874420166014
|
||||
1069,oni,8.0,7.9372826,0.06271743774414062
|
||||
621,oni,8.2,8.37565,0.17565040588378977
|
||||
968,oni,7.0,6.966305,0.033695220947265625
|
||||
297,oni,6.0,5.7628894,0.23711061477661133
|
||||
1212,oni,1.4,1.6360978,0.23609778881073007
|
||||
1232,oni,7.2,6.9321103,0.2678896903991701
|
||||
845,oni,7.5,7.5258875,0.025887489318847656
|
||||
259,oni,6.6,6.505166,0.09483394622802699
|
||||
432,oni,6.6,6.7569847,0.15698471069335973
|
||||
1059,oni,5.6,5.5380435,0.06195650100707972
|
||||
1157,oni,4.6,4.355861,0.24413881301879847
|
||||
43,oni,8.1,8.08124,0.018760299682616832
|
||||
653,oni,6.7,6.263284,0.4367157936096193
|
||||
865,oni,5.6,5.53293,0.06707010269165004
|
||||
209,oni,3.1,3.3612163,0.2612163066864013
|
||||
910,oni,7.3,7.5151834,0.21518344879150408
|
||||
1120,oni,8.2,8.383063,0.18306331634521555
|
||||
896,oni,11.1,10.215234,0.8847661972045895
|
||||
480,oni,3.2,3.3859277,0.18592767715454084
|
||||
1053,oni,4.6,4.43534,0.1646600723266598
|
||||
457,oni,6.5,6.5087705,0.008770465850830078
|
||||
443,oni,4.4,4.634786,0.23478612899780238
|
||||
566,oni,7.6,7.663207,0.06320705413818395
|
||||
136,oni,9.1,9.059532,0.040467834472655895
|
||||
212,oni,5.7,5.6477895,0.052210521697998225
|
||||
928,oni,10.3,9.718238,0.5817621231079109
|
||||
1168,oni,4.0,4.149542,0.14954185485839844
|
||||
554,oni,5.9,5.8169847,0.08301534652709996
|
||||
867,oni,9.0,9.131069,0.13106918334960938
|
||||
1255,oni,10.4,9.691372,0.708628082275391
|
||||
1154,oni,8.9,9.2293825,0.3293825149536129
|
||||
1110,oni,1.7,2.0302389,0.3302388668060303
|
||||
852,oni,6.6,6.5446224,0.05537757873535121
|
||||
1164,oni,5.4,5.845188,0.44518814086914027
|
||||
1133,oni,5.7,5.578541,0.12145919799804705
|
||||
261,oni,7.4,7.6588984,0.2588983535766598
|
||||
319,oni,4.4,4.567095,0.16709480285644496
|
||||
907,oni,7.9,8.020189,0.12018928527831996
|
||||
721,oni,9.3,8.969906,0.33009414672851634
|
||||
722,oni,9.4,9.258499,0.14150085449218786
|
||||
194,oni,9.4,9.450678,0.05067787170410121
|
||||
1090,oni,4.2,4.540201,0.3402011871337889
|
||||
988,oni,5.3,5.2196455,0.08035449981689435
|
||||
13,oni,7.2,7.3293734,0.1293733596801756
|
||||
416,oni,6.0,5.845188,0.15481185913085938
|
||||
304,oni,5.6,5.4814534,0.11854658126831019
|
||||
1408,oni,4.5,4.593335,0.09333515167236328
|
||||
1160,oni,6.3,6.065338,0.23466186523437482
|
||||
1262,oni,4.3,4.327031,0.02703113555908221
|
||||
1180,oni,6.5,6.422063,0.07793712615966797
|
||||
820,oni,10.7,10.07424,0.6257602691650384
|
||||
762,oni,10.3,9.964611,0.33538894653320384
|
||||
1165,oni,7.9,7.9121323,0.012132263183593395
|
||||
118,oni,3.0,2.7463155,0.25368452072143555
|
||||
72,oni,7.4,7.6135597,0.21355972290039027
|
||||
1421,oni,8.1,8.032013,0.06798706054687464
|
||||
242,oni,2.9,2.8971946,0.0028053760528563565
|
||||
886,oni,1.9,1.9517515,0.05175147056579599
|
||||
864,oni,8.1,8.247111,0.14711132049560582
|
||||
733,oni,3.8,3.5901544,0.2098455905914305
|
||||
281,oni,4.2,4.1172986,0.08270139694213885
|
||||
214,oni,7.8,7.899379,0.09937877655029315
|
||||
423,oni,5.9,6.2007046,0.3007045745849606
|
||||
1150,oni,4.1,3.2386503,0.8613496780395504
|
||||
1451,oni,5.1,5.1919827,0.09198274612426793
|
||||
951,oni,4.2,4.1377635,0.06223649978637713
|
||||
1039,oni,9.2,9.421019,0.2210186004638679
|
||||
53,oni,6.4,6.430334,0.030334091186523082
|
||||
1103,oni,4.8,4.630667,0.16933279037475568
|
||||
300,oni,4.0,4.3146954,0.3146953582763672
|
||||
377,oni,4.3,3.7255836,0.5744164466857908
|
||||
1220,oni,3.6,3.5168161,0.08318386077880868
|
||||
933,oni,7.1,7.331907,0.23190679550170934
|
||||
860,oni,10.6,10.310149,0.28985080718994105
|
||||
|
201
.old/test/validate_result_6.csv
Normal file
201
.old/test/validate_result_6.csv
Normal file
@@ -0,0 +1,201 @@
|
||||
songno,diff,상수,predicted_measure,error
|
||||
644,oni,4.4,4.3509674,0.049032592773437855
|
||||
1159,oni,7.1,7.237465,0.1374649047851566
|
||||
1322,oni,7.9,7.850716,0.0492838859558109
|
||||
387,oni,4.9,4.804673,0.09532680511474645
|
||||
434,oni,4.1,4.1712093,0.07120933532714879
|
||||
539,oni,6.0,5.876666,0.12333393096923828
|
||||
894,oni,1.7,1.6517099,0.04829008579254146
|
||||
541,oni,5.6,5.419343,0.18065700531005824
|
||||
306,oni,6.3,6.4742217,0.17422170639038104
|
||||
1306,oni,4.9,4.731516,0.1684841156005863
|
||||
267,oni,3.6,3.689395,0.08939495086669913
|
||||
920,oni,4.9,4.69801,0.20199003219604528
|
||||
1086,oni,10.6,10.089752,0.5102478027343746
|
||||
1214,oni,6.0,6.4056187,0.40561866760253906
|
||||
990,oni,10.9,9.670632,1.2293676376342777
|
||||
354,oni,4.8,4.4523187,0.3476813316345213
|
||||
90,oni,5.6,5.5476413,0.05235872268676722
|
||||
307,oni,4.1,3.9636607,0.1363392829895016
|
||||
761,oni,10.4,9.505325,0.8946746826171879
|
||||
896,oni,11.1,10.215234,0.8847661972045895
|
||||
874,oni,7.0,7.0029125,0.0029125213623046875
|
||||
465,oni,6.9,6.837492,0.06250801086425817
|
||||
833,oni,9.6,9.165459,0.4345413208007809
|
||||
983,oni,8.9,8.690888,0.20911159515380895
|
||||
1165,oni,7.9,7.9121323,0.012132263183593395
|
||||
866,oni,7.9,7.9159746,0.015974617004394176
|
||||
834,oni,9.7,9.58336,0.11664028167724538
|
||||
398,oni,6.3,6.204332,0.09566812515258771
|
||||
835,oni,10.2,9.703024,0.49697608947753835
|
||||
1304,oni,4.7,4.2533813,0.4466187477111818
|
||||
111,oni,4.7,4.5066733,0.19332666397094744
|
||||
797,oni,8.8,7.9628973,0.8371026992797859
|
||||
875,oni,5.1,5.04557,0.0544301033020016
|
||||
534,oni,4.0,3.9437454,0.05625462532043457
|
||||
182,oni,6.4,6.657069,0.2570692062377926
|
||||
467,oni,2.9,2.862545,0.037454986572265536
|
||||
925,oni,5.2,4.9190726,0.28092737197875994
|
||||
260,oni,8.8,7.5779324,1.2220676422119148
|
||||
221,oni,6.7,6.725834,0.025833892822265447
|
||||
184,oni,5.2,4.5262094,0.6737906455993654
|
||||
565,oni,4.7,4.9257283,0.22572832107543928
|
||||
915,oni,5.7,5.4805393,0.21946067810058612
|
||||
1194,oni,4.2,3.9531407,0.24685926437377947
|
||||
288,oni,8.2,8.141322,0.05867786407470632
|
||||
385,oni,5.1,5.0345116,0.06548843383789027
|
||||
668,oni,3.4,3.5601308,0.16013083457946786
|
||||
595,oni,9.5,9.133109,0.36689090728759766
|
||||
505,oni,3.0,3.9480019,0.9480018615722656
|
||||
1307,oni,6.9,6.8420954,0.0579046249389652
|
||||
1243,oni,1.1,1.061276,0.03872404098510751
|
||||
1241,oni,5.0,4.6463585,0.3536415100097656
|
||||
1298,oni,5.7,5.728607,0.028607177734374822
|
||||
1218,oni,1.4,1.6566312,0.2566312313079835
|
||||
1153,oni,1.8,2.1704838,0.37048382759094234
|
||||
675,oni,5.2,5.875123,0.6751230239868162
|
||||
108,oni,6.8,6.9671035,0.1671034812927248
|
||||
732,oni,2.4,2.3426375,0.0573624610900878
|
||||
34,oni,6.3,6.27956,0.020439910888671697
|
||||
120,oni,11.9,11.8358965,0.06410350799560582
|
||||
933,oni,7.1,7.331907,0.23190679550170934
|
||||
348,oni,3.9,3.733858,0.1661418914794921
|
||||
372,oni,6.4,6.345234,0.05476608276367223
|
||||
1421,oni,8.1,8.032013,0.06798706054687464
|
||||
1181,oni,3.3,3.7384562,0.4384562492370607
|
||||
136,oni,9.1,9.059532,0.040467834472655895
|
||||
504,oni,6.1,5.845188,0.254811859130859
|
||||
630,oni,9.3,8.637385,0.6626146316528327
|
||||
279,oni,4.7,4.948142,0.24814205169677717
|
||||
1015,oni,8.7,8.804349,0.10434894561767649
|
||||
343,oni,6.4,5.75634,0.6436599731445316
|
||||
1171,oni,6.1,6.1189337,0.0189336776733402
|
||||
237,oni,5.3,6.2021265,0.9021265029907228
|
||||
1278,oni,11.7,11.715541,0.01554088592529368
|
||||
1072,oni,9.8,9.565875,0.234124946594239
|
||||
621,oni,8.2,8.37565,0.17565040588378977
|
||||
62,oni,6.1,6.0770845,0.022915458679198863
|
||||
291,oni,5.9,5.845188,0.05481185913085973
|
||||
333,oni,1.1,1.4720416,0.3720416069030761
|
||||
32,oni,6.8,6.970789,0.17078895568847674
|
||||
1053,oni,4.6,4.43534,0.1646600723266598
|
||||
970,oni,7.2,7.0208073,0.17919273376464862
|
||||
1233,oni,4.1,3.903399,0.19660100936889613
|
||||
1255,oni,10.4,9.691372,0.708628082275391
|
||||
133,oni,4.8,5.009082,0.2090818405151369
|
||||
536,oni,6.7,6.679579,0.02042121887207049
|
||||
700,oni,9.6,9.639939,0.03993930816650426
|
||||
1084,oni,2.6,3.0994637,0.49946370124816886
|
||||
897,oni,4.5,4.108138,0.3918619155883789
|
||||
1352,oni,8.0,8.376083,0.3760833740234375
|
||||
321,oni,6.3,6.2436576,0.05634241104125959
|
||||
428,oni,6.5,6.475257,0.024743080139160156
|
||||
626,oni,6.3,6.4142413,0.11424131393432635
|
||||
287,oni,2.8,3.2971406,0.4971405982971193
|
||||
449,oni,8.1,7.9776797,0.12232027053832972
|
||||
617,oni,5.6,6.084587,0.4845870971679691
|
||||
946,oni,3.4,3.4010017,0.0010016918182373935
|
||||
1390,oni,5.7,5.536209,0.16379089355468768
|
||||
430,oni,1.5,1.7298045,0.22980451583862305
|
||||
60,oni,7.9,7.9494324,0.049432373046874645
|
||||
988,oni,5.3,5.2196455,0.08035449981689435
|
||||
530,oni,4.7,4.619874,0.08012599945068377
|
||||
730,oni,5.1,4.697263,0.40273723602294886
|
||||
594,oni,9.7,9.348086,0.35191364288330007
|
||||
359,oni,8.3,8.350011,0.05001087188720632
|
||||
209,oni,3.1,3.3612163,0.2612163066864013
|
||||
1227,oni,10.8,10.015021,0.7849786758422859
|
||||
1317,oni,11.2,10.480424,0.7195760726928704
|
||||
824,oni,1.3,1.4652954,0.16529543399810787
|
||||
1228,oni,4.1,3.8578901,0.24210987091064418
|
||||
911,oni,4.7,4.432701,0.2672988891601564
|
||||
615,oni,9.0,8.879463,0.12053680419921875
|
||||
699,oni,9.7,9.337942,0.36205787658691335
|
||||
422,oni,3.0,3.2640421,0.2640421390533447
|
||||
684,oni,7.5,7.035693,0.4643068313598633
|
||||
404,oni,8.5,8.037392,0.46260833740234375
|
||||
549,oni,8.3,7.9438715,0.35612850189209055
|
||||
452,oni,8.5,8.498182,0.0018177032470703125
|
||||
1400,oni,1.6,2.1304216,0.5304216384887694
|
||||
1061,oni,3.9,3.5892773,0.3107227325439452
|
||||
1402,oni,5.8,5.8168125,0.01681251525878924
|
||||
183,oni,7.0,7.051115,0.05111503601074219
|
||||
317,oni,2.9,3.59739,0.6973899364471436
|
||||
776,oni,7.7,7.219965,0.4800350189208986
|
||||
1350,oni,11.9,11.538368,0.3616317749023441
|
||||
714,oni,9.4,8.93766,0.4623397827148441
|
||||
1145,oni,7.2,7.3018465,0.1018465042114256
|
||||
868,oni,9.5,8.869226,0.6307735443115234
|
||||
82,oni,5.7,5.5701885,0.129811477661133
|
||||
1183,oni,6.5,6.3902035,0.10979652404785156
|
||||
612,oni,6.7,6.813999,0.11399917602539045
|
||||
1361,oni,1.5,1.7912393,0.29123926162719727
|
||||
1368,oni,7.5,7.64944,0.14943981170654297
|
||||
1342,oni,2.2,2.297284,0.097283887863159
|
||||
995,oni,6.4,6.4859424,0.08594236373901332
|
||||
930,oni,7.1,7.913493,0.8134931564331058
|
||||
1230,oni,3.4,3.2455196,0.15448036193847647
|
||||
1058,oni,6.4,6.4812675,0.08126745223998988
|
||||
1391,oni,7.8,7.8338575,0.033857536315918146
|
||||
323,oni,4.3,4.327031,0.02703113555908221
|
||||
800,oni,7.3,7.135235,0.16476516723632795
|
||||
1386,oni,5.4,5.1236534,0.276346588134766
|
||||
688,oni,6.3,6.2337136,0.06628637313842756
|
||||
451,oni,7.2,8.086525,0.8865249633789061
|
||||
276,oni,3.7,3.782309,0.08230905532836896
|
||||
1116,oni,4.2,4.2934246,0.09342460632324201
|
||||
914,oni,8.7,8.76552,0.06552009582519602
|
||||
454,oni,7.7,7.780956,0.0809557914733885
|
||||
880,oni,5.0,5.18964,0.18964004516601562
|
||||
1336,oni,2.9,3.0399966,0.13999662399292
|
||||
346,oni,6.4,6.5222197,0.12221965789794886
|
||||
1424,oni,6.4,6.2954216,0.10457839965820348
|
||||
1209,oni,4.1,4.285281,0.18528118133544957
|
||||
1226,oni,3.5,3.291145,0.20885491371154785
|
||||
1080,oni,8.0,8.098514,0.09851360321044922
|
||||
746,oni,8.0,8.106806,0.10680580139160156
|
||||
340,oni,5.2,5.115123,0.08487720489501971
|
||||
1203,oni,4.9,4.7891917,0.11080827713012731
|
||||
1118,oni,1.2,2.1188107,0.9188106536865235
|
||||
1295,oni,1.3,1.133282,0.16671805381774907
|
||||
1328,oni,9.9,9.375269,0.5247310638427738
|
||||
429,oni,4.7,4.3966427,0.30335731506347674
|
||||
1030,oni,4.9,5.055099,0.15509901046752894
|
||||
1457,oni,5.4,5.485291,0.08529100418090785
|
||||
471,oni,7.2,7.574646,0.3746459960937498
|
||||
1240,oni,4.2,4.3363075,0.13630752563476545
|
||||
56,oni,6.6,6.737589,0.13758888244628942
|
||||
360,oni,9.2,9.504893,0.3048933029174812
|
||||
1388,oni,6.1,5.9238286,0.17617139816284144
|
||||
304,oni,5.6,5.4814534,0.11854658126831019
|
||||
1323,oni,6.8,6.8110046,0.011004638671875178
|
||||
1191,oni,5.4,5.603399,0.20339879989623988
|
||||
881,oni,7.7,7.814657,0.11465721130371076
|
||||
999,oni,10.8,9.808392,0.9916084289550788
|
||||
1305,oni,7.8,7.7893615,0.010638523101806463
|
||||
1375,oni,1.1,1.3882558,0.2882558345794677
|
||||
278,oni,3.8,4.709072,0.9090721130371096
|
||||
523,oni,5.1,4.688936,0.41106376647949183
|
||||
856,oni,8.8,8.237783,0.5622165679931648
|
||||
1076,oni,2.1,2.0889874,0.011012649536132901
|
||||
859,oni,10.2,9.688175,0.5118247985839837
|
||||
510,oni,5.3,5.2113357,0.08866434097290021
|
||||
860,oni,10.6,10.310149,0.28985080718994105
|
||||
1098,oni,5.9,5.3342714,0.5657285690307621
|
||||
96,oni,8.8,8.476414,0.3235862731933601
|
||||
1211,oni,6.0,5.586297,0.41370296478271484
|
||||
103,oni,8.2,8.3685665,0.16856651306152415
|
||||
302,oni,6.1,5.975836,0.12416419982910121
|
||||
635,oni,8.5,8.438788,0.061211585998535156
|
||||
1346,oni,8.8,8.989751,0.18975086212158132
|
||||
851,oni,10.1,9.837338,0.26266155242919886
|
||||
264,oni,4.8,4.4578743,0.3421257019042967
|
||||
1401,oni,7.4,7.3951006,0.004899406433105824
|
||||
242,oni,2.9,2.8971946,0.0028053760528563565
|
||||
118,oni,3.0,2.7463155,0.25368452072143555
|
||||
65,oni,6.2,6.0759215,0.12407846450805682
|
||||
1329,oni,7.4,7.584384,0.18438396453857386
|
||||
1099,oni,11.0,9.8232155,1.1767845153808594
|
||||
1215,oni,8.3,8.44902,0.1490203857421868
|
||||
972,oni,7.5,7.1393,0.3607001304626465
|
||||
1172,oni,11.9,11.048339,0.8516611099243168
|
||||
|
201
.old/test/validate_result_7.csv
Normal file
201
.old/test/validate_result_7.csv
Normal file
@@ -0,0 +1,201 @@
|
||||
songno,diff,상수,predicted_measure,error
|
||||
723,oni,9.9,9.376441,0.5235589981079105
|
||||
879,oni,8.5,8.33581,0.16419029235839844
|
||||
293,oni,3.9,4.5801744,0.6801744461059571
|
||||
297,oni,6.0,5.7628894,0.23711061477661133
|
||||
988,oni,5.3,5.2196455,0.08035449981689435
|
||||
726,oni,4.6,4.15228,0.44772014617919886
|
||||
236,oni,2.2,2.4775774,0.2775774478912352
|
||||
1011,oni,5.8,5.5946207,0.20537929534912092
|
||||
422,oni,3.0,3.2640421,0.2640421390533447
|
||||
1339,oni,4.5,4.5587,0.0587000846862793
|
||||
845,oni,7.5,7.5258875,0.025887489318847656
|
||||
13,oni,7.2,7.3293734,0.1293733596801756
|
||||
459,oni,5.6,5.5550127,0.044987297058105113
|
||||
548,oni,6.5,6.6141577,0.11415767669677734
|
||||
399,oni,7.6,7.566705,0.033294773101806285
|
||||
1110,oni,1.7,2.0302389,0.3302388668060303
|
||||
1085,oni,10.0,9.612744,0.3872556686401367
|
||||
96,oni,8.8,8.476414,0.3235862731933601
|
||||
1035,oni,5.4,5.1531134,0.2468866348266605
|
||||
937,oni,5.1,5.195075,0.0950750350952152
|
||||
316,oni,7.1,6.120003,0.9799967765808102
|
||||
1103,oni,4.8,4.630667,0.16933279037475568
|
||||
984,oni,4.2,4.5411806,0.3411806106567381
|
||||
983,oni,8.9,8.690888,0.20911159515380895
|
||||
501,oni,7.6,7.7123227,0.11232271194458043
|
||||
1376,oni,1.9,2.5668554,0.6668554306030274
|
||||
144,oni,2.5,2.725388,0.2253880500793457
|
||||
390,oni,4.8,4.1861615,0.613838481903076
|
||||
270,oni,6.9,6.9537883,0.05378828048706019
|
||||
1400,oni,1.6,2.1304216,0.5304216384887694
|
||||
204,oni,2.4,2.719502,0.3195019721984864
|
||||
552,oni,6.5,6.4038367,0.09616327285766602
|
||||
467,oni,2.9,2.862545,0.037454986572265536
|
||||
1287,oni,3.2,3.1268172,0.07318277359008807
|
||||
527,oni,7.3,7.4277773,0.12777729034423846
|
||||
1105,oni,5.5,4.235367,1.2646331787109375
|
||||
640,oni,8.5,8.225748,0.27425193786621094
|
||||
577,oni,9.8,9.342824,0.4571760177612312
|
||||
1073,oni,2.3,2.394328,0.09432811737060565
|
||||
349,oni,6.8,6.479022,0.3209779739379881
|
||||
997,oni,4.0,4.2168503,0.21685028076171875
|
||||
134,oni,6.4,6.312104,0.08789577484130895
|
||||
400,oni,7.6,7.566705,0.033294773101806285
|
||||
1371,oni,6.5,6.3326335,0.16736650466918945
|
||||
402,oni,6.5,6.452997,0.04700279235839844
|
||||
1079,oni,5.6,5.3822875,0.21771249771118129
|
||||
1204,oni,3.1,3.1182175,0.01821746826171866
|
||||
51,oni,3.2,2.998054,0.20194597244262713
|
||||
1332,oni,1.5,2.2710903,0.7710902690887451
|
||||
1312,oni,2.9,3.1262274,0.22622737884521493
|
||||
925,oni,5.2,4.9190726,0.28092737197875994
|
||||
1331,oni,2.2,2.7129545,0.512954521179199
|
||||
860,oni,10.6,10.310149,0.28985080718994105
|
||||
1177,oni,3.4,3.871611,0.4716111183166505
|
||||
368,oni,1.8,2.6962068,0.8962068080902099
|
||||
262,oni,6.8,6.8975925,0.09759254455566424
|
||||
21,oni,8.1,7.9611,0.13889989852905238
|
||||
483,oni,7.1,7.3588047,0.2588047027587894
|
||||
1021,oni,7.0,6.821661,0.17833900451660156
|
||||
169,oni,3.7,3.7415326,0.04153256416320783
|
||||
574,oni,8.6,8.241462,0.3585382461547848
|
||||
266,oni,6.3,6.4265485,0.126548480987549
|
||||
1369,oni,11.8,11.984631,0.18463058471679616
|
||||
415,oni,1.8,2.84784,1.0478400707244873
|
||||
265,oni,10.2,9.425652,0.7743484497070305
|
||||
1451,oni,5.1,5.1919827,0.09198274612426793
|
||||
1324,oni,9.3,9.130554,0.1694458007812507
|
||||
90,oni,5.6,5.5476413,0.05235872268676722
|
||||
131,oni,8.2,8.129029,0.07097072601318288
|
||||
1111,oni,4.0,4.145422,0.14542198181152344
|
||||
212,oni,5.7,5.6477895,0.052210521697998225
|
||||
1259,oni,6.1,6.0426464,0.05735359191894496
|
||||
820,oni,10.7,10.07424,0.6257602691650384
|
||||
1271,oni,4.8,4.724819,0.07518081665039045
|
||||
530,oni,4.7,4.619874,0.08012599945068377
|
||||
680,oni,7.9,7.9497805,0.049780464172362926
|
||||
694,oni,3.5,4.001005,0.5010051727294922
|
||||
1176,oni,4.0,3.6295004,0.3704996109008789
|
||||
709,oni,2.5,3.2942243,0.7942242622375488
|
||||
536,oni,6.7,6.679579,0.02042121887207049
|
||||
211,oni,7.8,7.7671843,0.032815742492675604
|
||||
1053,oni,4.6,4.43534,0.1646600723266598
|
||||
157,oni,3.3,3.1216764,0.1783235549926756
|
||||
1137,oni,7.1,7.197917,0.09791698455810582
|
||||
1264,oni,7.5,7.736816,0.2368159294128418
|
||||
1261,oni,7.3,7.4277773,0.12777729034423846
|
||||
1404,oni,9.5,9.176101,0.3238992691040039
|
||||
1048,oni,9.4,9.316141,0.08385887145996129
|
||||
462,oni,7.3,6.9185348,0.3814652442932127
|
||||
580,oni,3.6,3.1813672,0.4186328411102296
|
||||
1434,oni,9.7,9.5976305,0.10236949920654226
|
||||
1263,oni,7.4,7.5086164,0.10861644744873011
|
||||
246,oni,1.1,1.8426442,0.7426442146301269
|
||||
1245,oni,8.4,8.364225,0.03577461242675817
|
||||
954,oni,9.7,9.612374,0.08762569427490163
|
||||
1391,oni,7.8,7.8338575,0.033857536315918146
|
||||
970,oni,7.2,7.0208073,0.17919273376464862
|
||||
861,oni,4.2,4.4093747,0.2093747138977049
|
||||
1405,oni,10.3,9.282177,1.0178230285644538
|
||||
652,oni,3.7,4.190357,0.49035720825195295
|
||||
348,oni,3.9,3.733858,0.1661418914794921
|
||||
1240,oni,4.2,4.3363075,0.13630752563476545
|
||||
824,oni,1.3,1.4652954,0.16529543399810787
|
||||
45,oni,7.9,8.064715,0.16471538543701136
|
||||
1236,oni,11.2,11.153378,0.046622467041014914
|
||||
332,oni,2.5,2.9927447,0.49274468421936035
|
||||
962,oni,2.6,3.1786516,0.5786515712738036
|
||||
1030,oni,4.9,5.055099,0.15509901046752894
|
||||
36,oni,1.6,1.8594168,0.25941684246063224
|
||||
1426,oni,6.2,5.8172493,0.38275070190429705
|
||||
896,oni,11.1,10.215234,0.8847661972045895
|
||||
611,oni,3.8,3.8965096,0.09650964736938494
|
||||
609,oni,5.8,5.289323,0.5106771469116209
|
||||
1307,oni,6.9,6.8420954,0.0579046249389652
|
||||
771,oni,3.3,3.3331902,0.03319020271301287
|
||||
154,oni,7.7,7.9209757,0.22097568511962873
|
||||
76,oni,3.5,3.6149366,0.11493659019470215
|
||||
200,oni,2.3,2.223773,0.0762269973754881
|
||||
94,oni,9.9,9.473127,0.42687263488769567
|
||||
615,oni,9.0,8.879463,0.12053680419921875
|
||||
880,oni,5.0,5.18964,0.18964004516601562
|
||||
822,oni,7.2,7.1134377,0.08656234741210955
|
||||
765,oni,11.9,11.395069,0.5049308776855472
|
||||
56,oni,6.6,6.737589,0.13758888244628942
|
||||
856,oni,8.8,8.237783,0.5622165679931648
|
||||
1419,oni,9.8,9.345617,0.4543827056884773
|
||||
1420,oni,3.7,3.7231805,0.02318053245544416
|
||||
456,oni,8.2,8.731038,0.5310380935668952
|
||||
917,oni,6.7,5.3931637,1.3068363189697267
|
||||
834,oni,9.7,9.58336,0.11664028167724538
|
||||
1145,oni,7.2,7.3018465,0.1018465042114256
|
||||
108,oni,6.8,6.9671035,0.1671034812927248
|
||||
736,oni,3.5,3.618028,0.11802792549133301
|
||||
345,oni,4.5,3.4398248,1.0601751804351807
|
||||
1149,oni,3.8,3.710602,0.08939795494079572
|
||||
472,oni,5.9,6.009906,0.10990581512451136
|
||||
31,oni,8.1,8.09505,0.004950141906737926
|
||||
714,oni,9.4,8.93766,0.4623397827148441
|
||||
466,oni,3.0,4.420792,1.4207921028137207
|
||||
779,oni,8.5,8.482459,0.017540931701660156
|
||||
734,oni,8.6,8.177258,0.42274246215820277
|
||||
1308,oni,8.4,8.65023,0.2502304077148434
|
||||
173,oni,6.0,5.917573,0.0824270248413086
|
||||
253,oni,5.0,5.038617,0.03861713409423828
|
||||
1042,oni,10.1,9.15089,0.9491096496582028
|
||||
612,oni,6.7,6.813999,0.11399917602539045
|
||||
1186,oni,1.9,2.0640535,0.16405353546142587
|
||||
1436,oni,6.0,5.912111,0.08788919448852539
|
||||
150,oni,6.3,6.2841473,0.015852737426757635
|
||||
1083,oni,7.5,5.1249447,2.3750553131103516
|
||||
777,oni,10.8,9.979303,0.8206966400146491
|
||||
98,oni,3.1,3.4718246,0.37182464599609366
|
||||
1118,oni,1.2,2.1188107,0.9188106536865235
|
||||
890,oni,11.0,11.081855,0.08185482025146484
|
||||
277,oni,3.2,2.558311,0.6416890144348146
|
||||
301,oni,2.8,3.031713,0.2317130088806154
|
||||
359,oni,8.3,8.350011,0.05001087188720632
|
||||
907,oni,7.9,8.020189,0.12018928527831996
|
||||
1373,oni,2.1,2.7734246,0.6734246253967284
|
||||
149,oni,4.8,5.013694,0.21369380950927752
|
||||
1181,oni,3.3,3.7384562,0.4384562492370607
|
||||
1126,oni,3.9,4.236051,0.3360510826110841
|
||||
1350,oni,11.9,11.538368,0.3616317749023441
|
||||
434,oni,4.1,4.1712093,0.07120933532714879
|
||||
420,oni,4.3,4.4294934,0.1294934272766115
|
||||
1337,oni,3.9,4.010494,0.11049423217773446
|
||||
1012,oni,9.7,9.215172,0.48482818603515554
|
||||
511,oni,2.3,2.8341331,0.5341331481933596
|
||||
1375,oni,1.1,1.3882558,0.2882558345794677
|
||||
1447,oni,10.4,10.219149,0.18085136413574254
|
||||
1187,oni,1.8,2.606092,0.8060919761657714
|
||||
711,oni,2.0,2.2765596,0.27655959129333496
|
||||
1146,oni,7.5,7.736816,0.2368159294128418
|
||||
350,oni,5.5,5.536312,0.036312103271484375
|
||||
976,oni,8.7,8.713133,0.013132858276367898
|
||||
559,oni,5.4,5.4344945,0.03449449539184535
|
||||
538,oni,8.6,8.172002,0.4279981613159176
|
||||
363,oni,8.1,7.6119237,0.48807630538940394
|
||||
356,oni,8.1,8.2789545,0.1789545059204105
|
||||
1438,oni,7.4,7.79311,0.39310989379882777
|
||||
111,oni,4.7,4.5066733,0.19332666397094744
|
||||
1389,oni,1.2,2.3112829,1.1112828731536866
|
||||
1243,oni,1.1,1.061276,0.03872404098510751
|
||||
312,oni,1.1,1.9396806,0.8396805763244628
|
||||
1015,oni,8.7,8.804349,0.10434894561767649
|
||||
785,oni,8.5,8.505435,0.005434989929199219
|
||||
1316,oni,2.8,2.868266,0.06826610565185565
|
||||
956,oni,2.1,2.52589,0.4258901119232177
|
||||
198,oni,2.4,2.7392402,0.3392401695251466
|
||||
1296,oni,7.9,7.9847984,0.08479843139648402
|
||||
351,oni,8.7,8.912447,0.21244697570800852
|
||||
505,oni,3.0,3.9480019,0.9480018615722656
|
||||
492,oni,1.9,2.398783,0.49878296852111825
|
||||
732,oni,2.4,2.3426375,0.0573624610900878
|
||||
247,oni,5.5,5.405316,0.09468412399291992
|
||||
1099,oni,11.0,9.8232155,1.1767845153808594
|
||||
695,oni,8.3,8.208186,0.09181385040283274
|
||||
1034,oni,5.9,5.8499846,0.050015354156494496
|
||||
1190,oni,5.5,5.4641275,0.035872459411621094
|
||||
746,oni,8.0,8.106806,0.10680580139160156
|
||||
|
201
.old/test/validate_result_8.csv
Normal file
201
.old/test/validate_result_8.csv
Normal file
@@ -0,0 +1,201 @@
|
||||
songno,diff,상수,predicted_measure,error
|
||||
1451,oni,5.1,5.1919827,0.09198274612426793
|
||||
317,oni,2.9,3.59739,0.6973899364471436
|
||||
285,oni,4.3,4.3387833,0.03878326416015643
|
||||
261,oni,7.4,7.6588984,0.2588983535766598
|
||||
359,oni,8.3,8.350011,0.05001087188720632
|
||||
1171,oni,6.1,6.1189337,0.0189336776733402
|
||||
861,oni,4.2,4.4093747,0.2093747138977049
|
||||
22,oni,5.5,5.295011,0.20498895645141602
|
||||
755,oni,6.9,7.2296677,0.3296676635742184
|
||||
406,oni,7.7,7.693886,0.006114196777343928
|
||||
127,oni,5.9,5.9468956,0.04689559936523402
|
||||
183,oni,7.0,7.051115,0.05111503601074219
|
||||
48,oni,5.6,5.4978957,0.10210428237915004
|
||||
233,oni,3.1,3.4442387,0.3442386627197265
|
||||
408,oni,3.6,3.389768,0.2102321147918702
|
||||
568,oni,7.5,7.328082,0.17191791534423828
|
||||
293,oni,3.9,4.5801744,0.6801744461059571
|
||||
1051,oni,8.7,8.919339,0.2193391799926765
|
||||
167,oni,7.1,7.137214,0.0372141838073734
|
||||
101,oni,1.4,1.6238686,0.22386858463287362
|
||||
454,oni,7.7,7.780956,0.0809557914733885
|
||||
852,oni,6.6,6.5446224,0.05537757873535121
|
||||
178,oni,6.8,6.8800697,0.0800697326660158
|
||||
1286,oni,2.2,2.5343087,0.33430867195129377
|
||||
1411,oni,9.1,8.809523,0.29047737121581996
|
||||
1166,oni,7.8,7.9244876,0.1244875907897951
|
||||
716,oni,6.8,6.8853464,0.08534641265869158
|
||||
1050,oni,9.2,9.424095,0.22409515380859446
|
||||
758,oni,10.8,9.948399,0.8516014099121101
|
||||
828,oni,4.1,4.206385,0.10638513565063512
|
||||
1303,oni,4.3,2.948968,1.3510320663452147
|
||||
53,oni,6.4,6.430334,0.030334091186523082
|
||||
930,oni,7.1,7.913493,0.8134931564331058
|
||||
525,oni,6.6,6.3501854,0.24981460571289027
|
||||
577,oni,9.8,9.342824,0.4571760177612312
|
||||
457,oni,6.5,6.5087705,0.008770465850830078
|
||||
538,oni,8.6,8.172002,0.4279981613159176
|
||||
1423,oni,4.7,4.6261406,0.0738594055175783
|
||||
1297,oni,9.4,9.196398,0.20360221862793004
|
||||
763,oni,10.8,9.695452,1.1045482635498054
|
||||
614,oni,6.4,5.970553,0.42944707870483434
|
||||
117,oni,8.0,8.2179575,0.2179574966430664
|
||||
87,oni,5.6,5.726159,0.1261590957641605
|
||||
346,oni,6.4,6.5222197,0.12221965789794886
|
||||
1422,oni,5.6,5.7453094,0.14530935287475621
|
||||
1196,oni,6.6,6.2691593,0.3308406829833981
|
||||
267,oni,3.6,3.689395,0.08939495086669913
|
||||
992,oni,10.1,9.259041,0.8409591674804684
|
||||
927,oni,8.9,8.5859165,0.3140834808349613
|
||||
1170,oni,6.9,7.0019712,0.10197124481201136
|
||||
429,oni,4.7,4.3966427,0.30335731506347674
|
||||
71,oni,6.0,5.845188,0.15481185913085938
|
||||
1410,oni,3.0,2.8184204,0.18157958984375
|
||||
438,oni,7.7,7.6389027,0.061097335815429865
|
||||
1114,oni,2.0,2.5233107,0.523310661315918
|
||||
1392,oni,5.4,7.2053556,1.8053556442260739
|
||||
304,oni,5.6,5.4814534,0.11854658126831019
|
||||
1159,oni,7.1,7.237465,0.1374649047851566
|
||||
1136,oni,2.7,3.2574682,0.5574682235717772
|
||||
732,oni,2.4,2.3426375,0.0573624610900878
|
||||
313,oni,2.6,2.9117153,0.31171526908874503
|
||||
754,oni,5.0,5.8170137,0.8170137405395508
|
||||
505,oni,3.0,3.9480019,0.9480018615722656
|
||||
191,oni,6.9,6.620808,0.279191875457764
|
||||
114,oni,7.0,6.7927685,0.2072315216064453
|
||||
701,oni,6.6,6.5500507,0.04994926452636683
|
||||
1271,oni,4.8,4.724819,0.07518081665039045
|
||||
111,oni,4.7,4.5066733,0.19332666397094744
|
||||
1406,oni,11.4,10.735728,0.6642717361450199
|
||||
1187,oni,1.8,2.606092,0.8060919761657714
|
||||
997,oni,4.0,4.2168503,0.21685028076171875
|
||||
1318,oni,8.9,8.928999,0.028998947143554332
|
||||
1216,oni,10.0,9.5192,0.48079967498779297
|
||||
1385,oni,3.2,2.8330605,0.36693949699401873
|
||||
420,oni,4.3,4.4294934,0.1294934272766115
|
||||
1108,oni,10.4,9.689839,0.7101606369018558
|
||||
31,oni,8.1,8.09505,0.004950141906737926
|
||||
1431,oni,7.8,7.896584,0.09658403396606463
|
||||
1281,oni,2.2,2.5469916,0.3469915866851805
|
||||
1317,oni,11.2,10.480424,0.7195760726928704
|
||||
1082,oni,5.0,4.8203955,0.17960453033447266
|
||||
555,oni,11.3,10.049599,1.2504013061523445
|
||||
171,oni,9.6,9.666423,0.06642284393310582
|
||||
637,oni,6.6,6.266298,0.33370218276977504
|
||||
323,oni,4.3,4.327031,0.02703113555908221
|
||||
105,oni,2.9,3.073173,0.17317304611206064
|
||||
1013,oni,8.3,8.191456,0.10854415893554759
|
||||
1311,oni,6.7,6.815501,0.11550121307373029
|
||||
126,oni,4.6,4.485203,0.11479721069335902
|
||||
36,oni,1.6,1.8594168,0.25941684246063224
|
||||
702,oni,10.6,10.179897,0.42010269165039027
|
||||
350,oni,5.5,5.536312,0.036312103271484375
|
||||
1219,oni,4.4,4.62963,0.229630088806152
|
||||
1020,oni,5.0,5.0843077,0.08430767059326172
|
||||
874,oni,7.0,7.0029125,0.0029125213623046875
|
||||
649,oni,7.6,7.212104,0.3878961563110348
|
||||
349,oni,6.8,6.479022,0.3209779739379881
|
||||
1169,oni,3.6,4.2148876,0.6148876190185546
|
||||
759,oni,9.0,8.656189,0.34381103515625
|
||||
302,oni,6.1,5.975836,0.12416419982910121
|
||||
1000,oni,8.0,8.003995,0.003994941711425781
|
||||
1175,oni,4.5,4.54766,0.047659873962402344
|
||||
513,oni,8.4,8.350839,0.0491613388061527
|
||||
1190,oni,5.5,5.4641275,0.035872459411621094
|
||||
1052,oni,8.1,7.9752064,0.12479362487792933
|
||||
1414,oni,5.2,5.329712,0.12971191406249982
|
||||
1070,oni,3.5,3.736236,0.2362360954284668
|
||||
898,oni,3.8,4.029142,0.22914190292358416
|
||||
247,oni,5.5,5.405316,0.09468412399291992
|
||||
1396,oni,4.6,3.8423722,0.7576278209686276
|
||||
343,oni,6.4,5.75634,0.6436599731445316
|
||||
405,oni,3.1,3.4590964,0.35909643173217765
|
||||
455,oni,5.7,5.487079,0.21292085647583026
|
||||
826,oni,10.5,9.781674,0.7183256149291992
|
||||
1115,oni,3.8,3.9233134,0.1233133792877199
|
||||
993,oni,10.0,9.799214,0.20078563690185547
|
||||
630,oni,9.3,8.637385,0.6626146316528327
|
||||
594,oni,9.7,9.348086,0.35191364288330007
|
||||
1160,oni,6.3,6.065338,0.23466186523437482
|
||||
397,oni,7.9,7.942276,0.042276000976562145
|
||||
1129,oni,9.8,9.580477,0.2195232391357429
|
||||
1366,oni,4.7,4.8216677,0.1216676712036131
|
||||
1054,oni,3.9,3.99446,0.09446010589599618
|
||||
855,oni,5.7,4.9179006,0.7820994377136232
|
||||
518,oni,11.4,11.650173,0.250173187255859
|
||||
1279,oni,8.4,8.668176,0.2681756973266598
|
||||
415,oni,1.8,2.84784,1.0478400707244873
|
||||
644,oni,4.4,4.3509674,0.049032592773437855
|
||||
616,oni,5.8,5.77202,0.027980136871337713
|
||||
1097,oni,5.1,5.135783,0.035783195495605824
|
||||
717,oni,5.6,5.3476925,0.2523075103759762
|
||||
947,oni,5.2,5.7635384,0.563538360595703
|
||||
73,oni,8.5,8.4226885,0.07731151580810547
|
||||
365,oni,10.0,8.945875,1.0541248321533203
|
||||
1257,oni,9.0,8.956529,0.043471336364746094
|
||||
549,oni,8.3,7.9438715,0.35612850189209055
|
||||
42,oni,1.1,2.9574435,1.8574434757232665
|
||||
44,oni,3.4,3.387909,0.012091064453124911
|
||||
275,oni,3.5,3.5875602,0.08756017684936523
|
||||
860,oni,10.6,10.310149,0.28985080718994105
|
||||
144,oni,2.5,2.725388,0.2253880500793457
|
||||
460,oni,2.7,2.8139534,0.11395339965820295
|
||||
137,oni,6.1,6.0426464,0.05735359191894496
|
||||
798,oni,9.1,8.862417,0.2375827789306637
|
||||
713,oni,8.3,8.379393,0.07939262390136648
|
||||
627,oni,11.5,10.365782,1.1342182159423828
|
||||
960,oni,10.1,9.670273,0.42972717285156214
|
||||
1259,oni,6.1,6.0426464,0.05735359191894496
|
||||
1350,oni,11.9,11.538368,0.3616317749023441
|
||||
1234,oni,6.6,6.50439,0.09561023712158168
|
||||
574,oni,8.6,8.241462,0.3585382461547848
|
||||
890,oni,11.0,11.081855,0.08185482025146484
|
||||
1403,oni,5.0,4.905402,0.09459781646728516
|
||||
1198,oni,7.0,7.4989223,0.49892234802246094
|
||||
989,oni,6.4,6.363348,0.03665199279785192
|
||||
612,oni,6.7,6.813999,0.11399917602539045
|
||||
197,oni,1.7,2.5009499,0.8009498596191407
|
||||
390,oni,4.8,4.1861615,0.613838481903076
|
||||
283,oni,8.5,8.440965,0.059035301208496094
|
||||
857,oni,7.7,7.948821,0.24882106781005842
|
||||
1255,oni,10.4,9.691372,0.708628082275391
|
||||
400,oni,7.6,7.566705,0.033294773101806285
|
||||
416,oni,6.0,5.845188,0.15481185913085938
|
||||
1455,oni,4.6,4.585906,0.014093971252441051
|
||||
834,oni,9.7,9.58336,0.11664028167724538
|
||||
1334,oni,4.0,4.209813,0.20981311798095703
|
||||
1415,oni,3.6,3.5990567,0.0009432792663575107
|
||||
1153,oni,1.8,2.1704838,0.37048382759094234
|
||||
226,oni,6.7,6.548712,0.15128822326660174
|
||||
1282,oni,3.8,4.334233,0.534232807159424
|
||||
150,oni,6.3,6.2841473,0.015852737426757635
|
||||
1210,oni,3.2,3.3614755,0.1614754676818846
|
||||
507,oni,5.8,5.805967,0.005966854095459162
|
||||
1071,oni,9.6,9.450291,0.14970932006835902
|
||||
569,oni,7.2,7.382146,0.18214588165283185
|
||||
81,oni,4.4,5.829715,1.4297147750854489
|
||||
91,oni,3.8,3.716854,0.08314590454101545
|
||||
2,oni,2.7,2.8962004,0.19620041847228986
|
||||
651,oni,7.1,6.437669,0.6623311996459957
|
||||
1237,oni,4.5,4.42432,0.07567977905273438
|
||||
335,oni,9.4,9.030155,0.36984481811523473
|
||||
593,oni,10.6,9.9727,0.627299880981445
|
||||
1347,oni,6.9,6.590419,0.3095811843872074
|
||||
503,oni,11.3,10.671308,0.6286924362182624
|
||||
40,oni,4.6,4.5613666,0.03863344192504847
|
||||
1165,oni,7.9,7.9121323,0.012132263183593395
|
||||
1432,oni,10.0,9.590779,0.40922069549560547
|
||||
585,oni,6.7,6.5668163,0.1331836700439455
|
||||
440,oni,6.8,6.4244413,0.3755586624145506
|
||||
1149,oni,3.8,3.710602,0.08939795494079572
|
||||
715,oni,8.4,8.413227,0.01322708129882777
|
||||
392,oni,9.0,8.880889,0.1191110610961914
|
||||
200,oni,2.3,2.223773,0.0762269973754881
|
||||
552,oni,6.5,6.4038367,0.09616327285766602
|
||||
1146,oni,7.5,7.736816,0.2368159294128418
|
||||
621,oni,8.2,8.37565,0.17565040588378977
|
||||
270,oni,6.9,6.9537883,0.05378828048706019
|
||||
1351,oni,9.3,9.762559,0.4625589370727532
|
||||
750,oni,8.8,9.02407,0.22406978607177663
|
||||
124,oni,5.5,5.4560986,0.04390144348144531
|
||||
|
201
.old/test/validate_result_9.csv
Normal file
201
.old/test/validate_result_9.csv
Normal file
@@ -0,0 +1,201 @@
|
||||
songno,diff,상수,predicted_measure,error
|
||||
697,oni,9.9,9.322553,0.5774473190307621
|
||||
593,oni,10.6,9.9727,0.627299880981445
|
||||
354,oni,4.8,4.4523187,0.3476813316345213
|
||||
1053,oni,4.6,4.43534,0.1646600723266598
|
||||
1302,oni,1.4,1.5472724,0.1472724437713624
|
||||
1258,oni,4.6,4.4628506,0.1371494293212887
|
||||
260,oni,8.8,7.5779324,1.2220676422119148
|
||||
1437,oni,7.5,7.7957687,0.29576873779296875
|
||||
484,oni,5.3,5.3123913,0.012391281127929865
|
||||
592,oni,7.1,7.0801096,0.01989040374755824
|
||||
186,oni,10.9,9.880772,1.0192283630371097
|
||||
103,oni,8.2,8.3685665,0.16856651306152415
|
||||
549,oni,8.3,7.9438715,0.35612850189209055
|
||||
572,oni,8.3,8.527885,0.22788543701171804
|
||||
388,oni,9.0,9.137562,0.13756179809570312
|
||||
757,oni,10.5,10.120777,0.3792228698730469
|
||||
36,oni,1.6,1.8594168,0.25941684246063224
|
||||
1324,oni,9.3,9.130554,0.1694458007812507
|
||||
1030,oni,4.9,5.055099,0.15509901046752894
|
||||
518,oni,11.4,11.650173,0.250173187255859
|
||||
742,oni,6.9,6.7455025,0.15449752807617223
|
||||
1435,oni,5.2,5.0266085,0.1733915328979494
|
||||
680,oni,7.9,7.9497805,0.049780464172362926
|
||||
43,oni,8.1,8.08124,0.018760299682616832
|
||||
198,oni,2.4,2.7392402,0.3392401695251466
|
||||
1333,oni,1.7,1.838375,0.13837497234344487
|
||||
309,oni,6.6,6.26643,0.33357009887695277
|
||||
120,oni,11.9,11.8358965,0.06410350799560582
|
||||
1292,oni,4.4,4.468697,0.0686970710754391
|
||||
675,oni,5.2,5.875123,0.6751230239868162
|
||||
1383,oni,9.3,9.224361,0.07563858032226634
|
||||
467,oni,2.9,2.862545,0.037454986572265536
|
||||
472,oni,5.9,6.009906,0.10990581512451136
|
||||
139,oni,4.8,4.6042676,0.1957324028015135
|
||||
63,oni,6.1,4.832204,1.2677961349487301
|
||||
525,oni,6.6,6.3501854,0.24981460571289027
|
||||
931,oni,7.7,7.59026,0.10973997116088885
|
||||
1117,oni,2.9,3.0611537,0.16115365028381357
|
||||
672,oni,2.4,2.623148,0.22314796447753915
|
||||
628,oni,10.7,9.843618,0.8563816070556634
|
||||
1006,oni,5.3,5.5312557,0.23125572204589862
|
||||
1204,oni,3.1,3.1182175,0.01821746826171866
|
||||
95,oni,7.3,7.362153,0.062153053283691584
|
||||
946,oni,3.4,3.4010017,0.0010016918182373935
|
||||
774,oni,9.0,9.228863,0.22886276245117188
|
||||
83,oni,6.0,6.248336,0.2483358383178711
|
||||
237,oni,5.3,6.2021265,0.9021265029907228
|
||||
1129,oni,9.8,9.580477,0.2195232391357429
|
||||
301,oni,2.8,3.031713,0.2317130088806154
|
||||
1158,oni,8.6,8.740654,0.1406539916992191
|
||||
471,oni,7.2,7.574646,0.3746459960937498
|
||||
1350,oni,11.9,11.538368,0.3616317749023441
|
||||
1364,oni,7.7,7.450409,0.24959106445312518
|
||||
898,oni,3.8,4.029142,0.22914190292358416
|
||||
1354,oni,7.0,7.4809437,0.4809436798095703
|
||||
403,oni,5.3,5.125764,0.17423610687255842
|
||||
698,oni,9.9,9.641409,0.2585910797119144
|
||||
151,oni,4.8,4.623654,0.17634611129760724
|
||||
248,oni,6.2,6.27658,0.07657985687255842
|
||||
993,oni,10.0,9.799214,0.20078563690185547
|
||||
1308,oni,8.4,8.65023,0.2502304077148434
|
||||
1331,oni,2.2,2.7129545,0.512954521179199
|
||||
1033,oni,4.3,4.3674026,0.06740255355834979
|
||||
614,oni,6.4,5.970553,0.42944707870483434
|
||||
1209,oni,4.1,4.285281,0.18528118133544957
|
||||
86,oni,6.8,7.345725,0.5457250595092775
|
||||
1411,oni,9.1,8.809523,0.29047737121581996
|
||||
1197,oni,4.5,4.3139343,0.186065673828125
|
||||
786,oni,9.3,8.820966,0.47903423309326243
|
||||
347,oni,5.7,5.845188,0.14518814086914045
|
||||
1276,oni,9.2,9.156151,0.04384918212890554
|
||||
895,oni,1.0,1.2011725,0.20117247104644775
|
||||
1400,oni,1.6,2.1304216,0.5304216384887694
|
||||
187,oni,7.4,7.523672,0.12367210388183558
|
||||
1359,oni,2.2,2.4671395,0.26713948249816877
|
||||
149,oni,4.8,5.013694,0.21369380950927752
|
||||
1245,oni,8.4,8.364225,0.03577461242675817
|
||||
1026,oni,4.1,3.8297968,0.2702032089233395
|
||||
312,oni,1.1,1.9396806,0.8396805763244628
|
||||
92,oni,2.4,3.0877912,0.6877912044525147
|
||||
1361,oni,1.5,1.7912393,0.29123926162719727
|
||||
1320,oni,8.0,7.8748026,0.1251974105834961
|
||||
977,oni,8.8,8.352481,0.4475191116333015
|
||||
247,oni,5.5,5.405316,0.09468412399291992
|
||||
179,oni,10.2,9.583749,0.6162511825561516
|
||||
1424,oni,6.4,6.2954216,0.10457839965820348
|
||||
167,oni,7.1,7.137214,0.0372141838073734
|
||||
138,oni,7.7,7.8239584,0.12395839691162092
|
||||
804,oni,5.7,5.78445,0.084450054168701
|
||||
1335,oni,4.0,3.8683329,0.1316671371459961
|
||||
220,oni,9.3,9.154587,0.1454132080078132
|
||||
1277,oni,5.0,5.122813,0.12281322479248047
|
||||
888,oni,6.1,5.907568,0.1924320220947262
|
||||
1125,oni,3.6,3.4895444,0.11045560836792001
|
||||
242,oni,2.9,2.8971946,0.0028053760528563565
|
||||
1348,oni,6.7,5.7091274,0.9908725738525392
|
||||
267,oni,3.6,3.689395,0.08939495086669913
|
||||
750,oni,8.8,9.02407,0.22406978607177663
|
||||
1388,oni,6.1,5.9238286,0.17617139816284144
|
||||
435,oni,5.7,5.4369884,0.26301164627075213
|
||||
1170,oni,6.9,7.0019712,0.10197124481201136
|
||||
1306,oni,4.9,4.731516,0.1684841156005863
|
||||
253,oni,5.0,5.038617,0.03861713409423828
|
||||
108,oni,6.8,6.9671035,0.1671034812927248
|
||||
817,oni,8.0,8.014091,0.014090538024902344
|
||||
241,oni,2.6,2.7528176,0.15281763076782218
|
||||
1180,oni,6.5,6.422063,0.07793712615966797
|
||||
574,oni,8.6,8.241462,0.3585382461547848
|
||||
1275,oni,4.1,4.2565866,0.15658655166626012
|
||||
1084,oni,2.6,3.0994637,0.49946370124816886
|
||||
1362,oni,6.1,5.8406997,0.25930032730102504
|
||||
1106,oni,9.1,9.420722,0.3207220077514652
|
||||
1027,oni,3.9,4.020381,0.12038097381591806
|
||||
747,oni,7.3,7.7551966,0.45519657135009783
|
||||
891,oni,6.8,6.728759,0.07124118804931623
|
||||
651,oni,7.1,6.437669,0.6623311996459957
|
||||
930,oni,7.1,7.913493,0.8134931564331058
|
||||
1149,oni,3.8,3.710602,0.08939795494079572
|
||||
498,oni,6.7,5.881829,0.8181712150573732
|
||||
868,oni,9.5,8.869226,0.6307735443115234
|
||||
1022,oni,2.7,2.4909775,0.2090224742889406
|
||||
537,oni,6.9,6.9082613,0.008261299133300426
|
||||
1037,oni,9.2,8.873722,0.32627792358398366
|
||||
703,oni,5.1,5.1526203,0.05262031555175817
|
||||
270,oni,6.9,6.9537883,0.05378828048706019
|
||||
992,oni,10.1,9.259041,0.8409591674804684
|
||||
1337,oni,3.9,4.010494,0.11049423217773446
|
||||
239,oni,7.6,9.329233,1.7292331695556644
|
||||
427,oni,9.1,8.9220085,0.17799148559570277
|
||||
654,oni,4.5,4.328125,0.171875
|
||||
1349,oni,6.3,5.845188,0.4548118591308592
|
||||
383,oni,6.1,6.0199423,0.08005771636962855
|
||||
1316,oni,2.8,2.868266,0.06826610565185565
|
||||
514,oni,7.7,7.8003054,0.1003053665161131
|
||||
860,oni,10.6,10.310149,0.28985080718994105
|
||||
541,oni,5.6,5.419343,0.18065700531005824
|
||||
530,oni,4.7,4.619874,0.08012599945068377
|
||||
1322,oni,7.9,7.850716,0.0492838859558109
|
||||
53,oni,6.4,6.430334,0.030334091186523082
|
||||
80,oni,8.4,8.461607,0.06160697937011683
|
||||
974,oni,1.5,2.088167,0.5881669521331787
|
||||
293,oni,3.9,4.5801744,0.6801744461059571
|
||||
1323,oni,6.8,6.8110046,0.011004638671875178
|
||||
335,oni,9.4,9.030155,0.36984481811523473
|
||||
816,oni,8.2,8.676427,0.47642688751220774
|
||||
1261,oni,7.3,7.4277773,0.12777729034423846
|
||||
924,oni,2.8,2.7967556,0.003244447708129705
|
||||
580,oni,3.6,3.1813672,0.4186328411102296
|
||||
1387,oni,4.0,3.7799487,0.22005128860473633
|
||||
358,oni,7.5,7.3555374,0.14446258544921875
|
||||
1284,oni,2.3,2.797853,0.4978529930114748
|
||||
934,oni,9.5,8.944782,0.5552177429199219
|
||||
1160,oni,6.3,6.065338,0.23466186523437482
|
||||
881,oni,7.7,7.814657,0.11465721130371076
|
||||
1293,oni,3.8,4.05702,0.25702018737792987
|
||||
507,oni,5.8,5.805967,0.005966854095459162
|
||||
1373,oni,2.1,2.7734246,0.6734246253967284
|
||||
430,oni,1.5,1.7298045,0.22980451583862305
|
||||
208,oni,4.5,4.484102,0.01589822769165039
|
||||
523,oni,5.1,4.688936,0.41106376647949183
|
||||
411,oni,4.8,4.3224406,0.4775593757629393
|
||||
1192,oni,5.7,5.762822,0.06282215118408185
|
||||
1455,oni,4.6,4.585906,0.014093971252441051
|
||||
511,oni,2.3,2.8341331,0.5341331481933596
|
||||
363,oni,8.1,7.6119237,0.48807630538940394
|
||||
1415,oni,3.6,3.5990567,0.0009432792663575107
|
||||
361,oni,8.0,8.176176,0.1761760711669922
|
||||
1079,oni,5.6,5.3822875,0.21771249771118129
|
||||
194,oni,9.4,9.450678,0.05067787170410121
|
||||
366,oni,1.5,2.3543668,0.8543667793273926
|
||||
534,oni,4.0,3.9437454,0.05625462532043457
|
||||
1111,oni,4.0,4.145422,0.14542198181152344
|
||||
131,oni,8.2,8.129029,0.07097072601318288
|
||||
1049,oni,9.5,9.412386,0.08761405944824219
|
||||
976,oni,8.7,8.713133,0.013132858276367898
|
||||
539,oni,6.0,5.876666,0.12333393096923828
|
||||
1231,oni,5.7,5.6410522,0.05894775390625018
|
||||
758,oni,10.8,9.948399,0.8516014099121101
|
||||
1118,oni,1.2,2.1188107,0.9188106536865235
|
||||
1220,oni,3.6,3.5168161,0.08318386077880868
|
||||
1368,oni,7.5,7.64944,0.14943981170654297
|
||||
1273,oni,6.9,5.924207,0.9757927894592289
|
||||
40,oni,4.6,4.5613666,0.03863344192504847
|
||||
1072,oni,9.8,9.565875,0.234124946594239
|
||||
1050,oni,9.2,9.424095,0.22409515380859446
|
||||
432,oni,6.6,6.7569847,0.15698471069335973
|
||||
1301,oni,2.0,2.1946142,0.19461417198181152
|
||||
315,oni,3.2,3.581308,0.3813078880310057
|
||||
926,oni,3.7,3.3538485,0.3461515426635744
|
||||
773,oni,4.0,3.9387102,0.06128978729248047
|
||||
782,oni,2.7,2.7994647,0.099464702606201
|
||||
1144,oni,2.7,2.792343,0.09234290122985822
|
||||
880,oni,5.0,5.18964,0.18964004516601562
|
||||
1043,oni,9.8,9.788532,0.011467742919922586
|
||||
1096,oni,5.1,3.3114526,1.7885473728179928
|
||||
1069,oni,8.0,7.9372826,0.06271743774414062
|
||||
790,oni,2.5,2.8459394,0.34593939781188965
|
||||
646,oni,2.3,2.4966152,0.1966151714324953
|
||||
456,oni,8.2,8.731038,0.5310380935668952
|
||||
699,oni,9.7,9.337942,0.36205787658691335
|
||||
|
152
.old/train.py
Normal file
152
.old/train.py
Normal file
@@ -0,0 +1,152 @@
|
||||
import pandas as pd
|
||||
import json, os, sys
|
||||
import numpy as np
|
||||
import torch
|
||||
import torch.nn as nn
|
||||
import torch.optim as optim
|
||||
from sklearn.preprocessing import StandardScaler
|
||||
|
||||
MAX_MARGIN_LIMIT = 10
|
||||
|
||||
class DifficultyNet(nn.Module):
|
||||
def __init__(self, input_dim):
|
||||
super(DifficultyNet, self).__init__()
|
||||
self.net = nn.Sequential(
|
||||
nn.Linear(input_dim, 128),
|
||||
nn.BatchNorm1d(128),
|
||||
nn.ReLU(),
|
||||
nn.Dropout(0.4),
|
||||
nn.Linear(128, 64),
|
||||
nn.ReLU(),
|
||||
nn.Dropout(0.3),
|
||||
nn.Linear(64, 32),
|
||||
nn.ReLU(),
|
||||
nn.Linear(32, 1),
|
||||
nn.Sigmoid()
|
||||
)
|
||||
|
||||
def forward(self, x):
|
||||
return self.net(x)
|
||||
|
||||
def train(script_dir, working_dir, data_dir, train_count, val_count, margin, val_iterations):
|
||||
device = torch.device("mps" if torch.backends.mps.is_available() else "cpu")
|
||||
print(f"🚀 Using Device: {device}")
|
||||
|
||||
# 데이터 로드 및 병합
|
||||
factors_path = os.path.join(working_dir, 'factors.json')
|
||||
if not os.path.exists(factors_path):
|
||||
os.system(f"bun run {os.path.join(script_dir, 'factorize.ts')} {data_dir} {working_dir}")
|
||||
|
||||
df_feat = pd.read_json(factors_path)
|
||||
df_meas = pd.read_csv(os.path.join(data_dir, 'measure.csv'))
|
||||
df_meas['diff'] = df_meas['diff'].replace('ura', 'edit')
|
||||
df_feat['songno'], df_meas['songno'] = df_feat['songno'].astype(int), df_meas['songno'].astype(int)
|
||||
df = pd.merge(df_feat, df_meas, on=['songno', 'diff'])
|
||||
|
||||
exclude_cols = ['songno', 'diff', 'title', 'course', '상수', 'predicted_measure', 'error']
|
||||
X_cols = [c for c in df_feat.columns if c not in exclude_cols]
|
||||
|
||||
scaler = StandardScaler()
|
||||
df[X_cols] = scaler.fit_transform(df[X_cols])
|
||||
with open(os.path.join(working_dir, 'scaler.json'), 'w') as f:
|
||||
json.dump({'mean': scaler.mean_.tolist(), 'std': scaler.scale_.tolist(), 'cols': X_cols}, f)
|
||||
|
||||
model_path = os.path.join(working_dir, 'model.pth')
|
||||
margin = float(margin)
|
||||
val_iterations = int(val_iterations)
|
||||
|
||||
model = DifficultyNet(len(X_cols)).to(device)
|
||||
attempt = 1
|
||||
|
||||
while True:
|
||||
print(f"\n[Attempt {attempt}] " + "-"*40)
|
||||
if os.path.exists(model_path):
|
||||
try: model.load_state_dict(torch.load(model_path, map_location=device))
|
||||
except: pass
|
||||
|
||||
train_df = df.sample(n=min(int(train_count), len(df)))
|
||||
X_train = torch.FloatTensor(train_df[X_cols].values).to(device)
|
||||
y_train = torch.FloatTensor(((train_df['상수'].values - 1) / 11)).unsqueeze(1).to(device)
|
||||
|
||||
base_lr = 0.001
|
||||
optimizer = optim.Adam(model.parameters(), lr=base_lr, weight_decay=1e-5)
|
||||
criterion = nn.L1Loss()
|
||||
|
||||
model.train()
|
||||
epoch = 0
|
||||
while True:
|
||||
optimizer.zero_grad()
|
||||
preds_train = model(X_train)
|
||||
loss = criterion(preds_train, y_train) # MSELoss 권장
|
||||
loss.backward()
|
||||
optimizer.step()
|
||||
|
||||
# 현재 학습 데이터에 대한 오차 분석
|
||||
with torch.no_grad():
|
||||
diff = torch.abs((preds_train * 12 + 0.5) - (y_train * 12 + 0.5))
|
||||
train_mae = torch.mean(diff).item()
|
||||
train_max = torch.max(diff).item()
|
||||
|
||||
if epoch % 1000 == 0:
|
||||
print(f" - Ep {epoch:5d} | MAE: {train_mae:.4f} | MAX: {train_max:.4f}")
|
||||
|
||||
# ✅ 조건 강화: MAE뿐만 아니라 MAX도 어느 정도 잡혔을 때만 검증으로 이동
|
||||
if train_mae < margin and train_max < (margin * MAX_MARGIN_LIMIT):
|
||||
print(f" ✅ Train Goal Reached (MAE: {train_mae} < {margin:.4f}, MAX: {train_max:.4f} < {(margin * MAX_MARGIN_LIMIT):.4f}). Moving to Val.")
|
||||
break
|
||||
|
||||
epoch += 1
|
||||
if epoch > 50000:
|
||||
print(" ⚠️ Timed out. Resampling...")
|
||||
break
|
||||
|
||||
if train_mae >= margin:
|
||||
torch.save(model.state_dict(), model_path)
|
||||
attempt += 1
|
||||
continue
|
||||
|
||||
# 3. 검증 단계
|
||||
print(f"3. Validating {val_iterations} iterations...")
|
||||
model.eval()
|
||||
all_passed = True
|
||||
with torch.no_grad():
|
||||
for i in range(1, val_iterations + 1):
|
||||
val_df = df.sample(n=min(int(val_count), len(df)))
|
||||
X_val = torch.FloatTensor(val_df[X_cols].values).to(device)
|
||||
y_val_raw = val_df['상수'].values
|
||||
preds = model(X_val) * 12 + 0.5
|
||||
y_val_tensor = torch.FloatTensor(y_val_raw).unsqueeze(1).to(device)
|
||||
diff_tensor = torch.abs(preds - y_val_tensor)
|
||||
mae = torch.mean(diff_tensor).item()
|
||||
max_error = torch.max(diff_tensor).item()
|
||||
|
||||
|
||||
# csv 저장
|
||||
# preds를 CPU 넘파이로 변환하고 1차원으로 펴주는 과정이 포함되어야 합니다.
|
||||
preds_np = preds.detach().cpu().numpy().flatten() if torch.is_tensor(preds) else preds
|
||||
|
||||
res_df = val_df[['songno', 'diff', '상수']].copy()
|
||||
res_df['predicted_measure'] = preds_np
|
||||
res_df['error'] = np.abs(preds_np - y_val_raw)
|
||||
|
||||
output_file = os.path.join(working_dir, f'validate_result_{i}.csv')
|
||||
res_df.to_csv(output_file, index=False)
|
||||
|
||||
if mae <= margin and max_error <= (margin * MAX_MARGIN_LIMIT):
|
||||
print(f" [Iter {i}] ✅ PASS (MAE: {mae:.4f}, MAX: {max_error:.4f})")
|
||||
else:
|
||||
print(f" [Iter {i}] ❌ FAIL (MAE: {mae:.4f} > {margin} || MAX: {max_error:.4f} > {margin * MAX_MARGIN_LIMIT})")
|
||||
all_passed = False
|
||||
break
|
||||
|
||||
if all_passed:
|
||||
print(f"\n✨ Final Success!")
|
||||
torch.save(model.state_dict(), model_path)
|
||||
return
|
||||
else:
|
||||
torch.save(model.state_dict(), model_path)
|
||||
attempt += 1
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) < 8: sys.exit(1)
|
||||
train(*sys.argv[1:8])
|
||||
25
.old/train.sh
Executable file
25
.old/train.sh
Executable file
@@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Arguments: script_dir working_dir data_dir train_count validate_count margin validate_iterations
|
||||
SCRIPT_DIR=${1:-"script"}
|
||||
WORKING_DIR=${2:-"."}
|
||||
DATA_DIR=${3:-"datas"}
|
||||
TRAIN_COUNT=${4:-100}
|
||||
VAL_COUNT=${5:-20}
|
||||
MARGIN=${6:-0.5}
|
||||
VAL_ITERATIONS=${7:-5}
|
||||
|
||||
# 작업 디렉토리가 없으면 생성
|
||||
if [ ! -d "$WORKING_DIR" ]; then
|
||||
echo "Creating working directory: $WORKING_DIR"
|
||||
mkdir -p "$WORKING_DIR"
|
||||
fi
|
||||
|
||||
# factors.json이 없으면 생성
|
||||
if [ ! -f "$WORKING_DIR/factors.json" ]; then
|
||||
echo "Factors file not found. Running factorization..."
|
||||
bun run "$SCRIPT_DIR/extract.ts" "$WORKING_DIR" "$DATA_DIR"
|
||||
fi
|
||||
|
||||
echo "Starting training..."
|
||||
python3 "$SCRIPT_DIR/train.py" "$SCRIPT_DIR" "$WORKING_DIR" "$DATA_DIR" "$TRAIN_COUNT" "$VAL_COUNT" "$MARGIN" "$VAL_ITERATIONS"
|
||||
118
.old/train.ts
Normal file
118
.old/train.ts
Normal file
@@ -0,0 +1,118 @@
|
||||
import { parseTja } from './parse';
|
||||
import { factorize, Factors } from './factorize';
|
||||
import { join } from 'path';
|
||||
import { readFileSync, writeFileSync, readdirSync } from 'fs';
|
||||
import { parse } from 'csv-parse/sync';
|
||||
|
||||
async function train() {
|
||||
const args = process.argv.slice(2);
|
||||
const workingDir = args[0];
|
||||
const scriptDir = args[1];
|
||||
const dataDir = args[2];
|
||||
const trainCount = parseInt(args[3]) || 100;
|
||||
const validateCount = parseInt(args[4]) || 20;
|
||||
const margin = parseFloat(args[5]) || 0.1;
|
||||
|
||||
const factorJsonPath = join(scriptDir, 'factor.json');
|
||||
// 항상 script/ 위치 참조
|
||||
let weights: Factors = JSON.parse(readFileSync(factorJsonPath, 'utf-8'));
|
||||
|
||||
// 결과물(로그 등)을 저장할 경로 (필요 시 활용)
|
||||
const logPath = join(workingDir, 'training_log.txt');
|
||||
|
||||
const measureCsv = readFileSync(join(dataDir, 'measure.csv'), 'utf-8');
|
||||
const records = parse(measureCsv, { columns: true, skip_empty_lines: true });
|
||||
|
||||
const tjaFiles = readdirSync(join(dataDir, 'tja')).filter(f => f.endsWith('.tja'));
|
||||
const shuffled = tjaFiles.sort(() => 0.5 - Math.random());
|
||||
const trainFiles = shuffled.slice(0, trainCount);
|
||||
const validateFiles = shuffled.slice(trainCount, trainCount + validateCount);
|
||||
|
||||
console.log(`Training with ${trainFiles.length} files...`);
|
||||
|
||||
// 학습 로직 (Sigmoid + [1, 12] scaling)
|
||||
const sigmoid = (x: number) => 1 / (1 + Math.exp(-x));
|
||||
|
||||
let error = Infinity;
|
||||
let iterations = 0;
|
||||
while (error > margin && iterations < 10) { // Spec에 따라 10번 반복
|
||||
let totalError = 0;
|
||||
let count = 0;
|
||||
|
||||
for (const file of trainFiles) {
|
||||
const songno = file.replace(/\D/g, '');
|
||||
const tjaContent = readFileSync(join(dataDir, 'tja', file), 'utf-8');
|
||||
const parsed = parseTja(tjaContent);
|
||||
if (!parsed) continue;
|
||||
|
||||
for (const diff of ['oni', 'edit'] as const) {
|
||||
const course = parsed[diff];
|
||||
if (!course) continue;
|
||||
|
||||
const target = records.find((r: any) => r.songno === songno && (r.diff === (diff === 'oni' ? 'oni' : 'ura')));
|
||||
if (!target) continue;
|
||||
|
||||
const factors = factorize(course);
|
||||
// 가중치 적용 전 정규화 (임의 값으로 가정)
|
||||
const normalizedFactors = {
|
||||
physical_density: Math.min(factors.physical_density / 20, 1),
|
||||
stamina_requirement: Math.min(factors.stamina_requirement, 1),
|
||||
pattern_complexity: Math.min(factors.pattern_complexity, 1),
|
||||
rhythmic_complexity: Math.min(factors.rhythmic_complexity, 1),
|
||||
reading_gimmick: Math.min(factors.reading_gimmick, 1)
|
||||
};
|
||||
|
||||
const rawPrediction = Object.keys(normalizedFactors).reduce((sum, key) =>
|
||||
sum + (normalizedFactors[key as keyof Factors] * weights[key as keyof Factors]), 0);
|
||||
|
||||
const prediction = (sigmoid(rawPrediction) * 11) + 1; // [1, 12]
|
||||
|
||||
const targetValue = parseFloat(target.상수);
|
||||
const diff_val = targetValue - prediction;
|
||||
totalError += Math.abs(diff_val);
|
||||
count++;
|
||||
|
||||
// 가중치 업데이트 (간단한 경사 하강법)
|
||||
for (const key in weights) {
|
||||
const k = key as keyof Factors;
|
||||
weights[k] += diff_val * normalizedFactors[k] * 0.01;
|
||||
}
|
||||
}
|
||||
}
|
||||
error = totalError / (count || 1);
|
||||
console.log(`Iteration ${iterations}: Mean Error = ${error.toFixed(4)}`);
|
||||
iterations++;
|
||||
}
|
||||
|
||||
writeFileSync(factorJsonPath, JSON.stringify(weights, null, 2));
|
||||
writeFileSync(join(workingDir, 'training_result.json'), JSON.stringify({ finalError: error, weights }, null, 2));
|
||||
console.log(`Training complete. Weights saved to ${factorJsonPath}, result saved to ${workingDir}`);
|
||||
|
||||
// 검증 로직
|
||||
console.log('\nValidation Results:');
|
||||
for (const file of validateFiles) {
|
||||
const songno = file.replace(/\D/g, '');
|
||||
const tjaContent = readFileSync(join(dataDir, 'tja', file), 'utf-8');
|
||||
const parsed = parseTja(tjaContent);
|
||||
if (!parsed) continue;
|
||||
|
||||
for (const diff of ['oni', 'edit'] as const) {
|
||||
const course = parsed[diff];
|
||||
if (!course) continue;
|
||||
|
||||
const target = records.find((r: any) => r.songno === songno && (r.diff === (diff === 'oni' ? 'oni' : 'ura')));
|
||||
if (!target) {
|
||||
console.log(`[!] No match for ${songno} diff=${diff === 'oni' ? 'oni' : 'ura'}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
const factors = factorize(course);
|
||||
const prediction = Object.keys(factors).reduce((sum, key) =>
|
||||
sum + (factors[key as keyof Factors] * weights[key as keyof Factors]), 0);
|
||||
|
||||
console.log(`[${songno}] Target: ${target.상수}, Predicted: ${prediction.toFixed(2)}, Diff: ${Math.abs(parseFloat(target.상수) - prediction).toFixed(2)}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
train();
|
||||
5
bun.lock
5
bun.lock
@@ -8,6 +8,7 @@
|
||||
"tja-parser": "^0.2.9",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "^1.3.13",
|
||||
"@types/iconv-lite": "^0.0.1",
|
||||
"@types/node": "^25.6.0",
|
||||
"typescript": "^6.0.3",
|
||||
@@ -17,10 +18,14 @@
|
||||
"packages": {
|
||||
"@babel/runtime": ["@babel/runtime@7.29.2", "", {}, "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g=="],
|
||||
|
||||
"@types/bun": ["@types/bun@1.3.13", "", { "dependencies": { "bun-types": "1.3.13" } }, "sha512-9fqXWk5YIHGGnUau9TEi+qdlTYDAnOj+xLCmSTwXfAIqXr2x4tytJb43E9uCvt09zJURKXwAtkoH4nLQfzeTXw=="],
|
||||
|
||||
"@types/iconv-lite": ["@types/iconv-lite@0.0.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-SsRBQxGw7/2/NxYJfBdiUx5a7Ms/voaUhOO9u2y9FTeTNBO1PXohzE4i3JfD8q2Te42HLTn5pyZtDf8j1bPKgQ=="],
|
||||
|
||||
"@types/node": ["@types/node@25.6.0", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ=="],
|
||||
|
||||
"bun-types": ["bun-types@1.3.13", "", { "dependencies": { "@types/node": "*" } }, "sha512-QXKeHLlOLqQX9LgYaHJfzdBaV21T63HhFJnvuRCcjZiaUDpbs5ED1MgxbMra71CsryN/1dAoXuJJJwIv/2drVA=="],
|
||||
|
||||
"complex.js": ["complex.js@2.4.3", "", {}, "sha512-UrQVSUur14tNX6tiP4y8T4w4FeJAX3bi2cIv0pu/DTLFNxoq7z2Yh83Vfzztj6Px3X/lubqQ9IrPp7Bpn6p4MQ=="],
|
||||
|
||||
"csv-parse": ["csv-parse@6.2.1", "", {}, "sha512-LRLMV+UCyfMokp8Wb411duBf1gaBKJfOfBWU9eHMJ+b+cJYZsNu3AFmjJf3+yPGd59Exz1TsMjaSFyxnYB9+IQ=="],
|
||||
|
||||
7357
datas/measure.json
Normal file
7357
datas/measure.json
Normal file
File diff suppressed because it is too large
Load Diff
12
docs/1. tja factorize.md
Normal file
12
docs/1. tja factorize.md
Normal file
@@ -0,0 +1,12 @@
|
||||
# TJA factorize
|
||||
TJA를 DNN에 사용하기 위해 factorize한다.
|
||||
|
||||
각 노트를 다음과 같이 변환한다.
|
||||
- [Note type, BPM, Scroll, Timing]
|
||||
- Note type은 0과 1만 사용한다.
|
||||
- Don -> 0
|
||||
- Ka -> 1
|
||||
- BPM은 100을 나누어 사용한다.
|
||||
- Scroll은 5를 나누어 사용한다.
|
||||
- Timing은 이전 노트와의 시간 차이를 사용한다. (단위 s)
|
||||
|
||||
40
docs/2. features.md
Normal file
40
docs/2. features.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# Feature
|
||||
DNN 분석을 위해 채보의 특성을 추출한다.
|
||||
|
||||
## Average density
|
||||
평균 밀도를 나타낸다.
|
||||
|
||||
$\frac{노트 수}{마지막 노트 타이밍 - 첫 노트 타이밍}$
|
||||
|
||||
## Peak density
|
||||
최고 밀도를 나타낸다.
|
||||
|
||||
어떤 노트를 기준으로 앞으로 1초내에 있는 노트들의 개수 중 최대값으로 구한다.
|
||||
|
||||
## Average BPM
|
||||
평균 BPM을 나타낸다.
|
||||
|
||||
$\frac{\Sigma BPM}{노트 수}$
|
||||
|
||||
## Average BPM 2
|
||||
평균 BPM을 나타내나, 다른 방식으로 구한다.
|
||||
극소수의 노트만 BPM이 다를 경우 평균 BPM에 미치는 영향이 클 수 있기 때문에, BPM의 제곱을 총합하여 평균을 구한다.
|
||||
|
||||
$\sqrt{\frac{\Sigma BPM^2}{노트수}}$
|
||||
|
||||
## BPM Change
|
||||
BPM 변화 횟수를 나타낸다. BPM 흔들림을 제외하기 위해, 이전 노트와의 BPM차이가 1.5 이상일 떄 1 증가한다.
|
||||
|
||||
## Scroll Change
|
||||
스크롤 변화 횟수를 나타낸다. 노트의 $BPM \times Scroll$의 값이 이전 노트와 1.5 이상 차이날 때 1 증가한다.
|
||||
|
||||
## Rhythm Complexity
|
||||
i번째 노트와 i-1번쨰 노트의 간격이 i-1번쨰 노트와 i-2번째 노트의 간격의 비율이 2의 거듭제곱이 아닐 때 1 증가한다.
|
||||
|
||||
## Color Complexity
|
||||
i번째 노트와 i-2번쨰 노트가 다른 종류일 때 증가하며, 간격의 제곱의 역수에 비례한다.
|
||||
|
||||
$\frac{\mathrm{color\ changed\ ?\ 1\ :\ 0}}{\Delta t^2}$
|
||||
|
||||
## Note Count
|
||||
노트의 개수
|
||||
56
docs/3-1.xgboost.md
Normal file
56
docs/3-1.xgboost.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# XGBoost 기반 난이도 상수 예측 모델
|
||||
|
||||
이 문서는 프로젝트의 핵심 학습 엔진인 XGBoost 모델의 구조, 하이퍼파라미터 및 파이프라인 과정을 설명합니다.
|
||||
|
||||
## 1. 모델 개요
|
||||
본 프로젝트는 태고의 달인 채보의 미세한 난이도 차이(상수)를 예측하기 위해 **XGBoost (Extreme Gradient Boosting)** 회귀 모델을 사용합니다. 8가지 주요 피처를 입력으로 받아 0.1 단위의 정밀한 난이도 상수를 출력하는 것을 목표로 합니다.
|
||||
|
||||
## 2. 하이퍼파라미터 설정
|
||||
`train/train_xgboost.py`에 정의된 주요 설정값은 다음과 같습니다.
|
||||
|
||||
| 파라미터 | 설정값 | 설명 |
|
||||
| :--- | :--- | :--- |
|
||||
| `N_ESTIMATORS` | 500 | 결정 트리의 개수 |
|
||||
| `MAX_DEPTH` | 6 | 각 트리의 최대 깊이 |
|
||||
| `LEARNING_RATE` | 0.05 | 학습률 (경사 하강 단계의 크기) |
|
||||
| `SUBSAMPLE` | 0.8 | 각 트리 학습 시 사용할 데이터 샘플 비율 (과적합 방지) |
|
||||
| `COLSAMPLE_BYTREE` | 0.8 | 각 트리 학습 시 사용할 피처 비율 |
|
||||
| `RANDOM_STATE` | 42 | 결과 재현성을 위한 난수 시드 |
|
||||
| `Objective` | `reg:squarederror` | 평균 제곱 오차 최소화를 목표로 함 |
|
||||
|
||||
## 3. 학습 프로세스 (Training Pipeline)
|
||||
|
||||
### A. 데이터 로드 및 매칭
|
||||
- `features.json`: 전처리 단계에서 추출된 채보별 피처 데이터.
|
||||
- `measure.csv`: 각 곡의 `songno`, `diff`에 대응하는 실제 난이도 상수(Label).
|
||||
- 두 데이터를 `(songno, difficulty)` 키를 기준으로 매칭하여 학습 데이터셋을 구성합니다.
|
||||
|
||||
### B. 전처리 및 정규화
|
||||
- **Feature Selection**: `songno`, `difficulty`를 제외한 모든 수치형 데이터를 피처로 사용합니다.
|
||||
- **Scaling**: `sklearn.preprocessing.StandardScaler`를 사용하여 피처의 평균을 0, 분산을 1로 정규화합니다. 이는 `color_complexity`와 같이 수치 범위가 큰 피처가 모델에 과도한 영향을 주는 것을 방지합니다.
|
||||
|
||||
### C. 모델 학습 및 지속 학습 (Warm Start)
|
||||
- `CONTINUE_TRAINING` 옵션이 활성화된 경우, 기존에 저장된 `model.pkl`과 `scaler.pkl`을 로드하여 이전 상태를 유지하며 추가 학습을 진행합니다.
|
||||
|
||||
## 4. 평가 지표
|
||||
- **MAE (Mean Absolute Error)**: 실제 상수와 예측값 간의 절대 오차 평균.
|
||||
- **Accuracy (±0.1)**: 예측값이 실제 값과 0.1 이내로 일치하는 비율을 측정하여 실질적인 예측 성능을 평가합니다.
|
||||
- **Feature Importance**: 학습 완료 후 각 피처가 예측에 기여한 중요도를 출력하여 모델의 판단 근거를 확인합니다.
|
||||
|
||||
## 5. 예측 프로세스 (Inference)
|
||||
`predict/predict_xgboost.py`를 통해 다음 과정을 거쳐 결과를 도출합니다.
|
||||
|
||||
1. 학습 시 저장된 `model.pkl`, `scaler.pkl`, `features.txt` 로드.
|
||||
2. 입력받은 `songno`에 해당하는 피처를 `features.json`에서 탐색.
|
||||
3. 학습 시와 동일한 순서로 피처 벡터를 구성하고 Scaler를 적용.
|
||||
4. 모델을 통해 예측을 수행하고 결과를 JSON 배열 형태로 출력.
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"songno": "1000",
|
||||
"diff": "oni",
|
||||
"predicted": 11.2345
|
||||
}
|
||||
]
|
||||
```
|
||||
BIN
output/.DS_Store
vendored
Normal file
BIN
output/.DS_Store
vendored
Normal file
Binary file not shown.
9824
output/lightgbm/compare.json
Normal file
9824
output/lightgbm/compare.json
Normal file
File diff suppressed because it is too large
Load Diff
17594
output/lightgbm/features.json
Normal file
17594
output/lightgbm/features.json
Normal file
File diff suppressed because it is too large
Load Diff
8
output/lightgbm/features_lgbm.txt
Normal file
8
output/lightgbm/features_lgbm.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
bpm_avg
|
||||
bpm_change
|
||||
color_complexity
|
||||
density_avg
|
||||
density_peak
|
||||
note_count
|
||||
rhythm_complexity
|
||||
scroll_change
|
||||
BIN
output/lightgbm/model_lgbm.pkl
Normal file
BIN
output/lightgbm/model_lgbm.pkl
Normal file
Binary file not shown.
BIN
output/lightgbm/scaler_lgbm.pkl
Normal file
BIN
output/lightgbm/scaler_lgbm.pkl
Normal file
Binary file not shown.
17594
output/lightgbm/temp.json
Normal file
17594
output/lightgbm/temp.json
Normal file
File diff suppressed because it is too large
Load Diff
9824
output/lightgbm2/compare.json
Normal file
9824
output/lightgbm2/compare.json
Normal file
File diff suppressed because it is too large
Load Diff
17594
output/lightgbm2/features.json
Normal file
17594
output/lightgbm2/features.json
Normal file
File diff suppressed because it is too large
Load Diff
8
output/lightgbm2/features_lgbm.txt
Normal file
8
output/lightgbm2/features_lgbm.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
bpm_avg
|
||||
bpm_change
|
||||
color_complexity
|
||||
density_avg
|
||||
density_peak
|
||||
note_count
|
||||
rhythm_complexity
|
||||
scroll_change
|
||||
BIN
output/lightgbm2/model_lgbm.pkl
Normal file
BIN
output/lightgbm2/model_lgbm.pkl
Normal file
Binary file not shown.
BIN
output/lightgbm2/scaler_lgbm.pkl
Normal file
BIN
output/lightgbm2/scaler_lgbm.pkl
Normal file
Binary file not shown.
17594
output/lightgbm2/temp.json
Normal file
17594
output/lightgbm2/temp.json
Normal file
File diff suppressed because it is too large
Load Diff
9824
output/lightgbm3/compare.json
Normal file
9824
output/lightgbm3/compare.json
Normal file
File diff suppressed because it is too large
Load Diff
17594
output/lightgbm3/features.json
Normal file
17594
output/lightgbm3/features.json
Normal file
File diff suppressed because it is too large
Load Diff
8
output/lightgbm3/features_lgbm.txt
Normal file
8
output/lightgbm3/features_lgbm.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
bpm_avg
|
||||
bpm_change
|
||||
color_complexity
|
||||
density_avg
|
||||
density_peak
|
||||
note_count
|
||||
rhythm_complexity
|
||||
scroll_change
|
||||
BIN
output/lightgbm3/model_lgbm.pkl
Normal file
BIN
output/lightgbm3/model_lgbm.pkl
Normal file
Binary file not shown.
BIN
output/lightgbm3/scaler_lgbm.pkl
Normal file
BIN
output/lightgbm3/scaler_lgbm.pkl
Normal file
Binary file not shown.
17594
output/lightgbm3/temp.json
Normal file
17594
output/lightgbm3/temp.json
Normal file
File diff suppressed because it is too large
Load Diff
9824
output/xgboost/compare.json
Normal file
9824
output/xgboost/compare.json
Normal file
File diff suppressed because it is too large
Load Diff
17594
output/xgboost/features.json
Normal file
17594
output/xgboost/features.json
Normal file
File diff suppressed because it is too large
Load Diff
8
output/xgboost/features.txt
Normal file
8
output/xgboost/features.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
bpm_avg
|
||||
bpm_change
|
||||
color_complexity
|
||||
density_avg
|
||||
density_peak
|
||||
note_count
|
||||
rhythm_complexity
|
||||
scroll_change
|
||||
BIN
output/xgboost/model.pkl
Normal file
BIN
output/xgboost/model.pkl
Normal file
Binary file not shown.
BIN
output/xgboost/scaler.pkl
Normal file
BIN
output/xgboost/scaler.pkl
Normal file
Binary file not shown.
17594
output/xgboost/temp.json
Normal file
17594
output/xgboost/temp.json
Normal file
File diff suppressed because it is too large
Load Diff
74
output/xgboost_copy/features.json
Normal file
74
output/xgboost_copy/features.json
Normal file
@@ -0,0 +1,74 @@
|
||||
[
|
||||
{
|
||||
"songno": "XODUS",
|
||||
"difficulty": "oni",
|
||||
"note_count": 1007,
|
||||
"density_avg": 8.14959935897436,
|
||||
"density_peak": 17,
|
||||
"bpm_avg": 202,
|
||||
"bpm_change": 0,
|
||||
"scroll_change": 14,
|
||||
"rhythm_complexity": 868,
|
||||
"color_complexity": 0.012565274045963932
|
||||
},
|
||||
{
|
||||
"songno": "Destructive Little Sister",
|
||||
"difficulty": "oni",
|
||||
"note_count": 1119,
|
||||
"density_avg": 7.917452830188679,
|
||||
"density_peak": 21,
|
||||
"bpm_avg": 247.5,
|
||||
"bpm_change": 0,
|
||||
"scroll_change": 17,
|
||||
"rhythm_complexity": 1079,
|
||||
"color_complexity": 0.016291673920775917
|
||||
},
|
||||
{
|
||||
"songno": "7 Wonders",
|
||||
"difficulty": "oni",
|
||||
"note_count": 794,
|
||||
"density_avg": 5.571929824561403,
|
||||
"density_peak": 12,
|
||||
"bpm_avg": 168,
|
||||
"bpm_change": 0,
|
||||
"scroll_change": 0,
|
||||
"rhythm_complexity": 726,
|
||||
"color_complexity": 0.006656416024691356
|
||||
},
|
||||
{
|
||||
"songno": "7 Wonders",
|
||||
"difficulty": "ura",
|
||||
"note_count": 1207,
|
||||
"density_avg": 8.47017543859649,
|
||||
"density_peak": 15,
|
||||
"bpm_avg": 168,
|
||||
"bpm_change": 0,
|
||||
"scroll_change": 0,
|
||||
"rhythm_complexity": 965,
|
||||
"color_complexity": 0.01463965596985236
|
||||
},
|
||||
{
|
||||
"songno": "Destruction 3 2 1",
|
||||
"difficulty": "oni",
|
||||
"note_count": 1160,
|
||||
"density_avg": 7.46659375,
|
||||
"density_peak": 15,
|
||||
"bpm_avg": 321.3209999999973,
|
||||
"bpm_change": 0,
|
||||
"scroll_change": 5,
|
||||
"rhythm_complexity": 1101,
|
||||
"color_complexity": 0.012682773678672012
|
||||
},
|
||||
{
|
||||
"songno": "Destruction 3 2 1",
|
||||
"difficulty": "ura",
|
||||
"note_count": 1491,
|
||||
"density_avg": 9.59714765625,
|
||||
"density_peak": 20,
|
||||
"bpm_avg": 321.32099999999707,
|
||||
"bpm_change": 0,
|
||||
"scroll_change": 8,
|
||||
"rhythm_complexity": 1417,
|
||||
"color_complexity": 0.028926671611070473
|
||||
}
|
||||
]
|
||||
@@ -5,6 +5,7 @@
|
||||
"tja-parser": "^0.2.9"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "^1.3.13",
|
||||
"@types/iconv-lite": "^0.0.1",
|
||||
"@types/node": "^25.6.0",
|
||||
"typescript": "^6.0.3"
|
||||
|
||||
15
predict.sh
15
predict.sh
@@ -1,15 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Arguments: script_dir working_dir tja_path difficulty
|
||||
SCRIPT_DIR=${1:-"script"}
|
||||
WORKING_DIR=${2:-"."}
|
||||
TJA_PATH=${3}
|
||||
DIFFICULTY=${4:-"oni"}
|
||||
|
||||
if [ -z "$TJA_PATH" ]; then
|
||||
echo "Usage: ./redict.sh <script_dir> <working_dir> <tja_path> [difficulty: oni|edit]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Running prediction for $TJA_PATH..."
|
||||
bun "$SCRIPT_DIR/predict.ts" "$WORKING_DIR" "$SCRIPT_DIR" "$TJA_PATH" "$DIFFICULTY"
|
||||
70
predict/predict_lightgbm.py
Normal file
70
predict/predict_lightgbm.py
Normal file
@@ -0,0 +1,70 @@
|
||||
import argparse
|
||||
import json
|
||||
import math
|
||||
import os
|
||||
import joblib
|
||||
import numpy as np
|
||||
import warnings
|
||||
|
||||
# 경고 무시 (Feature name 관련 경고 제거)
|
||||
warnings.filterwarnings("ignore", category=UserWarning)
|
||||
|
||||
# =========================================================
|
||||
# 파일명
|
||||
# =========================================================
|
||||
|
||||
FEATURES_FILENAME = "features.json"
|
||||
MODEL_FILENAME = "model_lgbm.pkl"
|
||||
SCALER_FILENAME = "scaler_lgbm.pkl"
|
||||
FEATURE_NAMES_FILENAME = "features_lgbm.txt"
|
||||
|
||||
def safe_float(value):
|
||||
if value is None: return 0.0
|
||||
x = float(value)
|
||||
return x if math.isfinite(x) else 0.0
|
||||
|
||||
def predict(working_dir: str, songno: str, feature: str = None):
|
||||
features_path = os.path.join(working_dir, FEATURES_FILENAME) if feature is None else feature
|
||||
model_path = os.path.join(working_dir, MODEL_FILENAME)
|
||||
scaler_path = os.path.join(working_dir, SCALER_FILENAME)
|
||||
feature_names_path = os.path.join(working_dir, FEATURE_NAMES_FILENAME)
|
||||
|
||||
if not os.path.exists(model_path):
|
||||
raise FileNotFoundError(f"Model not found at {model_path}")
|
||||
|
||||
model = joblib.load(model_path)
|
||||
scaler = joblib.load(scaler_path)
|
||||
|
||||
with open(feature_names_path, "r", encoding="utf-8") as f:
|
||||
feature_names = [line.strip() for line in f.readlines() if line.strip()]
|
||||
|
||||
with open(features_path, "r", encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
|
||||
targets = [item for item in data if str(item["songno"]) == str(songno)]
|
||||
if len(targets) == 0:
|
||||
raise ValueError(f"Chart not found: songno={songno}")
|
||||
|
||||
results = []
|
||||
for target in targets:
|
||||
row = [safe_float(target.get(k, 0)) for k in feature_names]
|
||||
X = np.array([row], dtype=np.float32)
|
||||
X = scaler.transform(X)
|
||||
pred = model.predict(X)[0]
|
||||
|
||||
results.append({
|
||||
"songno": str(songno),
|
||||
"diff": target.get("difficulty", "unknown"),
|
||||
"predicted": round(float(pred), 4)
|
||||
})
|
||||
|
||||
print(json.dumps(results, indent=2, ensure_ascii=False))
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--workingDir", required=True)
|
||||
parser.add_argument("--feature", required=False)
|
||||
parser.add_argument("--songno", required=True)
|
||||
args = parser.parse_args()
|
||||
|
||||
predict(args.workingDir, args.songno, args.feature)
|
||||
164
predict/predict_xgboost.py
Normal file
164
predict/predict_xgboost.py
Normal file
@@ -0,0 +1,164 @@
|
||||
import argparse
|
||||
import json
|
||||
import math
|
||||
import os
|
||||
import joblib
|
||||
import numpy as np
|
||||
|
||||
|
||||
# =========================================================
|
||||
# 파일명
|
||||
# =========================================================
|
||||
|
||||
FEATURES_FILENAME = "features.json"
|
||||
|
||||
MODEL_FILENAME = "model.pkl"
|
||||
SCALER_FILENAME = "scaler.pkl"
|
||||
FEATURE_NAMES_FILENAME = "features.txt"
|
||||
|
||||
|
||||
# =========================================================
|
||||
# safe float
|
||||
# =========================================================
|
||||
|
||||
def safe_float(value):
|
||||
if value is None:
|
||||
return 0.0
|
||||
|
||||
x = float(value)
|
||||
|
||||
if not math.isfinite(x):
|
||||
return 0.0
|
||||
|
||||
return x
|
||||
|
||||
|
||||
# =========================================================
|
||||
# 예측 함수
|
||||
# =========================================================
|
||||
|
||||
def predict(
|
||||
working_dir: str,
|
||||
songno: str,
|
||||
feature: str = None
|
||||
):
|
||||
# =====================================================
|
||||
# 경로
|
||||
# =====================================================
|
||||
|
||||
features_path = (
|
||||
os.path.join(working_dir, FEATURES_FILENAME)
|
||||
if feature is None
|
||||
else feature
|
||||
)
|
||||
|
||||
model_path = os.path.join(
|
||||
working_dir,
|
||||
MODEL_FILENAME
|
||||
)
|
||||
|
||||
scaler_path = os.path.join(
|
||||
working_dir,
|
||||
SCALER_FILENAME
|
||||
)
|
||||
|
||||
feature_names_path = os.path.join(
|
||||
working_dir,
|
||||
FEATURE_NAMES_FILENAME
|
||||
)
|
||||
|
||||
# =====================================================
|
||||
# 모델 로드
|
||||
# =====================================================
|
||||
|
||||
model = joblib.load(model_path)
|
||||
scaler = joblib.load(scaler_path)
|
||||
|
||||
# =====================================================
|
||||
# feature 이름 로드
|
||||
# =====================================================
|
||||
|
||||
with open(feature_names_path, "r", encoding="utf-8") as f:
|
||||
feature_names = [
|
||||
line.strip()
|
||||
for line in f.readlines()
|
||||
if line.strip()
|
||||
]
|
||||
|
||||
# =====================================================
|
||||
# features.json 로드
|
||||
# =====================================================
|
||||
|
||||
with open(features_path, "r", encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
|
||||
# =====================================================
|
||||
# target 찾기
|
||||
# =====================================================
|
||||
|
||||
targets = []
|
||||
|
||||
for item in data:
|
||||
if str(item["songno"]) == str(songno):
|
||||
targets.append(item)
|
||||
|
||||
if len(targets) == 0:
|
||||
raise ValueError(f"Chart not found: songno={songno}")
|
||||
|
||||
# =====================================================
|
||||
# feature vector 생성
|
||||
# =====================================================
|
||||
|
||||
results = []
|
||||
|
||||
for target in targets:
|
||||
row = []
|
||||
|
||||
for k in feature_names:
|
||||
value = target.get(k, 0)
|
||||
row.append(safe_float(value))
|
||||
|
||||
X = np.array([row], dtype=np.float32)
|
||||
|
||||
X = scaler.transform(X)
|
||||
|
||||
pred = model.predict(X)[0]
|
||||
|
||||
results.append({
|
||||
"songno": str(songno),
|
||||
"diff": target.get("difficulty", "unknown"),
|
||||
"predicted": round(float(pred), 4)
|
||||
})
|
||||
|
||||
print(json.dumps(results, indent=2, ensure_ascii=False))
|
||||
|
||||
|
||||
# =========================================================
|
||||
# main
|
||||
# =========================================================
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
parser.add_argument(
|
||||
"--workingDir",
|
||||
required=True
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--feature",
|
||||
required=False
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--songno",
|
||||
required=True
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
predict(
|
||||
args.workingDir,
|
||||
args.songno,
|
||||
args.feature
|
||||
)
|
||||
18
preprocess/factorize.ts
Normal file
18
preprocess/factorize.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { Course } from "tja-parser";
|
||||
import { filterHitNotes } from "./util";
|
||||
|
||||
export type NoteFactor = [type: 0 | 1, bpm: number, scroll: number, delta: number]
|
||||
export function factorize(course: Course) {
|
||||
const hitNotes = filterHitNotes(course);
|
||||
const factors: NoteFactor[] = [];
|
||||
for (let i = 0; i < hitNotes.length; i++) {
|
||||
const note = hitNotes[i];
|
||||
factors.push([
|
||||
(note.type === 1 || note.type === 3) ? 0 : 1,
|
||||
note.getBPM() / 100,
|
||||
note.getScroll() / 5,
|
||||
i === 0 ? 0 : (note.getTimingMS() - hitNotes[i - 1].getTimingMS()) / 1000
|
||||
])
|
||||
}
|
||||
return factors;
|
||||
}
|
||||
121
preprocess/featurize.ts
Normal file
121
preprocess/featurize.ts
Normal file
@@ -0,0 +1,121 @@
|
||||
import { Course, Bar, Note, HitNote } from 'tja-parser';
|
||||
|
||||
export namespace Feature {
|
||||
export function filterHitNotes(course: Course) {
|
||||
const notes: HitNote[] = [];
|
||||
course.noteGroups.forEach((g) => {
|
||||
if (g instanceof Bar) {
|
||||
for (const note of g.getNotes()) {
|
||||
if (note instanceof HitNote) {
|
||||
notes.push(note);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return notes;
|
||||
}
|
||||
|
||||
export function getAllNotes(course: Course) {
|
||||
const notes: { type: number, time: number }[] = [];
|
||||
for (const group of course.noteGroups) {
|
||||
if (group instanceof Bar) {
|
||||
notes.push(...group.getNotes().map((note) => ({
|
||||
//@ts-expect-error
|
||||
type: note.type,
|
||||
time: note.getTimingMS()
|
||||
})));
|
||||
}
|
||||
}
|
||||
return notes.sort((a, b) => a.time - b.time).filter(n => [1, 2, 3, 4].includes(n.type));
|
||||
}
|
||||
|
||||
// 밀도 관련
|
||||
export function getAverageDensity(notes: HitNote[]) {
|
||||
if (notes.length === 0) {
|
||||
return 0;
|
||||
}
|
||||
return notes.length / (notes[notes.length - 1].getTimingMS() - notes[0].getTimingMS()) * 1000
|
||||
}
|
||||
|
||||
export function getPeakDensity(notes: HitNote[]) {
|
||||
let peakDensity = 0;
|
||||
for (let i = 0; i < notes.length; i++) {
|
||||
let noteCount = 1;
|
||||
for (let j = i + 1; j < notes.length && (notes[j].getTimingMS() - notes[i].getTimingMS() <= 1000); j++) {
|
||||
noteCount++;
|
||||
}
|
||||
if (peakDensity < noteCount) {
|
||||
peakDensity = noteCount;
|
||||
}
|
||||
}
|
||||
return peakDensity;
|
||||
}
|
||||
|
||||
// BPM 관련
|
||||
export function getAverageBPM(notes: HitNote[]) {
|
||||
if(notes.length === 0) return 0;
|
||||
const averageBPM = notes.reduce((p, note) => p + note.getBPM().valueOf(), 0) / notes.length;
|
||||
return averageBPM;
|
||||
}
|
||||
|
||||
export function getBpmChange(notes: HitNote[]) {
|
||||
let bpmChange = 0;
|
||||
for (let i = 1; i < notes.length; i++) {
|
||||
if (Math.abs(notes[i].getBPM() - notes[i - 1].getBPM()) > 1.5) {
|
||||
bpmChange++;
|
||||
}
|
||||
};
|
||||
return bpmChange;
|
||||
}
|
||||
|
||||
// 스크롤 변화
|
||||
export function getScrollChange(notes: HitNote[]) {
|
||||
let bpmChange = 0;
|
||||
for (let i = 1; i < notes.length; i++) {
|
||||
if (Math.abs(notes[i].getBPM() * notes[i].getScroll() - notes[i - 1].getBPM() * notes[i - 1].getScroll()) > 1.5) {
|
||||
bpmChange++;
|
||||
}
|
||||
};
|
||||
return bpmChange;
|
||||
}
|
||||
|
||||
export function getRhythmComplexity(notes: HitNote[]) {
|
||||
let complexity = 0;
|
||||
for (let i = 2; i < notes.length; i++) {
|
||||
const d1 = notes[i].getTimingMS() - notes[i - 1].getTimingMS()
|
||||
const d2 = notes[i - 1].getTimingMS() - notes[i - 2].getTimingMS()
|
||||
|
||||
const ratio = d1 / d2;
|
||||
const log = Math.log2(ratio);
|
||||
|
||||
if (Math.abs(log - Math.round(log)) < 1e-3) {
|
||||
complexity++;
|
||||
}
|
||||
}
|
||||
return complexity;
|
||||
}
|
||||
|
||||
export function getColorComplexity(notes: HitNote[]) {
|
||||
let complexity = 0;
|
||||
for (let i = 2; i < notes.length; i++) {
|
||||
if (notes[i].type % 2 != notes[i - 2].type % 2) {
|
||||
complexity += 1 / ((notes[i].getTimingMS() - notes[i - 2].getTimingMS()) ** 2)
|
||||
}
|
||||
}
|
||||
return complexity;
|
||||
}
|
||||
}
|
||||
|
||||
export function featurize(course: Course) {
|
||||
const notes = Feature.filterHitNotes(course)
|
||||
return {
|
||||
note_count: notes.length,
|
||||
density_avg: Feature.getAverageDensity(notes),
|
||||
density_peak: Feature.getPeakDensity(notes),
|
||||
bpm_avg: Feature.getAverageBPM(notes),
|
||||
bpm_change: Feature.getBpmChange(notes),
|
||||
scroll_change: Feature.getScrollChange(notes),
|
||||
rhythm_complexity: Feature.getRhythmComplexity(notes),
|
||||
color_complexity: Feature.getColorComplexity(notes)
|
||||
};
|
||||
}
|
||||
45
preprocess/parse.ts
Normal file
45
preprocess/parse.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import tjaParser, { Bar, Branch, Course } from 'tja-parser'
|
||||
|
||||
export function parseTja(tja: string): Partial<Record<'oni' | 'edit', Course>> {
|
||||
const song = tjaParser.Song.parse(tja);
|
||||
|
||||
let oni: Course | undefined = undefined;
|
||||
let edit: Course | undefined = undefined;
|
||||
|
||||
if (song.course?.oni) {
|
||||
const noteGroups = song.course.oni.noteGroups;
|
||||
oni = song.course.oni;
|
||||
oni.noteGroups = []
|
||||
|
||||
for (const noteGroup of noteGroups) {
|
||||
if (noteGroup instanceof Bar) {
|
||||
oni.pushNoteGroups(noteGroup)
|
||||
}
|
||||
else if (noteGroup instanceof Branch) {
|
||||
const bar = noteGroup.master || noteGroup.advanced || noteGroup.normal;
|
||||
if (bar) {
|
||||
oni.pushNoteGroups(...bar)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (song.course?.edit) {
|
||||
const noteGroups = song.course.edit.noteGroups;
|
||||
edit = song.course.edit;
|
||||
edit.noteGroups = []
|
||||
|
||||
for (const noteGroup of noteGroups) {
|
||||
if (noteGroup instanceof Bar) {
|
||||
edit.pushNoteGroups(noteGroup)
|
||||
}
|
||||
else if (noteGroup instanceof Branch) {
|
||||
const bar = noteGroup.master || noteGroup.advanced || noteGroup.normal;
|
||||
if (bar) {
|
||||
edit.pushNoteGroups(...bar)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return { oni, edit }
|
||||
}
|
||||
15
preprocess/util.ts
Normal file
15
preprocess/util.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { Bar, Course, HitNote } from "tja-parser";
|
||||
|
||||
export function filterHitNotes(course: Course): HitNote[] {
|
||||
const notes: HitNote[] = [];
|
||||
course.noteGroups.forEach((g) => {
|
||||
if (g instanceof Bar) {
|
||||
for (const note of g.getNotes()) {
|
||||
if (note instanceof HitNote) {
|
||||
notes.push(note);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return notes;
|
||||
}
|
||||
148
script/compare.ts
Normal file
148
script/compare.ts
Normal file
@@ -0,0 +1,148 @@
|
||||
import Bun from 'bun';
|
||||
import path from 'node:path';
|
||||
import { parseArgs } from 'node:util';
|
||||
import fs from 'node:fs';
|
||||
|
||||
const { values } = parseArgs({
|
||||
args: Bun.argv,
|
||||
options: {
|
||||
workingDir: { type: "string" },
|
||||
dataDir: { type: "string" },
|
||||
script: { type: "string" },
|
||||
},
|
||||
strict: true,
|
||||
allowPositionals: true,
|
||||
});
|
||||
|
||||
if (!values.workingDir || !values.dataDir || !values.script) {
|
||||
console.error("Usage: bun run script/compare.ts --workingDir <dir> --dataDir <dir> --script <python_script>");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const workingDir = values.workingDir;
|
||||
const dataDir = values.dataDir;
|
||||
const predictScript = values.script;
|
||||
const tempFileName = "temp.json";
|
||||
const tempFilePath = path.join(workingDir, tempFileName);
|
||||
|
||||
// 1. 전처리 실행 (temp.json 생성하여 기존 features.json 보존)
|
||||
console.log("Step 1: Running preprocessing to temp.json...");
|
||||
const preprocessResult = Bun.spawnSync([
|
||||
"bun", "run", "script/preprocess.ts",
|
||||
"--workingDir", workingDir,
|
||||
"--dataDir", dataDir,
|
||||
"--fileName", tempFileName
|
||||
]);
|
||||
|
||||
if (!preprocessResult.success) {
|
||||
console.error("Preprocessing failed");
|
||||
console.error(preprocessResult.stderr.toString());
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// 2. measure.csv 로드
|
||||
console.log("Step 2: Loading measure.csv...");
|
||||
const measurePath = path.join(dataDir, "measure.csv");
|
||||
const measureContent = fs.readFileSync(measurePath, "utf-8");
|
||||
const measureMap = new Map<string, number>();
|
||||
|
||||
measureContent.split("\n").forEach((line, index) => {
|
||||
if (index === 0 || !line.trim()) return;
|
||||
const parts = line.split(",");
|
||||
if (parts.length >= 3) {
|
||||
const constant = parts[0];
|
||||
const songno = parts[1];
|
||||
const diff = parts[2];
|
||||
measureMap.set(`${songno.trim()}_${diff.trim()}`, parseFloat(constant));
|
||||
}
|
||||
});
|
||||
|
||||
// 3. temp.json 로드하여 대상 곡 목록 추출
|
||||
const features = JSON.parse(fs.readFileSync(tempFilePath, "utf-8"));
|
||||
const uniqueSongnos = Array.from(new Set(features.map((f: any) => f.songno)));
|
||||
|
||||
// 4. 예측 및 비교
|
||||
console.log(`Step 3: Predicting and comparing ${uniqueSongnos.length} songs...`);
|
||||
const comparisonResults: any[] = [];
|
||||
let processedCount = 0;
|
||||
|
||||
for (const songno of uniqueSongnos) {
|
||||
try {
|
||||
const predictProcess = Bun.spawnSync([
|
||||
"python3", predictScript,
|
||||
"--workingDir", workingDir,
|
||||
"--songno", songno as string,
|
||||
"--feature", tempFilePath
|
||||
]);
|
||||
|
||||
if (!predictProcess.success) {
|
||||
console.error(`\n[ERROR] Failed to predict songno ${songno}`);
|
||||
console.error(predictProcess.stderr.toString());
|
||||
processedCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
const output = predictProcess.stdout.toString().trim();
|
||||
// JSON 부분만 추출 (경고문 등이 섞여있을 경우 대비)
|
||||
const jsonStart = output.indexOf('[');
|
||||
const jsonEnd = output.lastIndexOf(']') + 1;
|
||||
|
||||
if (jsonStart === -1 || jsonEnd === 0) {
|
||||
console.error(`\n[ERROR] Invalid output format for songno ${songno}`);
|
||||
processedCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
const predictions = JSON.parse(output.substring(jsonStart, jsonEnd));
|
||||
|
||||
predictions.forEach((pred: any) => {
|
||||
const key = `${pred.songno}_${pred.diff}`;
|
||||
const actual = measureMap.get(key);
|
||||
|
||||
if (actual !== undefined) {
|
||||
comparisonResults.push({
|
||||
songno: pred.songno,
|
||||
diff: pred.diff,
|
||||
actual: actual,
|
||||
predicted: pred.predicted,
|
||||
error: Math.abs(actual - pred.predicted)
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
processedCount++;
|
||||
if (processedCount % 10 === 0 || processedCount === uniqueSongnos.length) {
|
||||
const percent = ((processedCount / uniqueSongnos.length) * 100).toFixed(1);
|
||||
process.stdout.write(`\rProgress: ${processedCount}/${uniqueSongnos.length} (${percent}%) `);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(`\nError processing songno ${songno}:`, err);
|
||||
processedCount++;
|
||||
}
|
||||
}
|
||||
console.log("\nPrediction finished.");
|
||||
|
||||
// 5. 결과 분석 및 저장
|
||||
if (comparisonResults.length === 0) {
|
||||
console.error("No comparison results were generated.");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const avgError = comparisonResults.reduce((acc, curr) => acc + curr.error, 0) / comparisonResults.length;
|
||||
const resultData = {
|
||||
summary: {
|
||||
total_compared: comparisonResults.length,
|
||||
average_absolute_error: avgError,
|
||||
timestamp: new Date().toISOString(),
|
||||
script_used: predictScript
|
||||
},
|
||||
details: comparisonResults.sort((a, b) => b.error - a.error)
|
||||
};
|
||||
|
||||
const comparePath = path.join(workingDir, "compare.json");
|
||||
fs.writeFileSync(comparePath, JSON.stringify(resultData, null, 2), "utf-8");
|
||||
|
||||
console.log(`\nComparison complete!`);
|
||||
console.log(`Total compared: ${comparisonResults.length}`);
|
||||
console.log(`Average Error: ${avgError.toFixed(4)}`);
|
||||
console.log(`Results saved to: ${comparePath}`);
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"physical_density": 1,
|
||||
"stamina_requirement": 1,
|
||||
"pattern_complexity": 1,
|
||||
"rhythmic_complexity": 1,
|
||||
"reading_gimmick": 1
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
import { Bar, Course } from 'tja-parser';
|
||||
|
||||
export interface Factors {
|
||||
physical_density: number;
|
||||
stamina_requirement: number;
|
||||
pattern_complexity: number;
|
||||
rhythmic_complexity: number;
|
||||
reading_gimmick: number;
|
||||
}
|
||||
|
||||
export namespace Factor {
|
||||
export function getAllNotes(course: Course): any[] {
|
||||
const notes: any[] = [];
|
||||
for (const group of course.noteGroups) {
|
||||
if (group instanceof Bar) {
|
||||
notes.push(...group.getNotes());
|
||||
}
|
||||
}
|
||||
return notes;
|
||||
}
|
||||
|
||||
export function getPhysicalDensity(course: Course): number {
|
||||
const notes = getAllNotes(course);
|
||||
if (notes.length === 0) return 0;
|
||||
const bars = course.noteGroups.length;
|
||||
return notes.length / (bars || 1);
|
||||
}
|
||||
|
||||
export function getStaminaRequirement(course: Course): number {
|
||||
const notes = getAllNotes(course);
|
||||
let maxStream = 0;
|
||||
let currentStream = 0;
|
||||
|
||||
for (const note of notes) {
|
||||
if (note.type !== '0') {
|
||||
currentStream++;
|
||||
} else {
|
||||
maxStream = Math.max(maxStream, currentStream);
|
||||
currentStream = 0;
|
||||
}
|
||||
}
|
||||
return Math.max(maxStream, currentStream) / 100;
|
||||
}
|
||||
|
||||
export function getPatternComplexity(course: Course): number {
|
||||
const notes = getAllNotes(course).filter(n => n.type === '1' || n.type === '2');
|
||||
let transitions = 0;
|
||||
|
||||
for (let i = 1; i < notes.length; i++) {
|
||||
if (notes[i].type !== notes[i-1].type) {
|
||||
transitions++;
|
||||
}
|
||||
}
|
||||
return notes.length > 0 ? transitions / notes.length : 0;
|
||||
}
|
||||
|
||||
export function getRhythmicComplexity(course: Course): number {
|
||||
let complexNotes = 0;
|
||||
const allNotes = getAllNotes(course);
|
||||
for (const group of course.noteGroups) {
|
||||
if (group instanceof Bar) {
|
||||
const division = group.getNotes().length;
|
||||
if (division % 4 !== 0 || division > 16) {
|
||||
complexNotes += division;
|
||||
}
|
||||
}
|
||||
}
|
||||
return allNotes.length > 0 ? complexNotes / allNotes.length : 0;
|
||||
}
|
||||
|
||||
export function getReadingGimmick(course: Course): number {
|
||||
// BPM 변화나 Scroll 변화 빈도 측정
|
||||
// tja-parser의 구조에 따라 구현 (여기서는 placeholder)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
export function factorize(course: Course): Factors {
|
||||
return {
|
||||
physical_density: Factor.getPhysicalDensity(course),
|
||||
stamina_requirement: Factor.getStaminaRequirement(course),
|
||||
pattern_complexity: Factor.getPatternComplexity(course),
|
||||
rhythmic_complexity: Factor.getRhythmicComplexity(course),
|
||||
reading_gimmick: Factor.getReadingGimmick(course)
|
||||
};
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
import tjaParser, { Bar, Branch, Course } from 'tja-parser'
|
||||
|
||||
export function parseTja(tja: string): Partial<Record<'oni' | 'edit', Course>> | null {
|
||||
try {
|
||||
const song = tjaParser.Song.parse(tja);
|
||||
|
||||
let oni: Course | undefined = undefined;
|
||||
let edit: Course | undefined = undefined;
|
||||
|
||||
if (song.course?.oni) {
|
||||
const noteGroups = song.course.oni.noteGroups;
|
||||
oni = song.course.oni;
|
||||
oni.noteGroups = []
|
||||
|
||||
for (const noteGroup of noteGroups) {
|
||||
if (noteGroup instanceof Bar) {
|
||||
oni.pushNoteGroups(noteGroup)
|
||||
}
|
||||
else if (noteGroup instanceof Branch) {
|
||||
const bar = noteGroup.master || noteGroup.advanced || noteGroup.normal;
|
||||
if (bar) {
|
||||
oni.pushNoteGroups(...bar)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (song.course?.edit) {
|
||||
const noteGroups = song.course.edit.noteGroups;
|
||||
edit = song.course.edit;
|
||||
edit.noteGroups = []
|
||||
|
||||
for (const noteGroup of noteGroups) {
|
||||
if (noteGroup instanceof Bar) {
|
||||
edit.pushNoteGroups(noteGroup)
|
||||
}
|
||||
else if (noteGroup instanceof Branch) {
|
||||
const bar = noteGroup.master || noteGroup.advanced || noteGroup.normal;
|
||||
if (bar) {
|
||||
edit.pushNoteGroups(...bar)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return { oni, edit }
|
||||
}
|
||||
catch (err){
|
||||
console.error(err)
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
import { parseTja } from './parse';
|
||||
import { factorize, Factors } from './factorize';
|
||||
import { join } from 'path';
|
||||
import { readFileSync } from 'fs';
|
||||
|
||||
async function predict() {
|
||||
const args = process.argv.slice(2);
|
||||
const workingDir = args[0];
|
||||
const scriptDir = args[1];
|
||||
const tjaPath = args[2];
|
||||
const difficulty = (args[3] || 'oni').toLowerCase() as 'oni' | 'edit';
|
||||
|
||||
if (!tjaPath) {
|
||||
console.error('Usage: bun script/predict.ts <working_dir> <script_dir> <tja_path> <difficulty>');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const factorJsonPath = join(scriptDir, 'factor.json');
|
||||
const weights: Factors = JSON.parse(readFileSync(factorJsonPath, 'utf-8'));
|
||||
|
||||
const tjaContent = readFileSync(tjaPath, 'utf-8');
|
||||
const parsed = parseTja(tjaContent);
|
||||
|
||||
if (!parsed || !parsed[difficulty]) {
|
||||
console.error(`Error: Could not find difficulty '${difficulty}' in TJA.`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const factors = factorize(parsed[difficulty]!);
|
||||
const prediction = Object.keys(factors).reduce((sum, key) =>
|
||||
sum + (factors[key as keyof Factors] * weights[key as keyof Factors]), 0);
|
||||
|
||||
console.log(`Prediction for ${tjaPath} (${difficulty}):`);
|
||||
console.log(`- Predicted Value: ${prediction.toFixed(4)}`);
|
||||
console.log('- Factors:', factors);
|
||||
}
|
||||
|
||||
predict();
|
||||
94
script/predict_tja.ts
Normal file
94
script/predict_tja.ts
Normal file
@@ -0,0 +1,94 @@
|
||||
import Bun from 'bun';
|
||||
import path from 'node:path';
|
||||
import { parseArgs } from 'node:util';
|
||||
import fs from 'node:fs';
|
||||
import { featurize } from '../preprocess/featurize';
|
||||
import { parseTja } from '../preprocess/parse';
|
||||
|
||||
const { values } = parseArgs({
|
||||
args: Bun.argv,
|
||||
options: {
|
||||
tja: {
|
||||
type: "string"
|
||||
},
|
||||
workingDir: {
|
||||
type: "string"
|
||||
},
|
||||
script: {
|
||||
type: "string"
|
||||
}
|
||||
},
|
||||
allowPositionals: true,
|
||||
});
|
||||
|
||||
if (!values.tja || !values.workingDir || !values.script) {
|
||||
console.error("Usage: bun script/predict_tja.ts --tja <path_to_tja> [--workingDir <dir>] [--script <python_script>]");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const tjaPath = values.tja;
|
||||
if (!fs.existsSync(tjaPath)) {
|
||||
console.error(`File not found: ${tjaPath}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const workingDir = values.workingDir!;
|
||||
const pythonScript = values.script!;
|
||||
|
||||
if (!fs.existsSync(pythonScript)) {
|
||||
console.error(`Python script not found: ${pythonScript}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// 1. TJA 파싱 및 피처 추출
|
||||
const tjaContent = fs.readFileSync(tjaPath, 'utf-8');
|
||||
const songno = path.basename(tjaPath, '.tja');
|
||||
const parsed = parseTja(tjaContent);
|
||||
|
||||
const features: any[] = [];
|
||||
if (parsed.oni) {
|
||||
features.push({
|
||||
songno,
|
||||
difficulty: 'oni',
|
||||
...featurize(parsed.oni)
|
||||
});
|
||||
}
|
||||
if (parsed.edit) {
|
||||
features.push({
|
||||
songno,
|
||||
difficulty: 'ura',
|
||||
...featurize(parsed.edit)
|
||||
});
|
||||
}
|
||||
|
||||
if (features.length === 0) {
|
||||
console.error("No Oni or Ura difficulty found in the TJA file.");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// 2. 임시 피처 파일 저장
|
||||
const tempFeaturePath = path.join(workingDir, `temp_predict_${Date.now()}.json`);
|
||||
fs.writeFileSync(tempFeaturePath, JSON.stringify(features, null, 2), 'utf-8');
|
||||
|
||||
try {
|
||||
// 3. Python 예측 스크립트 실행
|
||||
const proc = Bun.spawnSync([
|
||||
"python3",
|
||||
pythonScript,
|
||||
"--workingDir", workingDir,
|
||||
"--feature", tempFeaturePath,
|
||||
"--songno", songno
|
||||
]);
|
||||
|
||||
if (proc.success) {
|
||||
console.log(proc.stdout.toString());
|
||||
} else {
|
||||
console.error("Prediction failed:");
|
||||
console.error(proc.stderr.toString());
|
||||
}
|
||||
} finally {
|
||||
// 4. 임시 파일 삭제
|
||||
if (fs.existsSync(tempFeaturePath)) {
|
||||
fs.unlinkSync(tempFeaturePath);
|
||||
}
|
||||
}
|
||||
66
script/preprocess.ts
Normal file
66
script/preprocess.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
import Bun from 'bun';
|
||||
import path from 'node:path';
|
||||
import { parseArgs } from 'node:util';
|
||||
import fs, { mkdirSync } from 'node:fs';
|
||||
import { featurize } from '../preprocess/featurize';
|
||||
import { parseTja } from '../preprocess/parse'
|
||||
|
||||
const { values } = parseArgs({
|
||||
args: Bun.argv,
|
||||
options: {
|
||||
workingDir: {
|
||||
type: "string"
|
||||
},
|
||||
dataDir: {
|
||||
type: "string"
|
||||
},
|
||||
fileName: {
|
||||
type: "string"
|
||||
}
|
||||
},
|
||||
allowPositionals: true,
|
||||
})
|
||||
|
||||
if (!values.dataDir || !values.workingDir) {
|
||||
console.error("--workingDir --dataDir");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const workingDir = values.workingDir ?? '';
|
||||
if (!fs.existsSync(workingDir)) mkdirSync(workingDir)
|
||||
const dataDir = values.dataDir ?? '';
|
||||
|
||||
const tjaDir = path.join(dataDir, 'tja');
|
||||
const files = fs.readdirSync(tjaDir);
|
||||
|
||||
const features: ({ songno: string, difficulty: 'oni' | 'ura' } & {})[] = [];
|
||||
for (const file of files) {
|
||||
const tja = fs.readFileSync(path.join(tjaDir, file), 'utf-8');
|
||||
const songno = path.basename(file, '.tja');
|
||||
try {
|
||||
const parsed = parseTja(tja);
|
||||
const oni = parsed?.oni;
|
||||
const edit = parsed?.edit;
|
||||
if (oni) {
|
||||
features.push({
|
||||
songno,
|
||||
difficulty: 'oni',
|
||||
...featurize(oni)
|
||||
})
|
||||
}
|
||||
if (edit) {
|
||||
features.push({
|
||||
songno,
|
||||
difficulty: 'ura',
|
||||
...featurize(edit)
|
||||
})
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
console.error(err);
|
||||
console.error(file);
|
||||
}
|
||||
}
|
||||
|
||||
const featurePath = path.join(workingDir, values.fileName ?? 'features.json');
|
||||
fs.writeFileSync(featurePath, JSON.stringify(features, null, 2), 'utf-8');
|
||||
@@ -1,67 +0,0 @@
|
||||
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])
|
||||
189
script/train.ts
189
script/train.ts
@@ -1,108 +1,91 @@
|
||||
import { parseTja } from './parse';
|
||||
import { factorize, Factors } from './factorize';
|
||||
import { join } from 'path';
|
||||
import { readFileSync, writeFileSync, readdirSync } from 'fs';
|
||||
import { parse } from 'csv-parse/sync';
|
||||
import Bun from 'bun';
|
||||
import { execSync, spawn, spawnSync } from 'node:child_process';
|
||||
import { parseArgs } from 'node:util';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { featurize } from '../preprocess/featurize';
|
||||
import { parseTja } from '../preprocess/parse'
|
||||
|
||||
async function train() {
|
||||
const args = process.argv.slice(2);
|
||||
const workingDir = args[0];
|
||||
const scriptDir = args[1];
|
||||
const dataDir = args[2];
|
||||
const trainCount = parseInt(args[3]) || 100;
|
||||
const validateCount = parseInt(args[4]) || 20;
|
||||
const margin = parseFloat(args[5]) || 0.1;
|
||||
|
||||
const factorJsonPath = join(scriptDir, 'factor.json');
|
||||
// 항상 script/ 위치 참조
|
||||
let weights: Factors = JSON.parse(readFileSync(factorJsonPath, 'utf-8'));
|
||||
|
||||
// 결과물(로그 등)을 저장할 경로 (필요 시 활용)
|
||||
const logPath = join(workingDir, 'training_log.txt');
|
||||
|
||||
const measureCsv = readFileSync(join(dataDir, 'measure.csv'), 'utf-8');
|
||||
const records = parse(measureCsv, { columns: true, skip_empty_lines: true });
|
||||
|
||||
const tjaFiles = readdirSync(join(dataDir, 'tja')).filter(f => f.endsWith('.tja'));
|
||||
const shuffled = tjaFiles.sort(() => 0.5 - Math.random());
|
||||
const trainFiles = shuffled.slice(0, trainCount);
|
||||
const validateFiles = shuffled.slice(trainCount, trainCount + validateCount);
|
||||
|
||||
console.log(`Training with ${trainFiles.length} files...`);
|
||||
|
||||
// 학습 로직 (단순화된 경사 하강법 또는 반복 최적화)
|
||||
let error = Infinity;
|
||||
let iterations = 0;
|
||||
while (error > margin && iterations < 100) {
|
||||
let totalError = 0;
|
||||
let count = 0;
|
||||
|
||||
for (const file of trainFiles) {
|
||||
const songno = file.replace(/\D/g, '');
|
||||
const tjaContent = readFileSync(join(dataDir, 'tja', file), 'utf-8');
|
||||
const parsed = parseTja(tjaContent);
|
||||
if (!parsed) continue;
|
||||
|
||||
for (const diff of ['oni', 'edit'] as const) {
|
||||
const course = parsed[diff];
|
||||
if (!course) continue;
|
||||
|
||||
const target = records.find((r: any) => r.songno === songno && (r.diff === (diff === 'oni' ? 'oni' : 'ura')));
|
||||
if (!target) {
|
||||
// console.log(`[!] No target for ${songno} diff=${diff}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
const factors = factorize(course);
|
||||
const prediction = Object.keys(factors).reduce((sum, key) =>
|
||||
sum + (factors[key as keyof Factors] * weights[key as keyof Factors]), 0);
|
||||
|
||||
const targetValue = parseFloat(target.상수);
|
||||
const diff_val = targetValue - prediction;
|
||||
totalError += Math.abs(diff_val);
|
||||
count++;
|
||||
|
||||
// 가중치 업데이트
|
||||
for (const key in weights) {
|
||||
const k = key as keyof Factors;
|
||||
weights[k] += diff_val * factors[k] * 0.05; // 학습률 조정
|
||||
}
|
||||
}
|
||||
const { values } = parseArgs({
|
||||
args: Bun.argv,
|
||||
options: {
|
||||
workingDir: {
|
||||
type: "string"
|
||||
},
|
||||
dataDir: {
|
||||
type: "string"
|
||||
},
|
||||
trainScript: {
|
||||
type: "string"
|
||||
},
|
||||
trainSize: {
|
||||
type: 'string'
|
||||
},
|
||||
validSize: {
|
||||
type: 'string'
|
||||
}
|
||||
error = totalError / (count || 1);
|
||||
console.log(`Iteration ${iterations}: Mean Error = ${error.toFixed(4)}`);
|
||||
iterations++;
|
||||
}
|
||||
},
|
||||
allowPositionals: true,
|
||||
});
|
||||
|
||||
writeFileSync(factorJsonPath, JSON.stringify(weights, null, 2));
|
||||
writeFileSync(join(workingDir, 'training_result.json'), JSON.stringify({ finalError: error, weights }, null, 2));
|
||||
console.log(`Training complete. Weights saved to ${factorJsonPath}, result saved to ${workingDir}`);
|
||||
|
||||
// 검증 로직
|
||||
console.log('\nValidation Results:');
|
||||
for (const file of validateFiles) {
|
||||
const songno = file.replace(/\D/g, '');
|
||||
const tjaContent = readFileSync(join(dataDir, 'tja', file), 'utf-8');
|
||||
const parsed = parseTja(tjaContent);
|
||||
if (!parsed) continue;
|
||||
|
||||
for (const diff of ['oni', 'edit'] as const) {
|
||||
const course = parsed[diff];
|
||||
if (!course) continue;
|
||||
|
||||
const target = records.find((r: any) => r.songno === songno && (r.diff === (diff === 'oni' ? 'oni' : 'ura')));
|
||||
if (!target) {
|
||||
console.log(`[!] No match for ${songno} diff=${diff === 'oni' ? 'oni' : 'ura'}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
const factors = factorize(course);
|
||||
const prediction = Object.keys(factors).reduce((sum, key) =>
|
||||
sum + (factors[key as keyof Factors] * weights[key as keyof Factors]), 0);
|
||||
|
||||
console.log(`[${songno}] Target: ${target.상수}, Predicted: ${prediction.toFixed(2)}, Diff: ${Math.abs(parseFloat(target.상수) - prediction).toFixed(2)}`);
|
||||
}
|
||||
}
|
||||
if (!values.dataDir || !values.workingDir || !values.trainScript) {
|
||||
console.error("--workingDir --dataDir --trainDir");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
train();
|
||||
generateFeatures();
|
||||
const child = spawn("python3", [values.trainScript,
|
||||
"--workingDir", values.workingDir,
|
||||
"--dataDir", values.dataDir,
|
||||
"--trainSize", (Number(values.trainSize) || 500).toString(),
|
||||
"--validSize", (Number(values.validSize) || 100).toString(),
|
||||
]);
|
||||
child.stdout.pipe(process.stdout);
|
||||
child.stderr.pipe(process.stderr);
|
||||
child.on("close", () => {
|
||||
process.exit()
|
||||
})
|
||||
|
||||
// funcs
|
||||
function generateFeatures() {
|
||||
const workingDir = values.workingDir ?? '';
|
||||
if (!fs.existsSync(workingDir)) fs.mkdirSync(workingDir);
|
||||
const featurePath = path.join(workingDir, 'features.json');
|
||||
if (fs.existsSync(featurePath)) return;
|
||||
const dataDir = values.dataDir ?? '';
|
||||
|
||||
const tjaDir = path.join(dataDir, 'tja');
|
||||
const files = fs.readdirSync(tjaDir);
|
||||
|
||||
const features: ({ songno: string, difficulty: 'oni' | 'ura' } & {})[] = [];
|
||||
for (const file of files) {
|
||||
const tja = fs.readFileSync(path.join(tjaDir, file), 'utf-8');
|
||||
const songno = path.basename(file, '.tja');
|
||||
try {
|
||||
const parsed = parseTja(tja);
|
||||
const oni = parsed?.oni;
|
||||
const edit = parsed?.edit;
|
||||
if (oni) {
|
||||
features.push({
|
||||
songno,
|
||||
difficulty: 'oni',
|
||||
...featurize(oni)
|
||||
})
|
||||
}
|
||||
if (edit) {
|
||||
features.push({
|
||||
songno,
|
||||
difficulty: 'ura',
|
||||
...featurize(edit)
|
||||
})
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
console.error(err);
|
||||
console.error(file);
|
||||
}
|
||||
}
|
||||
|
||||
fs.writeFileSync(featurePath, JSON.stringify(features, null, 2), 'utf-8');
|
||||
console.log('features.json generated')
|
||||
}
|
||||
75
spec.md
75
spec.md
@@ -1,75 +0,0 @@
|
||||
# 학습
|
||||
## CLI
|
||||
- cli로 학습할 수 있는 쉘 스크립트를 작성한다.
|
||||
- argument
|
||||
- script_dir
|
||||
- working_dir
|
||||
- data_dir
|
||||
- train_data_count = 100
|
||||
- validate_data_count = 20
|
||||
- margin = 0.1
|
||||
|
||||
## 학습 모델
|
||||
|
||||
## 학습 과정
|
||||
1. `{data_dir}/tja`의 tja를 파싱한다.
|
||||
- `{script_dir}/parse.ts`를 사용한다.
|
||||
2. `oni`와 `edit` course를 factorize한다.
|
||||
- `{script_dir}/factorize.ts`를 사용하며, `{working_dir}/features.json`에 저장한다. 이 때, songno와 난이도(oni | edit)을 같이 저장하여야한다.
|
||||
- `{working_dir}/features.json`이 이미 존재하면 이 과정은 생략한다.
|
||||
3. factorized된 데이터를 `train_data_count` 만큼 랜덤으로 가져온다.
|
||||
4. train data로 학습을 진행한다.
|
||||
- 예측 값이 [1, 12]에 없으면 완전히 잘못 트레이닝 된 것이다.
|
||||
- `{data_dir}/measure.csv`로 오차 확인
|
||||
- course가 `edit`이면 measure.json에서는 `ura`이므로 적절히 매칭한다.
|
||||
- Train error를 계속 로깅한다.
|
||||
- Train error가 `margin`보다 클 경우 이 과정(4번)을 다시 진행한다.
|
||||
- 최대 10번만 진행한다.
|
||||
5. validate_data_count 만큼 랜덤으로 validate data를 가져온 후 validate data로 각각의 measure, 예측한 measure, 오차를 `validate_result_{n}.csv`로 저장한다.
|
||||
- `validate_result_{n}.csv`에는 `songno`, `difficulty`, `measure`, `predicted_measure`, `error`을 작성한다. (중요)
|
||||
- `n`에는 몇번째 iteration인지 적는다.
|
||||
6. 만약 validate한 데이터 중 오차가 `margin`보다 큰 것이 있다면 3~5과정을 다시 반복한다.
|
||||
7. 모델 파일을 저장한다.
|
||||
|
||||
### 유의 사항
|
||||
- 모든 출력되는 데이터는 working_dir에 저장한다.
|
||||
- 이미 working_dir에 모델이 존재하면 모델을 삭제하지 않고 업데이트하는 식으로 학습한다.
|
||||
- 애플 실리콘 cpu를 사용할 경우 적극적으로 gpu를 사용할 수 있도록 한다.
|
||||
|
||||
# 예측
|
||||
## CLi
|
||||
- cli로 예측 데이터를 뽑을 수 있는 쉘 스크립트를 작성한다.
|
||||
- argument
|
||||
- working_dir
|
||||
- tja
|
||||
- difficulty: oni | edit
|
||||
|
||||
## 예측 과정
|
||||
- `working_dir`에 있는 model로 예측을 진행한다.
|
||||
- `tja` argument에 tja파일이 존재한다.
|
||||
- `difficulty`로 예측을 진행할 난이도를 선택한다.
|
||||
|
||||
# Factor
|
||||
## 종류
|
||||
- physical_density: 곡의 전반적인 및 순간적인 타격 밀도 (Global NPS, Peak NPS)
|
||||
- stamina_requirement: 긴 연타 구간과 휴식 구간의 비율을 통한 체력 소모량
|
||||
- pattern_complexity: 색상 전환 및 손 배치 전환(Hand-switching)의 복잡도
|
||||
- rhythmic_complexity: 엇박, 다양한 음표 단위 사용 등으로 인한 리듬의 난해함
|
||||
- reading_gimmick: BPM 변화, 스크롤 속도(SV) 변동 등 시각적 요소 및 기믹
|
||||
|
||||
## 가중치 (하이퍼 파라미터)
|
||||
`script/factor.json`에 `Record<factor 이름, 가중치>`를 기록한다.
|
||||
|
||||
# Scripts
|
||||
## `script/parse.ts`
|
||||
- `parseTja` 함수
|
||||
- tja를 string으로 받는다.
|
||||
- `Partial<Record<'oni' | 'edit', Course>> | null`을 반환한다.
|
||||
- null이 반환되면 에러가 나온 것이므로 무시한다.
|
||||
## `script/factorize.ts`
|
||||
- `factorize` 함수
|
||||
- course를 input으로 받는다.
|
||||
- factor들을 반환한다.
|
||||
- `Factor` namespace
|
||||
- 각 factor을 반환하는 함수의 namespace이다.
|
||||
- `factorize` 함수는 `Factor` namespace에서 함수들을 호출하여 factor들을 반환한다.
|
||||
23
train.sh
23
train.sh
@@ -1,23 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Arguments: script_dir working_dir data_dir train_data_count validate_data_count margin
|
||||
SCRIPT_DIR=${1:-"script"}
|
||||
WORKING_DIR=${2:-"."}
|
||||
DATA_DIR=${3:-"datas"}
|
||||
TRAIN_COUNT=${4:-100}
|
||||
VAL_COUNT=${5:-20}
|
||||
MARGIN=${6:-0.1}
|
||||
|
||||
# 작업 디렉토리가 없으면 생성
|
||||
if [ ! -d "$WORKING_DIR" ]; then
|
||||
echo "Creating directory: $WORKING_DIR"
|
||||
mkdir -p "$WORKING_DIR"
|
||||
fi
|
||||
|
||||
# 피처 추출 (존재 시 생략)
|
||||
if [ ! -f "$WORKING_DIR/features.json" ]; then
|
||||
echo "Extracting features..."
|
||||
bun "$SCRIPT_DIR/extract.ts" "$WORKING_DIR" "$DATA_DIR" "$TRAIN_COUNT" "$VAL_COUNT"
|
||||
fi
|
||||
|
||||
echo "Training model..."
|
||||
python3 "$SCRIPT_DIR/train.py" "$SCRIPT_DIR" "$WORKING_DIR" "$DATA_DIR" "$TRAIN_COUNT" "$VAL_COUNT" "$MARGIN"
|
||||
152
train/train_lightgbm.py
Normal file
152
train/train_lightgbm.py
Normal file
@@ -0,0 +1,152 @@
|
||||
import argparse
|
||||
import csv
|
||||
import json
|
||||
import math
|
||||
import os
|
||||
import random
|
||||
import joblib
|
||||
import numpy as np
|
||||
import lightgbm as lgb
|
||||
from sklearn.preprocessing import StandardScaler
|
||||
from sklearn.metrics import mean_absolute_error
|
||||
|
||||
# =========================================================
|
||||
# Hyper Parameters
|
||||
# =========================================================
|
||||
|
||||
TRAIN_SIZE = 0
|
||||
VALID_SIZE = 0
|
||||
|
||||
RANDOM_STATE = 42
|
||||
|
||||
# LightGBM 특정 하이퍼파라미터
|
||||
PARAMS = {
|
||||
'objective': 'regression',
|
||||
'metric': 'mae',
|
||||
'verbosity': -1,
|
||||
'boosting_type': 'gbdt',
|
||||
'random_state': RANDOM_STATE,
|
||||
'learning_rate': 0.02, # 더 정밀한 학습을 위해 하향
|
||||
'num_leaves': 63, # 더 복잡한 패턴 학습을 위해 상향
|
||||
'feature_fraction': 0.9,
|
||||
'bagging_fraction': 0.8,
|
||||
'bagging_freq': 5,
|
||||
'n_estimators': 3000 # 학습량 대폭 상향
|
||||
}
|
||||
|
||||
CONTINUE_TRAINING = True
|
||||
ERROR_TOLERANCE = 0.1
|
||||
|
||||
# =========================================================
|
||||
# 파일명
|
||||
# =========================================================
|
||||
|
||||
FEATURES_FILENAME = "features.json"
|
||||
MEASURE_FILENAME = "measure.csv"
|
||||
MODEL_FILENAME = "model_lgbm.pkl"
|
||||
SCALER_FILENAME = "scaler_lgbm.pkl"
|
||||
FEATURE_NAMES_FILENAME = "features_lgbm.txt"
|
||||
|
||||
IGNORE_KEYS = {"songno", "difficulty"}
|
||||
|
||||
def safe_float(value):
|
||||
if value is None: return 0.0
|
||||
x = float(value)
|
||||
return x if math.isfinite(x) else 0.0
|
||||
|
||||
def train_model(working_dir: str, data_dir: str):
|
||||
random.seed(RANDOM_STATE)
|
||||
|
||||
features_path = os.path.join(working_dir, FEATURES_FILENAME)
|
||||
measure_path = os.path.join(data_dir, MEASURE_FILENAME)
|
||||
model_path = os.path.join(working_dir, MODEL_FILENAME)
|
||||
scaler_path = os.path.join(working_dir, SCALER_FILENAME)
|
||||
feature_names_path = os.path.join(working_dir, FEATURE_NAMES_FILENAME)
|
||||
|
||||
with open(features_path, "r", encoding="utf-8") as f:
|
||||
feature_data = json.load(f)
|
||||
|
||||
if len(feature_data) == 0:
|
||||
raise ValueError("features.json is empty")
|
||||
|
||||
feature_map = {(str(item["songno"]), str(item["difficulty"])): item for item in feature_data}
|
||||
feature_names = sorted([k for k in feature_data[0].keys() if k not in IGNORE_KEYS])
|
||||
|
||||
dataset = []
|
||||
with open(measure_path, "r", encoding="utf-8") as f:
|
||||
reader = csv.reader(f)
|
||||
next(reader, None)
|
||||
for row in reader:
|
||||
if len(row) < 3: continue
|
||||
measure, songno, diff = safe_float(row[0]), str(row[1]), str(row[2])
|
||||
key = (songno, diff)
|
||||
if key in feature_map:
|
||||
features = [safe_float(feature_map[key].get(k, 0)) for k in feature_names]
|
||||
dataset.append((features, measure))
|
||||
|
||||
random.shuffle(dataset)
|
||||
if len(dataset) < (TRAIN_SIZE + VALID_SIZE):
|
||||
raise ValueError(f"Not enough dataset ({len(dataset)} < {TRAIN_SIZE + VALID_SIZE})")
|
||||
|
||||
train_dataset = dataset[:TRAIN_SIZE]
|
||||
valid_dataset = dataset[TRAIN_SIZE:TRAIN_SIZE + VALID_SIZE]
|
||||
|
||||
X_train = np.array([x for x, _ in train_dataset], dtype=np.float32)
|
||||
y_train = np.array([y for _, y in train_dataset], dtype=np.float32)
|
||||
X_valid = np.array([x for x, _ in valid_dataset], dtype=np.float32)
|
||||
y_valid = np.array([y for _, y in valid_dataset], dtype=np.float32)
|
||||
|
||||
print(f"Train Size: {len(X_train)} | Valid Size: {len(X_valid)} | Features: {len(feature_names)}")
|
||||
|
||||
if CONTINUE_TRAINING and os.path.exists(scaler_path):
|
||||
print("Loading existing scaler...")
|
||||
scaler = joblib.load(scaler_path)
|
||||
else:
|
||||
print("Creating new scaler...")
|
||||
scaler = StandardScaler()
|
||||
scaler.fit(X_train)
|
||||
|
||||
X_train = scaler.transform(X_train)
|
||||
X_valid = scaler.transform(X_valid)
|
||||
|
||||
if CONTINUE_TRAINING and os.path.exists(model_path):
|
||||
print("Loading existing model for incremental training...")
|
||||
model = joblib.load(model_path)
|
||||
model.fit(
|
||||
X_train, y_train,
|
||||
eval_set=[(X_valid, y_valid)],
|
||||
init_model=model,
|
||||
callbacks=[lgb.early_stopping(stopping_rounds=100)]
|
||||
)
|
||||
else:
|
||||
print("Creating new LightGBM model...")
|
||||
model = lgb.LGBMRegressor(**PARAMS)
|
||||
model.fit(
|
||||
X_train, y_train,
|
||||
eval_set=[(X_valid, y_valid)],
|
||||
callbacks=[lgb.early_stopping(stopping_rounds=100)]
|
||||
)
|
||||
|
||||
pred = model.predict(X_valid)
|
||||
mae = mean_absolute_error(y_valid, pred)
|
||||
accuracy = np.sum(np.abs(pred - y_valid) <= ERROR_TOLERANCE) / len(y_valid)
|
||||
|
||||
print(f"\nMAE: {mae:.4f} | Accuracy (±{ERROR_TOLERANCE}): {accuracy:.4f}")
|
||||
|
||||
joblib.dump(model, model_path)
|
||||
joblib.dump(scaler, scaler_path)
|
||||
with open(feature_names_path, "w", encoding="utf-8") as f:
|
||||
for name in feature_names: f.write(name + "\n")
|
||||
|
||||
print(f"\nSaved to {working_dir}: {MODEL_FILENAME}, {SCALER_FILENAME}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--workingDir", required=True)
|
||||
parser.add_argument("--dataDir", required=True)
|
||||
parser.add_argument("--trainSize", required=True, type=int)
|
||||
parser.add_argument("--validSize", required=True, type=int)
|
||||
args = parser.parse_args()
|
||||
|
||||
TRAIN_SIZE, VALID_SIZE = args.trainSize, args.validSize
|
||||
train_model(args.workingDir, args.dataDir)
|
||||
369
train/train_xgboost.py
Normal file
369
train/train_xgboost.py
Normal file
@@ -0,0 +1,369 @@
|
||||
import argparse
|
||||
import csv
|
||||
import json
|
||||
import math
|
||||
import os
|
||||
import random
|
||||
import joblib
|
||||
import numpy as np
|
||||
|
||||
from xgboost import XGBRegressor
|
||||
from sklearn.preprocessing import StandardScaler
|
||||
from sklearn.metrics import mean_absolute_error
|
||||
|
||||
# =========================================================
|
||||
# Hyper Parameters
|
||||
# =========================================================
|
||||
|
||||
TRAIN_SIZE = 0
|
||||
VALID_SIZE = 0
|
||||
|
||||
RANDOM_STATE = 42
|
||||
|
||||
N_ESTIMATORS = 500
|
||||
MAX_DEPTH = 6
|
||||
LEARNING_RATE = 0.05
|
||||
SUBSAMPLE = 0.8
|
||||
COLSAMPLE_BYTREE = 0.8
|
||||
|
||||
CONTINUE_TRAINING = True
|
||||
|
||||
# 예측 성공으로 간주할 허용 오차
|
||||
ERROR_TOLERANCE = 0.1
|
||||
|
||||
# =========================================================
|
||||
# 파일명
|
||||
# =========================================================
|
||||
|
||||
FEATURES_FILENAME = "features.json"
|
||||
MEASURE_FILENAME = "measure.csv"
|
||||
|
||||
MODEL_FILENAME = "model.pkl"
|
||||
SCALER_FILENAME = "scaler.pkl"
|
||||
FEATURE_NAMES_FILENAME = "features.txt"
|
||||
|
||||
# =========================================================
|
||||
# 무시할 key
|
||||
# =========================================================
|
||||
|
||||
IGNORE_KEYS = {
|
||||
"songno",
|
||||
"difficulty"
|
||||
}
|
||||
|
||||
|
||||
# =========================================================
|
||||
# safe float
|
||||
# =========================================================
|
||||
|
||||
def safe_float(value):
|
||||
if value is None:
|
||||
return 0.0
|
||||
|
||||
x = float(value)
|
||||
|
||||
if not math.isfinite(x):
|
||||
return 0.0
|
||||
|
||||
return x
|
||||
|
||||
|
||||
# =========================================================
|
||||
# train
|
||||
# =========================================================
|
||||
|
||||
def train_model(
|
||||
working_dir: str,
|
||||
data_dir: str
|
||||
):
|
||||
random.seed(RANDOM_STATE)
|
||||
|
||||
# =====================================================
|
||||
# path
|
||||
# =====================================================
|
||||
|
||||
features_path = os.path.join(
|
||||
working_dir,
|
||||
FEATURES_FILENAME
|
||||
)
|
||||
|
||||
measure_path = os.path.join(
|
||||
data_dir,
|
||||
MEASURE_FILENAME
|
||||
)
|
||||
|
||||
model_path = os.path.join(
|
||||
working_dir,
|
||||
MODEL_FILENAME
|
||||
)
|
||||
|
||||
scaler_path = os.path.join(
|
||||
working_dir,
|
||||
SCALER_FILENAME
|
||||
)
|
||||
|
||||
feature_names_path = os.path.join(
|
||||
working_dir,
|
||||
FEATURE_NAMES_FILENAME
|
||||
)
|
||||
|
||||
# =====================================================
|
||||
# features.json
|
||||
# =====================================================
|
||||
|
||||
with open(features_path, "r", encoding="utf-8") as f:
|
||||
feature_data = json.load(f)
|
||||
|
||||
if len(feature_data) == 0:
|
||||
raise ValueError("features.json is empty")
|
||||
|
||||
# =====================================================
|
||||
# feature map
|
||||
# =====================================================
|
||||
|
||||
feature_map = {}
|
||||
|
||||
for item in feature_data:
|
||||
key = (
|
||||
str(item["songno"]),
|
||||
str(item["difficulty"])
|
||||
)
|
||||
|
||||
feature_map[key] = item
|
||||
|
||||
# =====================================================
|
||||
# feature names
|
||||
# =====================================================
|
||||
|
||||
feature_names = sorted([
|
||||
k for k in feature_data[0].keys()
|
||||
if k not in IGNORE_KEYS
|
||||
])
|
||||
|
||||
# =====================================================
|
||||
# dataset build
|
||||
# =====================================================
|
||||
|
||||
dataset = []
|
||||
|
||||
with open(measure_path, "r", encoding="utf-8") as f:
|
||||
reader = csv.reader(f)
|
||||
|
||||
next(reader, None)
|
||||
|
||||
for row in reader:
|
||||
if len(row) < 3:
|
||||
continue
|
||||
|
||||
measure = safe_float(row[0])
|
||||
songno = str(row[1])
|
||||
diff = str(row[2])
|
||||
|
||||
key = (songno, diff)
|
||||
|
||||
if key not in feature_map:
|
||||
print(
|
||||
f"[WARN] feature not found: "
|
||||
f"{songno} {diff}"
|
||||
)
|
||||
continue
|
||||
|
||||
feature_item = feature_map[key]
|
||||
|
||||
features = [
|
||||
safe_float(feature_item.get(k, 0))
|
||||
for k in feature_names
|
||||
]
|
||||
|
||||
dataset.append((
|
||||
features,
|
||||
measure
|
||||
))
|
||||
|
||||
# =====================================================
|
||||
# shuffle
|
||||
# =====================================================
|
||||
|
||||
random.shuffle(dataset)
|
||||
|
||||
required_size = TRAIN_SIZE + VALID_SIZE
|
||||
|
||||
if len(dataset) < required_size:
|
||||
raise ValueError(
|
||||
f"Not enough dataset "
|
||||
f"({len(dataset)} < {required_size})"
|
||||
)
|
||||
|
||||
# =====================================================
|
||||
# split
|
||||
# =====================================================
|
||||
|
||||
train_dataset = dataset[:TRAIN_SIZE]
|
||||
valid_dataset = dataset[
|
||||
TRAIN_SIZE:
|
||||
TRAIN_SIZE + VALID_SIZE
|
||||
]
|
||||
|
||||
X_train = np.array(
|
||||
[x for x, _ in train_dataset],
|
||||
dtype=np.float32
|
||||
)
|
||||
|
||||
y_train = np.array(
|
||||
[y for _, y in train_dataset],
|
||||
dtype=np.float32
|
||||
)
|
||||
|
||||
X_valid = np.array(
|
||||
[x for x, _ in valid_dataset],
|
||||
dtype=np.float32
|
||||
)
|
||||
|
||||
y_valid = np.array(
|
||||
[y for _, y in valid_dataset],
|
||||
dtype=np.float32
|
||||
)
|
||||
|
||||
print(f"Train Size: {len(X_train)}")
|
||||
print(f"Valid Size: {len(X_valid)}")
|
||||
print(f"Feature Count: {len(feature_names)}")
|
||||
|
||||
# =====================================================
|
||||
# scaler
|
||||
# =====================================================
|
||||
|
||||
if CONTINUE_TRAINING and os.path.exists(scaler_path):
|
||||
print("Loading existing scaler...")
|
||||
|
||||
scaler = joblib.load(scaler_path)
|
||||
|
||||
else:
|
||||
print("Creating new scaler...")
|
||||
|
||||
scaler = StandardScaler()
|
||||
scaler.fit(X_train)
|
||||
|
||||
X_train = scaler.transform(X_train)
|
||||
X_valid = scaler.transform(X_valid)
|
||||
|
||||
# =====================================================
|
||||
# model
|
||||
# =====================================================
|
||||
|
||||
if CONTINUE_TRAINING and os.path.exists(model_path):
|
||||
print("Loading existing model...")
|
||||
|
||||
model = joblib.load(model_path)
|
||||
|
||||
previous_booster = model.get_booster()
|
||||
|
||||
model.fit(
|
||||
X_train,
|
||||
y_train,
|
||||
xgb_model=previous_booster
|
||||
)
|
||||
|
||||
else:
|
||||
print("Creating new model...")
|
||||
|
||||
model = XGBRegressor(
|
||||
n_estimators=N_ESTIMATORS,
|
||||
max_depth=MAX_DEPTH,
|
||||
learning_rate=LEARNING_RATE,
|
||||
subsample=SUBSAMPLE,
|
||||
colsample_bytree=COLSAMPLE_BYTREE,
|
||||
objective="reg:squarederror",
|
||||
random_state=RANDOM_STATE
|
||||
)
|
||||
|
||||
model.fit(X_train, y_train)
|
||||
|
||||
# =====================================================
|
||||
# evaluate
|
||||
# =====================================================
|
||||
|
||||
pred = model.predict(X_valid)
|
||||
|
||||
mae = mean_absolute_error(y_valid, pred)
|
||||
|
||||
correct = np.sum(
|
||||
np.abs(pred - y_valid) <= ERROR_TOLERANCE
|
||||
)
|
||||
|
||||
accuracy = correct / len(y_valid)
|
||||
|
||||
print(f"\nMAE: {mae:.4f}")
|
||||
|
||||
print(
|
||||
f"Accuracy "
|
||||
f"(±{ERROR_TOLERANCE}): "
|
||||
f"{accuracy:.4f}"
|
||||
)
|
||||
|
||||
# =====================================================
|
||||
# feature importance
|
||||
# =====================================================
|
||||
|
||||
print("\nFeature Importance:")
|
||||
|
||||
importance = model.feature_importances_
|
||||
|
||||
pairs = list(zip(feature_names, importance))
|
||||
pairs.sort(key=lambda x: x[1], reverse=True)
|
||||
|
||||
for name, score in pairs:
|
||||
print(f"{name:25} {score:.6f}")
|
||||
|
||||
# =====================================================
|
||||
# save
|
||||
# =====================================================
|
||||
|
||||
joblib.dump(model, model_path)
|
||||
joblib.dump(scaler, scaler_path)
|
||||
|
||||
with open(feature_names_path, "w", encoding="utf-8") as f:
|
||||
for name in feature_names:
|
||||
f.write(name + "\n")
|
||||
|
||||
print("\nSaved:")
|
||||
print(model_path)
|
||||
print(scaler_path)
|
||||
print(feature_names_path)
|
||||
|
||||
|
||||
# =========================================================
|
||||
# main
|
||||
# =========================================================
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
parser.add_argument(
|
||||
"--workingDir",
|
||||
required=True
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--dataDir",
|
||||
required=True
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--trainSize",
|
||||
required=True
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--validSize",
|
||||
required=True
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
TRAIN_SIZE = int(args.trainSize)
|
||||
VALID_SIZE = int(args.validSize)
|
||||
|
||||
train_model(
|
||||
args.workingDir,
|
||||
args.dataDir
|
||||
)
|
||||
Reference in New Issue
Block a user