java中文分词的简单实现

中文分词

通俗来讲,中文分词是指将一句中文句子中的所有中文词汇相互分隔开来。它是文本挖掘的基础,有着十分广阔的应用前景。下面,我们来看一看对于这个技术的简单实现。

算法

对于中文分词技术的实现,有许多算法可以完成,目前大致可以把算法分为三大类:

  1. 基于字符串匹配的分词方法;
  2. 基于理解的分词方法;
  3. 基于统计的分词方法。

其中,基于字符串匹配的分词方法是把中文句子按照一定的策略将待分析的汉字串与已知且足够大的中文词典库进行比对,从而达到分词效果。而我们通常使用最多的分词策略,大致有三类,正向最大匹配法,逆向最大匹配法和最少切分法。

基于理解的分词方法是指让计算机模拟人对句子的理解进行分词。基于统计的分词方法是指找出上下文中出现较多的汉字组合,将这些组合视为词汇,代入到原文中进行分词。

在这里,我们就使用字符串匹配的分词方法,利用逆向最大匹配的策略,对中文句子进行简单的分词。

算法思路

逆向最大匹配法大致思想为:将整个字符串作为一个“词组”带入到词典中进行比对,若不成功,删除第一个字符,继续进行如此操作,直到成功或者只剩下最后一个字,再把结果放入一个字符串的数组中,最后删除原句中的结果,继续上面的操作。下面我将用一个例子解释这个操作:

原句:今晚月亮真漂亮啊
词典:“今晚”,“月亮”,“漂亮”
第一次代入:今晚月亮真漂亮啊(在词典中没有该词汇,删除首字符继续比对)
删除首字符:晚月亮真漂亮啊(在词典中没有该词汇,删除首字符继续比对)
删除首字符:月亮真漂亮啊(在词典中没有该词汇,删除首字符继续比对)
删除首字符:亮真漂亮啊(在词典中没有该词汇,删除首字符继续比对)

删除首字符:啊(在词典中没有该词汇,只剩下一个字,放入结果数组,并删除位于句尾的最后这个字,进行第二次代入)
第二次代入:今晚月亮真漂亮(在词典中没有该词汇,删除首字符继续比对)

删除首字符:漂亮(在词典中找到词汇“漂亮”,放入结果数组,并删除位于句尾的结果“漂亮”,进行第三次代入)

算法实现

下面是实现该算法的流程图(摘自网络,图片地址:https://p2.ssl.qhimgs1.com/bdr/240/t01d394ac7e308b34be.jpg)

在这里插入图片描述

代码及注释

public class secondwork {
	public static void main(String args[])
	{
		String[] cs =  {"你好","请问","什么","名字"};//词典
		String a = "你好!请问你叫什么名字?";
		System.out.print("原句:");
		System.out.print(a + '\n');
		System.out.print("拆分后为:");
		String[] cs2 = new String[100]; //结果数组
		int jud=0;//找到匹配字符串与否的标志
		int j=0;
		String temp=null;//初始化临时字符串
		for(;a.length()>0;)
		{
			for(int i = 0;i<a.length();i++)
			{
				temp = a.substring(i);//每次截取掉首个字符
				if(isin(cs,temp) == true)//如果目标字符串在数组中
				{
					cs2[j] = temp;
					jud = 1;
					int number = temp.length();
					a = a.substring(0,a.length()-number);
				}
			}
			if(jud == 0)//没有找到匹配字符串
			{
				cs2[j] = a.substring(a.length()-1,a.length());//将最后一个元素放在cs2里面
				a = a.substring(0, a.length()-1);//截掉最后一个元素继续循环。	
			}
			jud = 0;
			j++;
		}
		for(;j >= 0;j--)
		{
			if(cs2[j] != null)
				System.out.print(cs2[j]+"   ");
		}
	}
	
	/*
	
	 * 下面为判断字符串是否在词典中的函数方法
	
	*/
	
	static public boolean isin(String[] cs,String temp)//判断目标字符串是否在对比字符串数组中
	{
		int i;
		for(i = 0;i<cs.length;)
		{
			if(temp.equals(cs[i]))
				i = cs.length+1;
			else
				i++;
		}
		if(i == cs.length+1)
			return true;
		else
			return false;
	}
}

输出结果如下:
在这里插入图片描述

评价

逆向最大匹配法的思想使得这个策略十分容易实现,具有非常明显的简单易懂的特点,实现代码也不算太长。但是,逆向最大匹配算法对于一些比较特殊的句子,分词准确率可能会降低。例如下面这个句子:

爱迪生发明了很多东西

如果你的词典足够大,你会发现,按照逆向最大匹配的方法,计算机会将“明了”看做一个中文词汇分隔出来,继续向下走,计算机将分出词汇“生发”,这样一来,就会造成 “爱迪 生发 明了” 的错误。

没关系!我们还有正向最大匹配法,我们可以用正向最大匹配法,对这个句子进行分词,结果就对了。但是正向最大匹配法也会出现bug,怎么办呢,我们可以将正向和逆向结合,这样就是另外一种分词策略:双向最大匹配法,大大降低了出现bug的概率。

结语

任何算法都有它的优劣性,我们在使用算法时,不仅要使用算法,更要去考虑怎么样去优化算法,使算法更加贴合自己的需求。

以上便是我对中文分词的简单实现,感谢阅读!

  • 20
    点赞
  • 94
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
PerptronSegmenter是由StanfordNLP提供的一个Java中文分词器,它基于感知机算法训练得到,可以实现中文分词和词性标注。在使用PerceptronSegmenter进行中文分词时,可以结合规则、字典和语言模型等方法进行纠错,下面是一个简单的示例代码: ```java import edu.stanford.nlp.ie.crf.*; import edu.stanford.nlp.ling.*; import edu.stanford.nlp.ling.CoreAnnotations.*; import edu.stanford.nlp.sequences.*; import edu.stanford.nlp.util.*; import java.util.*; public class PerceptronSegmenterExample { public static void main(String[] args) { String text = "中国人民站起来了"; CRFClassifier segmenter = CRFClassifier.getClassifierNoExceptions("edu/stanford/nlp/models/segmenter/chinese/ctb.gz"); List<String> words = segmenter.segmentString(text); System.out.println("分词结果:" + words); // 对分词结果进行纠错 for (int i = 0; i < words.size(); i++) { String word = words.get(i); if (word.equals("中国人民")) { words.set(i, "中国人"); words.add(i + 1, "民"); } else if (word.equals("站起来")) { words.set(i, "站"); words.add(i + 1, "起来"); } } System.out.println("纠错后结果:" + words); } } ``` 在上面的示例代码中,我们首先使用PerceptronSegmenter对一个中文句子进行分词,然后通过遍历分词结果,对一些常见的错误词语进行纠错,例如将“中国人民”替换为“中国人”和“民”,将“站起来”替换为“站”和“起来”。最后输出纠错后的分词结果。需要注意的是,这只是一个简单的示例,实际情况下可能需要结合更多的规则、字典和语言模型等方法进行纠错。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值