Skip to content

新词发现小工具

Jason Tan edited this page Sep 5, 2017 · 4 revisions

#新词发现小工具

很高兴说这个,这是个有趣的小东西。其实本身是一个trie树。因为分词中集成了大量的。新词识别。 比如 人名识别,机构名识别,新词发现等,这些新词的出现对分词结果起着重要的影响,如何能将这些结果整合起来。 可以想到的有两种方式,

线性链模式:以新词发现的准确率为基准,进行一步一步的合并。 比如。先识别人名,(因为人名识别的准确率相对较高)再识别机构名,然后是地名等 这个方式的优点是速度快。程序逻辑清晰。在不同识别方式上不必要担心,词语权重不一致。 但是缺点也很明显,人名识别发生错误。造成后面的识别一错再错,比如“非洲八冠王曾夺世界季军”,如果先经历人名识别。会出现“王曾夺”错误的划分为人名。

集合模式:这个方式就是利用了learntool的特性。它将所有识别出来的认为是新词的词语。都完整的加入learntool中。之后再以新词为辞典。构建最优路径。

好了。说了这么多。大家一定认为跑题了。我们这里说的是新词发现小工具没错。真的跑题了

这个工具可以作为辞典整理的一个小东西。具体操作还是上代码把。不废话了


  package org.ansj.demo;

  import org.ansj.dic.LearnTool;
  import org.ansj.domain.Nature;
  import org.ansj.splitWord.analysis.NlpAnalysis;
  
  /**
   * 新词发现工具
   * @author ansj
   *
   */
  public class LearnToolDemo {
  	public static void main(String[] args) {
  		
  		//构建一个新词学习的工具类。这个对象。保存了所有分词中出现的新词。出现次数越多。相对权重越大。
  		LearnTool learnTool = new LearnTool() ;
  		
  		//进行词语分词。也就是nlp方式分词,这里可以分多篇文章
  		NlpAnalysis.parse("说过,社交软件也是打着沟通的平台,让无数寂寞男女有了肉体与精神的寄托。", learnTool) ;
  		NlpAnalysis.parse("其实可以打着这个需求点去运作的互联网公司不应只是社交类软件与可穿戴设备,还有携程网,去哪儿网等等,订房订酒店多好的寓意", learnTool) ;
  		NlpAnalysis.parse("张艺谋的卡宴,马明哲的戏",learnTool) ;
  
  		//取得学习到的topn新词,返回前10个。这里如果设置为0则返回全部
  		System.out.println(learnTool.getTopTree(10));
  		
  		//只取得词性为Nature.NR的新词
  		System.out.println(learnTool.getTopTree(10,Nature.NR));
  		
  	}
  }

关于learntool的结果保存。及重新训练

有好几个朋友提出过这个问题.的确当初做这个的时候没有完整的考虑。那么让我们看看他是怎么可以迭代训练吧。我直接上代码了,因为其内部newWord结构比较复杂。所以在write的时候。我放弃了没有激活的词,很可能这些词。会在以后激活,而且放弃了这些词的词性。全部为nw,但是这个词性也可能在以后的训练中纠正。目前我觉得最简单的保存方式只有如此。完整无损保存这个功能,可能会在以后的版本实现,我最终的意思是。现这么凑合用吧。也还行问题不大 !^_^

  /**
   * 将训练结果序列写入到硬盘中
   */
  List<Entry<String, Double>> topTree = learnTool.getTopTree(0);
  StringBuilder sb = new StringBuilder();
  for (Entry<String, Double> entry : topTree) {
  	sb.append(entry.getKey() + "\t" + entry.getValue()+"\n");
  }
  IOUtil.Writer("/home/ansj/temp/learnTool.snap", IOUtil.UTF8, sb.toString());
  sb = null;
  
  /**
   * reload训练结果
   */
  learnTool = new LearnTool() ;
  HashMap<String, Double> loadMap = IOUtil.loadMap("/home/ansj/temp/learnTool.snap", IOUtil.UTF8, String.class, Double.class);
  for (Entry<String, Double> entry : loadMap.entrySet()) {
  	learnTool.addTerm(new NewWord(entry.getKey(), Nature.NW, entry.getValue())) ;
  	learnTool.active(entry.getKey()) ;
  }
  System.out.println(learnTool.getTopTree(10));