analyze.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. const d = require('./docs/短剧变现/raw/_merged.json');
  2. const hypotheses = ['H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'H7', 'H8'];
  3. function groupByHypothesis(items) {
  4. const map = {};
  5. for (const h of hypotheses) map[h] = [];
  6. for (const item of items) {
  7. for (const h of (item.hypothesis || [])) {
  8. if (map[h]) map[h].push(item);
  9. }
  10. }
  11. return map;
  12. }
  13. function sentimentDist(items) {
  14. const dist = {};
  15. for (const item of items) {
  16. const s = item.sentiment || 'unknown';
  17. dist[s] = (dist[s] || 0) + 1;
  18. }
  19. return dist;
  20. }
  21. function topTags(items, n) {
  22. n = n || 20;
  23. const counts = {};
  24. for (const item of items) {
  25. for (const tag of (item.tags || [])) {
  26. counts[tag] = (counts[tag] || 0) + 1;
  27. }
  28. }
  29. return Object.entries(counts)
  30. .sort(function(a, b) { return b[1] - a[1]; })
  31. .slice(0, n);
  32. }
  33. function truncate(str, len) {
  34. if (!str) return '';
  35. return str.length > len ? str.slice(0, len) + '...' : str;
  36. }
  37. var grouped = groupByHypothesis(d.items);
  38. var overallTags = topTags(d.items, 20);
  39. var overallSentiment = sentimentDist(d.items);
  40. console.log('================================================================================');
  41. console.log(' 短剧变现数据分析报告');
  42. console.log('================================================================================');
  43. console.log('总条目数: ' + d.items.length);
  44. console.log('采集时间: ' + d.meta.collectedAt);
  45. console.log('');
  46. console.log('------------------------------------------------------------');
  47. console.log(' 整体情感分布:');
  48. console.log('------------------------------------------------------------');
  49. var ks = Object.keys(overallSentiment).sort(function(a, b) { return overallSentiment[b] - overallSentiment[a]; });
  50. for (var i = 0; i < ks.length; i++) {
  51. var s = ks[i];
  52. var c = overallSentiment[s];
  53. var pct = (c / d.items.length * 100).toFixed(1);
  54. console.log(' ' + s + ': ' + c + ' (' + pct + '%)');
  55. }
  56. console.log('');
  57. console.log('------------------------------------------------------------');
  58. console.log(' 全量 Top 20 标签:');
  59. console.log('------------------------------------------------------------');
  60. for (var i = 0; i < overallTags.length; i++) {
  61. var tag = overallTags[i][0];
  62. var count = overallTags[i][1];
  63. console.log(' ' + pad(i + 1, 2) + '. ' + pad(tag, 18) + ' ' + count);
  64. }
  65. console.log('');
  66. for (var hi = 0; hi < hypotheses.length; hi++) {
  67. var h = hypotheses[hi];
  68. var items = grouped[h];
  69. if (items.length === 0) continue;
  70. var sorted = items.slice().sort(function(a, b) { return b.likes - a.likes; });
  71. var sent = sentimentDist(items);
  72. var topN = sorted.slice(0, 8);
  73. console.log('------------------------------------------------------------');
  74. console.log(' ' + h + ' -- 共 ' + items.length + ' 条');
  75. console.log('------------------------------------------------------------');
  76. var sentParts = [];
  77. var sk = Object.keys(sent).sort(function(a, b) { return sent[b] - sent[a]; });
  78. for (var si = 0; si < sk.length; si++) {
  79. var ss = sk[si];
  80. var sc = sent[ss];
  81. sentParts.push(ss + ': ' + sc + ' (' + (sc / items.length * 100).toFixed(1) + '%)');
  82. }
  83. console.log(' 情感分布: ' + sentParts.join(' | '));
  84. console.log('');
  85. console.log(' Top 8 高点赞条目:');
  86. console.log(' ' + repeat('-', 74));
  87. for (var ti = 0; ti < topN.length; ti++) {
  88. var item = topN[ti];
  89. var tagStr = (item.tags || []).slice(0, 3).join(', ') || '(无)';
  90. console.log(' ' + (ti + 1) + '. [' + pad(item.platform, 6) + '] Likes:' + pad(String(item.likes), 7) + ' | ' + pad(item.keyword, 12) + ' | ' + pad(item.sentiment || '', 9) + ' | ' + tagStr);
  91. console.log(' ' + truncate(item.content, 80));
  92. console.log('');
  93. }
  94. console.log('');
  95. }
  96. console.log('================================================================================');
  97. console.log(' 全量 Top 20 标签汇总:');
  98. console.log('================================================================================');
  99. var maxCount = overallTags[0] ? overallTags[0][1] : 1;
  100. for (var i = 0; i < overallTags.length; i++) {
  101. var tag = overallTags[i][0];
  102. var count = overallTags[i][1];
  103. var bar = repeat('|', Math.max(1, Math.round(count / maxCount * 30)));
  104. console.log(' ' + pad(i + 1, 2) + '. ' + pad(tag, 18) + ' ' + pad(String(count), 4) + ' ' + bar);
  105. }
  106. function pad(s, n) {
  107. s = String(s);
  108. while (s.length < n) s = s + ' ';
  109. return s;
  110. }
  111. function repeat(ch, n) {
  112. var r = '';
  113. for (var i = 0; i < n; i++) r += ch;
  114. return r;
  115. }