第十二章 分词与词云可视化
第一节 词云图
概念:一种富文本信息可视化技术,通过布局算法用文字大小表示词频,辅以多种颜色,直观的反映词组重要性差异,展示文本关键摘要信息。完整的词云分析包括:分词、词频统计和可视化。
相关概念:标签云 词云
1997年,标签云(Tag Cloud)作为用户行为统计的网站可视化导航。
历史:
2008年,Jonathan Feinberg发布第一款在线词云Wordle。
2011年,清华大学自然语言处理与社会人文计算实验室上线“围脖关键词”词云。
工具:
工具 | 特点 | 案例 |
tagCloud | 标签云 | |
ToCloud | 标签云 | |
Tagul | 标签云和词云 | |
ManyEyes | 标签云,IBM开发,不能适形填充 | |
Tagxedo | ||
ImageChief | ||
ABCya | 幼儿学习网站 | |
WordItOut | ||
Wordle | 不支持中文。D3.JS已嵌入 | |
D3.JS | d3.layout.cloud.js库 |
算法:
第二节 D3词云图
用布局函数创建一个布局,设置相关参数---->计算布局---->调用绘制函数draw
案例:[源码]
<html>
<head>
<title>基于D3的词云图</title>
</head>
<body>
<script src="d3.v3.min.js"></script>
<script src="d3.layout.cloud.js"></script>
<script>
var fill = d3.scale.category20();
var words=[
{text:"佛陀",size:57},
{text:"新白娘子传奇",size:27},
{text:"我的团长我的团",size:22},
{text:"哈利波特",size:18},
{text:"Dicovery",size:17},
{text:"变形金刚5",size:16},
{text:"摔跤吧!爸爸",size:13},
{text:"芳华",size:13},
{text:"寻梦环游记",size:12},
{text:"加勒比海盗5",size:12}
];
var wc=d3.layout.cloud()
.size([600, 400]) //空间的布局尺寸
.words(words)
.padding(5) //词组间隙大小
.rotate(function() { return ~~(Math.random() * 2) * 90; }) //词组旋转
.font("Impact")
.fontSize(function(d) { return d.size; })
.on("end", draw)
.start();
function draw(words) {
d3.select("body").append("svg")
.attr("width", 600)
.attr("height", 400)
.append("g")
.attr("transform", "translate(300,200)")
.selectAll("text")
.data(words)
.enter().append("text")
.style("font-size", function(d) { return d.size + "px"; })
.style("font-family", "Impact")
.style("fill", function(d, i) { return fill(i); })
.attr("text-anchor", "middle")
.attr("transform", function(d) {
return "translate(" + [d.x, d.y] + ")rotate(" + d.rotate + ")";
})
.text(function(d) { return d.text; });
}
</script>
</body>
</html>
JSP中调用mysql数据库生成D3词云
首先要使用相关软件建立一个JSP网站,如Tomcat,或者简单的护卫神之类
连接数据库配置驱动jbdc
案例: JSP调用数据库中数据生成D3词云图
第三节 基于python的分词实例
一 jieba简介
中文分词:基于字符串匹配的分词方法、基于理解的分词方法、基于机器学习方法的研究。
安装:anaconda下使用手动安装,参考csdn Iovebecky介绍的方法
jieba分词特点:jieba.cut()提供了三种:精确模式、全模式、搜索引擎模式
案例:三种分词模式比较[源码 :官方github]
# encoding=utf-8
import jieba
seg_list = jieba.cut("我来到北京清华大学", cut_all=True)
print("Full Mode: " + "/ ".join(seg_list)) # 全模式
seg_list = jieba.cut("我来到北京清华大学", cut_all=False)
print("Default Mode: " + "/ ".join(seg_list)) # 精确模式
seg_list = jieba.cut("他来到了网易杭研大厦") # 默认是精确模式
print(", ".join(seg_list))
seg_list = jieba.cut_for_search("小明硕士毕业于中国科学院计算所,后在日本京都大学深造") # 搜索引擎模式
print(", ".join(seg_list))
案例:添加词典
词典格式:一词一行,词语、词频(可省略)、词性(可省略),用空格分隔,用utf-8编码。
#下面是jieba词典测试
#encoding=utf-8
import jieba
jieba.load_userdict("jiebaDict.txt") #添加用户词典
words=jieba.cut("他来到了那所被称为中国最牛科研特色的北京龙泉寺")
print("/".join(words))
案例:词性标注
只能解析中文
#下面是jieba词性标注测试
#encoding=utf-8
import jieba
import jieba.posseg as pseq
words=pseq.cut("他来到了那所被称为中国最牛科研特色的北京龙泉寺")
for key in words:
print(key.word,key.flag)
第四节 影视小说词云案例分析
一 基本流程:
文本分词-->过滤停用词-->统计词频-->词云可视化
词频统计:
encoding='gbk'
import jieba
with open('renmin.txt', 'r',encoding='utf-8') as f:
renmin=f.read()
jieba.load_userdict("renminDict.txt") #添加词典
seg_list = jieba.cut("renmin", cut_all=False) #分词
print("【精确模式】: " + "/ ".join(seg_list))
tf = {}
for seg in seg_list:
if seg in tf: # 如果该键存在于集合tf的对象中,则该键所属对象值加1
tf[seg] +=1
else: #否则,生成新词的键值对,初始值为1
tf[seg] = 1
ci = list(tf.keys()) #将分词结果中的所有键值,即词语,放置在一个列表
with open('stopword.txt', 'r') as ft:
stopword=ft.read()
for seg in ci: #逐个判断是否停用词,及对词语长度进行处理
if tf[seg]<20 or len(seg)<2 or seg in stopword or '一'in seg:
tf.pop(seg) #若属停用词,则删去该键值对
#过滤后的词语和词频分别存入列表ci和num中,并将data声明为列表,以存储键值对
ci, num, data = list(tf.keys()), list(tf.values()),[]
for i in range(len(tf)):
data.append((num[i],ci[i])) #逐个将键值对存入data中
data.sort() #升序排列
data.reverse() #逆序,得到所需的降序排列
f = open("result.txt", "w")
for i in range(len(data)):
f.write("[\""+data[i][1]+"\","+str(data[i][0])+"],") #以下文词云API所需数据格式存入文件
f.close()
使用Echarts2生成词云图[源码]
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>word</title>
<script src="d3.v3.min.js" charset="utf-8"></script>
<script src="js2wordcloud.js"></script>
</head>
<body>
<div id="cloud" style="width:1600px;height:800px"></div>
<script>
var data=[["侯亮平",1355],["李达康",780],["高育良",627],["祁同伟",553],["蔡成功",525],["老师",498],["书记",413],["沙瑞金",353],["高小琴",329],["陈海",295],["丁义珍",294],["陆亦可",283],["同志",272],["欧阳菁",271],["季昌明",252],["局长",231],["大风",191],["陈岩石",173],["刘新建",164],["集团",161],["这位",155],["汇报",155],["郑西坡",154],["情况",154],["山水",154],["赵瑞龙",151],["电话",150],["学习",150],["举报",148],["赵东来",141],["干部",137],["京州",130],["检察院",128],["看着",125],["学生",120],["领导",115],["工作",108],["大路",107],["反贪局",105],["手机",104],["工人",100],["厅长",100],["赵立春",98],["北京",95],["省委",94],["光明",93],["这是",92],["省委书记",90],["亮平",89],["连城",88],["儿子",88],["股权",86],["明白",86],["会计",84],["陈清泉",81],["政治",79],["吴慧芬",79],["审讯",77],["当年",76],["办公室",74],["处长",73],["面前",72],["肖钢玉",72],["国富",72],["意外",70],["两个",67],["达康",66],["证据",66],["警察",66],["政法",65],["希望",65],["发现",65],["关系",65],["离婚",64],["庆祝",63],["公安局",63],["告诉",62],["秘书",61],["银行",59],["老婆",58],["妻子",58],["吕州",58],["公安厅",58],["也许",58],["照片",57],["彩霞",57],["发生",57],["警车",55],["猴子",55],["政府",54],["市委书记",54],["人民",54],["市长",53],["坐下",53],["肯定",52],["有人",52],["实在",52],["安排",52],["王文革",51],["回来",50],["公司",50],["钟小艾",49],["眼睛",49],["发小",49],["仿佛",49],["赵德汉",48],["事情",47],["不想",47],["这才",45],["组织",45],["几个",45],["拆迁",44],["心中",44],["事件",44],["项目",43],["老人",43],["群众",43],["检察长",43],["机场",43],["指挥",43],["对手",43],["好好",43],["林城",42],["摇头",42],["地方",42],["不好",42],["腐败",41],["终于",41],["没想到",41],["时间",41],["声音",41],["危险",41],["苦笑",40],["指示",40],["员工",40],["司机",40],["伯仲",40],["中央",40],["贷款",39],["说话",39],["找到",39],["感觉",39],["同学",39],["老板",38],["手上",38],["心情",38],["度假村",38],["城市",38],["叹息",38],["华华",38],["经济",37],["本来",37],["早就",37],["放下",37],["承认",37],["想想",37],["大学",37],["办法",37],["保护",37],["身上",36],["老季",36],["提醒",36],["想到",36],["州市",36],["事实",36],["这话",35],["瑞金",35],["熟悉",35],["建议",35],["离开",34],["案子",34],["树立",34],["提出",34],["市委",34],["女人",34],["喜欢",34],["主动",34],["解释",33],["激动",33],["命令",33],["关键",33],["不错",33],["脸上",32],["紧张",32],["秘密",32],["油气",32],["梁璐",32],["材料",32],["意见",32],["怎么回事",32],["常委会",32],["坐在",32],["二人",32],["不到",32],["贪官",31],["谈话",31],["美食城",31],["线索",31],["窗口",31],["眼前",31],["留下",31],["点头",31],["担心",31],["怀疑",31],["好像",31],["变得",31],["麻烦",30],["那位",30],["责任",30],["调查",30],["老百姓",30],["纪委书记",30],["省委常委",30],["目光",30],["沙发",30],["有个",30],["报告",30],["感情",30],["很大",30],["影响",30],["录音",30],["举报人",30],["赵家",29],["账本",29],["解决",29],["结束",29],["结婚",29],["没错",29],["来到",29],["权力",29],["开发区",29],["办案",29],["侦查",29],["估计",29],["银行卡",28],["理解",28],["家里",28],["季检",28],["女儿",28],["同意",28],["口气",28],["几天",28],["为啥",28],["香港",27],["老马",27],["纪委",27],["社会",27],["检察官",27],["日子",27],["手续",27],["回家",27],["医院",27],["别墅",27],["做出",27],["东西",27],["不禁",27],["三个",27],["证人",26],["老易",26],["老同学",26],["窗外",26],["研究",26],["生活",26],["涉及",26],["法院",26],["欧阳",26],["检察",26],["机会",26],["我省",26],["总局",26],["常小虎",26],["师母",26],["回到",26],["啥事",26],["受贿",26],["历史",26],["出事",26],["公安",26],["交代",26],["丈夫",26],["面对",25],["这事",25],["起码",25],["警官",25],["离去",25],["矛盾",25],["真的",25],["片刻",25],["朋友",25],["地问",25],["回答",25],["判断",25],["交给",25],["中国",25],["两人",25],["高小凤",24],["门口",24],["走进",24],["话题",24],["脑袋",24],["育良",24],["渐渐",24],["有没有",24],["改革",24],["支持",24],["接到",24],["指着",24],["常委",24],["反贪",24],["参加",24],["企业",24],["不行",24],["队长",23],["门前",23],["车祸",23],["现场",23],["汽油",23],["打电话",23],["手下",23],["想起",23],["孩子",23],["学长",23],["头上",23],["大火",23],["只能",23],["区长",23],["利益",23],["内心",23],["代表",23],["不愿",23],["飞机",22],["迟疑",22],["说起",22],["表态",22],["老总",22],["湖畔",22],["时代",22],["拿出",22],["我要",22],["微笑",22],["平静",22],["市局",22],["小心",22],["对不起",22],["大门",22],["发出",22],["努力",22],["保证",22],["中心",22],["这场",21],["过桥",21],["老同志",21],["组织部",21],["政法委",21],["情绪",21],["开会",21],["对面",21],["回去",21],["反腐",21],["原则",21],["包括",21],["刘总",21],["人生",21],["院长",20],["赵公子",20],["落实",20],["群访",20],["缓缓",20],["看守所",20],["父亲",20],["放心",20],["摆手",20],["接过",20],["接受",20],["得知",20],["家伙",20],["宝宝",20],["孤鹰",20],["奸商",20],["土地",20],["四处",20],["号楼",20],["只得",20],["办公桌",20],["主任",20]];
var option = {fontSizeFactor: 0.1,
maxFontSize: 50,
minFontSize: 8,
gridSize:0,
fontWeight:600,
fontFamily: "华文黑体",
backgroundColor:'#F4F4EC',
origin:[100,100],
//备注显示框
tooltip: {show:true,
backgroundColor: 'black',
formatter: function(item) {
if(item[1] > 1355) return '';
else return item[0] + '有' + item[1] + '个'}
},
list: data,
color: 'green',
imageShape: 'renmin.png'};
var wc = new Js2WordCloud(document.getElementById('cloud'));
wc.setOption(option);
</script>
</body>
</html>
第五节 三维动态词云
Tagcanvas是一个开源的JSP,提供绘制三维标签云效果。
测试代码[源码:官方]
<html>
<head>
<title>Tagcanvas测试</title>
<script src="tagcanvas.min.js" type="text/javascript"></script>
<script type="text/javascript">
window.onload = function() {
try {
TagCanvas.Start('myCanvas','tags',{
textColour: '#ff0000',
outlineColour: '#ff00ff',
reverse: true,
depth: 0.8,
maxSpeed: 0.05
});
} catch(e) {
document.getElementById('myCanvasContainer').style.display = 'none';
}
};
</script>
</head>
<body>
<h1>基于Tag Canvas的3D标签云</h1>
<div id="myCanvasContainer">
<canvas width="800" height="600" id="myCanvas">
<p>基于Tag Canvas的3D标签云</p>
</canvas>
</div>
<div id="tags">
<ul>
<li><a href="http://xcy.hubu.edu.cn" target="_blank">张三</a></li>
<li><a href="http://xcy.hubu.edu.cn">李四</a></li>
<li><a href="http://xcy.hubu.edu.cn">王五</a></li>
<li><a href="http://xcy.hubu.edu.cn">赵六</a></li>
<li><a href="http://xcy.hubu.edu.cn">钱七</a></li>
<li><a href="http://xcy.hubu.edu.cn">吴八</a></li>
<li><a href="http://xcy.hubu.edu.cn">高九</a></li>
<li><a href="http://xcy.hubu.edu.cn">沙十</a></li>
</div>
</body>
</html>
使用图片替代的办法,获得更加的视角效果。
注意:图片最好是64以上
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>三维标签云</title>
<!--[if lt IE 9]><script type="text/javascript" src="excanvas.js"></script><![endif]-->
<script src="tagcanvas.min.js" type="text/javascript"></script>
<script type="text/javascript">
window.onload = function() {
try {
TagCanvas.Start('myTag','tags',{
textColour: '#63cdff',
outlineColour: '#63cdff',
reverse: true,
depth: 0,
maxSpeed: 0.05
});
} catch(e) {
document.getElementById('myCloudTag').style.display = 'none';
}
};
function changeshape(s) {
var locks = { hcylinder: 'y', vcylinder: 'y', hring: 'x', vring: 'y', sphere: '' };
lock = locks[s] || '';
shape = s;
TagCanvas.initial = (lock == 'x' && [0,0.2]) || (lock == 'y' && [0.2,0]) || [0.2,0.2];
restart();
}
changeshape('vcylinder')
</script>
</head>
<body style="background:#FFF">
<table width=100% border=0 bgcolor="#000">
<tr height=10%>
<td width=6%>
</td>
<td width=88% style=" height:1px;border:0px dotted #185598" %><a href="http://movies.we-yun.com:10010"><img src="logo/yingshisou.png" width=200></a>
</td>
<td width=6%>
</td>
</tr>
<tr height=10% bgcolor="#000" >
<td width=6%>
</td>
<td width=88% align=right style=" height:1px;border:0px dotted #185598" %>
<a href="index.jsp"><img src="star.png" height=50></a>
<a href="indexM.jsp"><img src="movie.png" height=30></a>
<a href="indexTV.jsp"><img src="tv.png" height=30></a>
</td>
<td width=6%>
</td>
</tr>
<tr height=50% bgcolor="#000" >
<td width=6%>
</td>
<td width=88% align=middle style=" height:0px;border:1px dotted #185598" bgcolor="#000" >
<div id="myCloudTag" >
<canvas width="1000" height="700" id="myTag">
<p>?靛奖</p>
</canvas>
</div>
<div id="tags">
<ul>
<li><a href="#">
<img src="001.jpg" width=100>
</a>
</li>
<li><a href="#">
<img src="002.jpg" width=100>
</a>
</li>
<li><a href="#">
<img src="003.jpg" width=100>
</a>
</li>
<li><a href="#">
<img src="004.jpg" width=100>
</a>
</li>
<li><a href="#">
<img src="005.jpg" width=100>
</a>
</li>
<li><a href="#">
<img src="006.jpg" width=100>
</a>
</li>
<li><a href="#">
<img src="007.jpg" width=100>
</a>
</li>
<li><a href="#">
<img src="008.jpg" width=100>
</a>
</li>
<li><a href="#">
<img src="009.jpg" width=100>
</a>
</li>
<li><a href="#">
<img src="010.jpg" width=100>
</a>
</li>
</ul>
</div>
</td>
<td width=6%>
</td>
</tr>
<tr height=10%>
<td width=6%>
</td>
<td width=88% style=" height:1px;border:0px dotted #185598" >
<center>
<hr style=" height:1px;border:none;border-top:1px dotted #185598" width=100%></hr>
<a href="http://movies.we-yun.com"><img src="logo/yss.png" height=60></a>
<a href="http://www.we-yun.com:10010"><img src="logo/gxsou.png" height=52></a>
</center>
</td>
<td width=6%>
</td>
</tr>
</table>
</body>
</html>