package ruc.irm.similarity.word.hownet.sememe;
import java.io.IOException;
import ruc.irm.similarity.util.BlankUtils;
/**
* 义原相似度计算, 实现了SememeParser中定义的抽象方法
*
* @author <a href="mailto:iamxiatian@gmail.com">夏天</a>
* @organization 中国人民大学信息资源管理学院 知识工程实验室
* @deprecated
*/
public class MySememeParser extends SememeParser {
public MySememeParser() throws IOException{
super();
}
/**
* 计算两个义原的相似度
*/
@Override
public double getSimilarity(final Sememe sememe1, final Sememe sememe2) {
Sememe sem1 = sememe1;
Sememe sem2 = sememe2;
if (sememe1 == null || sememe2 == null){
return 0.0f;
}else if(sememe1.getId() == sememe2.getId()){
return 1.0f;
}
//变为深度相同,然后一次上找共同的父节点
int level = sememe1.getDepth() - sememe2.getDepth();
for (int i = 0; i < ((level < 0) ? level * -1 : level); i++) {
if (level > 0){
sem1 = SEMEMES[sem1.getParentId()];
}else{
sem2 = SEMEMES[sem2.getParentId()];
}
}
while(sem1.getId() != sem2.getId()){
// 如果有一个已经到达根节点,仍然不同,则返回0
if (sem1.getId() == sem1.getParentId()
|| sem2.getId() == sem2.getParentId()) {
return 0.0f;
}
sem1 = SEMEMES[sem1.getParentId()];
sem2 = SEMEMES[sem2.getParentId()];
}
return sem1.getDepth()*2.0f/(sememe1.getDepth() + sememe2.getDepth());
}
/**
* 计算两个义元之间的相似度,由于义元可能相同,计算结果为其中相似度最大者 similarity = alpha/(distance+alpha),
* 如果两个字符串相同或都为空,直接返回1.0
*
* @param key1 第一个义原字符串
* @param key2 第二个义原字符串
* @return
*/
@Override
public double getSimilarity(String item1, String item2) {
if(BlankUtils.isBlankAll(item2, item2)){
return 1.0;
} else if(BlankUtils.isBlankAtLeastOne(item1, item2)){
return 0.0;
} else if(item1.equals(item2)){
return 1.0;
}
String key1 = item1.trim();
String key2 = item2.trim();
// 去掉()符号
if ((key1.charAt(0) == '(') && (key1.charAt(key1.length() - 1) == ')')) {
if (key2.charAt(0) == '(' && key2.charAt(key2.length() - 1) == ')') {
key1 = key1.substring(1, key1.length() - 1);
key2 = key2.substring(1, key2.length() - 1);
} else {
return 0.0;
}
}
// 处理关系义元,即x=y的情况
int pos = key1.indexOf('=');
if (pos > 0) {
int pos2 = key2.indexOf('=');
// 如果是关系义元,则判断前面部分是否相同,如果相同,则转为计算后面部分的相似度,否则为0
if ((pos == pos2)
&& key1.substring(0, pos).equals(key2.substring(0, pos2))) {
key1 = key1.substring(pos + 1);
key2 = key2.substring(pos2 + 1);
} else {
return 0.0;
}
}
// 处理符号义元,即前面有特殊符号的义元
String symbol1 = key1.substring(0, 1);
String symbol2 = key2.substring(0, 1);
for (int i = 0; i < Symbol_Descriptions.length; i++) {
if (symbol1.equals(Symbol_Descriptions[i][0])) {
if (symbol1.equals(symbol2)) {
key1 = item1.substring(1);
key2 = item2.substring(1);
break;
} else {
return 0.0; // 如果不是同一关系符号,则相似度直接返回0
}
}
}
if ((pos = key1.indexOf("|")) >= 0) {
key1 = key1.substring(pos + 1);
}
if ((pos = key2.indexOf("|")) >= 0) {
key2 = key2.substring(pos + 1);
}
// 如果两个字符串相等,直接返回距离为0
if (key1.equals(key2)) {
return 1.0;
}
Integer[] myset1 = getSememes(key1);
Integer[] myset2 = getSememes(key2);
double similarity = 0.0;
for(int id1:myset1){
for(int id2:myset2){
double s = getSimilarity(SEMEMES[id1], SEMEMES[id2]);
if(s>similarity){
similarity = s;
}
}
}
return similarity;
}
}