• 推荐系统:协同过滤基础


    实现协同过滤推荐有以下几个步骤:

    一、找出最相似的人或物品:TOP-N相似的人或物品 通过计算两两的相似度来进行排序,即可找出TOP-N相似的人或物品

    二、根据相似的人或物品产生推荐结果 利用TOP-N结果生成初始推荐结果,然后过滤掉用户已经有过记录的物品或明确表示不感兴趣的物品

    常用相似度指标

    释义:杰卡德相似度&余弦相似度&皮尔逊相关系数

    1、余弦相似度:用夹角的余弦值来度量相似的情况, 两个向量只要方向一致,无论程度强弱, 都可以视为’相似’;

    2、皮尔逊相关系数Pearson:实际上也是一种余弦相似度, 不过先对向量做了中心化,是两个变量的变化趋势是否一致, 不适合计算布尔值向量之间的相关度

    3、杰卡德相似度 Jaccard:两个集合的交集元素个数在并集中所占的比例, 非常适用于布尔向量表示

    总结:余弦相似度适合用户评分数据(实数值), 杰卡德相似度适用于隐式反馈数据(0,1布尔值)(是否收藏,是否点击,是否加购物车)

    users = ["User1", "User2", "User3", "User4", "User5"]
    items = ["Item A", "Item B", "Item C", "Item D", "Item E"]
    # 用户购买记录数据集
    datasets = [
        [1,0,1,1,0],
        [1,0,0,1,1],
        [1,0,1,0,0],
        [0,1,0,1,1],
        [1,1,1,0,1],
    ]
    import pandas as pd
    
    df = pd.DataFrame(datasets,
                      columns=items,
                      index=users)
    print(df)
    
           Item A  Item B  Item C  Item D  Item E
    User1       1       0       1       1       0
    User2       1       0       0       1       1
    User3       1       0       1       0       0
    User4       0       1       0       1       1
    User5       1       1       1       0       1
    

     

    # 直接计算某两项的杰卡德相似系数
    from sklearn.metrics import jaccard_score
    # 计算Item A 和Item B的相似度
    print(jaccard_score(df["Item A"], df["Item B"]))
    
    # 计算所有的数据两两的杰卡德相似系数
    from sklearn.metrics.pairwise import pairwise_distances
    # 计算用户间相似度
    user_similar = 1 - pairwise_distances(df.values, metric="jaccard")
    user_similar = pd.DataFrame(user_similar, columns=users, index=users)
    print("用户之间的两两相似度:")
    print(user_similar)
    
    # 计算物品间相似度
    item_similar = 1 - pairwise_distances(df.T.values, metric="jaccard")
    item_similar = pd.DataFrame(item_similar, columns=items, index=items)
    print("物品之间的两两相似度:")
    print(item_similar)
    
    
    0.2
    用户之间的两两相似度:
              User1  User2     User3  User4  User5
    User1  1.000000   0.50  0.666667    0.2    0.4
    User2  0.500000   1.00  0.250000    0.5    0.4
    User3  0.666667   0.25  1.000000    0.0    0.5
    User4  0.200000   0.50  0.000000    1.0    0.4
    User5  0.400000   0.40  0.500000    0.4    1.0
    物品之间的两两相似度:
            Item A    Item B  Item C  Item D    Item E
    Item A    1.00  0.200000    0.75    0.40  0.400000
    Item B    0.20  1.000000    0.25    0.25  0.666667
    Item C    0.75  0.250000    1.00    0.20  0.200000
    Item D    0.40  0.250000    0.20    1.00  0.500000
    Item E    0.40  0.666667    0.20    0.50  1.000000

    有了两两的相似度,接下来筛选TOP-N相似结果,并进行推荐

    User-Based CF

    import pandas as pd
    import numpy as np
    
    users = ["User1", "User2", "User3", "User4", "User5"]
    items = ["Item A", "Item B", "Item C", "Item D", "Item E"]
    # 用户购买记录数据集
    datasets = [
        [1,0,1,1,0],
        [1,0,0,1,1],
        [1,0,1,0,0],
        [0,1,0,1,1],
        [1,1,1,0,1],
    ]
    
    df = pd.DataFrame(datasets,
                      columns=items,
                      index=users)
    
    # 计算所有的数据两两的杰卡德相似系数
    from sklearn.metrics.pairwise import pairwise_distances
    # 计算用户间相似度
    user_similar = 1 - pairwise_distances(df.values, metric="jaccard")
    user_similar = pd.DataFrame(user_similar, columns=users, index=users)
    print("用户之间的两两相似度:")
    print(user_similar)

    用户之间的两两相似度:
              User1  User2     User3  User4  User5
    User1  1.000000   0.50  0.666667    0.2    0.4
    User2  0.500000   1.00  0.250000    0.5    0.4
    User3  0.666667   0.25  1.000000    0.0    0.5
    User4  0.200000   0.50  0.000000    1.0    0.4
    User5  0.400000   0.40  0.500000    0.4    1.0
    topN_users = {}
    # 遍历每一行数据
    for i in user_similar.index:
        # 取出每一列数据,并删除自身,然后排序数据
        _df = user_similar.loc[i].drop([i])
        _df_sorted = _df.sort_values(ascending=False)
    
        top2 = list(_df_sorted.index[:2])
        topN_users[i] = top2
    
    print("Top2相似用户:")
    print(topN_users)
    rs_results = {}
    # 构建推荐结果
    for user, sim_users in topN_users.items():
        rs_result = set()    # 存储推荐结果
        for sim_user in sim_users:
            # 构建初始的推荐结果
            rs_result = rs_result.union(set(df.loc[sim_user].replace(0,np.nan).dropna().index))
        # 过滤掉已经购买过的物品
        rs_result -= set(df.loc[user].replace(0,np.nan).dropna().index)
        rs_results[user] = rs_result
    print("最终推荐结果:")
    print(rs_results)

    Top2相似用户:
    {'User1': ['User3', 'User2'], 'User2': ['User1', 'User4'], 'User3': ['User1', 'User5'], 'User4': ['User2', 'User5'], 'User5': ['User3', 'User1']}
    最终推荐结果:
    {'User1': {'Item E'}, 'User2': {'Item B', 'Item C'}, 'User3': {'Item D', 'Item B', 'Item E'}, 'User4': {'Item A', 'Item C'}, 'User5': {'Item D'}}

    Item-Based CF

    import pandas as pd
    import numpy as np
    
    users = ["User1", "User2", "User3", "User4", "User5"]
    items = ["Item A", "Item B", "Item C", "Item D", "Item E"]
    # 用户购买记录数据集
    datasets = [
        [1,0,1,1,0],
        [1,0,0,1,1],
        [1,0,1,0,0],
        [0,1,0,1,1],
        [1,1,1,0,1],
    ]
    
    df = pd.DataFrame(datasets,
                      columns=items,
                      index=users)
    
    # 计算所有的数据两两的杰卡德相似系数
    from sklearn.metrics.pairwise import pairwise_distances
    # 计算物品间相似度
    item_similar = 1 - pairwise_distances(df.T.values, metric="jaccard")
    item_similar = pd.DataFrame(item_similar, columns=items, index=items)
    print("物品之间的两两相似度:")
    print(item_similar)
    
    topN_items = {}
    # 遍历每一行数据
    for i in item_similar.index:
        # 取出每一列数据,并删除自身,然后排序数据
        _df = item_similar.loc[i].drop([i])
        _df_sorted = _df.sort_values(ascending=False)
    
        top2 = list(_df_sorted.index[:2])
        topN_items[i] = top2
    
    print("Top2相似物品:")
    print(topN_items)
    
    rs_results = {}
    # 构建推荐结果
    for user in df.index:    # 遍历所有用户
        rs_result = set()
        for item in df.loc[user].replace(0,np.nan).dropna().index:   # 取出每个用户当前已购物品列表
            # 根据每个物品找出最相似的TOP-N物品,构建初始推荐结果
            rs_result = rs_result.union(topN_items[item])
        # 过滤掉用户已购的物品
        rs_result -= set(df.loc[user].replace(0,np.nan).dropna().index)
        # 添加到结果中
        rs_results[user] = rs_result
    
    print("最终推荐结果:")
    print(rs_results)

    物品之间的两两相似度:
            Item A    Item B  Item C  Item D    Item E
    Item A    1.00  0.200000    0.75    0.40  0.400000
    Item B    0.20  1.000000    0.25    0.25  0.666667
    Item C    0.75  0.250000    1.00    0.20  0.200000
    Item D    0.40  0.250000    0.20    1.00  0.500000
    Item E    0.40  0.666667    0.20    0.50  1.000000
    Top2相似物品:
    {'Item A': ['Item C', 'Item D'],
     'Item B': ['Item E', 'Item C'],
     'Item C': ['Item A', 'Item B'],
     'Item D': ['Item E', 'Item A'],
     'Item E': ['Item B', 'Item D']}
    最终推荐结果:
    {'User1': {'Item B', 'Item E'},
     'User2': {'Item B', 'Item C'},
     'User3': {'Item D', 'Item B'},
     'User4': {'Item C', 'Item A'},
     'User5': {'Item D'}}

     ALS协同过滤

    PySpark推荐模型之基于隐式反馈的矩阵分解ALS

  • 相关阅读:
    Eclipse下安装Pydev以及Helloworld实例 分类: Python 2015-07-23 23:30 29人阅读 评论(0) 收藏
    Eclipse下安装Pydev以及Helloworld实例
    Selenium学习笔记之013:控制滚动条到底部
    iOS开发Embedded dylibs/frameworks are only supported on iOS 8.0 and later for architecture armv7的解决方法
    UIView 和 CALayer 的区别和联系。
    iOS 防止数组越界的解决方法
    iOS中集成ijkplayer视频直播框架
    解析数据时,快速查看当前需要创建的数据模型的所有属性,不用每个都写,直接打印粘贴
    iOS开发中,能够方便使用的Xcode插件
    UIButton图片拉伸方法(很多需要按钮的地方我们只需要一张小图来进行缩放)
  • 原文地址:https://www.cnblogs.com/Christbao/p/15894782.html
Copyright © 2020-2023  润新知