建筑兔零基础自学python记录29|实战词云可视化项目——分人物阵营词云(上)7
我们在上次情感分析的基础上,不分积极消极,按文本中人物的阵营分为3队。可以猜想按照积极消极分类是有现成的feeling可以分析,但人物阵营却是没有现成资料,需要额外给出信息的。
图1
图2
上面两图的文字大小和数量有区别,关键在于调整了下图数据。这些参数都和导入的底图mk有关
(1)整段代码
from wordcloud import (WordCloud, get_single_color_func)
import imageio
import jieba
class SimpleGroupedColorFunc(object):
"""Create a color function object which assigns EXACT colors
to certain words based on the color to words mapping
Parameters
----------
color_to_words : dict(str -> list(str))
A dictionary that maps a color to the list of words.
default_color : str
Color that will be assigned to a word that's not a member
of any value from color_to_words.
"""
def __init__(self, color_to_words, default_color):
self.word_to_color = {word: color
for (color, words) in color_to_words.items()
for word in words}
self.default_color = default_color
def __call__(self, word, **kwargs):
return self.word_to_color.get(word, self.default_color)
class GroupedColorFunc(object):
"""Create a color function object which assigns DIFFERENT SHADES of
specified colors to certain words based on the color to words mapping.
Uses wordcloud.get_single_color_func
Parameters
----------
color_to_words : dict(str -> list(str))
A dictionary that maps a color to the list of words.
default_color : str
Color that will be assigned to a word that's not a member
of any value from color_to_words.
"""
def __init__(self, color_to_words, default_color):
self.color_func_to_words = [
(get_single_color_func(color), set(words))
for (color, words) in color_to_words.items()]
self.default_color_func = get_single_color_func(default_color)
def get_color_func(self, word):
"""Returns a single_color_func associated with the word"""
try:
color_func = next(
color_func for (color_func, words) in self.color_func_to_words
if word in words)
except StopIteration:
color_func = self.default_color_func
return color_func
def __call__(self, word, **kwargs):
return self.get_color_func(word)(word, **kwargs)
mk = imageio.v2.imread("chinamap.jpg")
w = WordCloud(width=1000,
height=700,
background_color='white',
font_path='msyh.ttc',
mask=mk,
scale=15,
max_font_size=60,
max_words=20000,
font_step=1)
f = open('三国演义.txt', encoding='utf-8')
txt = f.read()
txtlist = jieba.lcut(txt)
string = " ".join(txtlist)
w.generate(string)
color_to_words = {
'green': ['刘备', '刘玄德', '孔明', '诸葛孔明', '玄德', '关公', '玄德曰', '孔明曰',
'张飞', '赵云', '后主', '黄忠', '马超', '姜维', '魏延', '孟获',
'关兴', '诸葛亮', '云长', '孟达', '庞统', '廖化', '马岱'],
'red': ['曹操', '司马懿', '夏侯', '荀彧', '郭嘉', '邓艾', '许褚',
'徐晃', '许诸', '曹仁', '司马昭', '庞德', '于禁', '夏侯渊', '曹真', '钟会'],
'purple': ['孙权', '周瑜', '东吴', '孙策', '吕蒙', '陆逊', '鲁肃', '黄盖', '太史慈'],
'pink': ['董卓', '袁术', '袁绍', '吕布', '刘璋', '刘表', '貂蝉']
}
default_color = 'gray'
grouped_color_func = GroupedColorFunc(color_to_words, default_color)
w.recolor(color_func=grouped_color_func)
w.to_file('output13-三国.png')
让我们把代码中没见过的用蓝框圈出来~
具体代码解读:
(2)get_single_color_func为词云中的所有词语分配单一颜色
from wordcloud import (WordCloud, get_single_color_func)
这次从wordcloud里我们导入了WordCloud和get_single_color_func
WordCloud
类是用来生成词云的get_single_color_func
函数用于创建一个颜色函数,为词云中的所有词语分配单一颜色。
我们来看一下这段代码:
class SimpleGroupedColorFunc(object):
"""Create a color function object which assigns EXACT colors
to certain words based on the color to words mapping
Parameters
----------
color_to_words : dict(str -> list(str))
A dictionary that maps a color to the list of words.
default_color : str
Color that will be assigned to a word that's not a member
of any value from color_to_words.
"""
def __init__(self, color_to_words, default_color):
self.word_to_color = {word: color
for (color, words) in color_to_words.items()
for word in words}
self.default_color = default_color
def __call__(self, word, **kwargs):
return self.word_to_color.get(word, self.default_color)
(3)class SimpleGroupedColorFunc(object)
定义了一个映射颜色类
SimpleGroupedColorFunc
类根据颜色到单词的映射关系为特定的单词分配精确的颜色。如果某个单词不在映射关系中,则会为其分配默认颜色。
(4) “class” 定义类
“class” 用于定义类。类是一种用户自定义的数据类型。
#定义一个类的基本语法如下:
class ClassName:
# 类的文档字符串(可选)
"""类的描述信息"""
# 类的属性和方法定义
def __init__(self, 参数列表):
# 构造方法,用于初始化对象的属性
self.属性名 = 参数
def 方法名(self, 参数列表):
# 类的方法定义
pass
ClassName
:类的名称,通常遵循每个单词的首字母大写,其余字母小写。__init__
:称作构造方法,在创建类的实例时会自动调用,用于初始化对象的属性。self
:是一个约定俗成的参数名,代表类的实例本身。
所以我们可以对这段代码的结构进行梳理:
(5)字典dict
(key-value
)键值对
字典(dict
)是一种无序、可变且可哈希的集合数据类型,它以键值对(key-value
)的形式存储数据。
键(Key)在一个字典中,键必须是唯一的。如果在创建字典或更新字典时使用了重复的键,后面的键值对会覆盖前面的。
值(Value)字典的值可以是任意 Python 对象,包括数字、字符串、列表、元组、集合、字典等,甚至可以是自定义的类实例。值不需要是唯一的,不同的键可以对应相同的值。
(6)哈希值Hash Value:对数据计算后得到的一个固定长度的输出值
特点
- 确定性:相同输入相同的值。
- 高效性:过程非常快。
- 固定长度:无论输入数据的长度,输出长度固定。常见16 字节/32 字节的哈希值。
- 雪崩效应:输入的微小变化会导致哈希值发生很大的改变。
- 不可逆性:很难反向推导出原始输入数据。
在 Python 中,可变对象(如列表、字典、集合等)是不可哈希的,因为它们的值可以被修改。只有不可变对象(如整数、浮点数、字符串、元组等)才是可哈希的。
color_to_words : dict(str -> list(str))
color_to_word这里涉及到字典(dict
)的用法,键值对key-value对应:
- 键(key)是字符串(
str
)类型,表示color - 值(value)是字符串列表(
list(str)
)类型,表示words
self.word_to_color = {word: color
for (color, words) in color_to_words.items()
for word in words}
self.word_to_color
通过字典推导式创建的一个新字典,键值对key-value对应:
- 键(key)是word
- 值(value)是color
这里我们可能会疑惑怎么会有两个字典?为了解释清楚我用蓝橙两个框代表了两个字典,可以看到两者就是顺序互换的关系。让我给大家打个比方,我们用英汉字典来代表color_to_word字典,并简记为色词字典。用汉英字典来代表self.word_to_color,
简记为词色字典。比如一个英国人和一个中国人想要聊天,他们手里分别有一本字典。那英国人要让对方理解就要用英汉词典,反之亦然。
我们现在的情景就很类似,给的是绿色代表蜀中阵营,红色代表曹操阵营,紫色代表江东阵营。也就是我们现有了色词字典,但是任务是要把三国演义的文本进行颜色对应,这就要用到词色字典了。所以需要把给出的色词字典用py生成词色字典。这一处理方式是为了简化我们输入的工作量,同时加快结果输出的速度。
有了以上理解后本段代码就可理解为:
我们再来看下一段定义:
class GroupedColorFunc(object):
"""Create a color function object which assigns DIFFERENT SHADES of
specified colors to certain words based on the color to words mapping.
Uses wordcloud.get_single_color_func
Parameters
----------
color_to_words : dict(str -> list(str))
A dictionary that maps a color to the list of words.
default_color : str
Color that will be assigned to a word that's not a member
of any value from color_to_words.
"""
def __init__(self, color_to_words, default_color):
self.color_func_to_words = [
(get_single_color_func(color), set(words))
for (color, words) in color_to_words.items()]
self.default_color_func = get_single_color_func(default_color)
def get_color_func(self, word):
"""Returns a single_color_func associated with the word"""
try:
color_func = next(
color_func for (color_func, words) in self.color_func_to_words
if word in words)
except StopIteration:
color_func = self.default_color_func
return color_func
def __call__(self, word, **kwargs):
return self.get_color_func(word)(word, **kwargs)
从代码上看和刚刚解读的class SimpleGroupedColorFunc很像,但当我们观察生成词云的时候会发现同为蜀中阵营的刘关张虽然都是绿色,却绿的各不相同。如果只有刚刚解读的代码是无法实现这一特点的,所以这段class GroupedColorFunc代码实现的就是在整体色调中再进行颜色区分。
这段定义也很长,本次已经解读了很多内容了。这个我们就下次再解读~大家先尝试运行一下吧~
(7)总结:
- get_single_color_func为词云中的所有词语分配单一颜色
- “class” 定义类
- 字典
dict
(key-value
)键值对 - 哈希值Hash Value:对数据计算后得到的一个固定长度的输出值