组织机构实体主要指企事业单位、公司、组织、网站等。我的主要是从文本中识别出组织机构实体名称来。鉴于条件随机场在序列标注方面的优势,以及处理词语特征包括上下文环境特征方面,这次工作采用了条件随机场,具体工具为CRF++。

1.语料预处理

采用的语料是1998年1月份的《人民日报》语料,这个语料资源是公开的,从网上可以下载到。语料的格式如下所示:

基于条件随机场(CRF)的组织机构实体识别

语料中已经做好标注,其中nt表示组织机构实体,简单实体通过/分割词语与标注结果,复合实体通过[]来标示,里面每个词语再做单的标注。根据自己的要求对语料最好预处理工作,转换成自己需要的格式。

2.构建前后缀词典

组织机构实体词语一般都有明显的前后缀词语,比如前缀词语:中国、国家、各省市地区词语等,后缀词语包括集团、公司、总厂、分厂、研究所、研究院、大学等的,构建这些词典,用于后面词语匹配,提取特征。

3.模型训练过程。

读入训练语料,对于每一个词语提取词语特征,包括词语、词性、是否前后缀、字在词语中的位置等,将基于词语的标注方式转换为基于字的标注方式,生成CRF++输入文件。具体所需要提取的特征可以根据自己的需要开操作,生成的格式如下图所示。

基于条件随机场(CRF)的组织机构实体识别


采用CRF++对输入的训练语料迭代,生成CRF模型。windows下的执行代码为:

[java] view plain copy
  1.         StringBuffer buffer = new StringBuffer("");  
  2.         buffer.append("cmd /k start CRF++-0.58/crf_learn.exe ");//弹出命令行界面   "cmd /k start CRF++-0.58/crf_learn.exe -f 10"  
  3. //      buffer.append("CRF++-0.58/crf_learn.exe");//不弹出命令行界面  
  4.         buffer.append(" ");  
  5.         buffer.append(template).append(" ");  
  6.         buffer.append(dataFile).append(" ");  
  7.         buffer.append(modelFile);  
  8.         Runtime rt = Runtime.getRuntime();    
  9.         try {    
  10.             rt.exec(buffer.toString());  
  11.             logger.info("训练完成,生成CFR模型");  
  12.         } catch (IOException e) {    
  13.             logger.error(e.getMessage(),e);   
  14.         }  

4.实体抽取

对于新语料的识别处理类似,读取语料,进行分段、分句、词性识别等,对每一个词语标注特征,最终生成与训练过程中的输入语料格式一致的文件,采用步骤3中训练的模型进行识别抽取。一下代码调用CRF++进行识别,并最终产生识别文件。

[java] view plain copy
  1.         buffer.append("CRF++-0.58/crf_test.exe");  
  2.         buffer.append(" ");  
  3. //      buffer.append("-v1 -m").append(" ");//识别结果以v1形式显示  
  4.         buffer.append("-m").append(" ");  
  5.         buffer.append(modelFile).append(" ");  
  6.         buffer.append(testdataFile).append(" ");  
  7.         Runtime rt = Runtime.getRuntime();   
  8.         Process proc = null;  
  9.         OutputStream os = null;  
  10.         try {    
  11.             proc = rt.exec(buffer.toString());  
  12.             InputStream processIn = proc.getInputStream();  
  13.             File file = new File(recognitionTxt);  
  14.             if(file.exists() == false){  
  15.                 file.createNewFile();  
  16.             }  
  17.             os = new FileOutputStream(file);  
  18.             byte buf[] = new byte[100*1024];  
  19.             int l;  
  20.             while((l = processIn.read(buf)) != -1){  
  21.                 os.write(buf,0,l);  
  22.             }  
  23.             processIn.close();  
  24.             os.flush();  
  25.             os.close();  
  26.         } catch (IOException e) {   
  27.             logger.error(e.getMessage(),e);   
  28.         }finally{  
  29.             proc.destroy();  
  30.             logger.info("根据模型文件对测试语料识别结束");  
  31.         }  

最终测试准确率能够达到92.31%,召回率能够达到74.23% 。满足自己的任务需求,取得了不错的效果。

相关文章: