C#中使用jieba.NET、WordCloudSharp制作词云图

词云简介

“词云”由美国西北大学新闻学副教授、新媒体专业主任里奇·戈登(Rich Gordon)于2006年最先使用,是通过形成“关键词云层”或“关键词渲染”,对文本中出现频率较高的“关键词”的视觉上的突出
网上大部分文章介绍的是使用Python的jieba、wordcloud的库生成词云图,本文则介绍在C#中如何使用jieba.NET、WordCloudSharp库生成词云图,后者是前者的.NET实现。

准备工作

创建一个C#的控制台项目,通过NuGet添加引用对jieba.NETWordCloudSharp的引用,使用方法可以参考以下链接:

  • jieba.NET:https://github.com/anderscui/jieba.NET

  • WordCloudSharp:https://github.com/AmmRage/WordCloudSharp

安装之后,在packages\jieba.NET目录下找到Resources目录,将整个Resources目录拷贝到程序集所在目录,这里面是jieba.NET运行所需的词典及其它数据文件。

基本算法

算法主要步骤如下:

  • 提取关键词:基于TF-IDF算法、TextRank算法提取文本的关键词,按权重大小选取部分关键词。

  • 统计关键词词频:先将文本分词,统计每个词的词频,再筛选出关键词的词频。

  • 生成词云图:根据关键词及其词频信息在蒙版图片的基础上生成词图。

注:本文采用TF-IDF算法提取关键词,蒙版图目前只支持黑白图片

TF-IDF(词频-逆文档频率)算法是一种统计方法,用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降

算法实现

使用JiebaNet.Analyser.TfidfExtractor.ExtractTagsWithWeight(string text, int count = 20, IEnumerable allowPos = null)从指定文本中抽取关键词的同时得到其权重,代码如下:

/// <summary>
/// 从指定文本中抽取关键词的同时得到其权重
/// </summary>
/// <param name="text"></param>
/// <returns></returns>
static WordWeightPair[] ExtractTagsWithWeight(string text)
{var extractor = new TfidfExtractor();var wordWeight = extractor.ExtractTagsWithWeight(text, 50);StringBuilder sbr = new StringBuilder();sbr.Append("词语");sbr.Append(",");sbr.Append("权重");sbr.AppendLine(",");foreach (var item in wordWeight){sbr.Append(item.Word);sbr.Append(",");sbr.Append(item.Weight);sbr.AppendLine(",");}string filename = "关键词权重统计.csv";File.WriteAllText(filename, sbr.ToString(), Encoding.UTF8);Console.WriteLine("关键词提取完成:" + filename);return wordWeight.ToArray();
}

使用JiebaNet.Segmenter.Common下的Counter类统计词频,其实现来自Python标准库的Counter类(具体接口和实现细节略有不同),代码如下:

/// <summary>
/// 分词并统计词频:默认为精确模式,同时也使用HMM模型
/// </summary>
/// <param name="text"></param>
/// <param name="wordWeightAry"></param>
/// <returns></returns>
static KeyValuePair<string, int>[] Counter(string text, WordWeightPair[] wordWeightAry)
{var segmenter = new JiebaSegmenter();var segments = segmenter.Cut(text);var freqs = new Counter<string>(segments);KeyValuePair<string, int>[] countAry = new KeyValuePair<string, int>[wordWeightAry.Length];for (int i = 0; i < wordWeightAry.Length; i++){string key = wordWeightAry[i].Word;countAry[i] = new KeyValuePair<string, int>(key, freqs[key]);}StringBuilder sbr = new StringBuilder();sbr.Append("词语");sbr.Append(",");sbr.Append("词频");sbr.AppendLine(",");foreach (var pair in countAry){sbr.Append(pair.Key);sbr.Append(",");sbr.Append(pair.Value);sbr.AppendLine(",");}string filename = "词频统计结果.csv";File.WriteAllText(filename, sbr.ToString(), Encoding.UTF8);Console.WriteLine("词频统计完成:" + filename);return countAry;
}

使用WordCloudSharp生成词云图,蒙版图必须使用黑白图片,记得手动引用System.Drawing,代码如下:

/// <summary>
/// 创建词云图
/// </summary>
/// <param name="countAry"></param>
static void CreateWordCloud(KeyValuePair<string, int>[] countAry)
{            string markPath = "mask.jpg";string resultPath = "result.jpg";Console.WriteLine("开始生成图片,读取蒙版:" + markPath);Image mask = Image.FromFile(markPath);//使用蒙版图片var wordCloud = new WordCloud(mask.Width, mask.Height, mask: mask, allowVerical: true, fontname: "YouYuan");//不使用蒙版图片//var wordCloud = new WordCloud(1000, 1000,false, null,-1,1,null, false);var result = wordCloud.Draw(countAry.Select(it => it.Key).ToList(), countAry.Select(it => it.Value).ToList());result.Save(resultPath);Console.WriteLine("图片生成完成,保存图片:" + resultPath);
}

运行测试

以本文为分析文本生成词云图,代码如下:

static void Main(string[] args)
{string text = File.ReadAllText("待处理数据.txt");var wordWeight = ExtractTagsWithWeight(text);var wordFreqs = Counter(text, wordWeight);CreateWordCloud(wordFreqs);Console.Read();
}

蒙版图如下:

词云图如下(使用蒙版):

词云图如下(不使用蒙版):

在得到关键词的词频信息后,通过在线工具网站生成词云图片会更加方便一点,如词云文字、图悦等。

参考资料

  • jieba.NET是jieba中文分词的.NET版本(C#实现)

  • TF-IDF算法和TextRank算法的分析比较

  • Python生成词云图

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

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

相关文章

js框架页弹出页面关闭

2019独角兽企业重金招聘Python工程师标准>>> <!-- lang: js --> function to(href) {if (top.location self.location) {//window.opener null;window.opener.location.reload();window.open(, _self);window.close();} else {window.location.href href;}…

[超享]linux共享3160命令

点击进入Linux超全的命令学习博客[url]http://my0451.blog.sohu.com/action/m_list-ebi_3f3e214792-c_622615/entry/[/url]转载于:https://blog.51cto.com/jankie/11433

php和web服务器,php与web服务器关系

在解析这个问题前&#xff0c;先要讲述一个概念&#xff0c;什么是cgi程序&#xff1f;1.什么是cgi程序&#xff0c;cgi与fastcgi的区别CGI的中文名称是通用网关接口&#xff0c;是外部应用程序与web服务器之间的接口标准。CGI规范允许web服务器执行外部程序&#xff0c;并将它…

股市红涨绿跌色系定义真的是中国特色吗?

20080809 郑昀玩聚 与G共舞刚才发表的《适应中国特色 谷歌财经图标改绿色为红色.》&#xff0c;提及“在其他证券交易所&#xff0c;股市上涨都是使用绿色&#xff0c;下跌使用红色&#xff0c;唯独中国大陆的沪深股市&#xff0c;颜色显示相反”。 一.并非独此一家 实际上&…

狂言50年要拿30个诺奖的日本,如今怎么样了?

全世界只有3.14 % 的人关注了青少年数学之旅2019年10月9日&#xff0c;日本化学家吉野彰&#xff08;Akira Yoshino&#xff09;因在锂离子电池的发明和应用领域做出的卓越贡献&#xff0c;与美国科学家 John B. Goodenough、英国科学奖 M. Stanley Whittingham 一起荣获2019年…

VS2022+.NET6+C#10,.NET开发起飞

VS2022.NET6C#10一起体验是啥感觉&#xff1f;爽&#xff01;令人印象深刻的是VS2022打开超大项目的流畅&#xff0c;.NET6极致简化的MiniAPI框架&#xff0c;C#10各种炫酷新语法。看看下图的代码你能认识吗&#xff1f;来自.NET6的MiniAPI框架&#xff0c;直接在MapGet里面使用…

jdk8之lambda

2019独角兽企业重金招聘Python工程师标准>>> Oracle号称今年一定发布jdk8, 即使有bug, jdk8无疑最大的宠儿就是lambda表达式了&#xff0c;还是直接上代码&#xff0c;看看lambda表达式怎么了。 环境&#xff1a; openjdk8, eclipse4.3.1(支持jdk8编译) 实例代码&…

【转】Asp.Net中Excel操作权限的问题

近日在打开原来写的一个网页程序运行时&#xff0c;出现了Excel操作权限的问题&#xff0c;具体的说就是在代码中调用下面这段与Excel操作有关的语句时 Application curExcelApp new ApplicationClass(); 提示权限不足&#xff0c;具体的提示内容如下&#xff1a; 检索 COM 类…

再一贴[亲爱的,我不小心怀孕了~!]

这是我们第一次见面的酒吧。我们在这里度过了多少个夜晚&#xff0c;有过多少美好的回忆。  可是4月1日那天&#xff0c;我的心情很沉重&#xff0c;很忧郁。我不知道&#xff0c;这个消息对于我&#xff0c;对于你&#xff0c;对于我们意味着什么。我是如此渴望而又恐惧。 …

python路径长度限制,Linux下文件名长度限制

Linux下文件名长度限制出现场景&#xff1a;在迭代中有一个需求是将pdf文件名修改为所有班级的名称集合&#xff0c;出现的班级过多导致的文件名过长在linux下无法创建文件和文件夹的情况解决方式&#xff1a;经过查证&#xff0c;linux中文件名最长为255字符&#xff0c;文件路…

Visual Studio 2022 预览版2 发布啦

我们很高兴地宣布 Visual Studio 2022 的第二个预览版发布啦&#xff01;预览版 1 是有史以来第一个 64 位 Visual Studio&#xff0c;提供了改进的可扩展性。从预览版 2 开始&#xff0c;我们专注于提供有关个人和团队生产力、现代开发和不断创新等主题的新功能。在本文中&…

批作业是小学老师的一大乐趣 | 今日最佳

全世界只有3.14 % 的人关注了青少年数学之旅

【小安翻唱】凉宫春日的忧郁--冒険でしょでしょ第五届外语歌曲大赛助兴节目~绫魂论坛送aya的生日礼物筹备开始~...

第五届外语歌曲大赛如火如荼的进行的听了那么多参赛选手的歌曲自己也不由的也想唱唱正好遇上绫魂论坛的各位管理员为aya筹备生日礼物 好吧~ 我也来小唱一首 小小的final版送上~&#xff08;非正式版 请无视错词和中间以及最后的杂音 灭哈哈&#xff09; 顺便再借用了一下某位选…

免费电影下载

迅雷资源,速度稳定.我一直都在用..好东西不能一个人独享,拿出来分享..菜熊视讯最大的影视迅雷下载站&#xff01;完全免费&#xff0c;并且每天还大批量更新&#xff01;[url]http://www.caixiong.com/?445419.htm[/url]转载于:https://blog.51cto.com/douvip/12485

进入51cto之后的发展方向

这里是个不错的学习环境&#xff0c;值得珍惜。来到这里&#xff0c;我发现这里正是我梦寐以求的学习之天堂&#xff0c;这里可以肆无忌惮的贪婪的学习&#xff0c;可以感受到融洽的美好的氛围。我很愉快的开通的博客&#xff0c;并且珍惜这一次难得的机会去疯狂学习。我要确定…

oracle中文加密算法,Oracle数据库替代加密算法

替代密码算法的原理是使用替代法进行加密&#xff0c;就是将明文中的字符用其它字符替代 后形成密文。例如&#xff1a;明文字母a、b、c、d &#xff0c;用D、E、F、G做对应替换后形成密文。这里在Oracle的存储过程&#xff0c;通过替换加密算法来实现密码存入数据库时的加密。…

.net中单元测试

单元测试&#xff08;unit testing&#xff09;&#xff0c;是指对软件中的最小可测试单元进行检查和验证。对于单元测试中单元的含义&#xff0c;一般来说&#xff0c;要根据实际情况去判定其具体含义&#xff0c;如C语言中单元指一个函数&#xff0c;Java里单元指一个类&…

WCF后续之旅(11): 关于并发、回调的线程关联性(Thread Affinity)

对于一般的多线程操作&#xff0c;比如异步地进行基于文件系统的IO操作&#xff1b;异步地调用Web Service&#xff1b;或者是异步地进行数据库访问等等&#xff0c;是和具体的线程无关的。也就是说&#xff0c;对于这些操作&#xff0c;任意创建一个新的线程来执行都是等效的。…

成年人改变生活的方式,都是从它开始

全世界只有3.14 % 的人关注了青少年数学之旅2019已经不足80天&#xff0c;年初立下的flag倒了几个&#xff1f;史蒂夫马丁有一句话&#xff1a;“所有的人生谜语都可以从阅读中找到答案。”无论是读影评、读好书&#xff0c;亦或者涉猎趣闻轶事、汲取犀利观点&#xff0c;总会悄…

组策略链接顺序优先级

“链接顺序”最低的 GPO 最后处理&#xff0c;因此具有最高的优先级。