使用PPMI改进共现矩阵
使用PPMI改進共現矩陣
共現矩陣的元素表示兩個單詞同時出現的次數,這里的次數并不具備好的性質,舉個例子,有短語叫the car,因為the是個常用詞,如果以兩個單詞同時出現的次數為衡量相關性的標準,與drive 相比,the和car的相關性更強,這是不對的。
點互信息(Pointwise Mutual Information,PMI):表達式如下,P(x)表示x發生的概率,P(y)表示y發生的概率,P(x,y)表示x和y同時發生的概率。PMI的值越高,表明x與y相關性越強。
用共現矩陣重寫PMI表達式:將共現矩陣表示為C,將單詞X和Y的共現次數表示為C(x,y),將單詞x和y的出現次數分別表示為C(x)、C(y),將語料庫的單詞數量記為N。表達式如下。
正的點互信息(Positive PMI,PPMI):當兩個單詞的共現次數為0時, log0=-∞。為解決這個問題,實踐上會使用下述正的點互信息。可以將單詞間的相關性表示為大于等于0的實數。
共現矩陣轉化為PPMI矩陣的函數實現:代碼中防止 np.log2(0)=-inf 而使 用了微小值 eps。
分析一下源碼,函數里加一個print:
M = np.zeros_like(C, dtype=np.float32)N = np.sum(C)S = np.sum(C, axis=0)total = C.shape[0] * C.shape[1]print(C)print(M)print(N)print(S)print(total)輸出如下,可見N是把共現矩陣C中所有數相加;M是維度和C相同的全為0的數組,用來存PPMI矩陣;S是記錄每個詞和別的詞共現的次數,total是等于7*7,這個是輸出進展情況時候用的,用來判斷當前進度。
[[0 1 0 0 0 0 0][1 0 1 0 1 1 0][0 1 0 1 0 0 0][0 0 1 0 1 0 0][0 1 0 1 0 0 0][0 1 0 0 0 0 1][0 0 0 0 0 1 0]][[0. 0. 0. 0. 0. 0. 0.][0. 0. 0. 0. 0. 0. 0.][0. 0. 0. 0. 0. 0. 0.][0. 0. 0. 0. 0. 0. 0.][0. 0. 0. 0. 0. 0. 0.][0. 0. 0. 0. 0. 0. 0.][0. 0. 0. 0. 0. 0. 0.]]14[1 4 2 2 2 2 1]49下面這句代碼,S[j]和S[i]指的是i和j和別的詞共現的次數,這里就知道了,代碼的實現和PMI表達式定義其實還是有差別的,代碼是在共現范圍內判斷兩個詞的相關性。舉個例子,a和b共現了x次,b和其他人現了y次,a和其他人現了j次,群體中人的個數是n,那在這個群體里b和a現的程度就是(x * n)/(y * j) 。(‘現’理解成XO)。
pmi = np.log2(C[i, j] * N / (S[j]*S[i]) + eps)完整代碼:
def ppmi(C, verbose=False, eps = 1e-8):'''生成PPMI(正的點互信息):param C: 共現矩陣:param verbose: 是否輸出進展情況:return:'''M = np.zeros_like(C, dtype=np.float32)N = np.sum(C)S = np.sum(C, axis=0)total = C.shape[0] * C.shape[1]cnt = 0for i in range(C.shape[0]):for j in range(C.shape[1]):pmi = np.log2(C[i, j] * N / (S[j]*S[i]) + eps)M[i, j] = max(0, pmi)if verbose:cnt += 1if cnt % (total//100 + 1) == 0:print('%.1f%% done' % (100*cnt/total))return M例子:
text = 'You say goodbye and I say hello.' corpus, word_to_id, id_to_word = preprocess(text) vocab_size = len(word_to_id) C = create_co_matrix(corpus, vocab_size) W = ppmi(C)np.set_printoptions(precision=3) # 有效位數為3位 print('covariance matrix') print(C) print('-'*50) print('PPMI') print(W)輸出:PPMI矩陣各個元素均為大于等于0的實數。
covariance matrix [[0 1 0 0 0 0 0][1 0 1 0 1 1 0][0 1 0 1 0 0 0][0 0 1 0 1 0 0][0 1 0 1 0 0 0][0 1 0 0 0 0 1][0 0 0 0 0 1 0]] -------------------------------------------------- PPMI [[0. 1.807 0. 0. 0. 0. 0. ][1.807 0. 0.807 0. 0.807 0.807 0. ][0. 0.807 0. 1.807 0. 0. 0. ][0. 0. 1.807 0. 1.807 0. 0. ][0. 0.807 0. 1.807 0. 0. 0. ][0. 0.807 0. 0. 0. 0. 2.807][0. 0. 0. 0. 0. 2.807 0. ]]隨著語料庫詞匯量增加,各個單詞向量的維數也會增加,這個矩陣很多元素都是0,表明向量中的絕大多數元素并不重要,對于這些問題,一個常見的方法是向量降維。
總結
以上是生活随笔為你收集整理的使用PPMI改进共现矩阵的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: zigbee无线通信数码管实验、usbD
- 下一篇: c语言统计数字字母个数,请问这个用c怎么