基于NLP对书法字体进行分析、统计、可视化
选题3:
对十二个“一”的文艺创作作业进行文本分析、统计和可视化
任务主题:
对全体同学的文艺创作进行文本分析、统计和数据可视化
任务要求:
整理大家的作业数据,运用NLP技术(自然语言处理)对其进行分析,完成一篇图文结合的分析报告,特别是要分别对十二个“一”有关的文本分别进行统计。
实验步骤综合概况:
- python SnowNLP库配置
- python SnowNLP库学习
- 整理文本数据
- 批量导入处理数据
- 统计关键信息
- 数据分析
- 数据可视化
实验步骤具体呈现:
1.python SnowNLP库配置
SnowNLP的配置比较简单,可以去官网下载对应版本的whl文件也可以直接在cmd窗口直接:
pip3 install SnowNLP
2.python SnowNLP库学习
SnowNLP库封装性已经很不错了,调用起来也非常方便。在文本分析上,SnowNLP库可以对文本进行分词、词性标注、断句、情绪判断、拼音、繁体转简体、关键词提取等等功能。根据本次实验需要,我们只涉及到了词性标注、情绪判断、关键词提取、结论概况这几个接口的功能,对各个接口的用法可以参考老师发的传送门:SnowNLP快速入门
3.整理文本数据
这一步骤是整个实验工作量最大部分,即便看上去技术含量是如此的低。我也尝试用爬虫爬取各位同学的信息,但是发现同学发表博文的平台不同,网页的结构也差别较大。另外又因为是针对指定字体进行文本统计的,同学在撰写博文的时候格式花里胡哨,顺序也各色各样,利用爬虫简化工作量的就失败了。
于是花了一个上午,人工搬砖把链接里数技1701和数技1702每个同学的文本进行了统计整理。文本统计过程中主要发现了以下几个问题:
1.博客是图片格式而非文字文本。
2.没有一一分析十二个一的特点,而是杂糅在一起写了一个故事。
3.字体没有按照顺序排列或者是字体没有给出相应的标号。
在过滤完上述问题文本以后,两个班一共有效的博文约为35篇。我将统计的12个“一”的文本放入12个txt文件中方便进一步编程批处理:
4.批量导入处理数据
统计好了文本数据,只需要将每个文本传入库的接口中进行处理即可,下面给出批量导入文本的代码:
TrainFiles = os.listdir("G:\\ArtTechnique\\")
for eachfile in TrainFiles:
path = "G:\\ArtTechnique\\" + eachfile
Font_file = open(path, encoding="utf-8")
print(eachfile)
try:
Font_description = Font_file.read()
finally:
Font_file.close()
5.统计关键信息
考虑到实验需要,我通过SnowNLP一共统计了以下几类关键信息:
1.文本频繁词(分为动词、形容词、名词)
2.文本关键词
3.文本情感系数
4.文本结论概括
代码中对四个类别关键信息的统计分别对应四个函数接口:
''' **********************频繁词统计********************'''
def freStatic(Font):...
''' **********************关键词统计********************'''
def KeywordsStatic(Font):...
''' **********************情感分析********************'''
def Sentiments(Font):...
''' **********************结论概况********************'''
def Summary(Font):...
SnowNLP库中没有对频繁词统计功能的单独接口,所以为了实现频繁词统计,我先利用库中的词性划分功能将文本根据词性分类,然后对每一种类别的词性进行数量统计:
dict_adj = {} # 形容词字典
dict_v = {} # 动词字典
dict_n = {} # 名词字典
s = SnowNLP(Font)
for x in s.tags:
if (x[-1] == 'a'):#如果标签为形容词
if (x[0] in dict_adj):
dict_adj[x[0]] = dict_adj[x[0]] + 1
else:
dict_adj[x[0]] = 1
if (x[-1] == 'v' or x[-1] == 'vn'):#如果标签为动词、动名词
if (x[0] in dict_v):
dict_v[x[0]] = dict_v[x[0]] + 1
else:
dict_v[x[0]] = 1
if (x[-1] == 'n'):#如果标签为名词
if (x[0] in dict_n):
dict_n[x[0]] = dict_n[x[0]] + 1
else:
dict_n[x[0]] = 1
这儿主要是利用了字典的数据结构,让每个词作为key都有一个对应数量的value。关于其他信息的统计,只需直接调用库函数即可:
s.keywords(limit=10)#关键词
s.sentiments#情感系数
s.summary(limit=5)#结论概况
不过,在最后得到的统计中发现:十二个“一”的情感系数皆为1(0->1正向情感逐步增加)。于是我对库在文本情感分析的可靠性上产生了怀疑,又补充进行了一些单独文本的测试,结果发现SnowNLP是可以区分例如“不好,不负责责任,还需要努力”这样偏负面情感的词。对于在文本概况上有出现偏负向情感词,比如第二个“一”:
序号为2的“一”在文本概况中我们发现负向情感的评价偏多,所以我对该字体原始文本进行了观察:
由于同学将这十二个一看作不同的对象,有动漫角色、公司职员、面试者、追求者、兵器、坦克、水果、植物等等,这就导致了同一字体在情感的褒贬表达上有了比较大的偏差。如果将字体看作现实中的人,那么褒贬情感表达上就比较明显;如果将字体看作植物、兵器等等,那么在情感表达上不明显的,而且是偏褒义词的。在统计时发现,更多同学是将其比作神化的人物、动植物等等,这也就导致了所有字体的情感系数都偏高。但是我认为即便情感系数都为1,这个数值对于该实验文本分析依旧是有参考价值的。
6.数据分析与数据可视化
由于数据分析最好能和图表等可视乎信息结合起来,所以在具体展示的时候我将这两块内容合并到了一起。
分析对象:
分析对象的28维感受归一化数据表:
1号(A):
关于1号在文本分析中动词和名词提到的信息并没有什么价值,结合形容词、关键词、情感系数、文本概况我们发现1号总体给人在感受表现上是正面的,程度上是中上的并没有特别突出的特征。结合28维数据来看,1号总体的属性是偏正向的,而且是出于中上程度的,两个分析数据得出的结论是比较符合的。
2号(B):
从NLP文本分析结果上看,2号在形象上比较明显特征是高,瘦的;其总体给人带来的感受还是偏中性的。从28维数据看,这种文本上提取出的特征高、瘦便可以与其在弹性、锐利度、酸上数值较高的结果相对应。总体看2号的其他属性还是都偏向于中向的。
3号(C):
从NLP文本分析结果上看,3号在形象上比较明显特征是给人亲近和信任感的正面形象;其总体给人带来的感受还是偏积极的。从28维数据看,与其在责任心、宜人性的数值较高的结果相对应。其他属性也都偏向中性
4号(D):
从NLP文本分析结果上看,频繁词中出现了“哥哥”(难得名词词性起到了概况的作用啊),结合文本概况的特点和形容词特征,4号在形象上能给人足够的安全感,是积极的形象;从28维数据看,4号在责任心、硬度、密度上得分极高,在神经质上得分极低这与NLP的分析结果一致。
5号(E):
从NLP文本分析结果上看,频繁词身材、力量、强、有力,以及文本概况上5号都给人整体的感受是强健有力的;从28维数据看,5号在责任心、阻力、粗糙度、密度、韧性、硬度、重量、浑厚、苦的得分上都较高,与NLP分析结果类似。
6号(F):
从NLP文本分析结果上看,6号给人整体的形象上是一个优秀的团队合作者,一个值得信赖的伙伴,灵活度不高,其他的特征较为模糊;从28维数据看,6号在责任心、硬度上得分较高,结果相似
7号(G):
从NLP文本分析结果上看,7号的提取的特征是高、强的,可能有一些神经质其他特征的表述比较模糊;从28维数据看,7号是极为神经质的,责任心也极低。其在清脆、音高上值也较大这些比较吻合。
8号(H):
从NLP文本分析结果上看,8号受到同学们的喜爱,其形象也较为稳健,健康;从28维数据看,8号在责任心、宜人性上得分高,在神经质得分低,结果较为相似;
9号(I):
从NLP文本分析结果上看,9号形象是高大的,不过性格上更为活跃;从28维数据看,8号在开放性、外倾性、神经质、速度的得分上较高,在责任心上得分较低与NLP结果较为相似。不过从分析上看对于8号的分析,NLP显然做的不够好。
10号(J):
从NLP文本分析结果上看,10号的形象较为与众不同;从28维数据看,10号在责任心、力量、硬度、苦上得分都较高。两者结果关联度较低。
11号(K):
从NLP文本分析结果上看,11号较受人喜爱,形象上有着负责的特征;从28维数据看,11号在责任心、宜人性、甜度上得分都较高。两者结果关联度较高。
12号(L):
从NLP文本分析结果上看,12号有较高的特征,但是其他特征上都比较模糊;从28维数据看,12号宜人度、密度、粘稠度、湿润度、温度、甜度上得分都较低,在清脆、音高上、速度上得分较高。两者关联性不大。
以上便是在结合了NLP文本分析和28维数据的基础上对12个一进行的分析。(敲的手都要断了…)
十二个一的数据整体分析:
以部分的眼光看完问题以后,我们也可以尝试使用整体的眼光看待问题。接下来,我将12个字体的文本整理到了一起,对这12个样本整体进行NLP分析,详细统计了其中出现次数频繁的形容词、动词、名词,并将数据通过可视化处理,整理结果如下:
以上是统计出的各类词性中不同词在总文本中出现的次数和在总词频前9名中其次数所占比例。以下给出三种词性情况的柱状统计图:
从整体性上分析:
在分析整体文本数据的时候,我认为更加有分析价值的部分还是词频角度。对词频的分析实质上就是对测试者对这十二个一描述上总体特征的一个提炼概括,对于高频部分的用词即直接或间接地表现了同学们看待十二个一的出发角度、聚集的领域以及十二个一给人带来的直观印象、展开方向。
从形容词统计上看,同学们对一的描述集中在对其外观特征的剖析上,例如“高”、“大”、”小“、”可爱“等等用词都是对一的外观特征中长度、粗细、风格的一种描述。
从动词统计上看,同学们在像“是”、”会“一类谓词上使用的比较频繁。其实对于这类谓词多半分析的时候是会过滤处理的,不过我觉得该部分数据内容也具有一定的价值:结合具体文本数据,我们发现,大家对于十二个一多给予一种比较直接的评价,例如:”它看上去是一个觉悟最高,最雄的男人“,一般都是以A字体是一种怎么样的角色、A字体是怎么样的、A字体会给人怎么样的感觉、A字体像一个怎么样的人/物的语句,站在以自己为中心的视角对字体进行描述表达其特征,那么我们得到的评价感知也大多是从测试者角度的较为直观的评价,数据的参考价值得到了肯定。
从名词统计上看,”人“一词出现的频率最高,从文本中具体查看相关语句后我们发现,大多数同学更愿意将十二个一作为一个拥有具体形象的人物去描述其特征;另外”能力“”性格“等词的频繁出现可以看出,同学们将字体人格化以后不仅会从外观上描述也会从进一步联想到字体所具有的性格、能力上去描述。其中,我们又可以发现,”团队“”公司“”员工“三个词义上具有比较强关联的词同时上榜了。当然,这一原因和律大在布置作业时给出的可选择方向有一定关系,不过在许多方向描述一特征上,更多数的同学选择以团队的方式去描述。我认为这一方面可以看出这十二个一给人的直观感受上是可以作为一个社团聚类到一起的,也即他们给人的直观差异上并不大,这一方面和测试者的所接触的领域有关(大部分学生对于书法并不熟悉,不能很好感知到差别),另一方面也和字体本身书写呈现上相关(比如字体都是黑色的,底色都是白色的,书写的都是一)。
部分字体的可视化词云图:
在文本分析时我对频繁词进行了统计,这些统计的频繁词还可以作为词云来展示达到不错的可视化的效果。词云的生成可以通过python的WordCloud库进行:
def wordsCloud(Font):
dict_adj = "" # 形容词
s = SnowNLP(Font)
for x in s.tags:
if (x[-1] == 'a'):
dict_adj += x[0] +" "
mask = np.array(image.open("G:\\ART\\ALICE.jpg"))
wordcloud = WordCloud(font_path="G:\\ART\\haixiang.ttf",
mask=mask
).generate(dict_adj)
image_produce = wordcloud.to_image()
image_produce.show()
代码的逻辑大致为:将找到的文本中的形容词加入到一个大字符串中;为了增强艺术效果可以为词云设置蒙版,通过numpy库将将对应的图像传入,那么词云就会按照图片的轮廓生成了。当然为了更加美观,还可以应用下载的tff字体。下面就对部分“一的”形容词生成的词云进行一个展示: