应一些同学的要求,把最终的代码都贴出来了。。。。
一般不讲那么多东西,直接贴代码,想看原理直接找官网,文末有链接和参考文献。
public Map<String, String> EntityRecognition(String submitData) throws Exception
{
Map<String , String> returnDataMap = new TreeMap<String , String>(new LengthSort());
String returnData="";
int theFirstTime=0;
HashMap<String, Integer> submitDataMAP = new HashMap<String, Integer>();
Chunking chunking = entityDictionaryChunkerFF.chunk(submitData);
for (Chunk chunk : chunking.chunkSet()) {
int start = chunk.start();
int end = chunk.end();
String entity = submitData.substring(start,end); //find one entity
System.out.println("start: "+start+" end: "+end+" entity: "+entity);
//如果有些entity之前已经识别出来,就没必要在做检测了。
//因为对于同一段用户输入,同样的entity,识别出的maxEntity一定一样。
if(returnDataMap.containsKey(entity))
{
continue;
}
String ambiguationEntitysStr=FindAmbiguationEntity(entity); //judge if this entity is a ambiguation one
if(ambiguationEntitysStr.equals("0")) //the entity is not a ambiguation one
{
returnData+=entity+"=>";
System.out.println("returnData: "+returnData);
returnDataMap.put(entity, entity);
}
else //消歧处理
{
if(theFirstTime==0)
{
//对submitData分词
String tempWord="";
@SuppressWarnings("resource")
Analyzer analyzer = new StandardAnalyzer();
TokenStream ts=analyzer.tokenStream("", submitData); //注意,已经自动转成小写了
CharTermAttribute cta = ts.addAttribute(CharTermAttribute.class);
ts.reset();
while(ts.incrementToken())
{
//System.out.println(cta.toString());
tempWord=cta.toString();
//if(tempWord.length()<4) //跟.py文件的预处理保持一致
//{
// continue;
//}
if(submitDataMAP.containsKey(tempWord))
{
submitDataMAP.put(tempWord, submitDataMAP.get(tempWord)+1);
}
else
{
submitDataMAP.put(tempWord, 1);
}
}
ts.close();
theFirstTime++;
System.out.println("submitDataMAP: "+submitDataMAP.toString());
}
String[] ambiguationEntitys=ambiguationEntitysStr.split("<=");
int maxScore=-1,tempScore=-1;
String maxEntity="",tempEntity="";
for(int i=0;i<ambiguationEntitys.length;i++) //对所有可能的entity,使用abstract上下文选择最有可能的一个entity
{
tempEntity=ambiguationEntitys[i];
tempScore=CaculateScoreForDisambiguation(tempEntity, submitDataMAP);
if(maxScore<tempScore)
{
maxScore=tempScore;
maxEntity=tempEntity;
System.out.println("tempEntity: "+tempEntity+"=>tempScore:"+tempScore);
}
}
returnData+=entity+":"+maxEntity+"=>";//对于有ambiguation的entity,需要把原来的entity也返回,然后再index.jsp中用maxEntity替换原来的entity
System.out.println("returnData: "+returnData);
returnDataMap.put(entity, maxEntity);
}
}
//return returnData;
return returnDataMap;
}
//find if one entity is a ambiguation one
//if yes, return all candidate ambiguation entitys
public static String FindAmbiguationEntity(String entity) throws Exception
{
//Term是搜索的基本单位,一个 Term对象有两个 String类型的域组成。
//生成一个 Term对象可以有如下一条语句来完成:Term term = new Term(“fieldName”,”queryWord”);
//其中第一个参数代表了要在文档的哪一个 Field上进行查找,第二个参数代表了要查询的关键词。
//注意,如果不是用QueryParser,则不对”queryWord”进行任何解析,这里正是采用了这个特质才替换了上面的搜索方式!!!
Term term = new Term("entity", entity.toLowerCase()); //转换为小写
//TermQuery 是抽象类 Query 的一个子类,它同时也是 Lucene支持的最为基本的一个查询类。
//生成一个 TermQuery对象由如下语句完成: TermQuery termQuery = new TermQuery(new Term(“fieldName”,”queryWord”));
//它的构造函数只接受一个参数,那就是一个 Term对象。
TermQuery termQuery = new TermQuery(term);
System.out.println("Searching for: " + termQuery.toString());
TopDocs results=ambiguationEntitySearcher.search(termQuery, 1); //这边search有问题,一直search不上。。。。
ScoreDoc[] hits=results.scoreDocs;
//System.out.println("hits.length=>"+hits.length);
if(hits.length==0) //the entity is not a ambiguation one
{
return "0";
}
else
{
Document doc=ambiguationEntitySearcher.doc(hits[0].doc);
System.out.println("entity: " + doc.get("entity"));
System.out.println("ambiguationEntitys: " + doc.get("ambiguationEntitys"));
return doc.get("ambiguationEntitys");
}
}
关于函数“CaculateScoreForDisambiguation()”的代码就不贴了,每个人都有自己的办法,我的比较挫。。。
思路就是为每一个歧义实体 根据其所在的上下文 与 用户输入的上下文 之间的相似度去判断哪个歧义实体更有可能。。。
参考文献:
[1] Mendes, Pablo N, Jakob, Max, Garc&#, et al. DBpedia spotlight: Shedding light on the web of documents[C]// Proceedings of the 7th International Conference on Semantic Systems. ACM, 2011:1-8.
[2] Han X, Sun L. A Generative Entity-Mention Model for Linking Entities with Knowledge Base.[J]. Proceeding of Acl, 2011:945-954.
[4] http://alias-i.com/lingpipe/demos/tutorial/ne/read-me.html
[5] http://wiki.dbpedia.org/Downloads2014
[6] http://www.oschina.net/p/jieba(结巴分词)