| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- // 审计 Ch1-Ch3 实际展示的 VOC 证据质量:
- // 对每一条 getEvidence(...) 调用复现其结果,
- // 打印 "slide · 角色 · 平台 · 昵称 · 点赞 · 内容" → 让人眼见即可评估是否对路。
- const LA = require('./liver-analyze.js');
- const data = LA.loadMerged();
- const items = data.items;
- function printList(title, arr) {
- console.log('\n──────────────────────────────────────');
- console.log(title);
- console.log('──────────────────────────────────────');
- if (!arr || !arr.length) { console.log(' (空)'); return; }
- arr.forEach((it, i) => {
- const rating = typeof it.rating === 'number' ? ` ★${it.rating}` : '';
- const title = it.title ? ` | "${it.title.slice(0, 40)}"` : '';
- console.log(
- ` [${i + 1}] ${it.platform.toUpperCase()} · ${it.keyword} · ${it.nickname}${rating} · ♥${it.likes}${title}`
- );
- console.log(` 「${(it.content || '').replace(/\n/g, ' ').slice(0, 180)}」`);
- });
- }
- console.log('╔════════════════════════════════════════════════════════╗');
- console.log('║ 江中肝纯片 VOC 报告 · Ch1-Ch3 evidence 审计 ║');
- console.log('╚════════════════════════════════════════════════════════╝');
- // ===== 1.1 DMY 认知空白 =====
- printList('【1.1】XHS "肝纯片" + 水飞蓟提及(mind1)',
- LA.getEvidence(items, { keyword: '肝纯片', contentMatch: /水飞蓟|silymarin/i, top: 3, seed: 5 }));
- printList('【1.1】XHS "江中肝纯片" + 总黄酮提及(mind2)',
- LA.getEvidence(items, { keyword: '江中肝纯片', contentMatch: /总黄酮|成分|黄酮|护肝片/i, top: 2, seed: 7 }));
- printList('【1.1】XHS "藤茶" top 3(按 likes)',
- items.filter(it => it.keyword === '藤茶').sort((a, b) => (b.likes || 0) - (a.likes || 0)).slice(0, 3));
- printList('【1.1】Amazon dihydromyricetin ★≥4 top 3',
- items.filter(it => it.keyword === 'dihydromyricetin' && it.rating >= 4)
- .sort((a, b) => (b.likes || 0) - (a.likes || 0)).slice(0, 3));
- // ===== 1.2 海王金樽警示 =====
- printList('【1.2】"海王金樽" + 广告/老哒/硬广/[捂脸]',
- items.filter(it => it.keyword === '海王金樽' && /广告|老哒|硬广|洗脑|杠杠的|捂脸|福/i.test(it.content || ''))
- .sort((a, b) => (b.likes || 0) - (a.likes || 0)).slice(0, 4));
- printList('【1.2】"海王金樽" 正向寡淡(likes<10)',
- items.filter(it => it.keyword === '海王金樽' && /神|可以|性价比|get/i.test(it.content || '') && (it.likes || 0) < 10)
- .sort((a, b) => (b.likes || 0) - (a.likes || 0)).slice(0, 2));
- printList('【1.2】"解酒神器" 品类整体情绪',
- items.filter(it => it.keyword === '解酒神器' && /横竖|死呗|对手|笑哭|酒蒙子|催吐|商家/i.test(it.content || ''))
- .sort((a, b) => (b.likes || 0) - (a.likes || 0)).slice(0, 3));
- // ===== 2.1 藤茶千年食饮 =====
- printList('【2.1】XHS "藤茶" top 4(取前 4 作文化叙事)',
- items.filter(it => it.keyword === '藤茶').sort((a, b) => (b.likes || 0) - (a.likes || 0)).slice(0, 4));
- // ===== 2.2 DMY 科学力 =====
- printList('【2.2】Amazon dihydromyricetin ★≥4 top 4',
- items.filter(it => it.keyword === 'dihydromyricetin' && it.rating >= 4)
- .sort((a, b) => (b.likes || 0) - (a.likes || 0)).slice(0, 4));
- // ===== 2.3 水飞蓟反面 =====
- printList('【2.3】XHS "水飞蓟" + 怀疑/副作用关键词',
- items.filter(it => it.keyword === '水飞蓟' &&
- /效果寥寥|没效|不行|差远|双环醇|尿.*变|变橙|胃疼|不知道|是不是|进口|医生/i.test(it.content || ''))
- .sort((a, b) => (b.likes || 0) - (a.likes || 0)).slice(0, 3));
- printList('【2.3】XHS "奶蓟草" + 花/野花/苏格兰',
- items.filter(it => it.keyword === '奶蓟草' && /花|蓟|野花|苏格兰|止血/i.test(it.content || ''))
- .sort((a, b) => (b.likes || 0) - (a.likes || 0)).slice(0, 3));
- printList('【2.3】Amazon milk thistle ★≤2 top 3',
- items.filter(it => it.keyword === 'milk thistle' && it.rating <= 2)
- .sort((a, b) => (b.likes || 0) - (a.likes || 0)).slice(0, 3));
- printList('【2.3】Amazon silymarin ★≤2 top 2',
- items.filter(it => it.keyword === 'silymarin' && it.rating <= 2)
- .sort((a, b) => (b.likes || 0) - (a.likes || 0)).slice(0, 2));
- // ===== 3.2 五大竞品 =====
- printList('【3.2】Swisse top 2', items.filter(it => it.keyword === 'swisse护肝片').sort((a, b) => (b.likes || 0) - (a.likes || 0)).slice(0, 2));
- printList('【3.2】易善复 top 2', items.filter(it => it.keyword === '易善复').sort((a, b) => (b.likes || 0) - (a.likes || 0)).slice(0, 2));
- printList('【3.2】葵花护肝片 top 2', items.filter(it => it.keyword === '葵花护肝片').sort((a, b) => (b.likes || 0) - (a.likes || 0)).slice(0, 2));
- printList('【3.2】片仔癀护肝 top 2', items.filter(it => it.keyword === '片仔癀护肝').sort((a, b) => (b.likes || 0) - (a.likes || 0)).slice(0, 2));
- printList('【3.2】海王金樽 top 2', items.filter(it => it.keyword === '海王金樽').sort((a, b) => (b.likes || 0) - (a.likes || 0)).slice(0, 2));
- printList('【3.2】汤臣倍健护肝 top 1', items.filter(it => it.keyword === '汤臣倍健护肝').sort((a, b) => (b.likes || 0) - (a.likes || 0)).slice(0, 1));
- // ===== 3.3 三大人群 =====
- printList('【3.3A】脂肪肝 top 3',
- items.filter(it => it.keyword === '脂肪肝').sort((a, b) => (b.likes || 0) - (a.likes || 0)).slice(0, 3));
- printList('【3.3B】熬夜伤肝/熬夜护肝 top 3',
- items.filter(it => it.keyword === '熬夜伤肝' || it.keyword === '熬夜护肝')
- .sort((a, b) => (b.likes || 0) - (a.likes || 0)).slice(0, 3));
- printList('【3.3C】应酬解酒/解酒神器/酒局必备 top 3',
- items.filter(it => /应酬|解酒|酒局/.test(it.keyword || ''))
- .sort((a, b) => (b.likes || 0) - (a.likes || 0)).slice(0, 3));
- console.log('\n\n========== 数据质量自检 ==========');
- // 检查重复问题
- const dupMap = new Map();
- for (const it of items) {
- const key = `${it.platform}|${it.content?.slice(0, 50)}`;
- dupMap.set(key, (dupMap.get(key) || 0) + 1);
- }
- const dups = [...dupMap.entries()].filter(([k, v]) => v > 1).sort((a, b) => b[1] - a[1]);
- console.log(`重复评论(前 50 字相同): ${dups.length} 组`);
- console.log('Top 5 重复条目:');
- dups.slice(0, 5).forEach(([k, v]) => console.log(` ×${v} ${k.slice(0, 120)}`));
- // 空内容
- const empty = items.filter(it => !(it.content || '').trim());
- console.log(`\n空内容: ${empty.length}`);
- // 平台统计
- const byPlatform = {};
- for (const it of items) byPlatform[it.platform] = (byPlatform[it.platform] || 0) + 1;
- console.log('\n平台分布:', byPlatform);
- // 评论内容和 keyword 的 "相关性" 启发式
- function topicHit(it) {
- const c = it.content || '';
- const kw = it.keyword || '';
- // 如果评论字数 < 4 或 只有表情符号 视为无内容
- if (c.replace(/\s/g, '').length < 4) return 'too-short';
- // 如果评论里出现了 kw 的任何片段 视为相关
- if (kw && kw.length >= 2) {
- const parts = kw.split(/护肝|片|解酒/).filter(Boolean);
- for (const p of parts) { if (p.length >= 2 && c.includes(p)) return 'kw-hit'; }
- if (c.includes(kw)) return 'kw-hit';
- }
- return 'may-drift';
- }
- const hitStats = { 'kw-hit': 0, 'too-short': 0, 'may-drift': 0 };
- for (const it of items) hitStats[topicHit(it)]++;
- console.log('\n相关性启发式:', hitStats);
- console.log(` kw-hit = 评论文本直接提到 keyword 片段`);
- console.log(` too-short = 评论长度 < 4 字符(表情/短回复)`);
- console.log(` may-drift = 长评论但可能跑题`);
|