Arrays 查找两个多维数组之间的相似性(作为JSON文档)

Arrays 查找两个多维数组之间的相似性(作为JSON文档),arrays,algorithm,data-mining,similarity,recommendation-engine,Arrays,Algorithm,Data Mining,Similarity,Recommendation Engine,基本上,我有一个文件系统,其中包含如下文件: {"excellent":[1,2],"good":[1,2,3,4,5],"okay":[6],"bad":[7,8,9],"horrible":[9]} {"similar":[[1,0.987],[2,0.876],[3,0.765]...],"differs":[[4,0.012],[5,0.123],[6,0.234]...],"totalSimilarity":0.456} “优秀”永远是“好”的子集,“糟糕”永远是“坏”的子集,好、

基本上,我有一个文件系统,其中包含如下文件:

{"excellent":[1,2],"good":[1,2,3,4,5],"okay":[6],"bad":[7,8,9],"horrible":[9]}
{"similar":[[1,0.987],[2,0.876],[3,0.765]...],"differs":[[4,0.012],[5,0.123],[6,0.234]...],"totalSimilarity":0.456}
“优秀”永远是“好”的子集,“糟糕”永远是“坏”的子集,好、坏、好永远是独一无二的。但是,每个集合可以任意长,从0个元素到。。。武断的。我不能假设两个集合的长度相等,因此为什么Jaccard似乎适用于单个集合

我需要做的是计算:

  • 与此最相似的前25个文档
  • 最不相似的10个文档
  • 此文档与集合中所有其他文档之间的值介于0-1之间
  • 基本上,输出应该是另一个json文档,如下所示:

    {"excellent":[1,2],"good":[1,2,3,4,5],"okay":[6],"bad":[7,8,9],"horrible":[9]}
    
    {"similar":[[1,0.987],[2,0.876],[3,0.765]...],"differs":[[4,0.012],[5,0.123],[6,0.234]...],"totalSimilarity":0.456}
    
    我已经研究了Jaccard索引,对于一个简单的数组来说,这看起来很好。这是一个由五个数组组成的集合,例如,如果两个文档的良好集合和优秀集合之间都有相似性,这一点非常重要

    我能把五个Jaccard标记“平均”成一个主索引号吗?还是说信息太多了

    我是不是太努力了?类似于json字符串的Minhash的东西可以工作吗?我的第一个想法是它可能,但我担心的是,基于字符串散列的一些东西会认为“5”在“可怕”中与“5”处于“好”,这完全是向后的。此外,我担心这会受到以下事实的影响:一些用户在“good”下可能有100个条目,而其他用户只有5个条目,基于字符串的计算可能会因此而受阻

    老实说,虽然我想要上面#3的值,但我真的不知道如何计算它。我想知道文档与整个语料库有多相似

    是的,这是一个类似于推荐系统的算法。我已经从EasyRec到Mahout阅读了文档,要么他们似乎没有完全满足我的需要,要么数学开始超出我的头脑。我是PHP开发人员,不是理论物理学家。默认情况下,像EasyRec和Mahout这样的系统似乎不“理解”这样的事实,即这是五个独立的集合,它们都需要对齐才能被视为“相似…”,或者它们需要在其框架中进行一些严肃的编程工作,这让我有点头晕

    然而,有趣的是(至少对我来说),大多数推荐系统都在整个数据集上工作;我特别感兴趣的是根据用户的偏好对其进行聚类,并根据非常小的集合提出建议。老实说,我不太担心说“不知道,巴克!你太独特了”,所以我也不太担心冷启动之类的事情

    所以我在寻找建议,或者是一个算法,或者是一个对Jaccard平均值有效的支持,或者至少是一些可以阅读的文档,以便更好地理解这一切。我认识到推荐系统是一门严肃的计算机科学,有一些可靠的系统已经做到了这一点。我的问题是,他们中的许多人似乎对这个问题想得太多了,或者要求某人拥有统计学学士学位,以便能够将其输出到正常的输出。(这有点不公平……问题难不是宇宙的错。)

    最后,我更感兴趣的是找到一个算法来使用,而不是一个库或服务器来做(除非真的有一个简单的下降,我只是不理解),因为我想看看各种编程语言将如何处理算法在一点枪战

    我发现大多数推荐引擎/评级系统失败是因为它们的数据集太广。试图在整个宇宙中平均分数会造成平庸(见:元批评,烂番茄)。基本上,我希望能够对特定用户透明地说:

    与你最相似的用户(link,link,link)非常喜欢这个,而与你最相似的用户(link,link,link)非常讨厌这个,所以你可能会感兴趣

    与您最相似的用户(link,link,link)都认为这很好,所以您可能会感兴趣

    和你最不相似的用户(link,link,link)都认为这很可怕,所以你可能会感兴趣

    与你最不相似的用户(link,link,link)都认为这是好的,所以要么你讨厌它,要么我们不得不重新开始

    我想向用户解释一下,我认为他们是如何喜欢X的,因为网站上的许多推荐都是黑匣子,我发现如果没有任何解释,情况可能会非常糟糕。(啤酒网站推荐三种IPA,我对每一种IPA的评价都是“1”,原因很简单,因为有很多IPA,全世界似乎都喜欢IPA。)


    这也是我想要“完全相似性”的原因。如果你的“总体相似性”很低,那么推荐人就会四处游荡,我想以此作为借口。“你很独特,所以这些都是胡乱猜测。”“你不是很不爽,这其实很好,因为我很确定这些数据对你个人很有用。”

    这里是解决方案的第一个草图:

    1) 从数据中删除冗余:

    • 你说“优秀”永远是“好”的子集,“糟糕”永远是“坏”的子集。那么你的数据是多余的。从好条目中删除优秀条目,从坏条目中删除糟糕条目
    2) 使用数字权重而不是单词。您可能希望使用以下映射: 好->2,好->1,好->0,坏->-1,糟糕->-2

    • 这样,您将得到一个用户项目矩阵。每个用户一行,每个用户一列
      项目。数字条目表示用户对给定项目的首选项。这个 结果矩阵将是稀疏的和高维的。您需要申请 主成分分析或奇异值等降维机制 价值分解
    3) 一旦你缩小了尺寸