在我目前正在工作的一个项目中,大约有 200,000 个用户。对于这些用户中的每一个,我们定义了与其他用户的相似性度量。这会产生一个 200000x200000 的相似度矩阵。有点大。计算每个条目的简单方法(在 Ruby 中)需要几天时间。
我可以采用哪些策略来使计算矩阵字段变得可行?我应该把这个野兽放在什么数据存储中?
在我目前正在工作的一个项目中,大约有 200,000 个用户。对于这些用户中的每一个,我们定义了与其他用户的相似性度量。这会产生一个 200000x200000 的相似度矩阵。有点大。计算每个条目的简单方法(在 Ruby 中)需要几天时间。
我可以采用哪些策略来使计算矩阵字段变得可行?我应该把这个野兽放在什么数据存储中?
这里有一些零碎的答案,您告诉我们的内容仍然存在太多空白,无法提供一个好的答案,但是您可以自己填写。从您告诉我们的所有内容来看,我认为您的任务的主要部分不是有效地计算大型相似度矩阵,我认为主要部分是有效地从这样的矩阵中检索值并有效地更新矩阵。
正如我们已经确定的矩阵是稀疏和对称的;知道稀疏程度会很有用。这大大减少了存储需求,但我们不知道减少了多少。
您已经告诉我们一些关于用户资料更新的信息,但是您的相似度矩阵是否必须经常更新?我的期望(另一个假设)是,当用户修改他/她的个人资料时,相似性度量不会快速或急剧变化。据此,我假设使用过时几分钟(甚至几个小时)的相似性度量不会造成任何严重伤害。
我认为所有这些都将我们带入了数据库领域,它应该支持快速访问您指定的卷的存储相似性度量。我希望以适合您的需求和计算机能力可用性的时间间隔对这些措施进行批量更新,并且只对配置文件已更改的用户的措施进行更新。
至于第一个版本的相似度矩阵的初始创建,那么如果在后台需要一周的时间,你只需要做一次。
该度量可能是对称的,因此您只需将一半的矩阵存储在数据库中。但这并没有多大帮助。如果你有很多对,你也可以避免存储所有测量为零的对。
仅存储将实际显示的数据,例如每个用户的前 10 个最接近的用户。
并即时计算所有其他用户对的相似性度量。
仍然听起来像是保持最新状态的噩梦,甚至可能不存储任何东西。
存储矩阵,尤其是基于它计算任何东西是一场噩梦。很可能,您的相似性度量使用浮点数(4 字节)。这意味着未压缩的存储大小为 200000**2 * 4 字节= 160 GB。
这个问题有四个概念性的解决方案。
数据压缩:
数据缩减:您可以对用户进行聚类,然后为聚类构建相似度矩阵。如果您的集群每个大小为 200,那么您将只有一个 1000x1000 矩阵,因此只需要 4MB 来存储它。可能还有其他好处,例如速度和鲁棒性。
水平缩放:使用大机器。亚马逊有一个 2TB 内存,只要 3970 美元 ;-)
垂直缩放:构建块矩阵,这些块矩阵是可以处理的大矩阵块。