es实战-使用IK分词器进行词频统计

简介:通过IK分词器分词并生成词云。

本文主要介绍如何通过 IK 分词器进行词频统计。使用分词器对文章的词频进行统计,主要目的是实现如下图所示的词云功能,可以找到文章内的重点词汇。后续也可以对词进行词性标注,实体识别以及对实体的情感分析等功能。

词频统计服务具体模块如下:
数据输入:文本信息
数据输出:词 - 词频(TF-IDF等) - 词性等内容
使用的组件:分词器、语料库、词云展示组件等
功能点:白名单,黑名单,同义词等

现存的中文分词器有 IK、HanLP、jieba 和 NLPIR 等几种,不同分词器各有特点,本文使用 IK 实现,因为 ES 一般使用 medcl 等大佬封装的 IK 分词器插件作为中文分词器。
由于 ES 的 IK 分词器插件深度结合了 ES,仅对文本分词使用不到 ES 的内容,所以文本采用申艳超大佬版本的 IK。

1. IK 分词统计代码

IK 的代码相对比较简单,东西不多,将 String 拆分为词并统计代码如下:

  1. 单纯统计词频:
/*** 全文本词频统计** @param content  文本内容* @param useSmart 是否使用 smart* @return 词,词频* @throws IOException*/
private static Map<String, Integer> countTermFrequency(String content, Boolean useSmart) throws IOException {// 输出结果 MapMap<String, Integer> frequencies = new HashMap<>();if (StringUtils.isBlank(content)) {return frequencies;}DefaultConfig conf = new DefaultConfig();conf.setUseSmart(useSmart);// 使用 IKSegmenter 初始化文本信息并加载词典IKSegmenter ikSegmenter = new IKSegmenter(new StringReader(content), conf);Lexeme lexeme;while ((lexeme = ikSegmenter.next()) != null) {if (lexeme.getLexemeText().length() > 1) {// 过滤单字,也可以过滤其他内容,如数字和单纯符号等内容final String term = lexeme.getLexemeText();// Map 累加操作frequencies.compute(term, (k, v) -> {if (v == null) {v = 1;} else {v += 1;}return v;});}}return frequencies;
}
  1. 统计词频和文档频率:
/*** 文本列表词频和词文档频率统计** @param docs     文档列表* @param useSmart 是否使用只能分词* @return 词频列表 词-[词频,文档频率]* @throws IOException*/
private static Map<String, Integer[]> countTFDF(List<String> docs, boolean useSmart) throws IOException {// 输出结果 MapMap<String, Integer[]> frequencies = new HashMap<>();for (String doc : docs) {if (StringUtils.isBlank(doc)) {continue;}DefaultConfig conf = new DefaultConfig();conf.setUseSmart(useSmart);// 使用 IKSegmenter 初始化文本信息并加载词典IKSegmenter ikSegmenter = new IKSegmenter(new StringReader(doc), conf);Lexeme lexeme;// 用于文档频率统计的 SetSet<String> terms = new HashSet<>();while ((lexeme = ikSegmenter.next()) != null) {if (lexeme.getLexemeText().length() > 1) {final String text = lexeme.getLexemeText();// 进行词频统计frequencies.compute(text, (k, v) -> {if (v == null) {v = new Integer[]{1, 0};} else {v[0] += 1;}return v;});terms.add(text);}} // 进行文档频率统计:无需初始化 Map,统计词频后 Map 里面必有该词记录for (String term : terms) {frequencies.get(term)[1] += 1;}}return frequencies;
}

2. 获取词云 TopN 个词

获取 TopN 个词用于词云展示有多种排序方式,可以直接根据词频、文档频率或者 TF-IDF 等算法进行排序,本文仅根据词频求取 TopN。
M 个数字获取 TopN 有以下算法:

  • M 小 N 小:快速选择算法
  • M 大 N 小:小顶堆
  • M 大 N 大:归并排序

本文采用小顶堆方式实现,对应JAVA中的优先队列数据结构 PriorityQueue:

/*** 按出现次数,从高到低排序取 TopN** @param data 词和排序数字对应的 Map* @param TopN 词云展示的 TopN* @return 前 N 个词和排序值*/
private static List<Map.Entry<String, Integer>> order(Map<String, Integer> data, int topN) {PriorityQueue<Map.Entry<String, Integer>> priorityQueue = new PriorityQueue<>(data.size(), new Comparator<Map.Entry<String, Integer>>() {@Overridepublic int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {return o2.getValue().compareTo(o1.getValue());}});for (Map.Entry<String, Integer> entry : data.entrySet()) {priorityQueue.add(entry);}//TODO 当前100词频一致时(概率极低)的处理办法,if( list(0).value == list(99).value ){xxx}List<Map.Entry<String, Integer>> list = new ArrayList<>();//统计结果队列size和topN值取较小值列表int size = priorityQueue.size() <= topN ? priorityQueue.size() : topN;for (int i = 0; i < size; i++) {list.add(priorityQueue.remove());}return list;
}

3. IK 代码浅析

核心主类为IKSegmenter,需要关注的点有dic包也就是词典相关内容以及字符处理工具类CharacterUtilidentifyCharType()方法,目录结构如下:


IKSegmenter类结构如下图,其中 init() 为私有方法,初始化加载词典采用非懒加载模式,在第一次初始化IKSegmenter实例时会调用并加载词典,代码位于结构图下方。

// IKSegmenter 类构造方法
public IKSegmenter(Reader input, Configuration cfg) {this.input = input;this.cfg = cfg;this.init();
}
// IKSegmenter 类初始化
private void init() {//初始化词典单例Dictionary.initial(this.cfg);//初始化分词上下文this.context = new AnalyzeContext(this.cfg);//加载子分词器this.segmenters = this.loadSegmenters();//加载歧义裁决器this.arbitrator = new IKArbitrator();
}// Dictionary 类初始化词典
public static Dictionary initial(Configuration cfg) {if (singleton == null) {synchronized (Dictionary.class) {if (singleton == null) {singleton = new Dictionary(cfg);return singleton;}}}return singleton;
}

词典私有构造方法Dictionary()内会加载 IK 自带的词典以及扩展词典,我们也可以把自己线上不变的词典放到这里这样IKAnalyzer.cfg.xml中就只需要配置经常变更词典即可。

private Dictionary(Configuration cfg) {this.cfg = cfg;this.loadMainDict();// 主词典以及扩展词典this.loadmiaozhenDict();// 自定义词典加载,仿照其他方法即可this.loadStopWordDict();// 扩展停词词典this.loadQuantifierDict();// 量词词典
}

IKSegmenter类调用next()方法获取下一个词元时,会调用CharacterUtil类中的identifyCharType()方法识别字符种类,这里我们也可以自定义一些字符种类针对处理新兴的网络语言,如@、##等内容:

static int identifyCharType(char input) {if (input >= '0' && input <= '9') {return CHAR_ARABIC;} else if ((input >= 'a' && input <= 'z') || (input >= 'A' && input <= 'Z')) {return CHAR_ENGLISH;} else {Character.UnicodeBlock ub = Character.UnicodeBlock.of(input);//caster 增加#为中文字符if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS|| ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS|| ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A ||input=='#') {//目前已知的中文字符UTF-8集合return CHAR_CHINESE;} else if (ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS //全角数字字符和日韩字符//韩文字符集|| ub == Character.UnicodeBlock.HANGUL_SYLLABLES|| ub == Character.UnicodeBlock.HANGUL_JAMO|| ub == Character.UnicodeBlock.HANGUL_COMPATIBILITY_JAMO//日文字符集|| ub == Character.UnicodeBlock.HIRAGANA //平假名|| ub == Character.UnicodeBlock.KATAKANA //片假名|| ub == Character.UnicodeBlock.KATAKANA_PHONETIC_EXTENSIONS) {return CHAR_OTHER_CJK;}}//其他的不做处理的字符return CHAR_USELESS;
}

由于 IK 内容不多,建议大家可以从头捋一遍,包括各个实现ISegmenter接口的各个自分词器等内容。

4. 进行词云展示

词云展示可以使用 Kibana 自带的词云 Dashboard,或者比较热门的 WordCloud。自己测试可以使用线上的微词云快速便捷查看词云效果:导入两列的 XLS 文件即可,左侧控制栏也可以对形状字体等进行配置美化。


展示效果如下图所示:

5. 总结

本文主要通过 IK 分词器实现了词频统计功能,用于词云的展示,不仅仅适用于 ES,任何数据源文档都可以进行词频统计。但是功能比较基础,感兴趣的同学可以实现一下词排序方式变更(tf/idf)、词性标注、实体识别和情感分析等功能;IK 分词器较为局限,需要使用 HanLP(自带词性标注)等更高级的分词器以及 NLP 相关知识来辅助,也可以参考百度 AI 的词法分析模块。

原文链接

本文为阿里云原创内容,未经允许不得转载。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/511502.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IC Nansha|AMD高级副总裁、大中华区总裁潘晓明:制程、架构、平台优化突破计算边界

6月25日&#xff0c;中国南沙国际集成电路产业论坛在广州南沙顺利举行。AMD高级副总裁、大中华区总裁潘晓明出席了本次会议&#xff0c;并在高峰论坛环节中以《高性能计算的未来》为主题发表了演讲。 &#xff08;AMD高级副总裁、大中华区总裁 潘晓明&#xff09; 作为一家深耕…

爱数SMART 2022峰会开启,分享数据战略与建设数据驱动型组织方法论

6月28日&#xff0c;爱数SMART 2022线上峰会全球直播正式开启。主论坛上&#xff0c;爱数正式提出了企业制定数据战略以及建设数据驱动型组织的方法论&#xff0c;并推出开源计划与数字伙伴计划2.0&#xff0c;共创数据驱动型组织。 通过清晰的数据战略&#xff0c;从容加速数据…

云原生时代开发者工具变革探索与实践

简介&#xff1a;本篇内容分享了原生时代开发者工具变革探索与实践。 分享人&#xff1a;马洪喜 行云创新CEO 正文&#xff1a;本篇内容将通过三个部分来介绍云原生时代开发者工具变革探索与实践。 一、云原生模块化开发概览 二、软件模块化开发特点 三、ADD产品简介 一、…

喜马拉雅 Apache RocketMQ 消息治理实践

简介&#xff1a;本文通过喜马拉雅的RocketMQ治理实践分享&#xff0c;让大家了解使用消息中间件过程中可能遇到的问题&#xff0c;避免实战中踩坑。 作者&#xff1a;曹融&#xff0c;来自喜马拉雅&#xff0c;从事微服务和消息相关中间件开发。 本文通过喜马拉雅的RocketMQ治…

Docker 容器为什么傲娇?全靠镜像撑腰!

作者 | 飞向星的客机来源 | CSDN博客&#x1f31f; 前言Docker 镜像是 Docker 容器的基石&#xff0c;容器是镜像的运行实例&#xff0c;有了镜像才能启动容器。Docker 镜像是一个只读的模板&#xff0c;一个独立的文件系统&#xff0c;包括运行一个容器所需的数据&#xff0c;…

HBase读链路分析

简介&#xff1a;HBase的存储引擎是基于LSM-Like树实现的&#xff0c;更新操作不会直接去更新数据&#xff0c;而是使用各种type字段&#xff08;put&#xff0c;delete&#xff09;来标记一个新的多版本数据&#xff0c;采用定期compaction的形式来归档合并数据。这种数据结构…

PolarDB for PostgreSQL 开源路线图

简介&#xff1a;作者&#xff1a;蔡乐 本文主要分享一下Polar DB for PG的开源路线图&#xff0c;虽然路线图已经拟定&#xff0c;但是作为开源产品&#xff0c;所有参与者都能提出修改意见&#xff0c;包括架构核心特性的技术以及周边生态和工具等&#xff0c;希望大家能够踊…

5分钟入门Lindorm SearchIndex

简介&#xff1a;SearchIndex是Lindorm宽表的二级索引&#xff0c;主要用来帮助业务实现快速的检索分析。本篇文章介绍如何通过简单的SQL接口操作SearchIndex。 一、引言 云原生多模数据库Lindorm&#xff0c;支持海量数据的低成本存储和弹性按需付费&#xff0c;提供宽表、时…

最后的 48 小时!云 XR 专题赛邀你一起绽放精彩,我们赛场见!

2022 年是 5G 应用规模化发展的关键之年。随着5G的深入发展&#xff0c;涵盖百亿级“人机物”的智能连接正加速构建&#xff0c;经济社会发展不断向虚实融合演进&#xff0c;基础设施形态也不断向云网融合升级。随着连接对象的拓展和基础设施的升级&#xff0c;XR、元宇宙等新业…

Snowflake核心技术解读系列——架构设计

简介&#xff1a;Snowflake取得了巨大的商业成功&#xff0c;技术是如何支撑起它的千亿美元市值呢&#xff1f;它技术强在哪&#xff1f;本文为大家倾情解读Snowflake的核心技术原理。 背景&#xff1a;2020年9月16日&#xff0c;Snowflake成功IPO&#xff0c;交易首日市场估值…

Apsara Stack 技术百科 | 可运营的行业云,让云上资源跑起来

简介&#xff1a;企业级云管理平台&#xff0c;如何打造千人千面的个性化体验&#xff0c;从应用、云资源、硬件等进行全局智能优化&#xff0c;实现资源配置的最佳配比&#xff0c;构建精细化运营能力&#xff1f; 距离第一例新冠疫情病例的发现&#xff0c;不知不觉中已经过去…

中国数据库崛起,阿里云李飞飞:中国云数据库多种主流技术创新已领先国外

“中国云数据库在很多主流技术创新上已经领先国外。”李飞飞表示&#xff0c;“PolarDB未来还会不断基于新一代云计算架构进行创新突破&#xff0c;持续释放云计算的资源池化潜力&#xff0c;让客户享受到更多云原生技术的红利。” “中国云数据库在很多主流技术创新上已经领先…

十年再出发,Dubbo 3.0 Preview 即将在 3 月发布

简介&#xff1a;随着Dubbo和HSF的整合&#xff0c;我们在整个开源的体系中更多地去展现了 HSF 的能力&#xff0c;能够让更多的人通过使用 Dubbo 像阿里巴巴之前使用 HSF 一样更好的构建服务化的系统。 2011 年&#xff0c;阿里 B2B 团队决定将项目开源&#xff0c;一年时间就…

如何帮助金融客户“用好云”?

简介&#xff1a;如何帮助金融客户“用好云”&#xff1f;做「政企数智创新的同行者」&#xff0c;这对于阿里云混合云来说不仅仅是一句口号&#xff0c;更是在千行百业践行的行动指南。 “我一秒钟几千万上下&#xff0c;会跟你们吃杂碎面&#xff1f;” 这句出自星爷电影台…

nuc8i7beh安装linux随机重启,指南:nuc8i5beh安装黑苹果的教程,接近完美运行

黑苹果采购硬件设施nuc8i5beh镁光m.2 1100 256固态硬盘三星 DDR4 2400笔记本内存条HKC电脑显示器8G U盘(这个之前有&#xff0c;不属于采购的)所需软件Mojave 10.14.6网盘下载Catalina 10.15.2balenaEtcher&#xff1a;下载地址bios65文件&#xff1a;下载地址nuc8 安装软件包&…

低代码、端到端,一小时构建IoT示例场景,声网发布灵隼物联网云平台

2020年&#xff0c;全球 IoT 设备连接数量首次超过非 IoT 设备。市场在高速增长&#xff0c;但音视频物联网的开发门槛依然很高。 6月28日&#xff0c;声网在线上举办主题为“视听无界&#xff0c;智联万物”的产品发布会&#xff0c;正式发布了“灵隼物联网云平台”&#xff0…

云知声 Atlas 超算平台: 基于 Fluid + Alluxio 的计算加速实践

简介&#xff1a;本文主要介绍云知声 Atlas 超算平台基于 Fluid Alluxio 的计算加速实践&#xff0c;以及 Fluid 是如何为 Atlas 带来全新的数据集管理方式的。 Fluid 是云原生基金会 CNCF 下的云原生数据编排和加速项目&#xff0c;由南京大学、阿里云及 Alluxio 社区联合发…

eBPF技术应用云原生网络实践系列之基于socket的service | 龙蜥技术

简介&#xff1a;如何使用 socket eBPF进一步提升Service 网络的转发性能&#xff1f; 背景介绍 Kubernetes 中的网络功能&#xff0c;主要包括 POD 网络&#xff0c;service 网络和网络策略组成。其中 POD 网络和网络策略&#xff0c;都是规定了模型&#xff0c;没有提供默认…

从开店营销到智能化私域运营,有赞发布人工智能引擎Jarvis

“以往在私域发起一场营销活动&#xff0c;从活动策划&#xff0c;到历史数据分析&#xff0c;再到内容排期&#xff0c;整个策划阶段往往需要一周以上的时间&#xff0c;而现在通过营销画布&#xff08;MA&#xff09;以及其中内嵌的人工智能能力&#xff0c;只需要30分钟不到…

“云网管” ---云上构建网络自动化体系

简介&#xff1a;云网管是基于阿里云网络多年技术和经验沉淀打造的云上智能网络管理运维平台&#xff0c;提供企业网络全生命周期管理运维的能力&#xff0c;让部署更快捷、运维更高效、网络更透明。 1.背景 云网管是基于阿里云网络多年技术和经验沉淀打造的云上智能网络管理…