Python 实现矩阵分解

详细的理论解释和Java实现参考: 附上详细的理论解释和Java实现LTA_ALBlack的博客

在多标签学习中,标签矩阵Y,存在标签缺失情况,利用Funk-SVD,将矩阵Y 分解为矩阵U 和V ,使得满足 Y = U * V,即可将确失标签补充。具体步骤如下:

1、随机初始化 U、V。

2、确定包含正则化的损失函数。

3、对损失函数求导,利用梯度下降法,更新U、V。

4、循环步骤3,直到损失函数小于某个值为止。

from math import *
import numpy as np
import matplotlib.pyplot as plt

def matrix_factorization(Y, rank, aplha, beta, steps):
    '''
    :param Y: label matrix m*n
    :param U: 对象向隐含标签的映射 m*k
    :param V: 标签向隐含标签的映射 m*k
    :param K: 隐向量的维度
    :param aplha: 学习率
    :param beta: 正则化参数
    :param steps:
    :return:
    '''
    print('开始分解原矩阵:\n')

    Y = np.array(Y)

    # Number of rows of label matrix Y
    rows_Y = len(Y)

    # Number of columns of label matrix Y
    columns_Y = len(Y[0])  # 原矩阵R的列数

    # Random initialization matrix. [0 1]
    U = np.random.rand(rows_Y, rank)
    V = np.random.rand(columns_Y, rank)
    # Transpose
    V = V . T

    result=[]

    # update parameters using gradient descent method
    print('开始训练: \n')
    for step in range(steps):
        for i in range(len(Y)):
            for j in range(len(Y[0])):
                eij=Y[i][j]-np.dot(U[i,:],V[:,j])
                for k in range(rank):
                    if Y[i][j]>0:
                        # update parameters
                        U[i][k]=U[i][k]+aplha*(2*eij*V[k][j]-beta*U[i][k])
                        V[k][j]=V[k][j]+aplha*(2*eij*U[i][k]-beta*V[k][j])

        # loss
        e=0
        for i in range(len(Y)):
            for j in range(len(Y[i])):
                if Y[i][j] > 0:
                    e = e + pow(Y[i][j] - np.dot(U[i, :], V[:, j]), 2)  # loss
                    for k in range(rank):
                        e = e + (beta / 2) * (pow(U[i][k], 2) + pow(V[k][j], 2))  # loss with regularization
        result.append(e)
        if e < 0.001:
            break
    print('training Finshed 。。。。')

    return U, V.T, result


if __name__ == '__main__':   #主函数
    Y=[                 #原始矩阵
        [5,3,0,1],
        [4,0,0,1],
        [1,1,0,5],
        [1,0,0,4],
        [0,1,5,4]
    ]
    Y=np.array(Y)

    U,V,result=matrix_factorization(Y, 3, aplha=0.0002,beta=0.02,steps=5000)

    # show the result
    print(result)
    print('原矩阵',Y)
    Y_MF=np.dot(U,V.T)
    print('计算出的矩阵',Y_MF)

    # display the results with a chart
    plt.plot(range(len(result)),result)
    plt.xlabel("time")
    plt.ylabel("loss")
    plt.show()







你可能感兴趣的:(用Python,实现多标签学习,矩阵,线性代数)