This commit is contained in:
2026-04-25 15:50:38 +09:00
parent da4201fb20
commit df82515a33
37 changed files with 162982 additions and 393 deletions

View File

@@ -1,25 +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"
},
tja: {
type: "string"
},
predictScript: {
type: "string"
},
workingDir: { type: "string" },
dataDir: { type: "string" },
script: { type: "string" },
},
strict: true,
allowPositionals: true,
});
if (!values.tja || !values.workingDir || !values.predictScript) {
console.error("--workingDir --dataDir --trainDir");
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 songno = "temp";
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}`);

View File

@@ -13,9 +13,11 @@ const { values } = parseArgs({
},
dataDir: {
type: "string"
},
fileName: {
type: "string"
}
},
strict: true,
allowPositionals: true,
})
@@ -60,5 +62,5 @@ for (const file of files) {
}
}
const featurePath = path.join(workingDir, 'features.json');
const featurePath = path.join(workingDir, values.fileName ?? 'features.json');
fs.writeFileSync(featurePath, JSON.stringify(features, null, 2), 'utf-8');