基于Java的向量空间模型的两人相似度评分算法

基于Java的向量空间模型的两人相似度评分算法,java,algorithm,vector,artificial-intelligence,text-mining,Java,Algorithm,Vector,Artificial Intelligence,Text Mining,我正试图用Java实现一个向量空间模型算法,根据它的关键字得到两个人之间的相似性分数。因此,我有以下课程: Person-有一个关键字列表 关键词- 字符串文本; 整数分 关键词得分是指该人对该关键词的提及次数 关于如何在Java中实现这一点,有什么建议吗 这很容易 首先,您应该创建向量表示,为每个表示其关键字的人创建示例地图。 其次,我建议您选择公制。 所以现在真正的代码: static double cosine_similarity(Map<String, Double>

我正试图用Java实现一个向量空间模型算法,根据它的关键字得到两个人之间的相似性分数。因此,我有以下课程:

Person-有一个关键字列表

关键词- 字符串文本; 整数分

关键词得分是指该人对该关键词的提及次数

关于如何在Java中实现这一点,有什么建议吗

这很容易

首先,您应该创建向量表示,为每个表示其关键字的人创建示例地图。 其次,我建议您选择公制。 所以现在真正的代码:

  static double cosine_similarity(Map<String, Double> v1, Map<String, Double> v2) {
            Set<String> both = Sets.newHashSet(v1.keySet());
            both.retainAll(v2.keySet());
            double sclar = 0, norm1 = 0, norm2 = 0;
            for (String k : both) sclar += v1.get(k) * v2.get(k);
            for (String k : v1.keySet()) norm1 += v1.get(k) * v1.get(k);
            for (String k : v2.keySet()) norm2 += v2.get(k) * v2.get(k);
            return sclar / Math.sqrt(norm1 * norm2);
    }
这很容易

首先,您应该创建向量表示,为每个表示其关键字的人创建示例地图。 其次,我建议您选择公制。 所以现在真正的代码:

  static double cosine_similarity(Map<String, Double> v1, Map<String, Double> v2) {
            Set<String> both = Sets.newHashSet(v1.keySet());
            both.retainAll(v2.keySet());
            double sclar = 0, norm1 = 0, norm2 = 0;
            for (String k : both) sclar += v1.get(k) * v2.get(k);
            for (String k : v1.keySet()) norm1 += v1.get(k) * v1.get(k);
            for (String k : v2.keySet()) norm2 += v2.get(k) * v2.get(k);
            return sclar / Math.sqrt(norm1 * norm2);
    }

我认为上面的示例代码中有一个bug。下面是更正后的代码

static double cosine_similarity(Map<String, Double> v1, Map<String, Double> v2) {
        Set<String> both = Sets.newHashSet(v1.keySet());
        both.removeAll(v2.keySet());

        double sclar = 0, norm1 = 0, norm2 = 0;

        /* We need to perform cosine similarity only on words that 
         * exist in both lists */
        for (String k : both)  {
           sclar += v1.get(k) * v2.get(k);
           norm1 += v1.get(k) * v1.get(k);
           norm2 += v2.get(k) * v2.get(k);
        }
        return sclar / Math.sqrt(norm1 * norm2);
}

我认为上面的示例代码中有一个bug。下面是更正后的代码

static double cosine_similarity(Map<String, Double> v1, Map<String, Double> v2) {
        Set<String> both = Sets.newHashSet(v1.keySet());
        both.removeAll(v2.keySet());

        double sclar = 0, norm1 = 0, norm2 = 0;

        /* We need to perform cosine similarity only on words that 
         * exist in both lists */
        for (String k : both)  {
           sclar += v1.get(k) * v2.get(k);
           norm1 += v1.get(k) * v1.get(k);
           norm2 += v2.get(k) * v2.get(k);
        }
        return sclar / Math.sqrt(norm1 * norm2);
}

有没有什么特别的原因需要您自己用Java实现VSM?就我个人而言,我会用WEKA来做类似的事情。重新发明轮子的理由比家庭作业多。我不认为这个问题是完全不合理的。在WEKA中,我在哪里可以得到能够为我做到这一点的类/方法?这里不需要机器学习,只想根据关键词比较两个人。提取关键字的模块已经使用了一些机器算法来改进其工作?只需计算两个特征向量之间的余弦相似性或其他度量。是否有任何特殊原因需要您自己在Java中实现VSM?就我个人而言,我会用WEKA来做类似的事情。重新发明轮子的理由比家庭作业多。我不认为这个问题是完全不合理的。在WEKA中,我在哪里可以得到能够为我做到这一点的类/方法?这里不需要机器学习,只想根据关键词比较两个人。提取关键字的模块已经使用了一些机器算法来改进其工作?只需计算两个特征向量之间的余弦相似性或其他度量。另外,'both.removeAll'应该是'both.retainal',因为我们想找到两个集合v1和v2的交集,所以,'both.removeAll'应该是'both.retainal',因为我们想找到两个集合v1和v2的交集,实际上yura是正确的。在计算norm1和norm2时,需要分别循环每个贴图。这样,我们可以考虑两个字符串之间的不匹配。否则,相似度将只计算在共享的单词上,sim分数将被虚假夸大。事实上,yura是正确的。在计算norm1和norm2时,需要分别循环每个贴图。这样,我们可以考虑两个字符串之间的不匹配。否则,相似度将只计算在共享单词上,sim分数将被错误夸大。