② 사전 보강 — 실측으로 찾은 어휘 공백을 메움
- 인원: 2인·3인 추가 (4/6/10/20인만 있어 기준 2인 업체가 노릴 키워드가 없었다)
- 단독 명사형: 군산 독채 / 스테이 / 풀빌라 (조합형만 있어 단독 검색을 놓쳤다)
- 분위기 11종(감성·조용한·사진찍기 좋은·인생샷 …), 여행형태 9종(뚜벅이·1박2일 …)
- scripts/import-related.ts — 검색광고 키워드도구 내려받기 병합 (파일 임포터)
③ 사전 오염 정리
- source='llm' 27건 삭제 (강남 미용실·해운대 한식당이 군산 펜션 사전에 있었다)
- 매칭 후보를 업체 업종으로 한정 + source IN ('dataset','manual') 만 조회
- 적재 시 데이터셋에서 빠진 행 삭제 — upsert 만 하면 재빌드마다 누적된다 (974 → 1072)
④ 고객 언어 레인 (w=0.9)
- hashtags + reviewSignals(원문 아닌 빈도 집계) 를 별도 레인으로
- 사업자 표현보다 검색어에 가까우므로 유형 다음으로 높게 잡음
- 스테이머뭄 데이터는 아직 없음 — 인스타는 로그인 월이라 스크래퍼가 채워야 함
⑤ 레인 토큰 중복 제거
- '신흥동' 과 '신흥동 일본식가옥' 이 별개 원소라 같은 낱말이 두 번 실렸다
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
36 lines
1.5 KiB
TypeScript
36 lines
1.5 KiB
TypeScript
/**
|
|
* 고정 데이터셋 정책 위반분 정리.
|
|
* npx tsx scripts/purge-nondataset.ts [--apply]
|
|
*
|
|
* 사전(keyword)에는 큐레이션된 데이터셋만 남아야 한다. 과거 generate 테스트가
|
|
* 만든 source='llm' 행이 섞여 있으면 다른 업종 키워드가 매칭 후보에 들어온다.
|
|
*/
|
|
import { createSql } from '../src/db/db';
|
|
|
|
async function main() {
|
|
const apply = process.argv.includes('--apply');
|
|
const sql = createSql();
|
|
|
|
const rows = await sql<Array<{ source: string; n: number; sample: string[] }>>`
|
|
SELECT source, count(*)::int AS n, (array_agg(canonical ORDER BY canonical))[1:6] AS sample
|
|
FROM keyword GROUP BY source ORDER BY n DESC`;
|
|
console.log('출처별 현황');
|
|
for (const r of rows) console.log(` ${r.source.padEnd(10)} ${String(r.n).padStart(5)} ${r.sample.join(', ')}`);
|
|
|
|
const doomed = await sql<Array<{ n: number }>>`
|
|
SELECT count(*)::int AS n FROM keyword WHERE source NOT IN ('dataset', 'manual')`;
|
|
const n = doomed[0]?.n ?? 0;
|
|
if (n === 0) { console.log('\n정리 대상 없음'); await sql.end(); return; }
|
|
|
|
if (!apply) {
|
|
console.log(`\n정리 대상 ${n}건. 실제로 지우려면 --apply 를 붙일 것.`);
|
|
await sql.end();
|
|
return;
|
|
}
|
|
const del = await sql`DELETE FROM keyword WHERE source NOT IN ('dataset', 'manual') RETURNING id`;
|
|
console.log(`\n✅ ${del.length}건 삭제 (merchant_keyword 는 CASCADE)`);
|
|
await sql.end();
|
|
}
|
|
|
|
main().catch((e) => { console.error('❌', e); process.exit(1); });
|