def personal_rank_matrix(graph, root, alpha, recom_num=10):
    """
    :param graph: user item graph
    :param root: the fix user to recom
    :param alpha: the prob to random walk
    :param recom_num: recom item num
    :return: a dict, key itemid, value pr score
    """
    m, vertex, address_dict = mat_util.graph_to_m(graph)
    if root not in address_dict:
        return {}
    score_dict = {}
    recom_dict = {}

    mat_all = mat_util.mat_all_point(m, vertex, alpha)
    index = address_dict[root]
    initial_list = [[0] for i in range(len(vertex))]
    initial_list[index] = [1]
    r_zero = np.array(initial_list)

    res = gmres(mat_all, r_zero, tol=1e-8)[0]

    for i in range(len(res)):
        point = vertex[i]
        if len(point.strip().split('_')) < 2:
            continue
        if point in graph[root]:
            continue
        score_dict[point] = round(res[i], 3)
    for co in sorted(score_dict.items(),
                     key=operator.itemgetter(1),
                     reverse=True)[:recom_num]:
        point, score = co[0], co[1]
        recom_dict[point] = score
    return recom_dict
Esempio n. 2
0
def personal_rank_mat(graph, root, alpha, recom_num=10):
    """
    Args:
        graph:user item graph
        root:the fix user to recom
        alpha:the prob to random walk
        recom_num:recom item num
    Return:
        a dict, key: itemid, value: pr score
    A*r = r0
    """
    m, vertex, address_dict = mat_util.graph_to_m(graph)
    vertex = np.array([v for v in vertex])
    if root not in address_dict:
        return {}
    score_dict = {}
    recom_dict = {}
    mat_all = mat_util.mat_all_point(m, vertex, alpha)
    index = address_dict[root]
    initial_list = [[0] for row in range(len(vertex))]
    initial_list[index] = [1]
    r_zero = np.array(initial_list)
    res = gmres(mat_all, r_zero, tol=1e-8)[0]
    for index in range(len(res)):
        point = vertex[index]
        if len(point.strip().split("_")) < 2:
            continue
        if point in graph[root]:
            continue
        score_dict[point] = round(res[index], 3)
    for zuhe in sorted(score_dict.items(), key=lambda v: v[1],
                       reverse=True)[:recom_num]:
        point, score = zuhe[0], zuhe[1]
        recom_dict[point] = score
    return recom_dict
def personal_rank_mat(graph, root, alpha, recom_num=10):
    """
    :param graph: user item graph 用户物品的二分图
    :param root:  the fix user to recom 固定用户推荐
    :param alpha: the prob to random walk 随机游走的概率
    :param recom_num: recom item num
    :return: a dict, key :itemid ,value:pr score

    线代相关知识:求矩阵的逆矩阵,即解线性方程 Ax = E (A*r = r0)
    """
    m, vertex, address_dict = mat_util.graph_to_m(graph)
    if root not in address_dict:
        return {}

    score_dict = {}
    recom_dict = {}

    # 求其逆,便可以得到推荐结果
    mat_all = mat_util.mat_all_point(m, vertex, alpha)

    # 首先得到root顶点的index,得到index的目的是为了获得r0矩阵
    index = address_dict[root]

    # 初始化r0矩阵
    initial_list = [[0] for row in range(len(vertex))]
    initial_list[index] = [1]
    r_zero = np.array(initial_list)
    # r_zero = np.concatenate(r_zero,axis=0)

    # 解线性方程,得到的是一个元组,其中tol指的是误差
    res = gmres(mat_all, r_zero, tol=1e-8)[0]

    for index in range(len(res)):
        # 首先判断该顶点是否是item顶点
        point = vertex[index]
        if len(point.strip().split("_")) < 2:
            continue
        # 若已经行为过,则也没有必要记录
        if point in graph[root]:
            continue

        score_dict[point] = round(res[index], 3)

    # 讲pr值排序,返回推荐结果
    for zuhe in sorted(score_dict.items(),
                       key=operator.itemgetter(1),
                       reverse=True)[:recom_num]:
        point, score = zuhe[0], zuhe[1]
        recom_dict[point] = score
    return recom_dict