[自然語言處理](https://app.notion.com/p/3e6fc631b03081b4a9e8f91f3411f61f) › [W3(9/24)](https://app.notion.com/p/3e6fc631b03081ff9776f36fab3e6e50) › 02|影片 [0:36:38–0:53:48](https://www.youtube.com/watch?v=g0QE6O17BWE&t=2198s)|投影片 W1_NLP_brief p.70–80|上一章 [01 詞向量的起源與類比(0:02–0:36)](https://app.notion.com/p/3e6fc631b0308169a5ebc6aa047ff58d)|下一章 [03 word2vec 的訓練方式(1:02–1:28)](https://app.notion.com/p/3e6fc631b03081f1b4bfe71efbd2cd7a) ## 重點 - 分布假說(distributional hypothesis):看一個字身邊常出現哪些字,就知道它的意思。cat 和 dog 身邊的字幾乎一樣,所以意思相近。 - 神經網路出現以前的做法是 LSA:先數「字跟字」或「字跟文章」一起出現幾次,做成一張大表,再用 SVD 只留最重要的 K 個方向。這樣一來,從沒一起出現、但鄰居相同的字也會被拉近。 - LSA 的致命傷:表格跟詞表一樣大(可能 10 萬 × 10 萬),SVD 算不動;多一篇新文章就要整個重算。所以後來改成「用學的」,也就是下一章的 word2vec。 ## Exam-ready - **Distributional hypothesis**: "A word is characterized by the company it keeps." (Firth 1957) "In other words, similar words will appear in similar contexts"(brief p.70) - **Latent Semantic Analysis**: "Words with similar meanings tend to appear in similar textual contexts or co-occur across similar documents."(brief p.71) - **Co-occurrence matrix**: "Using a corpus of text as input, draw a window of a defined length around each word and count co-occurrence statistics. The resulting matrix contains our word vectors."(brief p.71) - **SVD on co-occurrence**: "SVD on this co-occurrence matrix … Reduce dimension … Use the 2 biggest singular value to represent words"(brief p.73) - **Why LSA**: "serious problems for retrieval methods based on term matching … vector-space similarity approach works only if the terms of the query are explicitly presented in the relevant documents"(brief p.74) - **LSI**: "Uses a linear algebra technique called singular value decomposition (SVD) … attempts to estimate the hidden structure that generates terms given concepts … discovers the most important associative patterns between words and concepts"(brief p.75) - **Term-document matrix**: "each row is the vector-space representation of a document … each column contains occurrences of a term in each document in the dataset"(brief p.76) - **LSI steps**: "compute the SVD of X: X = UΣVᵀ … Σ - singular value matrix (diagonal matrix) … set to zero all but largest K singular values - Σ̂ … obtain the reconstruction of X by: X̂ = UΣ̂Vᵀ"(brief p.76) - **Problems**: "The original matrix still has the same dimension as our vocabulary size - potentially 100,000 x 100,000 … The matrix is extremely sparse … We can perform Singular Value Decomposition (SVD) for dimensionality reduction, however at a quadratic computational cost … Adding a new word changes the entire matrix"(brief p.80) ## [0:36:38](https://www.youtube.com/watch?v=g0QE6O17BWE&t=2198s) 分布假說:看一個字的鄰居 電腦要從哪裡學「字的意思」?答案來自語言學家 Firth(1957):一個字的意思,由它的鄰居決定。cat 和 dog 在大量文章裡,旁邊都是 licked、fur、eat、run 這些字,所以意思相近;你不會看到文章寫「卡車舔牠的貓」,所以 truck 的鄰居跟 cat 不一樣。目標是讓電腦學出一種表示(representation,用一串數字代表一個字),剛好能反映哪些字常一起出現的機率(co-occurrence probability,共現機率)。
用生活例子講,分布假說在說什麼? 讀英文遇到生字,不查字典也猜得出來:「The ___ licked its fur」,空格填 cat 或 dog 都通,填 truck 或 wheel 就很怪。能填進同一個空格的字,意思通常相近。 投影片 p.70 下方還有一例:banking 的前後是 government debt、crises、regulation、system。這些鄰居合起來,就描繪出 banking 的意思。 所以對你的影響是:這章的 LSA、下一章的 word2vec、之後的 GloVe,全都在做同一件事:把「鄰居很像」變成「向量很近」。
老師原話是什麼? 「就是有點像你去讀一個英文句子,這個字你不知道,但是你可以看出前後文在講,這個字大概是什麼意思」(0:37:19) 「如果這兩個字 cat 跟 dog,他的周邊的字幾乎都一樣,在我眾多語料裡面,他們旁邊發生的字都一樣,你大概可以猜出他們兩個字的概念是一樣」(0:37:30) 「你不會看到一個文章在描述卡車舔他的貓」(0:37:41) 「能不能讓電腦去學會一個表示,這個表示剛好可以 hit 到這個 co-occurrence probability」(0:37:57)
別人怎麼教這個? 維基百科 [Distributional semantics](https://en.wikipedia.org/wiki/Distributional_semantics):一頁看完分布假說的來源(Harris 1954、Firth 1957)。Firth 更常被引用的說法是 "You shall know a word by the company it keeps";考試照投影片寫 "A word is characterized by the company it keeps."
## [0:38:09](https://www.youtube.com/watch?v=g0QE6O17BWE&t=2289s) 以前的做法:共現矩陣小例子 講 word2vec 之前,老師先看神經網路以前的做法。老師說 LSI 現在不實用、不好算也不夠準,但在當年很厲害:只靠讀語料、不用人工標註的資料,就能學出貓和狗的關係。第一步是共現矩陣(co-occurrence matrix):定一個窗口(window,每個字左右各看幾個字),數每兩個字一起出現幾次。下表是 Stanford 課程的三句話,窗口大小 1(只看緊鄰的字):I like deep learning./I like NLP./I enjoy programming.
共現次數IlikeenjoydeeplearningNLPprogramming
**I**0210000
**like**2001010
**enjoy**1000001
**deep**0100100
**learning**0001000
**NLP**0100000
**programming**0010000
它到底怎麼運作?手算一次 1. 列出所有相鄰的字對。第一句:I–like、like–deep、deep–learning。第二句:I–like、like–NLP。第三句:I–enjoy、enjoy–programming。 2. 每出現一次,就在兩個對稱的格子各加 1。I–like 出現兩次,所以 I 那列的 like 格是 2。 3. 每一列就是那個字的向量。deep =(like 1、learning 1),NLP =(like 1)。 4. 用 cosine similarity 比較。deep 對 NLP:內積 1,長度是 √2 和 1,cos = 1/√2 ≈ 0.71。兩個字從來沒相鄰過,卻很像,因為都接在 like 後面。 5. like 對 enjoy:兩個都跟 I 相鄰,內積 2,長度是 √6 和 √2,cos = 2/√12 ≈ 0.58。 6. deep 對 learning:cos = 0。它們明明相鄰,但鄰居完全不同(deep 的鄰居是 like、learning;learning 的鄰居只有 deep)。 重點:分布假說比的是「鄰居像不像」,不是「兩個字有沒有常常一起出現」。 語料太少也會有怪結果:I 對 NLP 的 cos ≈ 0.89(兩個都跟 like 相鄰)。老師也說只有三句,很難講什麼統計 (0:41:04)。
要先懂什麼?向量與 cosine similarity 向量就是一串數字。這裡每個字用 7 個數字表示:跟 7 個字各相鄰幾次。 cosine similarity(餘弦相似度)看兩個向量的方向有多接近:cos = (a·b) / (|a| × |b|)。a·b 是對應位置相乘再加總;|a| 是長度,每個數平方、加總、開根號。 結果介於 −1 到 1。次數都是正的,所以這裡介於 0 到 1:1 代表方向完全一樣,0 代表毫無交集。 所以對你的影響是:作業一「每個字找五個最相似的字」用的 Gensim most_similar,就是用 cosine 排名。
老師原話是什麼? 「老師現在也不會用 LSI…但是他不 practical,也不好用,也不好算,然後算出來也不是那麼準」(0:38:19) 「我不用做監督式學習的資料,我就可以 train 這種貓跟狗的關係」(0:38:40)
## [0:40:26](https://www.youtube.com/watch?v=g0QE6O17BWE&t=2426s) 用 SVD 降維 共現矩陣有幾個字就有幾維,又大又多 0。第二步是 SVD(singular value decomposition,奇異值分解,把一個矩陣拆成三個矩陣相乘):拆開後只留最大的幾個奇異值,也就是最重要的幾個「隱藏方向」,每個字就只剩幾個數字。投影片只留 2 個,畫到平面上:deep 和 NLP 靠在一起,因為兩個都接在 like 後面。 **注意:老師說這裡不講 SVD 怎麼算 (0:40:27、0:44:39),但他假設你線性代數學過 (0:44:16、0:47:47)。短版補在下面。** [[IMG: C:\D槽\TAICA課程\_work\notes-v2\nlp-w3\img\nlp_w3_ch02_brief_p073.png | brief p.73:只留 2 個最大的奇異值,把 7 個字畫在平面上;紅框是靠在一起的字]]
要先懂什麼?SVD 短版 任何 m×n 的矩陣 X 都能拆成 X = UΣVᵀ。 U:每一橫列是一個字在各個「隱藏概念」上的座標。 Σ:對角矩陣,對角線上是奇異值 σ1 ≥ σ2 ≥ … ≥ 0。數字越大,那個概念越重要。 Vᵀ:每一直行是一篇文件(或一個上下文字)在各個概念上的座標。 只留前 K 個奇異值、其餘設成 0,得到的是「只用 K 個概念的矩陣裡,最接近原本 X 的那一個」(誤差平方和最小)。 每個字的 K 維向量:取 U 的前 K 個直行,乘上對應的 σ。p.73 的平面圖就是 K = 2。 老師補充:SVD 在推薦系統也很常用;因為計算量很大,實務上常用逼近、訓練的方式算 (0:48:06)。 所以對你的影響是:看到 "largest K singular values",就想成「只留最重要的 K 個概念」。
它到底怎麼運作?從共現矩陣到平面圖 1. 7×7 的共現矩陣 C 做 SVD:C = UΣVᵀ。 2. 只留最大的 2 個奇異值。 3. 每個字取 U 的前 2 個直行(乘上 σ1、σ2),得到 2 個數字,當成平面上的 (x, y)。 4. 畫出來,鄰居相似的字就會靠近。 老師口頭說乘回去之後,就可以得到每一個字的向量 (0:40:47)。更精確地說,平面座標來自第 3 步的 U;乘回去得到的是同樣大小的重建矩陣,下一個檢索例子用的是它。 learning 和 programming 也被圈在一起,老師沒解釋。三句話的例子只能看趨勢,不要過度解讀。
別人怎麼教這個? - Steve Brunton [Singular Value Decomposition (SVD): Overview](https://www.youtube.com/watch?v=gXbThCXjZFM):SVD 在做什麼、為什麼能降維。 - Visual Kernel [SVD Visualized](https://www.youtube.com/watch?v=vSczTbgc8Rc):用動畫看「旋轉、伸縮、再旋轉」。
## [0:43:49](https://www.youtube.com/watch?v=g0QE6O17BWE&t=2629s) 為什麼需要 LSA 傳統搜尋靠關鍵字比對(term matching):查詢裡的字要真的出現在文章裡,才找得到。這會出兩種方向相反的錯(p.74):有出現不見得是相關,沒出現不見得是無關。LSA 想找出字背後的「概念」,讓查詢不必一字不差。老師把接下來的內容比喻成「參觀博物館」:看看前人在神經網路出現前怎麼做,核心就是 SVD。 **注意:0:42:31–0:43:48 因為麥克風干擾,逐字稿變成亂碼,約 1 分鐘內容遺失(大約是 p.74 的前半)。這段照投影片補。**
p.74 的說法英文術語例子關鍵字比對會怎樣
有出現不見得是相關**polysemy**(一詞多義)查 apple 手機,找到講蘋果水果的文章找到不相關的(誤判)
沒出現不見得是無關**synonymy**(同一個意思有很多說法)查 car,漏掉只寫 automobile 的文章漏掉相關的(漏找)
要先懂什麼?向量空間模型怎麼搜尋 向量空間模型(vector-space model):把每篇文章和查詢都寫成「詞表上每個字出現幾次」的向量,再用 cosine 排名。 例:詞表是 (car, automobile, engine)。文章 A「car engine」= (1, 0, 1),文章 B「automobile engine」= (0, 1, 1),查詢「car」= (1, 0, 0)。 cos(查詢, A) = 1/√2 ≈ 0.71;cos(查詢, B) = 0。B 明明也在講車,卻完全找不到。這就是 p.74 說的 "works only if the terms of the query are explicitly presented"。 LSA 對同義詞特別有效;一詞多義只能部分改善,因為每個字還是只有一個向量。
用生活例子講? 你在圖書館的電腦查「腳踏車」,系統只比對字面,寫「自行車」「單車」的書全部漏掉(沒出現不見得是無關)。查「蘋果」,卻跑出一堆講 iPhone 的書(有出現不見得是相關)。LSA 想做的是:看出「腳踏車、自行車、單車」常出現在相同的上下文,把它們歸成同一個概念。
老師原話是什麼? 「因為有一詞多義」(0:43:49) 「沒有出現也不見得是無關,因為本來就是一個意思可以用很多種的方式來表示」(0:43:51) 「就是參觀一下博物館,說以前這些古人用的這樣的技術到底長什麼樣子」(0:44:04)
## [0:45:00](https://www.youtube.com/watch?v=g0QE6O17BWE&t=2700s) 十篇文章範例:Linux 與基因體 投影片用十篇新聞標題示範:d1–d5 講 Linux 作業系統,d6–d10 講基因體(genome)。兩組主題無關,唯一的橋是 database:d5 寫 mySQL database,d8 寫 genome database。把它們做成詞-文件矩陣(term-document matrix,每一列是一個關鍵字、每一行是一篇文章,格子是出現次數)。因為兩組用字完全分開,搜尋 Dolly(複製羊)時,前五篇絕對找不到。 這張表跟前面的共現矩陣不同(前面是「字 × 字」,這裡是「字 × 文章」),但老師說精神一樣 (0:40:08)。
詞/文章d1d2d3d4d5d6d7d8d9d10
open-source1000100000
software1001000000
Linux0001000000
released0111000000
Debian0110000000
Gentoo0010100000
**database**0000**1**00**1**00
Dolly0000010001
sheep0000010000
genome0000001110
DNA0000002001
**注意:p.76 定義的 X 是「每一列一篇文章」,p.78 畫的是它的轉置 Xᵀ(每一列一個字),所以標題寫 Xᵀ。兩種擺法做 SVD,只是 U 和 V 的角色互換。**
這十篇文章寫了什麼? - d1 Indian government goes for open-source software - d2 Debian 3.0 Woody released - d3 Wine 2.0 released with fixes for Gentoo 1.4 and Debian 3.0 - d4 gnuPOD released: iPOD on Linux… with GPLed software - d5 Gentoo servers running at open-source mySQL database - d6 Dolly the sheep not totally identical clone - d7 DNA news: introduced low-cost human genome DNA chip - d8 Malaria-parasite genome database on the Web - d9 UK sets up genome bank to protect rare sheep breeds - d10 Dolly's DNA damaged (只有投影片畫底線的 11 個字進詞表;d7 的 DNA 出現兩次,所以格子是 2。)
老師原話是什麼? 「當我要搜尋這個 Dolly 羊的時候,我絕對不會找到前五篇的東西,因為關鍵字都沒有出現」(0:47:05)
## [0:48:40](https://www.youtube.com/watch?v=g0QE6O17BWE&t=2920s) 只留前 K 個奇異值再乘回去 對詞-文件矩陣做 SVD,得到 10 個奇異值 2.57、2.49、1.99…0.10。只留最大的 2 個(K = 2),其餘設成 0,再乘回去,得到重建矩陣 X̂。原本是 0 的格子,現在出現小小的正值或負值:database 這一列在十篇文章裡都有值了;d5 這篇 Linux 文章也跟 genome、DNA 沾上一點邊。老師的說法是:靠 database 這個字,把概念傳到另一群文章去。 [[IMG: C:\D槽\TAICA課程\_work\notes-v2\nlp-w3\img\nlp_w3_ch02_brief_p079.png | brief p.79:K = 2 的重建矩陣。框起來的是 database 列和 d5 行,最右邊一行是 d5 原本的值]]
它到底怎麼運作?用四個字手算一次 詞表只挑四個字:car、automobile、engine、flower。三篇文章:d1「car engine」、d2「automobile engine」、d3 提到 flower 兩次。 原矩陣(每列一個字,依序是 d1、d2、d3):car (1, 0, 0);automobile (0, 1, 0);engine (1, 1, 0);flower (0, 0, 2)。 SVD 拆出三個概念: - σ = 2:「花」概念,只有 flower 和 d3。 - σ = √3 ≈ 1.73:「車」概念。字的權重 car 0.41、automobile 0.41、engine 0.82;文章權重 d1 0.71、d2 0.71。 - σ = 1:「用 car 還是 automobile」的差別。car +0.71、automobile −0.71;d1 +0.71、d2 −0.71。 K = 2:丟掉最小的 σ = 1,也就是丟掉「用詞的差別」。 乘回去:car 在 d2 的格子 = 1.73 × 0.41 × 0.71 ≈ 0.5。所以 car 變成 (0.5, 0.5, 0),automobile 也是 (0.5, 0.5, 0),engine 變成 (1, 1, 0),flower 不變。 結果:搜尋 car 時,d2 從 0 分變成 0.5 分,跟 d1 並列。d2 從頭到尾沒寫 car,卻被找到了。這就是「沒出現不見得是無關」的解法。
為什麼重建後會出現負數? SVD 的方向有正有負。只留 K 個方向再乘回去,是「用少數概念去近似」,有些格子會被估得比 0 還小。 負數可以讀成「這篇文章跟這個字的概念方向相反」。例如 p.79 的 DNA 在 d1–d4 是 −0.03 到 −0.06,表示 Linux 文章離基因概念更遠。老師說這樣可以把概念拉得更開 (0:50:21)。 反過來,d1 原本沒有 released,重建後是 0.63(綠圈);Linux 原本只在 d4,重建後 d2、d3 也有 0.37、0.50(橘字)。同一組文章的字,會互相補上。 d5 跟 Dolly、genome 沾上邊,老師也承認這個例子看起來有點怪;但語料更多、共現關係更複雜時,LSI 的結果其實不錯 (0:50:40)。 我用 p.78 的矩陣自己重算,奇異值是 2.55、2.40、1.94…,跟 p.79 印的不完全一樣,原因不確定;但「0 變非 0、出現負數」的現象一樣。考試照投影片的數字寫。
用生活例子講,只留前 K 個在做什麼? 像壓縮照片:只留最主要的幾個成分,細節會被抹掉,輪廓留下來。在 LSA 裡,被抹掉的細節是「這篇用 car 還是 automobile」,留下來的輪廓是「這篇在講車」。所以用 car 查,也找得到寫 automobile 的文章。
老師原話是什麼? 「我就靠這個 Database 去 propagate 這個 concept 出去了」(0:50:02) 「但是如果你的語料更多一點,你的關聯 co-occurrence 更複雜一點的時候,你就發現這個 LSI 做出來的東西其實還不錯」(0:50:46) 「在沒有這種大模型的年代的時候,誒這個技巧其實是非常神乎其技的」(0:50:59)
## [0:51:20](https://www.youtube.com/watch?v=g0QE6O17BWE&t=3080s) LSA 與 LSI 的差別和致命傷 這整套方法叫 LSA(latent semantic analysis,潛在語意分析);拿去做檢索、建索引時,叫 LSI(latent semantic indexing,潛在語意索引)。它在沒有神經網路的年代,只靠計算就得到字與字、文章與文章的關係。但它有兩個致命傷:SVD 太貴,真實語料動輒十萬維,電腦直接卡住;而且不能只補新資料,多一篇新文章就要整個重算。所以後來改成「用學的」、能算多少算多少,走向機率和語言模型的想法,也就是下一章的 word2vec。
p.80 的問題白話數字感
same dimension as our vocabulary size詞表多大,矩陣就多大10 萬 × 10 萬 = 100 億格;每格用 8 bytes 存要 80 GB
extremely sparse幾乎都是 0p.78 的小例子 110 格只有 22 格不是 0;一篇文章若用了 500 個不同的字,十萬維裡 99.5% 是 0
SVD at a quadratic computational cost字數變 10 倍,計算量至少變 100 倍老師:十萬維,電腦就卡住 (0:52:15)
Adding a new word changes the entire matrix不能增量更新(incremental update)多一個字或一篇新文章,整個 SVD 重算
要先懂什麼?quadratic cost 是什麼意思 Big-O 描述「資料變大時,計算量怎麼長」。quadratic(平方)就是 O(n²):n 變 10 倍,計算量變 100 倍。 從 1 萬維到 10 萬維,平方成長就是 100 倍。老師先問 1 萬 × 1 萬做 SVD 成本多少 (0:48:32),再說 10 萬維電腦直接卡住 (0:52:15)。 **注意:投影片寫 quadratic。線性代數教科書對 m×n 矩陣(m ≥ n)完整 SVD 的說法是 O(mn²),n×n 方陣就是 O(n³),比平方還貴。考試寫投影片的 quadratic。**
用生活例子講,為什麼不能增量更新? LSI 像一座圖書館,照「全館藏書算出來的主題」排書架。進了一本新領域的書,主題本身可能跟著變,只好全館重新分類。word2vec 這類「用學的」方法比較像店員:新書來了看一眼,微調自己的印象,不必整館重排。 老師也提到:一個方法發表後,常有人接著研究怎麼增量更新、怎麼刪掉某個概念,但用 SVD 很難做 (0:52:59)。
老師原話是什麼? 「那這個方法其實就叫 LSA」(0:51:20) 「所以這樣的一個技術我們叫 LSI」(0:51:35) 「你就發現做一個十萬維,十萬維的電腦就卡在那就做不出來這樣子」(0:52:15) 「他沒辦法 incremental 去 update」(0:52:36) 「那我們就用學的用算的,能夠算多少就算多少」(0:53:22) 「所以後面就有這種比較 probability 的想法,其實比較像是 language 的 model 的想法」(0:53:31)
## Self-check
Q1. State the distributional hypothesis. Using "The cat licked its fur" and "The dog licked its fur", explain why "cat" and "dog" should get similar vectors. **Answer**: The distributional hypothesis says "a word is characterized by the company it keeps" (Firth 1957): similar words appear in similar contexts. "cat" and "dog" share the same context words (licked, its, fur, and also eat, run, bite), so their co-occurrence vectors point in similar directions and have high cosine similarity, while words such as "wheel" or "sophisticated" rarely appear in those contexts. 中文重點:鄰居一樣,向量就接近。
Q2. Corpus: "I like deep learning." "I like NLP." "I enjoy programming." With a window size of 1, what is the co-occurrence count of (I, like)? Compute the cosine similarity of "deep" and "NLP" from their rows and explain why it is non-zero. **Answer**: count(I, like) = 2. deep = (like: 1, learning: 1) and NLP = (like: 1), so cos = 1 / (√2 × 1) ≈ 0.71. It is non-zero although "deep" and "NLP" never co-occur, because both share the neighbor "like". Distributional similarity measures shared contexts, not direct co-occurrence (e.g. cos(deep, learning) = 0). 中文重點:比的是共同鄰居,不是兩個字有沒有相鄰。
Q3. Describe the steps of Latent Semantic Indexing on a term-document matrix X. Why can an entry that is 0 in X become non-zero, even negative, in the reconstruction? **Answer**: (1) Build the term-document matrix X. (2) Compute the SVD X = UΣVᵀ, where Σ is the diagonal singular value matrix. (3) Set to zero all but the largest K singular values to get Σ̂. (4) Reconstruct X̂ = UΣ̂Vᵀ. X̂ is a rank-K approximation built from only K latent concepts, so a term's value in a document is estimated from the concepts they share. Terms linked by co-occurrence (e.g. "database" bridging Linux and genome news) spread to documents where they never appeared (positive values), and documents far from a concept can get small negative values. 中文重點:只留 K 個概念重建,概念會透過共現的字傳到別的文章。
Q4. Give two limitations of SVD-based methods such as LSA that motivated learning-based word embeddings like word2vec. **Answer**: (1) The matrix has the same dimension as the vocabulary (potentially 100,000 × 100,000) and is extremely sparse. (2) SVD has a quadratic computational cost, so it does not scale to large corpora. (3) Adding a new word changes the entire matrix, so the SVD must be recomputed; it cannot be updated incrementally. 中文重點:太大太稀疏、SVD 太貴、不能增量更新。