分布式算法设计

1).MapReduce




python 稀疏矩阵乘稀疏矩阵 稀疏矩阵相乘python_相似度


python 稀疏矩阵乘稀疏矩阵 稀疏矩阵相乘python_相似度_02


MapReduce两个基本算子抽象下,所谓Hadoop和Spark分布式计算框架并没有本质上的区别,仅仅是实现上的差异。阅读了不少分布式算法的实现(仅仅是实现,不涉及原理推导),大部分思路比较直观,大不了几个阶段的MapReduce就可以实现。这里主要介绍一个曾经困扰我好久且终于柳暗花明的问题,即“大规模稀疏矩阵乘法”。


python 稀疏矩阵乘稀疏矩阵 稀疏矩阵相乘python_相似度_03


上图单元格中的数字为归一化处理后的每个用户对每个商品的行为分值,是一个高维的稀疏矩阵(比如有1亿商品,5000万的用户),假设矩阵为


;

任意两个商品相似度计算,只需将相应的两个商品行向量计算内积即可。假设

为矩阵


的转置矩阵,共有M个用户,N个商品,则所有商品的相似度可以看成N*N的矩阵S,满足:


python 稀疏矩阵乘稀疏矩阵 稀疏矩阵相乘python_分块_04


在传统的推荐召回策略(Item-based、User-based等)中,核心就是计算实体对(<商品,商品><用户,用户>)间的相似度。目前大多数介绍"Item-based"或"User-based"的博文中,多是统计曾共同出现在同一session内的实体对的相似度共现频次。这里所谓的session是指用户在一次购物过程共同点击过的商品共同加入购物车的商品共同下单的商品。下面举一个简单的例子。

假设,我们已经有用户历史下单数据,在此基础上研发一个简单基于Item-based的推荐系统。

首先,由用户session(用户已购买商品)构建<商品i,商品j>共现矩阵(Co-occurrence Matrix)。


python 稀疏矩阵乘稀疏矩阵 稀疏矩阵相乘python_相似度_05


其次,归一化共现矩阵。


python 稀疏矩阵乘稀疏矩阵 稀疏矩阵相乘python_相似度_06


最后,根据每个用户的历史行为对未购买的商品做出预测打分,并做出推荐。


python 稀疏矩阵乘稀疏矩阵 稀疏矩阵相乘python_sed_07


上述方法在实际生产环境中得到了广泛应用,但也有其局限性。

优点:

1).计算复杂度低

2).实现简单适于业务早期快速上线

缺点:

1). 数据稀疏问题加剧。仅仅统计session共现,不能覆盖所有的Pair。

2).表达力有限。常见Pair相似度计算方法有余弦相似度欧式距离相似度等,显然上述方法不太容易替换相似度计算方法。

上文参考自:

https://www.jianshu.com/p/318bfacb4b5ewww.jianshu.com


所以更通用的策略是计算”全域商品“两两之间的相似度,即前文提到的


,同时保留与

某一商品最相关的N(超参数)的商品。完整的系统流程可能如下:

python 稀疏矩阵乘稀疏矩阵 稀疏矩阵相乘python_python 稀疏矩阵乘稀疏矩阵_08



要怎么算呢? 乍一看这个问题挺简单的,不就是矩阵相乘吗? 但如果考虑下

矩阵维度再估算下时空复杂度,就不是那么回事了。 首先,单台服务器是否可以装进整个矩阵? 其次,亿* 亿 级别的计算量要计算多久? 既然单机不行就分布式呗。问题的核心是怎么分呢?

python 稀疏矩阵乘稀疏矩阵 稀疏矩阵相乘python_相似度_09


这里简单介绍一种在生产环境中已经验证过的方法。如上图,为了实现分布式,先将A矩阵分成K个行分块


分为

k个列分块,将 对应行列分块分发到同一台机器。先计算 分块内的所有商品的相似度(余弦相似度、欧几里得相似度等),再 汇总计算商品在所有分块中的所有商品的相似度。

暂时先介绍下思路。更详细请期待<<策略算法工程师之路>>,届时会有更完整的流程及代码,在工程实现上还是有很多的trick的。


python 稀疏矩阵乘稀疏矩阵 稀疏矩阵相乘python_python 稀疏矩阵乘稀疏矩阵_10