基於條件隨機場(CRF)的組織機構實體識別

組織機構實體主要指企事業單位、公司、組織、網站等。我的主要是從文本中識別出組織機構實體名稱來。鑑於條件隨機場在序列標註方面的優勢,以及處理詞語特徵包括上下文環境特徵方面,這次工作採用了條件隨機場,具體工具爲CRF++。

1.語料預處理

採用的語料是1998年1月份的《人民日報》語料,這個語料資源是公開的,從網上可以下載到。語料的格式如下所示:


語料中已經做好標註,其中nt表示組織機構實體,簡單實體通過/分割詞語與標註結果,複合實體通過[]來標示,裏面每個詞語再做單的標註。根據自己的要求對語料最好預處理工作,轉換成自己需要的格式。

2.構建前後綴詞典

組織機構實體詞語一般都有明顯的前後綴詞語,比如前綴詞語:中國、國家、各省市地區詞語等,後綴詞語包括集團、公司、總廠、分廠、研究所、研究院、大學等的,構建這些詞典,用於後面詞語匹配,提取特徵。

3.模型訓練過程。

讀入訓練語料,對於每一個詞語提取詞語特徵,包括詞語、詞性、是否前後綴、字在詞語中的位置等,將基於詞語的標註方式轉換爲基於字的標註方式,生成CRF++輸入文件。具體所需要提取的特徵可以根據自己的需要開操作,生成的格式如下圖所示。



採用CRF++對輸入的訓練語料迭代,生成CRF模型。windows下的執行代碼爲:

		StringBuffer buffer = new StringBuffer("");
		buffer.append("cmd /k start CRF++-0.58/crf_learn.exe ");//彈出命令行界面   "cmd /k start CRF++-0.58/crf_learn.exe -f 10"
//		buffer.append("CRF++-0.58/crf_learn.exe");//不彈出命令行界面
		buffer.append(" ");
		buffer.append(template).append(" ");
		buffer.append(dataFile).append(" ");
		buffer.append(modelFile);
		Runtime rt = Runtime.getRuntime();  
        try {  
            rt.exec(buffer.toString());
            logger.info("訓練完成,生成CFR模型");
        } catch (IOException e) {  
        	logger.error(e.getMessage(),e); 
        }

4.實體抽取

對於新語料的識別處理類似,讀取語料,進行分段、分句、詞性識別等,對每一個詞語標註特徵,最終生成與訓練過程中的輸入語料格式一致的文件,採用步驟3中訓練的模型進行識別抽取。一下代碼調用CRF++進行識別,並最終產生識別文件。

		buffer.append("CRF++-0.58/crf_test.exe");
		buffer.append(" ");
//		buffer.append("-v1 -m").append(" ");//識別結果以v1形式顯示
		buffer.append("-m").append(" ");
		buffer.append(modelFile).append(" ");
		buffer.append(testdataFile).append(" ");
		Runtime rt = Runtime.getRuntime(); 
		Process proc = null;
		OutputStream os = null;
        try {  
            proc = rt.exec(buffer.toString());
			InputStream processIn = proc.getInputStream();
			File file = new File(recognitionTxt);
			if(file.exists() == false){
				file.createNewFile();
			}
			os = new FileOutputStream(file);
			byte buf[] = new byte[100*1024];
			int l;
			while((l = processIn.read(buf)) != -1){
				os.write(buf,0,l);
			}
			processIn.close();
			os.flush();
			os.close();
        } catch (IOException e) { 
        	logger.error(e.getMessage(),e); 
        }finally{
        	proc.destroy();
        	logger.info("根據模型文件對測試語料識別結束");
        }

最終測試準確率能夠達到92.31%,召回率能夠達到74.23% 。滿足自己的任務需求,取得了不錯的效果。





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章