## 基礎概念 ### 什麼是非負矩陣分解(NMF) NMF(Non-negative Matrix Factorization,非負矩陣分解)是一種 常用於機器學習和數據分析的降維技術。可以運用在圖像識別、語音識別和文本分類等機器學習領域。顧名思義,NMF就是把一個非負矩陣分解為兩個非負矩陣: $$X_{m \times n} \approx W_{m \times k}H_{k \times n}$$ 其中k決定了分解後的矩陣的模樣(晚點解釋在文本分析的意義),決定了分解後的樣貌。 ![image](https://hackmd.io/_uploads/BJeI3Gd8T.png) ### 原理 $$\underbrace{arg\;min}_{W,H}\frac{1}{2}\sum\limits_{i,j}(X_{ij}-(WH)_{ij})^2$$ ### 常用的套件-Scikit-Learn ### 實例 [程式點這裡](https://colab.research.google.com/drive/1zA3gGd23DeD_JKMSxaoxK-46gju758M0?usp=sharing) 首先,建置一個4x5的矩陣X,然後建立NMF模型 ``` import numpy as np X = np.array([[1,1,5,2,3], [0,6,2,1,1], [3, 4,0,3,1], [4, 1,5,6,3]]) from sklearn.decomposition import NMF model = NMF(n_components=2, alpha=0.01) ``` 然後查看得到的W和H ``` W = model.fit_transform(X) H = model.components_ print("矩陣 W:") print(W) print("\n矩陣 H:") print(H) ``` 輸出 ``` W= [[7.89187028e-04 1.07159065e+00] [6.42160408e-02 2.62639320e-01] [4.49708099e-02 4.99087654e-01] [5.81574466e-04 1.70942244e+00]] H= [[ 8.64825434 87.99892014 0. 12.39745705 4.84721887] [ 2.06236067 0.62254879 3.28821824 3.1102805 2.0292366 ]] ``` 驗算一下 ``` W = np.array([[7.89187028e-04, 1.07159065e+00], [6.42160408e-02, 2.62639320e-01], [4.49708099e-02, 4.99087654e-01], [5.81574466e-04, 1.70942244e+00]]) H = np.array([[8.64825434, 87.99892014, 0., 12.39745705, 4.84721887], [2.06236067, 0.62254879, 3.28821824, 3.1102805, 2.0292366]]) X_approx = np.dot(W, H) X_approx = np.round(X_approx, decimals=2) # 比較X print("近似的 X:") print(X_approx) print("真正的X:") print(X) ``` 輸出 ``` 近似的 X: [[2.22 0.74 3.52 3.34 2.18] [1.1 5.81 0.86 1.61 0.84] [1.42 4.27 1.64 2.11 1.23] [3.53 1.12 5.62 5.32 3.47]] 真正的X: [[1 1 5 2 3] [0 6 2 1 1] [3 4 0 3 1] [4 1 5 6 3]] ``` W和H相乘應該要是X,但似乎不太像...WHY? ## 使用NMF做文本分析 ![enso1qaoae](https://hackmd.io/_uploads/rJ3aF3vU6.png) ### TF-IDF矩陣 TF-IDF(Term Frequency-Inverse Document Frequency)矩陣是一種在自然語言處理中常用的數據表示方法。可以將文本數據轉換為數字形式讓電腦能夠處理這些資料。以頻率而不是次數來看待文字的重要性,讓文章與文章之間比較有可比較性。 #### TF-IDF矩陣分為兩個部分 * Term Frequency (TF - 詞頻): 衡量一個詞在單個文檔中出現的頻率。通常使用的計算公式是詞頻(某個詞在文檔中出現的次數)除以文檔中所有詞的總數。 $$ tf(t,d)=\left(\frac{詞t在文檔d中出現的次數}{文檔d中所有詞的總數}\right)~$$ ![image](https://hackmd.io/_uploads/B10gOS_IT.png) * Inverse Document Frequency (IDF - 逆文檔頻率): 衡量一個詞在整個文檔集合中的重要性。常見的計算方式是使用總文檔數目除以包含該詞的文檔數目的對數。 $$ ~idf_t = \log\left(\frac{D}{d_t}\right)~$$ ![image](https://hackmd.io/_uploads/HymMuSuLa.png) 問:為什麼要取log? #### 最後將兩項指標相乘 ![image](https://hackmd.io/_uploads/ByZd_r_LT.png) ![image](https://hackmd.io/_uploads/Bk2LjSuI6.png) ### 操作原理 將文本轉換為TF-IDF矩陣後,進行NMF運算 先回到剛剛的定義式 $$X_{m \times n} \approx W_{m \times k}H_{k \times n}$$ 此時,可以這樣來解釋: 我們的資料集X中有m個文本和n個詞,所選的k就是文本的主題數。分解後的$W_{m \times k}$代表第m個文本和第k個主題的相關度,$H_{k \times n}$代表第n個詞和第k個主題的相關度,這裡的相關度都是指機率。 ### 優缺點 * 效能高(擷取特徵) * 忽略語意ex:我阿公已經走了一年多了(走路?過世?)、請把獵人結局燒給我(燒錄?燃燒?) ### 關於我們的專題... 資料蒐集:how? 文本是中文 資料清洗 ## 稍微複雜的範例 [參考文章](https://towardsdatascience.com/introduction-to-topic-modeling-using-scikit-learn-4c3f3290f5b9) [程式碼](https://colab.research.google.com/drive/1zJVExmLdxs_xb53iPPKqPLc6BvDo6LLh?usp=sharing)