推荐系统(个人小结)

推荐系统

最近在看公司的旧的推荐系统的,可能没有spark的als过滤好,但是我觉得蛮有特点,这个用来记录一下的

从HDFS中获取数据源

APP的数据格式:

    df_log = df_log
                .filter(
                        df_log.col("page_id").isin(appPageId.toArray())
                )
                .filter(
                        df_log.col("context_id").isNotNull()
                );
        // 使用deviceID作为USER_ID。并构造ITEM_ID:CITY_CHANNEL_LISTID
        df_log = df_log.selectExpr("cast (device_id as string) as USER_ID",
                "concat(city,'_',context_id) as ITEM_ID");

        df_log = df_log.filter(df_log.col("USER_ID").isNotNull())
                .filter(df_log.col("ITEM_ID").isNotNull());
        df_log = df_log.dropDuplicates();
USER_IDITEM_ID
device_idcity_contextid

WEB的数据格式:

 df_log = df_log.filter(df_log.col("ga_channel").isin("newhouse", "villa"))
                .filter(df_log.col("ga_contextid").isNotNull());

        // 使用GUID作为USRE_ID。并构造ITEM_ID:CITYID_CHANNEL_LISTID
        df_log = df_log.selectExpr("cast (guid as string) as USER_ID",
                "concat(cityid,'_',ga_contextid) as ITEM_ID");

        df_log = df_log.filter(df_log.col("USER_ID").isNotNull())
                .filter(df_log.col("ITEM_ID").isNotNull());
        df_log = df_log.dropDuplicates();
USER_IDITEM_ID
guidcityid_ga_contextid

针对spark的datafram进行处理

从上面可以看出,这些数据时日志数据,并且数据是一一对应的,所以生产对应的JavaPairRDD<String, String> pairRDD

分别求出其中的userid和iemid,并且生产userid对应的行索引、itemid对应的列索引。

spark的广播,广播变量可以让程序高效地向所有工作节点发送一个较大的只读值,以供一个或多个Spark操作使用

从而生成两个广播参数

userIndexBiMapitemIndexBiMapuiRDD
(USER_Id,rowindex)(ITEM_Id,colindex)(rowindex,colindex)

后面会经常用到这三个参数,前两个值是没有重复的,后面的一个值是在日志里面的信息

svd相似性计算

svd是deep learning上面非常基础,也是非常重要的一个内容,我也花费了大量的时间学习和整理linear algebra.到现在还不是很清楚,后期我会整理一下的。

spark MLlib 核心基础:向量 and 矩阵
CoordinateMatrix 是通过RDD[MatrixEntry]实例创建,MatrixEnry是(long,long,Double)形式。坐标矩阵可以转化为IndexedRowMatrix

通过上面的uiRDD 生产评分矩阵,存在对应的关系的话,在矩阵中赋值1. 就形成了简单的一个矩阵中值只有1和0
的坐标矩阵。

rows indexed rows of this matrix param,nRows number of rows,A non-postive value means unknown, and then the number of rows will be determinded by the max row index plus one param.nClos number of columns. A non-postive value means unknown, and then the number of columns will be determined by the size of the first row

上面是indexedRowMatrix说明

compute the singular value decompostion of this indexedRowMatrix, Denote this matrix by A(m*n),this will compute matrices U S V such that A=U*S*V^T
the cost and implemenation of this method is identical to that in RowMatrix with the addition of indices
At most k largest non-zero singular values and associated vectors are returned, if there are k such values,then the dimensions of the return will be
Parameters: k- number of singular values to keep, we might return less than k if there are numerically zero singular values
Parameters computeU - whether to compute U
Parameters rCond - the reciprocal condition number. All singular values smaller than rCond*sigma(0)are threated as zero, where sigma(0) is the largest singular value
SingularValueDecomposition(U, s, V)

上面是spark的computeSVD

column-major dense matrix,the entry values are stored in a single array of doubles with columns listed in sequence.

上面是DenseMatrix,其实核心就是转置矩阵

从而得到UsV中的V的值,然后将矩阵V转置. 为后期的推荐提供转置后的矩阵V。

如果推荐的类型是猜你喜欢推荐,则将userRSIDIndexBiMap,itemRSIDIndexBiMap,computer,uiRDD直接保存在文件中。

构建过滤器

根据推荐的类型设置,过滤器,对结果进行筛选。猜你喜欢的有两个过滤条件:

  • 推荐的条数
  • 对自己的过滤,主要是看推荐的结果中是否有重复的item

构建jaccard推荐器

    public JaccardItemRecommender(
            JavaSparkContext sc,
            BiMap<String, Integer> userRSIDIndexBiMap,
            BiMap<String, Integer> itemRSIDIndexBiMap,
            SVDItemSimilarityComputer computer,
            CandidateFilter filter,
            JobConfiguration jobConf) {
        this.sc = sc;
        this.computer = computer;
        this.jobConf = jobConf;
        this.filter = filter;
        this.userRSIDIndexBiMap = userRSIDIndexBiMap;
        this.itemRSIDIndexBiMap = itemRSIDIndexBiMap;
    }

最核心的推荐算法recommend

  • 构建constructItemBiMap,通过查询数据提取房源对应的数据,sql如下:select WP.PRJ_ID as prjId, CI.CITY_ID_WEB_IP as cityId,CI.CITY_NAME as cityName, CI.CITY_KEY as cityKey, WC.ITEMNAME as name, WP.PRJ_LISTID as listId,WC.CHANNEL as channel, WP.PRJ_DIST as dist,WP.PRJ_BLOCK as block,WP.MAP_X as mapx, WP.MAP_Y as mapy,WC.PRICE as price,WC.PRICE_MORE as priceMore, WC.SALESTAT as salestats from dwb_web_w_channel WC inner join dwb_web_project WP on WC.PRJ_ID = WP.PRJ_ID inner join dwd_city_info CI on WP.PRJ_CITY = CI.CITY_ID where WP.prj_disp = 1 and salestat=3
变量名indexItemBiMap
参数(cols,Item)
Item的实体类
private int prjId;
private int cityId;
private String cityName;
private String cityKey;
private int listId;
private String name;
private int channel;
private int dist;
private int block;
private String mapx;
private String mapy;
private int price;
private String priceMore;
变量名indexItemBiMap
参数(colsindex, Item)

- ratings.groupBy(new Functors.GroupByItem())
通过spark的groupBy 将itemid的colsindex提炼出来,
参数样式:colsindex:(rowsindex,colsindex),(rowsindex,colsindex) 相同的colsindex

变量名ratingsGroupByItem
参数(colsindex,[(rowsindex,colsindex),(rowsindex,colsindex)…])

- numVisiterPerItem 就是后面的list计数colsindex:the number of colsindex

变量名numVisiterPerItem
参数(colsindex,the number of colsindex)

- ratingsWithNumVisiter 参数的格式为rowsindex,colsindex,the number of colsindex

变量名ratingsWithNumVisiter
参数(rowsindex,colsindex,the number of colsindex)

- ratingsWithNumVisiterKeyByUser 参数的格式为rowsindex:(rowsindex,colsindex,the number of colsindex)

变量名ratingsWithNumVisiterKeyByUser
参数rowsindex:(rowsindex,colsindex,the number of colsindex)

- ratingsWithNumVisiterKeyByUser 参数的格式为
<ITEM_A,ITEM_B> -> <ITEM_A_COUNT, ITEM_B_COUNT,COMMON_COUNT>

变量名ratingsWithNumVisiterKeyByUser
参数(itema_colsindex),(itemb_colsindex)->(itema_colsindex_count),(itemb_colsindex_count),(common_count)

狭义jaccar相似度,计算两个集合之间的相似程度,元素的取值为0或1。

对于集合A和B,Jaccard相似度计算如下:Jaccard(A,B)=|A intersect B|/|A union B| 相似度数值在[0,1]之间

  • jaccardSimilarityEntries先求出没有关联的数据,userid,针对没有关联出来的数据,赋值,数据格式为(rowsindex,0,0). 这样的话,我们就得到一个矩阵,矩阵的左边都是房源,房源值是他们之间的相似度。
  • Functors.recommend 是在spark中的推荐核心算法
变量名rowMatrixindexItemBiMapBroadcastfiltersvdComputerrecommendNum
参数(itemA,itemB,score)Integer, Item过滤器svd的算法推荐的条数

算法的原理是:

  • 先将userid和city_ga_context从行为记录中提炼出来的,是一对一对的。
  • 给userid和city_ga_context去重,并赋予行索引和列索引
  • 这个是为了计算svd(这儿还不是很清楚)[为后面服务的]
  • 后面用rowsindex表示userid,colsindex表示itemid。
    这儿我们就得到一张表
xxxitemAitemBitemC
userA
userB
userC

- 在行为记录中,我们以item为维度,groupby。这样我们就得到了item有多少次的访问记录

useritemthe number of viewing
userAitemAnumber
userBitemBnumber
userCitemCnumber

- 通过user,自己关联,将同一个用户浏览过的item通过userid关联在一起形成了

变量名样式
参数(itema_colsindex),(itemb_colsindex)->(itema_colsindex_count),(itemb_colsindex_count)

- 然后对于这个itemA 和itemB的key值 进行累加得到一个common_count,记录下来

变量名样式
参数(itema_colsindex),(itemb_colsindex)->(itema_colsindex_count),(itemb_colsindex_count),(common_count)

我们由上面的数据,绘制出一个表数据:

xxxitemaitemb
….
itemajaccard_score
….
itembjaccard_score
….

以上的数据,我们已经将userid去掉了,然后我们表数据一行中的每一列的数据进行计算,如果存在jaccard_score,则直接使用jaccard_score.如果没有的话,我们会使用svd的来计算这个值。

  • 这样我们就计算出,每个item的相关性最高的几个item。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值