使用PPMI改进共现矩阵
使用PPMI改進共現(xiàn)矩陣
共現(xiàn)矩陣的元素表示兩個單詞同時出現(xiàn)的次數(shù),這里的次數(shù)并不具備好的性質(zhì),舉個例子,有短語叫the car,因為the是個常用詞,如果以兩個單詞同時出現(xiàn)的次數(shù)為衡量相關(guān)性的標準,與drive 相比,the和car的相關(guān)性更強,這是不對的。
點互信息(Pointwise Mutual Information,PMI):表達式如下,P(x)表示x發(fā)生的概率,P(y)表示y發(fā)生的概率,P(x,y)表示x和y同時發(fā)生的概率。PMI的值越高,表明x與y相關(guān)性越強。
用共現(xiàn)矩陣重寫PMI表達式:將共現(xiàn)矩陣表示為C,將單詞X和Y的共現(xiàn)次數(shù)表示為C(x,y),將單詞x和y的出現(xiàn)次數(shù)分別表示為C(x)、C(y),將語料庫的單詞數(shù)量記為N。表達式如下。
正的點互信息(Positive PMI,PPMI):當兩個單詞的共現(xiàn)次數(shù)為0時, log0=-∞。為解決這個問題,實踐上會使用下述正的點互信息??梢詫卧~間的相關(guān)性表示為大于等于0的實數(shù)。
共現(xiàn)矩陣轉(zhuǎn)化為PPMI矩陣的函數(shù)實現(xiàn):代碼中防止 np.log2(0)=-inf 而使 用了微小值 eps。
分析一下源碼,函數(shù)里加一個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是把共現(xiàn)矩陣C中所有數(shù)相加;M是維度和C相同的全為0的數(shù)組,用來存PPMI矩陣;S是記錄每個詞和別的詞共現(xiàn)的次數(shù),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和別的詞共現(xiàn)的次數(shù),這里就知道了,代碼的實現(xiàn)和PMI表達式定義其實還是有差別的,代碼是在共現(xiàn)范圍內(nèi)判斷兩個詞的相關(guān)性。舉個例子,a和b共現(xiàn)了x次,b和其他人現(xiàn)了y次,a和其他人現(xiàn)了j次,群體中人的個數(shù)是n,那在這個群體里b和a現(xiàn)的程度就是(x * n)/(y * j) 。(‘現(xiàn)’理解成XO)。
pmi = np.log2(C[i, j] * N / (S[j]*S[i]) + eps)完整代碼:
def ppmi(C, verbose=False, eps = 1e-8):'''生成PPMI(正的點互信息):param C: 共現(xiàn)矩陣: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) # 有效位數(shù)為3位 print('covariance matrix') print(C) print('-'*50) print('PPMI') print(W)輸出:PPMI矩陣各個元素均為大于等于0的實數(shù)。
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. ]]隨著語料庫詞匯量增加,各個單詞向量的維數(shù)也會增加,這個矩陣很多元素都是0,表明向量中的絕大多數(shù)元素并不重要,對于這些問題,一個常見的方法是向量降維。
總結(jié)
以上是生活随笔為你收集整理的使用PPMI改进共现矩阵的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: zigbee无线通信数码管实验、usbD
- 下一篇: c语言统计数字字母个数,请问这个用c怎么