Hive基于UDF进行文本分词 (2)

Ansj中文分词 这是一个ictclas的java实现.基本上重写了所有的数据结构和算法.词典是用的开源版的ictclas所提供的.并且进行了部分的人工优化 内存中中文分词每秒钟大约100万字(速度上已经超越ictclas) 文件读取分词每秒钟大约30万字 准确率能达到96%以上 目前实现了....

10:Lucene中文分词库ICTCLAS4J

ictclas4j中文分词系统是sinboy在中科院张华平和刘群老师的研制的FreeICTCLAS的基础上完成的一个java开源分词项目,简化了原分词程序的复杂度,旨在为广大的中文分词爱好者一个更好的学习机会。

代码实现 第一步:引入依赖

这里我们引入了两个依赖,其实是两个不同分词工具

<dependency> <groupId>org.ansj</groupId> <artifactId>ansj_seg</artifactId> <version>5.1.6</version> <scope>compile</scope> </dependency> <dependency> <groupId>com.janeluo</groupId> <artifactId>ikanalyzer</artifactId> <version>2012_u6</version> </dependency>

在开始之前我们先写一个demo 玩玩,让大家有个基本的认识

@Test public void testAnsjSeg() { String str = "我叫李太白,我是一个诗人,我生活在唐朝" ; // 选择使用哪种分词器 BaseAnalysis ToAnalysis NlpAnalysis IndexAnalysis Result result = ToAnalysis.parse(str); System.out.println(result); KeyWordComputer kwc = new KeyWordComputer(5); Collection<Keyword> keywords = kwc.computeArticleTfidf(str); System.out.println(keywords); }

输出结果

我/r,叫/v,李太白/nr,,/w,我/r,是/v,一个/m,诗人/n,,/w,我/r,生活/vn,在/p,唐朝/t [李太白/24.72276098504223, 诗人/3.0502185968368885, 唐朝/0.8965677022546215, 生活/0.6892230219652541] 第二步:引入停用词词库

因为是停用词词库,本身也不是很大,所以我直接放在项目里了,当然你也可以放在其他地方,例如HDFS 上

Hive基于UDF进行文本分词

第三步:编写UDF

代码很简单我就不不做详细解释了,需要注意的是GenericUDF 里面的一些方法的使用规则,至于代码设计的好坏以及还有什么改进的方案我们后面再说,下面两套实现的思路几乎是一致的,不一样的是在使用的分词工具上的不一样

ansj的实现

/** * Chinese words segmentation with user-dict in com.kingcall.dic * use Ansj(a java open source analyzer) */ // 这个信息就是你每次使用desc 进行获取函数信息的时候返回的 @Description(name = "ansj_seg", value = "_FUNC_(str) - chinese words segment using ansj. Return list of words.", extended = "Example: select _FUNC_('我是测试字符串') from src limit 1;\n" + "[\"我\", \"是\", \"测试\", \"字符串\"]") public class AnsjSeg extends GenericUDF { private transient ObjectInspectorConverters.Converter[] converters; private static final String userDic = "/app/stopwords/com.kingcall.dic"; //load userDic in hdfs static { try { FileSystem fs = FileSystem.get(new Configuration()); FSDataInputStream in = fs.open(new Path(userDic)); BufferedReader br = new BufferedReader(new InputStreamReader(in)); String line = null; String[] strs = null; while ((line = br.readLine()) != null) { line = line.trim(); if (line.length() > 0) { strs = line.split("\t"); strs[0] = strs[0].toLowerCase(); DicLibrary.insert(DicLibrary.DEFAULT, strs[0]); //ignore nature and freq } } MyStaticValue.isNameRecognition = Boolean.FALSE; MyStaticValue.isQuantifierRecognition = Boolean.TRUE; } catch (Exception e) { System.out.println("Error when load userDic" + e.getMessage()); } } @Override public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException { if (arguments.length < 1 || arguments.length > 2) { throw new UDFArgumentLengthException( "The function AnsjSeg(str) takes 1 or 2 arguments."); } converters = new ObjectInspectorConverters.Converter[arguments.length]; converters[0] = ObjectInspectorConverters.getConverter(arguments[0], PrimitiveObjectInspectorFactory.writableStringObjectInspector); if (2 == arguments.length) { converters[1] = ObjectInspectorConverters.getConverter(arguments[1], PrimitiveObjectInspectorFactory.writableIntObjectInspector); } return ObjectInspectorFactory.getStandardListObjectInspector(PrimitiveObjectInspectorFactory.writableStringObjectInspector); } @Override public Object evaluate(DeferredObject[] arguments) throws HiveException { boolean filterStop = false; if (arguments[0].get() == null) { return null; } if (2 == arguments.length) { IntWritable filterParam = (IntWritable) converters[1].convert(arguments[1].get()); if (1 == filterParam.get()) filterStop = true; } Text s = (Text) converters[0].convert(arguments[0].get()); ArrayList<Text> result = new ArrayList<>(); if (filterStop) { for (Term words : DicAnalysis.parse(s.toString()).recognition(StopLibrary.get())) { if (words.getName().trim().length() > 0) { result.add(new Text(words.getName().trim())); } } } else { for (Term words : DicAnalysis.parse(s.toString())) { if (words.getName().trim().length() > 0) { result.add(new Text(words.getName().trim())); } } } return result; } @Override public String getDisplayString(String[] children) { return getStandardDisplayString("ansj_seg", children); } }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wsspgw.html