[自然語言處理](https://app.notion.com/p/3e6fc631b03081b4a9e8f91f3411f61f) › [W2(9/17)](https://app.notion.com/p/3e6fc631b03081a18b13fad72a8874fd) › 06|影片 [1:48:46–2:07:15](https://www.youtube.com/watch?v=MnA5KUETSg4&t=6526s)|投影片 W1_NLP_brief_v2 p.48–52|上一章 [05 資訊檢索、索引與前處理(1:20–1:48)](https://app.notion.com/p/3e6fc631b0308148a521f4d07ae31526)|下一章 [07 課堂提問與 BM25(2:16–2:29)](https://app.notion.com/p/3e6fc631b030819ca51ee21869f5c86d)
## 重點
- 向量空間模型把每篇文件變成一支固定長度的向量:詞表有幾個字就有幾維,所以向量很長、但幾乎都是 0(稀疏)。兩篇文件像不像,就看兩支向量的夾角(cosine)。
- TF-IDF 是替每個字打的權重:TF 看這個字在這篇文章出現得多頻繁(要除以文章長度),IDF 看它在整個文件集有多稀有。每篇都有的字 IDF=0,完全沒有鑑別力。
- 這些老方法在 RAG 裡仍然有用:向量長度都縮成 1 時,cosine 就等於內積,向量資料庫做的正是這件事;稠密的 embedding 再加上稀疏的 TF-IDF,關鍵字檢索會更準。
## Exam-ready
- **Vector-space model**: "Text documents are mapped to a high-dimensional vector space"(W1_NLP_brief_v2 p.48)【老師強調】(1:49:28)
- 中文:每篇文件都被放進一個維度很高的向量空間,變成空間裡的一支向量。白話:一篇文章變成一串固定長度的數字。high-dimensional(高維度)。
- **Sparse representation**: "Vector-space representations are sparse, |V| >> |d| (the number of distinct terms in any single document)"(W1_NLP_brief_v2 p.48)
- 中文:向量空間的表示法很稀疏:詞表大小 |V| 遠大於任何一篇文件裡不重複的字數 |d|。白話:3 萬格裡只有幾百格有值,其他都是 0。sparse(稀疏)、distinct terms(不重複的字)。
- **Term frequency (TF)**, `TF_ij = n_ij / |d_i|`: "A term that appears many times within a document is likely to be more important than a term that appears only once"(W1_NLP_brief_v2 p.49)
- 中文:在一篇文件裡出現很多次的字,很可能比只出現一次的字重要。公式是「字 j 在文件 i 出現的次數 ÷ 文件 i 的總字數」。occurrence(出現次數)。
- **Inverse document frequency (IDF)**, `IDF_j = log(n / n_j)`: "A term that occurs in a few documents is likely to be a better discriminator than a term that appears in most or all documents"(W1_NLP_brief_v2 p.50)【老師強調】(1:56:31)
- 中文:只出現在少數文件的字,比出現在大部分或全部文件的字,更能拿來區分文件。n 是文件總數,n_j 是包含字 j 的文件篇數。discriminator(鑑別器,能把東西分開的依據)。
- **IDF**: "absolute measure of term importance"(W1_NLP_brief_v2 p.50)
- 中文:IDF 是一個字「本身」有多重要的量尺。白話:它只看這個字在整個文件集裡稀不稀有,跟你正在看哪一篇文章無關。
- **Document similarity**: "Ranks documents by measuring the similarity between each document and the query"(W1_NLP_brief_v2 p.51)
- 中文:檢索時,先算出每篇文件和查詢有多相似,再依相似度排名。rank(排名)、query(查詢)。
- **Cosine coefficient**, `cos(x, x') = xᵀx' / (‖x‖ · ‖x'‖)`: "In a vector-space representation the cosine coefficient of two document vectors is a measure of similarity"(W1_NLP_brief_v2 p.51)
- 中文:在向量空間裡,兩個文件向量的 cosine 值就是它們的相似度。公式是兩支向量的內積,除以兩支向量長度的乘積。coefficient(係數)。
- **Cosine vs. dot product**: "Cosine similarity vs. dot product"(W1_NLP_brief_v2 p.51)【老師強調】(2:02:20)
- 中文:cosine 相似度和內積的差別。cosine 多除了長度,只看方向;向量長度都先縮成 1 時,兩者相等。dot product(內積)。
- **TF-IDF variants**: "Many search engines allow for different weightings for queries v.s. documents"(W1_NLP_brief_v2 p.52)
- 中文:很多搜尋引擎允許查詢和文件用不同的加權算法,例如查詢用 ltn、文件用 lnc。weighting(加權方式)。
## [1:48:46](https://www.youtube.com/watch?v=MnA5KUETSg4&t=6526s) 向量空間模型
上一章的倒排索引(inverted index)只能回答「有沒有這個關鍵字」;使用者如果丟進一整篇文章要你找相似的,就需要能比較「像不像」的表示法。向量空間模型(vector-space model)的做法是:詞表(vocabulary)有 3 萬個字,空間就是 3 萬維;文章有這個字,那一維填 1,沒有就填 0。為什麼要這樣做?因為文章長短不一,變成向量後長度卻全都一樣,電腦才能直接比。一篇文章不重複的字通常只有兩三百個,3 萬格裡只有約 300 格有值,所以叫稀疏(sparse)向量。
比喻:像大家都填同一張 3 萬個選項的「興趣勾選表」,每人只勾幾百格;表格格式一樣,對一對勾到的格子重疊多少,就知道兩個人像不像。
下圖是投影片的示意:每個字是一條座標軸(ω1、ω2、ω3),文件 d 和 d′ 各是一支箭頭 x 和 x′。
[[IMG: C:\D槽\TAICA課程\_work\notes-v2\nlp-w2\img\brief_W1_NLP_brief_p048.png | 向量空間模型:每個字是一個維度,每篇文件是一支向量]]
兩支箭頭的夾角 α 越小,兩篇文章越像。這就是本章後面 cosine 相似度的由來。
考試可能怎麼問:Explain how the vector-space model represents a document and why the vector is sparse.(說明向量空間模型怎麼表示一篇文件,以及為什麼向量很稀疏)
它到底怎麼運作?(進階,可跳過)
假設詞表只有 4 個字,順序是[報導、大谷翔平、全壘打、股票]。
- 文章「大谷翔平 全壘打 報導」→ (1, 1, 1, 0)
- 文章「股票 報導」→ (1, 0, 0, 1)
投影片把文件寫成一串字 d = (ω(1), ω(2), …, ω(|d|))。老師補充:實際上是先把每個字變成 one-hot 向量(只有自己那格是 1),例如「大谷翔平」是 (0, 1, 0, 0);再把整篇的 one-hot 向量 OR 起來(任一個是 1 就填 1),就得到上面的文件向量。真實的 3 萬維裡,只有約 1% 的格子有值。
老師原話是什麼?
- 「可能你覺得很 Trivial 但是其實這個概念還蠻重要的」(1:49:28)
- 「這是一種固定的表示方式對電腦的理解來講是比較有利的」(1:50:00)
- 「所以是個非常 Sparse 的一個 Vector」(1:52:16)
## [1:52:22](https://www.youtube.com/watch?v=MnA5KUETSg4&t=6742s) TF:詞頻與正規化
只記「有沒有出現」太粗糙;同一個字出現越多次,通常越重要,這個次數叫詞頻 TF(term frequency)。老師的例子:一篇新聞一直出現「大谷翔平」,就是在講他;如果「大谷翔平」只出現一次,其他都是一大堆道奇隊的球員,那篇大概跟他沒那麼有關。為什麼還要除以文章的總字數(正規化,normalize)?因為次數是絕對值,3 萬字的長文章隨便都能出現很多次,不除的話長文章永遠壓過短文章。
比喻:一個人講 5 分鐘提到某人 10 次,比講 2 小時提到 20 次更在意那個人;要看比例,不是看總次數。
考試可能怎麼問:Why should term frequency be normalized by document length?(為什麼 TF 要除以文章長度)
它到底怎麼運作?(進階,可跳過)
投影片公式:`TF_ij = n_ij / |d_i|`。n_ij 是字 j 在文件 i 出現的次數,|d_i| 是文件 i 的總字數。
- 文章 A:200 字,「大谷翔平」出現 10 次 → TF = 10 ÷ 200 = 0.05
- 文章 B:2,000 字,「大谷翔平」出現 20 次 → TF = 20 ÷ 2,000 = 0.01
只看次數,B 贏(20 > 10);正規化後,A 贏(0.05 > 0.01)。A 整篇在講大谷,B 只是順便提到,正規化後的結果才對。
老師原話是什麼?
- 「你一定要 Normalize 不然會被大文章所 Dominate」(1:53:49)
## [1:54:01](https://www.youtube.com/watch?v=MnA5KUETSg4&t=6841s) IDF:逆文件頻率
TF 只看一篇文章內部;IDF(inverse document frequency,逆文件頻率)改看整個文件集:這個字出現在幾篇文件裡?篇數越少,IDF 越高。老師的例子:一萬篇新聞每篇都寫「某某記者報導」,「報導」出現在全部一萬篇,IDF=log(一萬 ÷ 一萬)=log 1=0,權重直接歸零,幾乎可以濾掉。為什麼要「倒過來」算?因為每篇都有的字分不出文章之間的差別,稀有的字才有鑑別力,所以 IDF 被叫做鑑別器(discriminator)。
注意:老師口頭說成「這個字總共出現幾次」,投影片的定義(紅字)是「有幾篇文件包含這個字」。同一篇裡出現 10 次,也只算 1 篇。
比喻:班上認人時,「有戴眼鏡」一半的人都有,幫不上忙;「左臉有顆痣」只有一個人有,一說就知道是誰。
考試可能怎麼問:What does IDF measure, and what is the IDF of a term that appears in every document?(IDF 在衡量什麼?每篇都有的字 IDF 是多少?)
它到底怎麼運作?(進階,可跳過)
投影片公式:`IDF_j = log(n / n_j)`。n 是文件總數(老師口頭叫它大 N),n_j 是包含字 j 的文件篇數。log 以 10 為底時,log 100 = 2 的意思是「10 乘兩次等於 100」,而 log 1 = 0。
沿用 n = 10,000 篇新聞:
- 「報導」:10,000 篇都有 → log(10,000 ÷ 10,000) = log 1 = 0
- 「大谷翔平」:100 篇有 → log(10,000 ÷ 100) = log 100 = 2
- 某個罕見人名:只有 1 篇有 → log 10,000 = 4(最大值)
TF-IDF 就是兩者相乘。文章 A 裡「大谷翔平」的 TF 是 0.05 → 0.05 × 2 = 0.1;「報導」在 A 出現 2 次,TF = 0.01 → 0.01 × 0 = 0。「報導」出現再多次也拿不到分。
老師原話是什麼?
- 「所以 IDF 是一個很重要的工具用來鑑別一個字詞的重要性」(1:55:27)
## [1:55:34](https://www.youtube.com/watch?v=MnA5KUETSg4&t=6934s) 為什麼做 RAG 還要懂 TF-IDF
做 RAG(先到資料庫檢索資料,再讓 LLM 回答)時,很多人直接把句子轉成 embedding(模型算出來的稠密向量)來比相似度,但效果常常不夠好,因為句子的 embedding 有點模糊,關鍵字細節會被抹平。在稠密向量(dense vector)之外再加上 TF-IDF 的稀疏向量(sparse vector),關鍵字對得上的文件就會被拉上來,所以 TF-IDF 雖然古老,仍是非常強的 baseline(比較基準)。IDF 在這裡的角色:一萬篇都有的字,查了等於把所有結果丟給使用者;只出現在一篇的字,一查就知道該回哪一篇。
下圖是「稠密+稀疏」一起用的流程(我補充:常叫 hybrid search,混合檢索)。
```mermaid
flowchart LR
Q["使用者的問題"] --> E["轉成 embedding(稠密向量)"]
Q --> T["轉成 TF-IDF(稀疏向量)"]
E --> R1["意思相近的文件"]
T --> R2["關鍵字對得上的文件"]
R1 --> M["合併排名"]
R2 --> M
M --> L["交給 LLM 回答"]
```
兩條路各找一批文件,合併後交給 LLM。稀疏那條路負責把人名、型號、專有名詞對準。
比喻:找一本書時同時問兩個人,一個是懂內容但記得有點模糊的朋友(embedding),一個是只照關鍵字查的圖書館索引卡(TF-IDF);兩個一起問,比只問一個準。
考試可能怎麼問:Why is TF-IDF still considered a strong baseline for retrieval in RAG systems?(為什麼 TF-IDF 在 RAG 檢索裡仍是很強的 baseline)
老師原話是什麼?
- 「通常你轉成句子的 embedding 它其實會有點模糊度」(1:56:02)
- 「雖然它是很古老的東西但是它是一個非常 Strong 的 Baseline」(1:56:24)
- 「大家就要記住 IDF 是用來幹嘛」(1:56:31)
## [1:57:07](https://www.youtube.com/watch?v=MnA5KUETSg4&t=7027s) IDF 的正規化與分佈
一個字只出現在一篇文件時,IDF 最大。把 IDF 再除以 log n(n 是文件總數),值就落在 0 到 1 之間,這是正規化後的 IDF;不正規化就沒有上限,但因為取了 log,也大不到哪裡去。IDF 是經驗公式(heuristic,前輩訂出來、大家發現好用就一直用的規則),但它和 Entropy(熵,衡量不確定性的量)有理論上的關係(投影片引 Papineni 2001)。
下圖是投影片右邊的散佈圖:每個點是一個字,橫軸是這個字出現的頻率(取 log10),縱軸是它的 IDF。
[[IMG: C:\D槽\TAICA課程\_work\notes-v2\nlp-w2\img\brief_W1_NLP_brief_p050.png | IDF 的分佈:越常見的字 IDF 越低,在 log 刻度上接近一條直線]]
越常見的字越靠右下(IDF 低,stop words 在這裡,通常會先拿掉),越罕見的字越靠左上(多半是稀有字或專有名詞)。畫這張圖是為了檢查鑑別力:你想分開的那些字如果全擠在中間、IDF 都差不多,就代表這個權重不適合你的應用,要換一種變形。
比喻:像考卷的分數分佈,想分出高下的學生全擠在 70 分附近,這份考卷就沒有鑑別度,要改題目。
考試可能怎麼問:How can IDF be normalized to the range 0 to 1, and how would you check whether it discriminates well?(IDF 怎麼正規化到 0~1?怎麼檢查它有沒有鑑別力?)
它到底怎麼運作?(進階,可跳過)
正規化後的 IDF=`log(n / n_j) / log n`(老師的說法是「log 以 n 為底」,意思一樣)。沿用 n = 10,000,log 10,000 = 4:
- 「報導」:0 ÷ 4 = 0
- 「大谷翔平」:2 ÷ 4 = 0.5
- 只出現在 1 篇的罕見字:4 ÷ 4 = 1(最大值)
不管資料集有幾篇,最大值永遠是 1,不同資料集算出來的 IDF 才比得起來(我補充)。
老師原話是什麼?
- 「但是其實 IDF 有一些理論的基礎它其實跟 Entropy 會有點關係」(1:58:30)
- 「我想要區分的字呢如果都集中在中間這一塊那表示我這個演算法不好」(1:58:53)
## [1:59:58](https://www.youtube.com/watch?v=MnA5KUETSg4&t=7198s) cosine 相似度與內積
乘上 TF-IDF 之後,每篇文件是一支 3 萬維、大多是 0 的向量。兩篇文件像不像,看兩支向量的夾角:完全一樣就沒有夾角,cos 0° = 1,這就是 cosine 相似度。很多同學分不清它和內積(dot product):cosine 就是內積再除以兩支向量的長度,所以只看方向、不管長短。如果事先把所有向量的長度都縮成 1(全部放在半徑 1 的球面上),cosine 就直接等於內積;向量資料庫(vector database)算相似度,做的就是這件事。
用 TF-IDF 做檢索,文字版步驟:
1. 定好詞表,每個字是一維。
2. 每篇文件算出每個字的 TF × IDF,變成一支向量,再把長度縮成 1。
3. 查詢也用同樣的方法變成向量。
4. 查詢和每篇文件算 cosine(長度都是 1 時,就是內積)。
5. 依分數由高到低排,前幾名就是結果。
下圖是這段的因果:
```mermaid
flowchart LR
A["每篇文件變成向量"] --> B["長度都縮成 1"]
B --> C["cosine 等於內積"]
C --> D["只算內積就能排名"]
D --> E["向量資料庫就在做這件事"]
```
老師補一句:現在向量資料庫存的多半是模型壓縮過的稠密向量,很多概念黏在一起、「糊糊的」,比稀疏向量難解讀。
比喻:比兩個人的口味看的是比例、不是份量:一人點一碗、一人點十碗同樣的牛肉麵,口味其實一樣。cosine 只看比例(方向),內積會被份量(長度)影響。
考試可能怎麼問:What is the difference between cosine similarity and dot product, and when are they equal?(cosine 和內積差在哪?什麼時候相等?)
它到底怎麼運作?(進階,可跳過)
投影片公式:`cos(x, x') = xᵀx' / (‖x‖ · ‖x'‖)`,分子是內積,分母是兩支向量的長度相乘。
為了好算,詞表縮成三個字[報導、大谷翔平、全壘打],權重用整數:
- 查詢「大谷翔平 全壘打」:q = (0, 1, 1),長度 √2 ≈ 1.41
- 文章 A(短,專講大谷打全壘打):A = (0, 3, 4),長度 5
- 文章 B(長,沒做正規化所以數字大):B = (0, 8, 2),長度 √68 ≈ 8.25
內積:q·A = 3 + 4 = 7,q·B = 8 + 2 = 10 → 內積說 B 比較像。
cosine:7 ÷ (1.41 × 5) ≈ 0.99,10 ÷ (1.41 × 8.25) ≈ 0.86 → cosine 說 A 比較像,這才對。
驗證:先把長度縮成 1,A 變 (0, 0.6, 0.8),q 變 (0, 0.71, 0.71),內積 = 0.71 × 0.6 + 0.71 × 0.8 ≈ 0.99,和 cosine 一樣。
投影片旁邊的 O(|d| + |d′|) 是計算量:只要掃過兩篇文件「有值的格子」,不用真的算滿 3 萬維。
老師原話是什麼?
- 「所以在算相似度在算 cos 夾角的時候其實就是兩個向量的內積」(2:01:39)
- 「那這件事情其實還蠻重要的尤其是到時候現在你說做 LLM 做 RAG 你會建所謂的 Vector Database」(2:02:20)
## [2:03:38](https://www.youtube.com/watch?v=MnA5KUETSg4&t=7418s) TF-IDF 的各種變形
TF-IDF 沒有唯一的標準算法,TF、DF、正規化三部分各有好幾種變形(投影片 p.52 的表)。最偷懶的是直接拿次數當權重;次數差太多(一萬次對一兩次)就取 log 壓小差距;或把 TF 壓到 0.5~1 之間。壓扁不是等於沒做嗎?差別在最低分被墊高:本來只拿 0.1 的罕見字現在至少有 0.5,不會被常見字蓋掉。另外查詢短、文件長,兩邊可以用不同算法再做內積,例如查詢用 ltn、文件用 lnc。
下圖是 ltn.lnc 的意思:
```mermaid
flowchart LR
Q["查詢(很短)"] --> QW["ltn:TF 取 log、乘 IDF、不正規化"]
D["文件(很長)"] --> DW["lnc:TF 取 log、不乘 IDF、cosine 正規化"]
QW --> S["兩邊做內積得到分數"]
DW --> S
```
三個字母依序代表 TF、DF、正規化的算法。老師說這些都很 heuristic(憑經驗湊的),但能把你的應用想強調的東西拉出來就有用,做 RAG 時也用得到。
比喻:像調音響的等化器,沒有「正確」設定;古典和搖滾各調一套,聽起來對就好。
考試可能怎麼問:Why might a search engine use different TF-IDF weighting schemes for queries and documents?(為什麼查詢和文件可以用不同的 TF-IDF 算法)
它到底怎麼運作?(進階,可跳過)
- 取 log:`1 + log(tf)`。出現 1 次 → 1;10 次 → 2;10,000 次 → 5。一萬倍的差距縮成 5 倍。
- 壓到 0.5~1(augmented):`0.5 + 0.5 × tf / 最大 tf`。沿用文章 A,出現最多的字是「大谷翔平」10 次。只出現 1 次的字,原本比例 1 ÷ 10 = 0.1,壓完變 0.5 + 0.05 = 0.55;「大谷翔平」是 1。差距從 10 倍縮到不到 2 倍。
- 為什麼查詢不用正規化(我補充):查詢向量除以自己的長度,等於每篇文件的分數都乘上同一個數,排名不會變,所以可以省掉。
- 為什麼文件不乘 IDF(我補充):查詢那邊乘過一次,內積時就算進去了。
- 注意(我補充):Manning 的資訊檢索課本把文件寫在前(例如 lnc.ltc),和老師這裡的讀法相反。
老師原話是什麼?
- 「本來只有 0.1 他現在可以變 0.5」(2:05:20)
- 「你的 query 跟 document 長相不一樣的時候你可能需要有不同的權重計算的方式」(2:06:41)
- 「其實你在做 RAG 的時候就會用到這些想法」(2:06:51)
## Self-check
Q1. What is IDF used for, and what is the IDF of a term that appears in every document of the collection?(中文:IDF 是用來做什麼的?一個出現在每篇文件裡的字,IDF 是多少?)
**Answer**: IDF measures how well a term discriminates between documents. It is computed as `IDF_j = log(n / n_j)`, where n is the total number of documents and n_j is the number of documents that contain term j. A term that appears in every document has n_j = n, so its IDF is log 1 = 0: it carries no weight because it cannot tell documents apart. A term that appears in only one document gets the highest IDF.
中文:IDF 是用來判斷一個字有沒有「鑑別力」,也就是能不能把文件區分開。算法是 log(文件總數 ÷ 包含這個字的文件篇數)。每篇都有這個字時,括號裡是 1,log 1 = 0,權重是 0:查它等於把所有文件丟回來。只出現在一篇的字 IDF 最高,一查就知道是哪一篇。
Q2. Why is term frequency usually normalized by the length of the document?(中文:為什麼 TF 通常要除以文件長度?)
**Answer**: A raw count is an absolute number, so long documents naturally contain more occurrences of almost every term. Without normalization, long documents would dominate short ones. Dividing the count n_ij by the document length |d_i| turns it into a proportion, so a short document that focuses on a term can score higher than a long document that only mentions it in passing.
中文:原始次數是絕對值,長文章幾乎每個字都出現得比較多,不除以長度的話,長文章會一直壓過短文章。除以總字數變成「比例」後,短短卻專講這個主題的文章,才能贏過很長、只是順便提到的文章。
Q3. What is the difference between cosine similarity and dot product, and why does this matter for vector databases?(中文:cosine 相似度和內積差在哪?這跟向量資料庫有什麼關係?)
**Answer**: The dot product sums the products of matching dimensions, so it is affected by vector length. Cosine similarity divides the dot product by the lengths of the two vectors, so it only measures the angle (direction) between them. If all vectors are normalized to length 1, cosine similarity equals the dot product. Vector databases used in RAG rely on this: they store normalized vectors and rank them by dot product, which is the same as ranking by cosine similarity.
中文:內積是把同一維度的值相乘再加總,所以向量越長,內積越大。cosine 是內積再除以兩支向量的長度,只看夾角(方向),不管長短。所有向量的長度都先縮成 1 時,cosine 就等於內積。RAG 的向量資料庫就是這樣做:存長度為 1 的向量、用內積排名,結果和用 cosine 排名一樣。
Q4. Why is TF-IDF still useful in RAG systems that already use dense embeddings?(中文:RAG 已經用了稠密的 embedding,為什麼 TF-IDF 還有用?)
**Answer**: Sentence embeddings are dense vectors that blur many concepts together, so exact keywords can be lost. Adding a sparse TF-IDF vector brings back keyword matching, and IDF gives higher weight to rare, discriminative terms. Combining sparse and dense vectors often improves retrieval, so TF-IDF is old but still a very strong baseline.
中文:句子的 embedding 是稠密向量,很多概念黏在一起、有點模糊,人名、型號這類精確關鍵字容易被抹平。再加上 TF-IDF 的稀疏向量就能把關鍵字對準,而且 IDF 會讓稀有、有鑑別力的字拿到較高權重。兩者一起用,檢索常常更準,所以 TF-IDF 雖然古老,仍是非常強的 baseline。
讀完了嗎?下一章:[07 課堂提問與 BM25(2:16–2:29)](https://app.notion.com/p/3e6fc631b030819ca51ee21869f5c86d)|回到週頁:[W2(9/17)](https://app.notion.com/p/3e6fc631b03081a18b13fad72a8874fd)