データ・マイニング-低ランク・マトリクスのリカバリと非負のマトリクスの分解


1.低ランクマトリクス回復
低ランクマトリクス回復は主に推奨アルゴリズムに適用され,マトリクス中の未採点位置を採点する.具体的な原理はここを導きましょう.http://download.csdn.net/download/zk_j1994/9983147
コード:
# -*- coding: utf-8 -*-
"""
           

1.             ;

"""
import numpy as np
import matplotlib.pyplot as plt

np.random.seed(1)

def load_data():
    data = [[0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 5],
            [0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 3],
            [0, 0, 0, 0, 4, 0, 0, 1, 0, 4, 0],
            [3, 3, 4, 0, 0, 0, 0, 2, 2, 0, 0],
            [5, 4, 5, 0, 0, 0, 0, 5, 5, 0, 0],
            [0, 0, 0, 0, 5, 0, 1, 0, 0, 5, 0],
            [4, 3, 4, 0, 0, 0, 0, 5, 5, 0, 1],
            [0, 0, 0, 4, 0, 4, 0, 0, 0, 0, 4],
            [0, 0, 0, 2, 0, 2, 5, 0, 0, 1, 2],
            [0, 0, 0, 0, 5, 0, 0, 0, 0, 4, 0],
            [1, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0]]
    return np.array(data)

def gradAscent(data, K, max_iter, alpha, beta):
    """       P, Q     ,         """
    if not isinstance(data, np.matrix):
        data = np.mat(data)
        
    #    P, Q  
    n, m = data.shape
    P = np.mat(np.random.random((n, K)))
    Q = np.mat(np.random.random((K, m)))
    print("
P =
{0}".format(P)) print("
Q =
{0}".format(Q)) loss_list = [] _iter = 0 while _iter < max_iter: # P, Q for i in range(n): for j in range(m): if data[i, j] > 0: error = (data[i, j] - P[i, :] * Q[:, j])[0, 0] # (i, j) for k in range(K): P[i, k] = P[i, k] + alpha * (2 * error * Q[k, j] - beta * P[i, k]) Q[k, j] = Q[k, j] + alpha * (2 * error * P[i, k] - beta * Q[k, j]) # loss = 0 for i in range(n): for j in range(m): if data[i, j]> 0: for k in range(K): loss += P[i, k] * Q[k, j] loss = np.sum(abs(data[i, j] - loss)) loss_list.append(loss) if loss <= 1e-3: break _iter += 1 return P, Q, loss_list def draw_loss(loss): plt.plot(range(len(loss)), loss) plt.show() if __name__ == "__main__": data = load_data() P, Q, loss = gradAscent(data, 5, 20000, 0.0002, 0.02) print("
=
{0}".format(P * Q)) draw_loss(loss)

loss降下プロセス:

2.非負のマトリックス分解
非負行列分解は低ランク行列回復と類似しており,それらの3つの行列の要素はいずれも非負を要求している.異なるのは、低ランクマトリクス回復が、元のマトリクスの0を予測する位置である.負の行列分解ではなく,元の行列が完全であると考えられる.原行列R(n*m)=M(n*k)xN(k*m)とする.非負のマトリックスの応用は主に以下の通りである.
2.1テキストマイニング
テキストマトリクスがn*m,すなわちn記事,m単語であり,その要素が単語の出現回数であると仮定する.マトリクスを分解した後、kは特徴の個数または主題の個数である.Mでは、各文章の最も重要ないくつかのテーマを簡単に得ることができます.Nの中で私たちは各テーマの最も重要な単語を簡単に得ます.
# -*- 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 = 2000):
    """
           ,   
    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("
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 if __name__ == "__main__": # 1. data = [[0, 0, 0, 0, 2, 4, 0, 0, 3, 0, 5], [0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 3], [0, 0, 0, 0, 4, 0, 0, 1, 0, 4, 0], [3, 3, 4, 0, 0, 0, 0, 2, 2, 0, 0], [5, 4, 5, 0, 0, 0, 0, 5, 5, 0, 0], [0, 0, 0, 0, 5, 0, 1, 0, 0, 5, 0], [4, 3, 4, 0, 0, 0, 0, 5, 5, 0, 1], [0, 0, 0, 4, 0, 4, 0, 0, 0, 0, 4], [0, 0, 0, 2, 0, 2, 5, 0, 0, 1, 2]] weight, feature = factorize(data, 3) recover = np.mat(weight) * np.mat(feature) """ 0 : 0 7 ( ) weight[0,:] = [0.009, 2.817, 0.589, 0, 0, 0, 0] feature , 。 0 2 , 3 : 2.817: [ 10 , 5 , 8 ] 0.589: [ 4 , 9 , 5 ] , 2.817 ( ) """ # 2. data = [[5, 5, 3, 0, 5, 5, 4, 3, 2, 1, 4, 1, 3, 4, 5], [5, 0, 4, 0, 4, 4, 3, 2, 1, 2, 4, 4, 3, 4, 0], [0, 3, 0, 5, 4, 5, 0, 4, 4, 5, 3, 0, 0, 0, 0], [5, 4, 3, 3, 5, 5, 0, 1, 1, 3, 4, 5, 0, 2, 4], [5, 4, 3, 3, 5, 5, 3, 3, 3, 4, 5, 0, 5, 2, 4], [5, 4, 2, 2, 0, 5, 3, 3, 3, 4, 4, 4, 5, 2, 5], [5, 4, 3, 3, 2, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0], [5, 4, 3, 3, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1], [5, 4, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2], [5, 4, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1]] # 2.1 sklearn from sklearn.decomposition import NMF Model = NMF(n_components=2) W = Model.fit_transform(data) """ NMF weight , NMF , ; """ # 3. # , ,

3.注意
明らかにKが大きいほど、P、Q行列はより複雑で、元の行列をよりよくフィッティングすることができるが、過フィッティングを招きやすい.Kが小さいほど,P,Qはより簡単で,モデルはより簡素である.
同時に,非負のマトリクス分解では,kの大きさはすべての文章がどれだけのテーマを生成できるかを決定し,一般に経験に基づいて決定したり,kの大きさを調節したりすることを試みる.
参考文献
http://m.blog.csdn.net/winone361/article/details/50705739
https://wenku.baidu.com/view/7bbaf0739b6648d7c1c74687#28
http://blog.csdn.net/google19890102/article/details/51124556