Sql 如何找到使用其兴趣的相似用户

Sql 如何找到使用其兴趣的相似用户,sql,algorithm,similarity,nearest-neighbor,Sql,Algorithm,Similarity,Nearest Neighbor,我正在尝试创建一个系统,该系统能够找到与last.fm上的邻居有着相似喜爱的电影/书籍/兴趣等的用户。共享最多共同兴趣的用户将具有最高匹配,并将显示在用户配置文件中(5个最佳匹配左右) 有没有合理快速的方法来做到这一点?显而易见的解决方案是创建一个包含用户ID和兴趣ID的表,并将一个用户与所有其他用户进行比较,但这将在包含。。。比如说,百万用户每人有20个兴趣爱好 我假设存在一些有效的解决方案,因为last.fm工作得很好。我更喜欢使用一些常见的SQL数据库,比如mySQL或pgSQL,但任何东

我正在尝试创建一个系统,该系统能够找到与last.fm上的邻居有着相似喜爱的电影/书籍/兴趣等的用户。共享最多共同兴趣的用户将具有最高匹配,并将显示在用户配置文件中(5个最佳匹配左右)

有没有合理快速的方法来做到这一点?显而易见的解决方案是创建一个包含用户ID和兴趣ID的表,并将一个用户与所有其他用户进行比较,但这将在包含。。。比如说,百万用户每人有20个兴趣爱好

我假设存在一些有效的解决方案,因为last.fm工作得很好。我更喜欢使用一些常见的SQL数据库,比如mySQL或pgSQL,但任何东西都可以

谢谢你的建议


更新:
事实证明,最大的问题是在SQL数据库中查找最近的邻居,因为没有一个开源数据库支持这种搜索。
因此,我的解决方案是修改ANN,使其作为服务运行,并从PHP(例如使用sockets)查询它——即使在内存中有数以百万计的用户,比如说7维,也没什么大不了的,而且运行速度快得令人难以置信

针对较小数据集的另一个解决方案是以下简单查询:

SELECT b.user_id, COUNT(1) AS mutual_interests
FROM `users_interests` a JOIN `users_interests` b ON (a.interest_id = b.interest_id)
WHERE a.user_id = 5 AND b.user_id != 5
GROUP BY b.user_id ORDER BY mutual_interests DESC, b.user_id ASC

20-50ms,每100K用户平均有20个兴趣(10000个可能兴趣)

您想要解决近似最近邻问题。将用户特征编码为某个空间中的向量,然后在该空间中找到最接近的其他用户

确切地说,你想要使用什么样的空间,什么样的距离度量,这些都可能是根据你的数据进行实验评估的结果。幸运的是,有一个C++包可以用来解决各种问题和各种度量和算法以满足您的需求:


编辑:这里的运行时间确实取决于功能的数量。但在高维几何中有一个方便的定理,即如果在任意高维中有n个点,并且只关心近似距离,则可以将它们向下投影到O(logn)维而不会丢失。请参见此处()。(通过将点乘以随机+1/-1值矩阵来执行随机投影)。例如,请注意log(1000000)=6

这是一个很难解决的问题,它随着您的用例发生了很大的变化。解决此问题的最佳方法是通过聚集兴趣来减少问题集。谢谢,将特征编码为特殊向量似乎是个好主意。然而,这个ANN库(可能是任何C++方法)都需要将整个用户/利益表保存在内存中,这将有点太贵,加上作者声称它只执行“数千到几十万,高达20的尺寸”,但是可能会有成千上万的维度(想象一下有多少电影)。实际上,你可以投射到更小的维度来解决这个问题。让我更新我的答案,让你看看相关的定理。啊,这就解释了这个谜团:)还有一个问题——添加新的兴趣/维度也需要重建简化的维度,对吗?(至少不时)是的,您必须更新投影,并在添加特征时缓慢增加维度。