雜記 › 技術筆記 › 字頻還是詞頻:同一句中文,一份 23 項榜單和一份空表

字頻還是詞頻:同一句中文,一份 23 項榜單和一份空表

做中文稿的關鍵字排查,動作通常都一樣:把整段正文貼進頻率統計、切到詞頻、等一張榜單。第一次拿到「總單詞數 0」和一行「暫無資料」時,很難把它和剛貼進去的那 25 個漢字聯想在一起——字明明都在框裡。

空表不是壞了,是抽取只認 ASCII 字母

範本第 152 行的抽取正則是 /[a-zA-Z]+/g,詞的定義就是連續 ASCII 字母串。同一句「中文根本不按詞切分所以字頻統計會把每個漢字單獨計數」交給文本頻率統計,兩個分頁給出兩份完全不同的東西:字元頻率下是 25 字元、23 項榜單,榜首「字」2 次 8.0%,第二項「計」同為 8.0%,其餘上榜的漢字各 1 次 4.0%,23 項顯示佔比加起來正好 100.0%;英文詞頻下是 0 個詞,把每個漢字之間敲上空格再餵進去仍然是 0——它不按空白切詞,手動分詞救不回來。

同一句 25 字中文 字元頻率:23 項 字 8.0% 計 8.0% 中 4.0% 文 4.0% 其餘漢字各 1 次 英文詞頻:0 詞 暫無資料 總單詞數 0 逐字加空格仍 0

圖 1:同一句 25 字中文的兩份榜單

漢字、標點、全形空格在這張榜裡同權

字元模式的跳過名單只有空格、換行、定位、回車這 4 個字元(範本第 123 行),其餘全部計入。前 5 名裡出現「。」並不奇怪:43 字元的段落裡它以 3 次 7.0% 擠進前 5;全形空格更不在跳過名單,5 字元的 A B C 裡它以 2 次 40.0% 直接坐榜首。

分母也帶著這些字元:58 字元的範本混排樣例只計到 49 個,41 項佔比之和只有 83.5%,缺的 16.5% 正是被跳過卻留在分母裡的空白。計數單位是 UTF-16 碼元,50 個表情符加 abc 長度是 103、碼點只有 53,一個表情被拆成 2 項、各 50 次 48.5%。

停用詞開關改的不只是名次,還有分母

範本自帶那段 117 字元、24 個詞的英文樣例最能暴露口徑。停用詞欄位留空時榜單 17 項,榜首 the 4 次 16.7%,逐行佔比加起來 100.3%——多出的部分是 17 行 toFixed(1) 的捨入殘差。把預設那張 30 詞的表打開,榜首換成 fox 2 次 8.3%,第 1 到第 4 名 fox、over、dog、again 同頻並列,不同單詞 17 個減到 11 個,佔比之和掉到 62.6%。

同一份 117 字元樣例 the 16.7% fox 8.3% over 8.3% dog 8.3% again 8.3% 停用詞 OFF:17 項 榜首 the,佔 16.7% 佔比之和 100.3% 停用詞 ON:11 項 榜首 fox,佔 8.3% 佔比之和 62.6%

圖 2:停用詞開與關的 top5 與佔比之和

這 62.6% 不是留存率:分母仍是過濾前的 24 個詞,11 項計數之和只有 15 個詞次,24 減 15 = 9 才是被抹掉的詞次。開關帶來的不是名次位移而是換人——原本並列第 5 檔的四個詞被抬成榜首,唯一的第 1 名 the 直接消失。

勾上「區分大小寫」,停用詞表半失效

詞表裡的 30 項載入時被統一轉成小寫,匹配卻拿原樣大小寫查表。勾上「區分大小寫」後句首的 The 逃過過濾,榜首變成 The 2 次 8.3%,統計欄照樣報排除停用詞 30 個。停用詞清空再勾同一個開關,the 家族被拆成 The 2 與 the 2 兩行、各 8.3%,而合併口徑本是一行 4 次 16.7%——任何一行都不到真實佔比的一半。

同頻並列時,三個模式三套次序

三個模式用的是同一個按次數降序的比較器,排序穩定,於是並列名次完全取決於排序前陣列的來源,而這三處來源不同:

  • 字元模式取自 Object.keys,整數型鍵被提到最前按數值升序:輸入 1234567890 的榜首是 0,b a a b 5 5 z 給出 5、b、a、z,數字 5 被頂到第 1 位(15.4%)。
  • 詞模式也取自 Object.keys,但鍵只能是字母串,於是純首次出現序:zebra apple zebra apple 裡 zebra 2 次 50.0% 排在 apple 之前,字典序會給出相反結果。
  • 關鍵詞模式就是你寫清單的順序,與文字裡誰先出現無關。

帶數字的詞還會整體塌縮:w0 到 w4999 這 5000 個編號詞只剩 1 行 w 5000 次 100.0%,版本號、SKU 這類清單全被併成同一行。

關鍵詞那一欄的百分比不是密度

它的分子是命中次數、分母是字元數。43 字元的預設樣例裡「人工智慧」出現 3 次,介面顯示 7.0%;按實際佔用的 12 個字元算是 27.9%,差 4 倍。清單還不去重:同一個詞寫 3 行再加 1 行別的,關鍵詞數報 4 個、總命中次數報 10 次,而文字裡真實只有 4 處。匹配也不重疊,aaa 裡找 aa 報 1 次 33.3%(真實 2 個位置),aaaa 報 2 次 50.0%(真實 3 個)。榜單也沒有取前 N 項的開關,1000 行關鍵詞就渲染 1000 行。

模式什麼算一項佔比分母並列時誰在前中文實測
字元頻率非空白字元,含標點與全形空格文字長度,空白留在裡面數字插隊,其餘按首次出現25 字元出 23 項,榜首 8.0%
英文詞頻連續 ASCII 字母串過濾前的詞數 24首次出現序同一句話 0 個詞
關鍵詞清單裡的每一行,不去重字元數(非佔用字元)清單的書寫序3 次顯示 7.0%,實佔 27.9%

這份榜單能回答什麼,不能回答什麼

能回答的是相對多少:463 字元的一段固定英文裡榜首確實是 e(50 次),與單字母頻率表的說法一致,但工具列印 10.8%,只按 379 個字母算是 13.2%,教科書那個 12.7% 兩頭都不沾——差額全來自留在分母的 78 個空白與 6 個標點。

不能回答的是中文的詞:詞由 ASCII 字母序列定義,中文在這張榜上永遠不出現,關鍵詞那欄又拿字元數當分母。真要用的話,可以先用文字排序去重把關鍵詞清單壓成唯一行,免得重複行把總命中次數抬高;如果本來只要「這篇稿多少字」那種總量,字數統計講的是另一套口徑,跟排名無關。

Q:中文為什麼永遠是 0 個詞?

詞的定義是 /[a-zA-Z]+/g 抓到的連續 ASCII 字母,漢字進不了這個字元類。逐字敲空格仍是 0——它不按空白切詞;重音字母反倒被當切分符,café 只剩 caf 一項。

Q:佔比加起來不等於 100%,是算錯了嗎?

三種成因實測都存在:停用詞留空時 17 項之和 100.3%,是逐行保留一位小數的捨入殘差;字元模式 41 項之和只有 83.5%,因為空白被跳過卻留在分母;停用詞打開後 11 項之和 62.6%,因為分母仍是過濾前的 24 詞。能不能相加,取決於分子與分母是不是同一份集合。

Q:並列同頻時榜首到底算誰?

看模式:字元模式裡 ASCII 數字按數值升序插隊,1234567890 的榜首是 0;詞模式按首次出現,zebra 排在 apple 前;關鍵詞模式照抄清單書寫順序。三套都不是字典序,同頻時不要把第 1 行當唯一答案。

📎 相關文章

文本合併後行數對不上:缺尾末換行、被吃掉的 BOM 和不可靠的順序 2026-10-26 Excel 貼上轉 JSON:日期、長數字與精度在貼上那一刻就已經變了 2026-10-26 條碼解碼只吐原文:EAN-13 檢查碼、UPC-A 的前導零與 CODE128 的模 103 2026-10-26 二維碼解碼實測:糾錯等級救不了遮擋,每模組 2 像素才是生死線 2026-10-26 CSS 壓縮沒吃掉 calc 的空格,美化卻把 .btn:hover 劈成了兩截 2026-10-26