最後更新:2026年9月14日

CHI 3242 課程大綱

第2週 語言、文本與編碼

1. 互動可視化與影片

2. 什麼是「文本」?

對你來說,文本是字、句子、故事。對電腦來說,文本只是一串數字。電腦不會「看」中文或英文——它只認得兩種狀態:開與關,寫成 0 和 1。所有文字、標點、表情,都要先變成數字,才能儲存或傳送。讀回來時,必須用同一套規則;規則用錯,就會看到亂碼。這套規則叫編碼(encoding)。下面從最小的單位講起。

3. 比特:最小的開關

一個比特(bit,也作位元)就是一個只能是 0 或 1 的開關。比特愈多,能區分的東西就愈多——每多一個,選擇就翻一倍。

比特數所有可能一共幾種
10 12
200 01 10 114
3000 001 010 011 100 101 110 1118

規律很簡單:n 個比特 → 2n 種可能。8 個比特合稱一個字節(byte,也作位元組),共 256 種值(0–255)。檔案在硬碟裡、在網路上移動的,就是這些字節。

一長串 0 和 1 不好讀,所以也常寫成十六進位(hex):二進位每位只有 0 和 1,hex 每位有 0–9 和 A–F,共十六個符號。同一個數字,兩種寫法而已。

4. ASCII:先夠用英文

電腦最早要處理的是英文。工程師用 7 個比特(128 種)編了一張小表,叫 ASCII(American Standard Code for Information Interchange,美國資訊交換標準代碼):英文字母、數字、常見標點,每個字符對應一個數字。美國標準協會在 1963 年公布第一版;1967 年的修訂補上小寫字母,大致就是今天仍在用的那 128 格。第八個比特補 0,所以每個 ASCII 字正好佔 1 個字節。下表三欄是同一個編號的三種寫法。

字符十進位hex二進位
A654101000001
a976101100001
0483000110000
!332100100001

128 格很快就滿了。中文、日文、表情都不在表裡——ASCII 從來沒打算裝下它們。後來各地各自發明編碼:中國大陸 1980 年公布 GB 2312,台灣資策會 1984 年訂出 Big5,1995 年的 GBK 再擴大大陸那一套。同一個檔案用錯規則打開,就變成亂碼。

5. Unicode:一張世界文字的大目錄

Unicode 的辦法是:做一張幾乎涵蓋全世界文字的大表,每個字符領一個獨一無二的編號。構想始於 1987 年 Xerox 與 Apple 的工程師(名稱由 Joe Becker 提出);Unicode 聯盟 1991 年成立,同年出版 Unicode 1.0。這個編號叫碼位(code point)。它只回答「這個字是幾號」,不規定這個號碼在檔案裡要怎麼存。

碼位習慣寫成 U+ 再加上一串 hex:

例如「A」的編號是十進位 65,hex 寫成 41,所以是 U+0041(前面多兩個 0,只是把位數寫齊)。「中」的編號是十進位 20013,hex 寫成 4E2D,所以是 U+4E2D。看到 U+4E2D,只要讀成:Unicode 表上,「中」的號碼是 4E2D。

6. UTF-8:把號碼存成字節

UTF-8 負責下一步:把碼位寫成字節,才能存檔或上網。1992 年 9 月,Ken Thompson 與 Rob Pike 為貝爾實驗室的 Plan 9 作業系統設計了它,讓舊的 ASCII 檔仍然合法;後來它成了網路的預設編碼。它是變長的——號碼小就少佔幾格,號碼大就多佔幾格。英文字母仍只佔 1 個字節(跟 ASCII 一模一樣),中文常佔 3 個,少數古字或表情佔 4 個。英文檔案因此維持小巧,又能裝下全球文字。

同一個字在不同編碼下會變成不同的字節。可用上面的字符編碼瀏覽器實際看這些差異。

電腦怎麼知道「這個字佔幾格」

UTF-8 在每個字節的開頭做記號:

開頭的記號叫首字節與接續字節。記號佔掉的位子以外,剩下的 x 用來填碼位的二進位。

字節數碼位範圍開頭記號例子(二進位)同一串(hex)
1U+0000 – U+007F0xxxxxxxA → 0100000141
2U+0080 – U+07FF110xxxxx 10xxxxxxé → 11000011 10101001C3 A9
3U+0800 – U+FFFF1110xxxx 10xxxxxx 10xxxxxx中 → 11100100 10111000 10101101E4 B8 AD
4U+10000 – U+10FFFF11110xxx 10xxxxxx 10xxxxxx 10xxxxxx🚀 → 11110000 10011111 10011010 10000000F0 9F 9A 80

表裡的「碼位範圍」也是 U+ 加 hex:例如 U+0000–U+007F 就是編號 00 到 7F,正好是全部 ASCII。

以「中」走一遍。同一個編號,先寫十進位,再寫 hex,再拆成 3 個字節(每個 8 個比特):

  1. 十進位:20013
  2. hex:4E2D(所以寫成 U+4E2D)
  3. 3 個字節:UTF-8 把這個號碼存成 8 + 8 + 8 個比特。3 字節的模板是 1110xxxx 10xxxxxx 10xxxxxx;把 4E2D 的二進位(0100 1110 0010 1101)填進 x,得到:
8 個比特hex
第 1 字節11100100E4
第 2 字節10111000B8
第 3 字節10101101AD

粗體是開頭記號;橙色是從碼位填進去的比特。檔案裡實際存的,就是 E4 B8 AD。

兩個直接後果。第一,UTF-8 包含全部 ASCII:hex 00 到 7F 的寫法完全相同,舊的英文檔本身就是合法的 UTF-8。第二,每個字節的開頭都在說「我是一個字的開頭」還是「我接在後面」,所以即使從中間開始讀,也能找到字與字的界線。

7. 中文分詞

英文以空格分隔詞,電腦很容易切分;中文書寫時詞與詞之間沒有空格,例如「我喜歡吃火鍋」要切成「我/喜歡/吃/火鍋」才有意義。分詞(segmentation)就是把一串中文字切成一個個詞的過程。分詞工具不少,例如 spaCy、HanLP、THUNLP;本課用 jieba,它會根據詞典與統計機率來判斷切分位置。分詞結果會直接影響後續的詞頻、搭配、主題模型等所有分析,因此是中文文本處理的第一步。

注意:jieba 的詞典是為簡體中文訓練的,直接拿繁體文本去跑,切分品質會明顯變差。若你的文本是繁體(例如台灣、香港出版的小說),請先用 opencc 套件把文本轉換成簡體,再分句、再用 jieba 分詞。

8. 詞袋模型(Bag of Words, BoW)

把一篇文本看作一個「袋子」,只統計每個詞出現幾次,完全忽略詞的順序與語法。例如「貓追狗」和「狗追貓」在詞袋模型裡是一樣的:{貓:1, 狗:1, 追:1}。這個簡化看似粗糙,但對許多任務(如比較兩篇文章的主題、作者用詞差異)已經足夠,也是向量空間模型與主題模型的基礎。

9. 停用詞(stopwords)

停用詞指在文本中出現頻率極高、但對區分文本意義幫助不大的詞,例如中文的「的、了、是、在、我、你」、英文的 "the, is, of, a"。做詞頻或主題分析前,常會先把停用詞移除,以免它們蓋過真正有訊息量的詞。停用詞表並無通用標準,應依語料與研究問題調整——例如研究「我」的頻率變化時,「我」就不能當停用詞刪掉。

10. Zipf 定律

Zipf 定律:在一段夠長的文本中,把所有詞按出現次數由高到低排列,第 n 名的詞的頻率大約與 n 成反比——也就是說,排名第 1 的詞出現次數約是第 2 名的兩倍、第 3 名的三倍,依此類推。結果是少數幾個詞佔了大部分出現次數,而長長的「尾巴」裡有大量只出現一兩次的罕見詞。這解釋了為什麼停用詞會主導詞頻表,也說明文本資料為何高度不均。

11. 課堂練習

到 qhchina-data/corpora 選一本小說的 .txt,把下面提示裡的 [link] 換成檔案網址,再貼進 OpenCode:

提示

Please download this novel as a .txt file [link]

Then write a .py script that:
- uses jieba to segment the text into words, removing punctuation marks
- prints the 10 most frequent words
- saves a simple png bar chart of the 100 most frequent words (columns only, no labels or annotations)

jieba and matplotlib are already installed; do not create a virtual environment.

完成後,看終端機印出的前 10 個詞,再開 .png。左邊幾根最高的柱,多半就是停用詞;整張圖由高到低迅速落下,就是 Zipf 定律。

若你用的是 Codespace,做完後請把結果 commit 並 push 到 GitHub。Codespace 被刪掉以後,沒有推上去的檔案就找不回來。