集體智慧編程第十章尋找獨立特徵:在數據集未明顯標註的情況下,尋找數據集的潛在特徵,比如SVD分解U,V矩陣都存在隱空間。
1. NMF
從數據中提取重要特徵的技術被稱爲非負矩陣分解(NMF)。
假設我們手上有一個對多篇文章進行單詞計數信息統計的文章矩陣。我們將這個矩陣分解爲兩個更小的矩陣,使得二者相乘幾乎完全等於原來的矩陣,這兩個矩陣分別是特徵矩陣和權重矩陣。假設原矩陣R(10 *1000) = M(10 *K) x N(K*1000)
1.1 NMF的特徵矩陣
在特徵矩陣中,每一行對應一個特徵,每個單詞對應一列。矩陣中的數字代表了某個單詞相對於某個特徵的重要程度。這裏N矩陣即爲特徵矩陣。
1.2 權重矩陣
該矩陣的每一行對應一篇文章,每一列對應一個特徵,矩陣中的數字代表了當前特徵對於當前文章的重要程度。這裏M矩陣即爲特徵矩陣。
1.3 求解特徵矩陣和權重矩陣
# -*- coding: utf-8 -*-
"""
非負矩陣分解用於 - 主題模型
使用了一種很奇特的算法: 乘法更新法則恢復原矩陣
"""
import numpy as np
np.random.seed(1)
def _cal_diff(matrix, recover):
"""
計算重構矩陣與原矩陣之間的誤差
recover:
重構矩陣
"""
return abs(matrix - recover).sum()
def factorize(m, fea_num = 6, _iter = 1000):
"""
對矩陣進行分解, 重構
m:
一行代表一篇文章, 一列代表一個單詞;
fea_num:
爲當前matrix尋找feature的個數;
該算法的核心 - 四個矩陣
hn = w' * m
hd = w' * w * feature
"""
if not isinstance(m, np.matrix):
m = np.matrix(m)
print("請確保輸入m是一個行爲文章, 列爲單詞的矩陣.")
# 1. 隨機初始化權重矩陣和特徵矩陣
weight = np.matrix(np.random.random((m.shape[0], fea_num)))
feature = np.matrix(np.random.random((fea_num, m.shape[1])))
# 2. 循環更新矩陣
for i in range(_iter):
# 2.1 計算重構矩陣和原矩陣的誤差
lose = _cal_diff(m, weight * feature)
if i % 10 == 0: print("\n原矩陣與重構矩陣之間的lose = {0}".format(lose))
if lose <= 1e-3: return weight, feature
# 2.2 更新特徵矩陣
hn = weight.T * m; hd = weight.T * weight * feature
feature = np.matrix(np.array(feature) * np.array(hn) / np.array(hd))
# 2.3 更新權重矩陣
wn = m * feature.T; wd = weight * feature * feature.T
weight = np.matrix(np.array(weight) * np.array(wn) / np.array(wd))
return weight, feature
2. NMF文本挖掘的意義
通過NMF分解,我們可以爲文章尋找多個較爲重要的主題,同時給出每個主題的關鍵詞。