自然語言處理基於java實現(1) 之 中文分詞
下一篇<自然語言處理基於java實現(2) 之 詞性註釋>
程式原始碼下載
一. 題目如下:
1、針對人民日報語料,編寫程式:
抽取詞表
統計總詞數、不同的詞及其次數。輸出檔案格式:
第一行是語料庫中的總詞數,之後每行一個詞及其次數,按照詞頻從小到大排序。如:
總詞數:10000
#韓國:169
#民族:571
……
去除語料中的分詞和詞性標記,形成未加工的語料(原始文字)
2、基於上述詞表,編寫一個正向最大匹配分詞程式。程式功能:
輸入:沒有分過詞的檔案或一段文字
輸出:分過詞的檔案或一段文字。
3、編寫一個評價程式,自動評價分詞結果的準確率。
人民日報語料擷取小部分如下:
19980101-02-002-001/m 忠誠/a 的/u 共產主義/n 戰士/n ,/w 久經考驗/l 的/u 無產階級/n 革命家/n 劉/nr 瀾濤/nr 同志/n 逝世/v
19980101-02-002-002/m (/w 附/v 圖片/n 1/m 張/q )/w
19980101-02-002-003/m 根據/p 劉/nr 瀾濤/nr 同志/n 生前/t 遺願/n 和/c 家屬/n 的/u 意見/n ,/w 劉/nr 瀾濤/nr 同志/n 的/u 喪事/n 從簡/v ,/w 不/d 舉行/v 儀式/n 、/w 不/d 保留/v 骨灰/n 。/w
二. 我們的目的是:
1. 將如”忠誠”,”的”等等(除去19980101-02-002-001/m,以及詞性標註/w等等)詞,進行統計
2. 對統計的詞進行出現次數升序排序
3. 基於詞庫,用最大正向匹配演算法,對任意句子進行分詞
4. 寫一個評價程式
三. 直接上程式碼:
package experiment1;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
/**
* 詞庫
*/
public class Thesaurus{
/**
* 儲存結構為:
* Entry<單詞,次數>
*/
private List<Entry<String, Integer>> list = new ArrayList<>();
/**
* 載入詞庫,初始化
*/
public Thesaurus(String content){
//進行分詞統計
final Map<String,Integer> MAP = createMAP(content);
//排序並存入list中
sortMapByValue(MAP);
}
/**
* 分詞
* @param str 分詞的句子
* @param symbol 分割的符號
* @return
*/
public String spitWord(final String str,final String symbol){
StringBuilder target = new StringBuilder();
int start = 0;
while(start<str.length()){
boolean noWord = true;
for(int end = str.length();end>start;end--){
String now = str.substring(start, end);
for(Entry<String,Integer> e:list){
if(e.getKey().equals(now)){
target.append(symbol).append(now);
start = end;
noWord = false;
break;
}
}
}
if(noWord){
target.append(symbol).append(str.charAt(start++));
}
}
return target.substring(symbol.length()).toString();
}
public int numOfSize(){
return list.size();
}
/**
* 分詞
* @param str 要分詞的句子
* @return 分詞後的字串陣列
*/
public String[] spitWord(final String str){
return spitWord(str,",,,,").split(",,,,");
}
/**
* 對map按照value排序,並存入list中
* @param map
*/
private void sortMapByValue(Map<String, Integer> map) {
//這裡將map.entrySet()轉換成list
list.addAll(map.entrySet());
//然後通過比較器來實現排序
Collections.sort(list,new Comparator<Map.Entry<String,Integer>>() {
//升序排序
public int compare(Entry<String, Integer> o1,
Entry<String, Integer> o2) {
return o1.getValue().compareTo(o2.getValue());
}
});
}
/**
* 對文字alls的內容進行分詞統計,存入map中
* @param alls
* @return
*/
private Map<String, Integer> createMAP(String alls) {
final Map<String,Integer> map = new HashMap<String,Integer>();
//去掉空白符號
StringBuilder sb = new StringBuilder (alls.replaceAll("\\s", ""));
int start = 0;
while(start<sb.length()){
int end = sb.indexOf("/",start+1);
if(sb.charAt(end+1)!='m'){
String s = sb.substring(start, end);
if(map.containsKey(s)){
map.put(s, map.get(s)+1);
}else{
map.put(s, 1);
}
}
start = end+2;
}
return map;
}
public List<Entry<String, Integer>> getList() {
return list;
}
}
三. 實現步驟:
0. 建一個詞庫類,不需要解釋吧
**// 儲存結構為:
// Entry<單詞,出現次數>
private List<Entry<String, Integer>> list = new ArrayList<>();**
- 第一步,將文字進行字串切割成詞
- 第二步,統計詞彙
以下把第一二步一次性實現了
/**
* 對文字alls的內容進行分詞統計,存入map中
* @param alls
* @return
*/
private Map<String, Integer> createMAP(String alls) {
final Map<String,Integer> map = new HashMap<String,Integer>();
//去掉空白符號
StringBuilder sb = new StringBuilder (alls.replaceAll("\\s", ""));
int start = 0;
while(start<sb.length()){
int end = sb.indexOf("/",start+1);
if(sb.charAt(end+1)!='m'){
String s = sb.substring(start, end);
if(map.containsKey(s)){
map.put(s, map.get(s)+1);
}else{
map.put(s, 1);
}
}
start = end+2;
}
return map;
}
3.對獲得的統計容器map進行排序:
/**
* 對map按照value排序,並存入list中
* @param map
*/
private void sortMapByValue(Map<String, Integer> map) {
//這裡將map.entrySet()轉換成list
list.addAll(map.entrySet());
//然後通過比較器來實現排序
Collections.sort(list,new Comparator<Map.Entry<String,Integer>>() {
//升序排序
public int compare(Entry<String, Integer> o1,
Entry<String, Integer> o2) {
return o1.getValue().compareTo(o2.getValue());
}
});
}
4.正向最大匹配:
正向最大匹配是怎麼回事呢?
比如句子:美國政府把視線轉向亞太地區
1) 向詞庫查詢,”美國政府把視線轉向亞太地區”是否是一個詞,是,則成功匹配,否則執行2)
2) 向詞庫查詢,”美國政府把視線轉向亞太地”是否是一個詞,是,則成功匹配,否則執行3)
3) 向詞庫查詢,”美國政府把視線轉向亞太”是否是一個詞,是,則成功匹配,否則按照規律繼續執行,直至匹配成功
寫了兩個方法,方便不同情況的呼叫
/**
* 分詞
* @param str 分詞的句子
* @param symbol 分割的符號
* @return
*/
public String spitWord(final String str,final String symbol){
StringBuilder target = new StringBuilder();
int start = 0;
while(start<str.length()){
boolean noWord = true;
for(int end = str.length();end>start;end--){
String now = str.substring(start, end);
for(Entry<String,Integer> e:list){
if(e.getKey().equals(now)){
target.append(symbol).append(now);
start = end;
noWord = false;
break;
}
}
}
if(noWord){
target.append(symbol).append(str.charAt(start++));
}
}
return target.substring(symbol.length()).toString();
}
/**
* 分詞
* @param str 要分詞的句子
* @return 分詞後的字串陣列
*/
public String[] spitWord(final String str){
return spitWord(str,",,,,").split(",,,,");
}
5.評價程式
以下是一個簡單的實現:
package experiment1;
import java.util.HashMap;
import java.util.Map;
public class Assess {
/**
* 獲得s1和s2分詞的相似分數0-100分
* @param s1
* @param s2
* @return
*/
public static int get(String s1, String s2) {
Map<Integer,Integer> map1 = get(s1);
Map<Integer,Integer> map2 = get(s2);
int goal = 0;
for(int key:map1.keySet()){
if(map1.get(key)==map2.get(key)){
goal++;
}
}
return goal*100/map1.size();
}
/**
* 獲得分詞序列號
* @param s
* @return
*/
public static Map<Integer,Integer> get(String s) {
int start = 0;
int num = 0;
Map<Integer,Integer> map = new HashMap<Integer,Integer>();
while(start<s.length()){
int end = s.indexOf("'",start+1);
if(end==-1){
end = s.length();
}
map.put(start-num, end-num);
num++;
start = end+1;
}
return map;
}
}
6.最後,寫個測試吧:
1) Junit測試
package test;
import static org.junit.Assert.*;
import org.junit.Ignore;
import org.junit.Test;
import experiment1.Assess;
public class AssessTest {
@Test
public void testGet() {
// 0 2 3 4 5 6 8
String s1 = "你問'我'愛'你'有'多深";
// 0 1 2 3 4 5 6 8
String s2 = "你'問'我'愛'你'有'多深";
assertEquals(83, Assess.get(s1,s2));
String s3 = "我們'去'小王'家'休息'一會";
String s4 = "我們'去'小王'家'休息'一'會";
assertEquals(83, Assess.get(s3, s4));
}
@Ignore
@Test
public void testGet2() {
// 0 2 3 4 5 6 8
String s1 = "你問'我'愛'你'有'多深";
// 0 1 2 3 4 5 6 8
String s2 = "你'問'我'愛'你'有'多深";
assertEquals(Assess.get(s1).keySet(), Assess.get(s2).keySet());
String s3 = "休息'一會";
String s4 = "休息'一'會";
assertEquals(Assess.get(s3).keySet(), Assess.get(s4).keySet());
}
}
2) main測試
package test;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import experiment1.Assess;
import experiment1.Thesaurus;
import util.FileRW;
/**
* 測試實驗一
* @author Administrator
*
*/
public class Test1 {
public static void main(String[] args) {
Thesaurus thesaurus = new Thesaurus(FileRW.read("199801.txt"));
Scanner in = new Scanner(System.in);
List<Integer> list = new ArrayList<>();
System.out.println("請輸入測試的次數");
int times = in.nextInt();
in.nextLine();
while(times-->0){
System.out.println("請輸入句子:");
String s1 = in.nextLine();
System.out.println("請輸入標準答案(請用'分詞):");
String s2 = in.nextLine();
String s3 = thesaurus.spitWord(s1, "'");
System.out.println("系統分詞結果:\n"+s3);
list.add(Assess.get(s2,s3));
}
int average = 0;
System.out.print("每句分詞成績: ");
for(int goal :list){
System.out.print(goal+" ");
average += goal;
}
average = average/list.size();
System.out.println("\n平均得分: "+average);
in.close();
}
}
相關推薦
自然語言處理基於java實現(1) 之 中文分詞
下一篇<自然語言處理基於java實現(2) 之 詞性註釋> 程式原始碼下載 一. 題目如下: 1、針對人民日報語料,編寫程式: 抽取詞表 統計總詞數、不同的詞及其次數。輸出檔案格式: 第一行
Python自然語言處理實戰(3):中文分詞技術
3.1、中文分詞簡介 在英文中,單詞本身就是“詞”的表達,一篇英文文章就是“單詞”加分隔符(空格)來表示的,而在漢語中,詞以字為基本單位的,但是一篇文章的語義表達卻仍然是以詞來劃分的。 自中文自動分詞被提出以來,歷經將近30年的探索,提出了很多方法,可
自然語言處理工具HanLP-N最短路徑分詞
本篇給大家分享baiziyu 寫的HanLP 中的N-最短路徑分詞。以為下分享的原文,部分地方有稍作修改,內容
Java呼叫ICTCLAS2016 之中文分詞
win7 64位,java呼叫 1.下載ICTCLAS20160405171043_ICTCLAS2016分詞系統下載包 , 2.找到漢語分詞.....20140928/sample/Java/JNA,把該路徑下的JnaTest_NLPIR工程,匯入Myeclipse,
基於python的自然語言處理 分類和標註詞彙之5.5N-gram標註
一元標註器unigram tagging一元標註器利用一種簡單的統計演算法,對每個識別符號分配最有可能的標記。建立一元標註器的技術稱為訓練。>>> fromnltk.corpus import brown>>> importnltk>
python自然語言處理(NLP)1------中文分詞1,基於規則的中文分詞方法
python中文分詞方法之基於規則的中文分詞 目錄 常見中文分詞方法 推薦中文分詞工具 參考連結 一、四種常見的中文分詞方法: 基於規則的中文分詞 基於統計的中文分詞 深度學習中文分詞 混合分詞方法 基於規則的中
自然語言處理之中文分詞器詳解
中文分詞是中文文字處理的一個基礎步驟,也是中文人機自然語言互動的基礎模組,不同於英文的是,中文句子中沒有詞的界限,因此在進行中文自然語言處理時,通常需要先進行分詞,分詞效果將直接影響詞性,句法樹等模組
python自然語言處理(一)之中文分詞預處理、統計詞頻
一個小的嘗試。。資料來源資料集 一共200條關於手機的中文評論,以XML格式儲存。分詞工具 python-jieba預處理包括去停用詞、去標點符號和數字去停用詞:使用的是他人總結的 停用詞表去標點符號和數字:用正則表示式。原本打算的是中文標點符號從網上覆制,英文標點符號用st
自然語言處理之中文分詞器-jieba分詞器詳解及python實戰
中文分詞是中文文字處理的一個基礎步驟,也是中文人機自然語言互動的基礎模組,在進行中文自然語言處理時,通常需要先進行分詞。本文詳細介紹現在非常流行的且開源的分詞器結巴jieba分詞器,並使用python實
利用Tensorflow進行自然語言處理(NLP)系列之二高階Word2Vec
一、概述 在上一篇中,我們介紹了Word2Vec即詞向量,對於Word Embeddings即詞嵌入有了些基礎,同時也闡述了Word2Vec演算法的兩個常見模型 :Skip-Gram模型和CBOW模型,本篇會對兩種演算法做出比較分析並給出其擴充套件模型-GloVe模型。
第六章(1.2)自然語言處理實戰——打造屬於自己的中文word2vector工具
一、環境 二、實戰演練 訓練語料source.txt 9月12日隨著頒獎典禮的結束,我院獲得了商委系統運動會系列活動之一——足球比賽的季軍,本次比賽立時十天,十二隻球隊分成兩個小組比賽。我院代表隊以小組第二名的成績出現,在和另一小組第二名石油公
自然語言處理(NLP) - 數學基礎(1) - 總述
正如我在<2019年總結>裡說提到的, 我將開始一系列自然語言處理(NLP)的筆記. 很多人都說, AI並不難啊, 調現有庫和雲的API就可以啦. 然而實際上並不是這樣的. 首先, AI這個領域十分十分大, 而且從1950年圖靈提出圖靈測試, 1956年達特茅
自然語言處理(NLP) - 數學基礎(1) - 排列組合
正如我在<自然語言處理(NLP) - 數學基礎(1) - 總述>一文中所提到的NLP所關聯的概率論(Probability Theory)知識點是如此的多, 飯只能一口一口地吃了, 我們先開始最為大家熟知和最基礎的知識點吧, 排列組合. 雖然排列組合這個知識點大家是相當地熟知,
HanLP《自然語言處理入門》筆記--1.新手上路
1. 新手上路 自然語言處理(Natural Language Processing,NLP)是一門融合了電腦科學、人工智慧及語言學的交叉學科,它們的關係如下圖所示。這門學科研究的是如何通過機器學習等技術,讓計算機學會處理人類語言,乃至實現終極目標--理解人類語言或人工智慧。 美國電腦科學家Bill Ma
中文自然語言處理向量合集(字向量,拼音向量,詞向量,詞性向量,依存關係向量)
ChineseEmbedding Chinese Embedding collection incling token ,postag ,pinyin,dependency,word embedding.中文自然語言處理向量合集,包括字向量,拼音向量,詞向量,詞性向量,依存關係向量.共5
ElasticSearch-6.4.1安裝中文分詞器Analysis-ik.
一:使用背景和安裝過程. 1. ElasticSearch-6.4.1.(Windows環境下) &nbs
hanlp原始碼解析之中文分詞演算法詳解
詞圖 詞圖指的是句子中所有詞可能構成的圖。如果一個詞A的下一個詞可能是B的話,那麼A和B之間具有一條路徑E(A,B)。一個詞可能有多個後續,同時也可能有多個前驅,它們構成的圖我稱作詞圖。 需要稀疏2維矩陣模型,以一個詞的起始位置作為行,終止位置作為列,可以得到一個二維矩陣。例如:“他說的確實
基於高版本Lucene的中文分詞器(IK分詞器)的DEMO
注意 為了大家方便,我沒有遮蔽資料庫,專案中用的資料來源請各位碼友不要亂搞~謝謝 緣起 日前專案中需要用到Lucene.且需要中文分詞,看了下IK分詞器,但是IK分詞器貌似只支援到lucene的3.X。後期的版本就不支援了,在網上找了一部分資料,自己寫了一個demo.因為中間
Hanlp原始碼解析之中文分詞演算法
詞圖 詞圖指的是句子中所有詞可能構成的圖。如果一個詞A的下一個詞可能是B的話,那麼A和B之間具有一條路徑E(A,B)。一個詞可能有多個後續,同時也可能有多個前驅,它們構成的圖我稱作詞圖。 需要稀疏2維矩陣模型,以一個詞的起始位置作為行,終止位置作為列,可以得到一個二維矩陣。例如:“他說的確實
python_NLP實戰之中文分詞技術
一、規則分詞 1.1 正向最大匹配演算法 # 正向最大匹配演算法 MM法 規則分詞 class MM(object): def __init__(self): self.window_size=3 def cut(self,text)