一. 网页抓取
对于同学的创作进行文本处理首先需要通过爬虫技术得到TXT文本。
首先从链接里复制所有人的链接如下:
观察链接,发现一个比较麻烦的事情:每个人用的网站不尽相同,因此也增大了爬虫的难度。但大部分人用的是CSDN博客,小部分人使用简书与石墨文档。
对网页使用比例统计如下:
因此首先研究CSDN网页爬取
csdn中目标内容如下:
其路径级别分别是:
[图片上传失败...(image-f40fa-1578630736864)]
初始爬下来的结果如下:
很麻烦,最开始是动态网页,很难找到它的具体工作方法,虽然花花时间也能找到。
但没有时间了,而且我们的目标不是网页爬取。综合考虑:观察规律,调程序要用的时间还不如复制粘贴,复制CSDN文章用时不过30分钟,于是CSDN的文章都来自复制粘贴
简书网站也同样,最初形式是动态网页,初步获取结果是JSON文件,没有有用信息。于是简书的内容也都是复制粘贴。
比较友好的是石墨文档了,虽然数量较少,爬虫并不能节省很多时间,但我还是做了尝试,初步结果如下:
![](https://img.haomeiwen.com/i13925828/5f1f3ff32472122b.png)
代码如下:
import requests from bs4 import BeautifulSoup import re def getHTMLText(url): try:
r = requests.get(url, timeout=30)
r.raise_for_status() # 如果状态码不是200,产生异常 r.encoding = 'utf-8' # 字符编码格式改成 utf-8 return r.text except: # 异常处理 return " error " def findHTMLText(text):
soup = BeautifulSoup(text, "html.parser") # 返回BeautifulSoup对象 return soup.find_all(string=re.compile('article')) # 结合正则表达式,实现字符串片段匹配 url = "https://blog.csdn.net/feit2417/article/details/85925586" text = getHTMLText(url) # 获取html文本内容 res = findHTMLText(text) # 匹配结果 print(res) # 打印输出
最终结果如txts文件夹所示,爬取130份作品。这里要对数量说明的是:
-
抓取时间较早,十二文艺拓展的作品上传的不是很多。
-
在浏览信息时也发现一些同学由于上传的是图片,整体信息量很少,或者有得干脆没有文字,只有图片,这个对于文本分析这一项不是很友好。所以没有抓取。
-
对于小众网站,如微博,B站,有一些采取手动复制粘贴,一部分如B站不能进行网页复制的就放弃了,但放弃的数量并不多,并不影响结果。
某位同学的作品展示,由于一些原因,不是很想将作品与人一一对应,感觉不太好。
![](https://img.haomeiwen.com/i13925828/4c0a28c6f7dca04a.png)
二. 语料处理
如博客https://www.jianshu.com/p/b87e01374a65中所言,对于获取到的文本信息,进行数据预处理是比较重要的一项工作,对此,我根据NLP库所支持的功能以及本次统计的目标,做出基本数据处理如下:
1. 语料清洗
对于爬取的网页信息,删除一些冗余的广告,标识符,文字等是比较重要的一步,这些多余的文字会对文本分析产生噪声影响。但爬虫技术本身就简省了很多冗余的信息,它仅仅挑选出文本内容,问题反而是由于缺少了标题,一些重要的信息被隐去,标题对于文本内容有很大的指导性。所幸,链接里部分人给出了标题,减轻一些工作。
第二个问题就是由于图片的爬取带来的多余空格,多余标记,CSDN的复制粘贴会自动有一些话,图片会带来较多的空格等问题
![](https://img.haomeiwen.com/i13925828/7b3bd3b3dc914c1c.png)
代码如下:(sortTxt.py)
<pre style="text-indent:18.0pt;background:#2B2B2B">if __name__=="__main__":
sourcePath="C:\\Users\\spark\\Desktop\\新建文件夹/" sinkPath="C:\\Users\\spark\\Desktop\\新建文件夹/txts/" file=open(sourcePath+"ex.txt","r",encoding='utf-8')
fileIndex=110 content="" while 1:
line=file.readline() if not line:break
if line=="pp\n":
file_w=open(sinkPath+str(fileIndex)+".txt","w",encoding='utf-8')
file_w.write(content)
file_w.close()
content="" fileIndex+=1 else: if line=="\n": continue
if line.find("版权声明")!= -1: continue
if line.find("原文链接")!= -1:
continue content+=line
file.close()</pre>
2. 词性标注
文本分析中,一些连接词,,语气助词等没有什么意义:如“的”,“了”等,但会出现很多次,并且一些名词,动词包含了重要信息:名词表现了文本内容的对象,而动词则会体现一些情感倾向。除此之外,博客中也提到,虽然对于简单的NLP库处理,词性标注的作用并不多,但是在人工智能中用于知识表示与推理,词性标注与总结则会很有用。因此我做了初步尝试如下:
![](https://img.haomeiwen.com/i13925828/68522f2a73b89f1b.png)
对于相同的此行进行归类,形成词汇库,结果如文件夹Paticiple所示。
如下图:总结了量词,连词,名词,动词,副词,标点还有一些TAG不是很能看懂,但由于跟本次实验目标无关,因此不做深究。
![](https://img.haomeiwen.com/i13925828/e38b174c5137327c.png)
代码如下:
<pre style="margin-bottom:12.0pt;text-indent:18.0pt;background:#2B2B2B">from snownlp import SnowNLP import os def FindLoc(labels,tag): for i in range(len(labels)): if labels[i]==tag: return i return len(labels) if __name__=="__main__":
sourcePath="C:\\Users\\spark\\Desktop\\新建文件夹/txts/" sinkPath="C:\\Users\\spark\\Desktop\\新建文件夹\\processing\\Pariciple/" for roots, dirs, files in os.walk(sourcePath):#获取结点 for filename in files:
file=open(sourcePath+filename,'r',encoding="utf-8")
content = file.read()
content = SnowNLP(content)
tags = [x for x in content.tags]
lists = []
label = [] for tag in tags:
loc = FindLoc(label, tag[1]) if loc == len(label):
label.append(tag[1])
lists.append([])
lists[loc].append(tag[0])
file_w=open(sinkPath+filename,'w',encoding="utf-8") for i in range(len(lists)):
file_w.write(label[i])
file_w.write(": ") for each in lists[i]:
file_w.write(each)
file_w.write(" ")
file_w.write("\n")
file_w.close()
file.close()</pre>
3. 断句
断句同样有助于对文本内容的整理,虽然中文的竹式结构断句的作用不是很大,但是对于英语,断句能够清晰有力的摘取到一个句子的主谓宾,有利于对句意的了解与分析。而且,对于基于全文的词汇统计与情感分析与基于句子的分析效果是不一样的,一段话可能欲扬先抑,因此会出现某些句子的情感倾向于负面,某些倾向于正面。
断句阶段里,对每一个同学的文本进行断句分析,并将结果写入Sentence文件夹中,在后面的情感分析和信息量统计中将会用到。
![](https://img.haomeiwen.com/i13925828/9392eb908616dd59.png)
代码如下:(3_sentence.py)
<pre style="text-indent:18.0pt;background:#2B2B2B">from snownlp import SnowNLP import os def FindLoc(labels,tag): for i in range(len(labels)): if labels[i]==tag: return i return len(labels) if __name__=="__main__":
sourcePath="C:\\Users\\spark\\Desktop\\新建文件夹/txts/" sinkPath="C:\\Users\\spark\\Desktop\\新建文件夹\\processing\\sentences/" for roots, dirs, files in os.walk(sourcePath):#获取结点 for filename in files:
file=open(sourcePath+filename,'r',encoding="utf-8")
content = file.read()
content = SnowNLP(content)
sentences=content.sentences # sentences=SnowNLP(sentences)
# print(sentences.tf)
# print(sentences.idf) file_w = open(sinkPath + filename, 'w', encoding="utf-8") for each in sentences:
file_w.write(each)
file_w.write("\n")
file_w.close()
file.close()</pre>
4. 信息量统计
同样有一点值得好奇的是:大家的作业含金量如何?
并且,主观评价又与机器评价的差距在哪里?
因此,信息评价也是很有趣的一部分。博文中有用到IDF与TF评价标准。前者是统计词汇出现的频率,而后者则表示文档中词汇的重要性。
下面是做的基于断句的IDF TF检验:
![](https://img.haomeiwen.com/i13925828/f1b8226da99551ab.png)
效果并不是想象中那样。原因是基于断句的数量统计,对象是断句,其实、应该在断句基础上再次分词,使得整个文本根据断句形成一条一条的内容,每一条内容中有词汇。
作出改动后效果如下:
基于断句的分词:
![](https://img.haomeiwen.com/i13925828/5d423c3f5990b15c.png)
结果:idf.txt
![](https://img.haomeiwen.com/i13925828/bd0108546a58fe43.png)
代码如下:
<pre style="margin-bottom:12.0pt;text-indent:18.0pt;background:#2B2B2B">from snownlp import SnowNLP import os import numpy as np def FindLoc(labels,tag): for i in range(len(labels)): if labels[i]==tag: return i return len(labels) if __name__=="__main__":
sourcePath="C:\\Users\\spark\\Desktop\\新建文件夹/processing/sentences/" sinkPath="C:\\Users\\spark\\Desktop\\新建文件夹\\processing\\TFIDF/" file_w = open(sinkPath + "idfs.txt", 'w', encoding="utf-8") for roots, dirs, files in os.walk(sourcePath):#获取结点 for filename in files:
file=open(sourcePath+filename,'r',encoding="utf-8")
content=[] while 1:
line=file.readline() if not line:break line=SnowNLP(line)
content.append(line.words)
content = SnowNLP(content)
tf=content.tf
idf=content.idf
res=sorted(idf.items(),key=lambda d:d[1],reverse=True)
v=list(idf.values())
meanValue=np.mean(v)
file_w.write(str(meanValue))
file_w.write("\t") for each in res: if each[1]>meanValue:
file_w.write(each[0])
file_w.write("\n")
file.close()
file_w.close() </pre>
5. 情感分析
NLP库中有趣的还有情感分析功能,博文中也提到根据词汇库可以自己判断情感倾向。因此,设想同学创作作品进行情感分析,尤其可以根据十二个一的情感倾向统计,从而获得人们对于十二个一的大致整体印象。这会很有趣。
但结果是这样的:(sentiments.txt)
![](https://img.haomeiwen.com/i13925828/e264ecefab0a6e5f.png)
这样精确的1.0总让人怀疑是不是出错了,然而对比例子与自己的方法,并没有什么BUG,
我试图给自己结论如下:
1. 调库的函数本来就不是十分精确
2. 对于十二个一,作业中的情感倾向本来就比较模糊,偏向正面。
代码如sentiments.py所示
6. 摘要
摘要就很有意思了,对于大量文本的摘要有利于信息提炼,形成词云也很不错嘛
结果如下:sammary.txt
要说明一下的是摘要,情感判断与信息量统计是以一个人为单位统计所有人的结果。
![](https://img.haomeiwen.com/i13925828/1ea74b33dd7f7a03.png)
代码如下:points.py
<pre style="margin-bottom:12.0pt;text-indent:18.0pt;background:#2B2B2B">from snownlp import SnowNLP import os def FindLoc(labels,tag): for i in range(len(labels)): if labels[i]==tag: return i return len(labels) if __name__=="__main__":
sourcePath="C:\\Users\\spark\\Desktop\\新建文件夹/txts/" sinkPath="C:\\Users\\spark\\Desktop\\新建文件夹\\processing\\" file_w = open(sinkPath + "summery.txt", 'w', encoding="utf-8") for roots, dirs, files in os.walk(sourcePath):#获取结点 for filename in files:
file=open(sourcePath+filename,'r',encoding="utf-8")
content = file.read()
content = SnowNLP(content)
summary=content.summary(limit=3) for each in summary:
file_w.write(each)
file_w.write("\n")
file.close()
file_w.close()</pre>
7.生成词云
词云的制作往往能有效,直观得展现文本的重要信息
对所有人的摘要进行词云可视化:
![](https://img.haomeiwen.com/i13925828/e3b59df1db4fc869.png)
有用的关键词有“喜欢”,“不会”,“团队”等,反映了同学对十二个一创作内容多用团队,有情感倾向。但同时也有很多繁杂的信息,因此对部分单个人的作品做出慈词云分析如下:
1.txt 关键词:杀手,任务 2.txt 关键词:魔法,人类
![](https://img.haomeiwen.com/i13925828/af92ba967d9a55a0.png)
![](https://img.haomeiwen.com/i13925828/a2b265c7d9de5f34.png)
三. 结果分析
信息量可视化:
![](https://img.haomeiwen.com/i13925828/943e289f4b0663c7.png)
情感判断可视化:
![](https://img.haomeiwen.com/i13925828/f6725fc9757bc3de.png)
词云:
![](https://img.haomeiwen.com/i13925828/bec0f00da3422906.png)
总结:
总结这次实验效果并没有达到理想中对十二个一进行分析,原因有二:
- 题目很杂,十二个一的标定很不清楚。因为题目也同时设置了大五人格测试,角色幻想(4个)以及12个一,因此很难拿对应是那个题目,即使题目又单拎出来,但也不容易分类,而且对于十二个一大家的编号又不尽相同,顺序不一,难以归类。除非人工去做,靠机器就得判断图像,判断语义,这个难度与工作量过高。
NLP库的效果也不是十分好
网友评论