softwarerec/src/main/java/com/ow2/rec/util/SimilarityCounter.java

76 lines
1.9 KiB
Java
Raw Normal View History

//Copyright (c) 2016 Yarong Zeng, NUDT.
2016-09-02 09:32:44 +08:00
package com.ow2.rec.util;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
public class SimilarityCounter {
//两个文本结合 以及各自个各个分量的权重的倒数
public static float countSimilarity(List<String>prj,int[]prjWeight,List<String>tag,int[]tagWeight){
//如果没有共同的元素就直接返回0
List<String> prjTmp = new LinkedList<String>(prj);
prjTmp.retainAll(tag);
if(prjTmp.size() == 0){
return 0;
}
//如果完全匹配就直接返回1
if(prj.containsAll(tag) && tag.containsAll(prj))
return 1;
//如果项目名称为单个字母直接返回0
if(prj.size() == 1 && prj.get(0).length() == 1){
return 0;
}
Set<String> union= new HashSet<String>();//此集合用于存储项目和标签匹配时他们的原子性元素的并集
union.addAll(prj);
union.addAll(tag);
//生成两个向量
float prjVector[] = new float[union.size()];
float tagVector[] = new float[union.size()];
int i = 0;
for(String item : union){
if(prj.contains(item))
prjVector[i] = 1.0F / prjWeight[prj.indexOf(item)];
if(tag.contains(item))
tagVector[i] = 1.0F / tagWeight[tag.indexOf(item)];
i++;
}
//两个向量的点积
float dotMulti = 0,absPrjUnSqrt = 0, absTagUnSqrt =0;
for(i = 0; i< prjVector.length; i++){
dotMulti += prjVector[i] * tagVector[i];
absPrjUnSqrt += prjVector[i] * prjVector[i];
absTagUnSqrt += tagVector[i] * tagVector[i];
}
float absPrj = 0, absTag =0;
absPrj = (float) Math.sqrt(absPrjUnSqrt );
absTag = (float) Math.sqrt(absTagUnSqrt );
return formatFloat(dotMulti / ( absPrj * absTag),3);
}
private static float formatFloat(float f,int num){
int base = (int) Math.pow(10,num);
return (float) (Math.round(f * base))/base;
}
}