《情感分析人工智能如何洞察心理》--玩转文本大数据
网络爬虫与文本数据分析:从数据采集到可视化
一、网络爬虫基础
网络爬虫是模拟浏览器发送网络请求,接收响应,按照一定规则自动抓取互联网信息的程序。主要完成三个任务:
-
爬取网络数据
-
解析网络数据
-
存储网络数据
1.1 爬取网络数据
爬取数据的核心是使用requests库模拟 HTTP 请求,获取网页原始数据。
# 调用request库
import requests
# 网页链接
url = 'https://www.baidu.com'
# 发送请求,获取网页数据
html = requests.get(url)
# 修改编码方式(避免中文乱码)
html.encoding=('utf-8')
# 显示网页数据相应状态,显示获取到的数据
print(html)
print(html.text)
代码解释:
requests.get(url)向百度首页发送 GET 请求,返回包含响应信息的对象;html.encoding='utf-8'指定编码格式,解决中文乱码问题;html打印响应状态(如<Response [200]>表示请求成功),html.text打印网页源码。
1.2 解析网络数据
网页源码是结构化的 HTML,需用Beautiful Soup库解析提取目标数据(依赖lxml解析器,需提前安装:pip install beautifulsoup4 lxml)。
# 调用 bs4库
from bs4 import BeautifulSoup
# 使用爬取的网页数据
data = html.text
# 创造一个BeautifulSoup对象,使用lxml解析器
soup = BeautifulSoup(data,'lxml')
# 寻找class为mnav的数据(百度导航栏链接)
html_text = soup.find_all('a',attrs={'class':'mnav'})
# 展示class为mnav的数据
print(html_text)
代码解释:
BeautifulSoup(data,'lxml')将网页源码转为可解析的对象;find_all('a',attrs={'class':'mnav'})批量查找所有class="mnav"的<a>标签,精准提取目标元素。
1.3 存储网络数据
爬取解析后的数据可通过文件存储(如 TXT),无需手动新建文件,代码会自动创建。
# 简单可以使用文件存储方式,将内容存入自己设置的txt中。
# 无需外部新建,自动创建
fw = open('baidu.txt','w')
# 遍历寻找到的数据,获取其中的文本,存入文档。
for text in html_text:
text = text.get_text() # 获取文本
fw.write(text) # 注意:需放在for循环内,否则仅存储最后一条数据
fw.write('\n')
fw.close()
代码解释:
open('baidu.txt','w')以写入模式打开文件(不存在则创建);text.get_text()提取标签内的纯文本;- 循环写入每条文本并换行,最后关闭文件(避免数据丢失)。
二、文本数据预处理
爬取或本地的文本数据(如《出师表》译文)需先预处理,才能进行后续分析,核心步骤包括分词、去停用词、词性标注。
2.1 文本分词
使用jieba库(需安装:pip install jieba)对文本进行分词,将连续的文本拆分为单个词汇。
# 调用jieba库对每句话进行分词
import jieba
# 以字节方式读取文件中的数据(csb.txt为出师表译文)
content = open("csb.txt",'rb')
# 调用jieba库对每行句子进行分词,并存入列表
seg_1 = [jieba.lcut(con) for con in content]
# 打印列表
print(seg_1)
# 列表中有大量的标点符号和一些没有用的“啊”等语气词
代码解释:
jieba.lcut(con)使用精确模式分词,返回列表;- 分词结果包含标点、语气词等无效词汇,需后续过滤。
2.2 去除停用词
停用词(如 “的”“啊”、标点)无实际语义,需过滤。需自备停用词表(ting.txt),包含所有需去除的词汇。
方式 1:列表过滤
# 去除语气词
# 建立空集合
punctuation = set()
# 遍历停用词文件的每一行,删除字符串头和尾的空白字符,加到列表中
stopwords = [line.strip() for line in open('ting.txt','r',encoding="utf-8").readlines()]
# 集合更新,将要传入的元素拆分,作为个体传入集合中
punctuation.update(stopwords)
# 过滤停用词
mytext = []
# 遍历分词列表的每一行
for sentence in seg_1:
words = []
# 遍历每一行的每一个词
for word in sentence:
# 如果这个词不在列表中
if word not in punctuation:
# 将这个词放到新的文本列表中
words.append(word)
# 将所有的文本列表存入列表
mytext.append(words)
# 打印输出
print(mytext)
方式 2:函数封装(更通用)
import jieba
# 创建停用词list函数
def stopwordslist(filepath):
# 遍历停用词文件的每一行,删除空白字符,加到列表中
stopwordss = [word.strip() for word in open(filepath,'r',encoding='utf-8').readlines()]
return stopwordss
# 建立对句子进行分词并去除停用词的函数
def seg_sentence(sentence):
# 删除字符串头和尾的空白字符进行分词
sentence_seged = jieba.cut(sentence.strip())
# 调用停用词list函数建立停用词词典
stopwords = stopwordslist('ting.txt') # 加载停用词的路径
outstr = "" # 建立空字符串
# 遍历这句话每一个词
for word in sentence_seged:
# 该词正常,存入词典
if word not in stopwords and word != '\t':
outstr += word
outstr += '|' # 用|分隔词汇
return outstr
# 加载要处理的文件的路径
inputs = open('csb.txt','r',encoding='utf-8')
# 加载处理后的文件路径
outputs = open('csb_stop.txt','w',encoding='utf-8')
# 遍历初始文档的每一行,分词并去停用词
for line in inputs:
line_seg = seg_sentence(line) # 返回值是字符串
outputs.write(line_seg) # 写入去停用词后的字符串
outputs.close()
inputs.close()
代码解释:
- 封装函数后可复用,适配不同文本文件;
- 最终将去停用词后的文本存入
csb_stop.txt,词汇间用|分隔,方便后续分析。
2.3 词性标注
使用jieba.posseg对词汇标注词性(如名词 n、动词 v),便于精准分析文本特征。
# 调用jieba库,对每句话进行分词
import jieba
import jieba.posseg as posseg # posseg标注词性
# 输入需要分词和进行词性标注的文档
filename = "csb_stop.txt"
# 打开并阅读文档
with open(filename,encoding='utf-8') as f : mytext = f.read()
# 字符串切片转化为列表
mytext = mytext.split('|')
# 遍历列表每一行
for line in mytext:
seg_str = line
# posseg标注词性,w和tag
seg_lig = jieba.posseg.cut(seg_str)
# 输出标注好的词性
print("".join(["%s /%s" % (w,tag) for w,tag in seg_lig]))
# 词性的意思看词性编码表
代码解释:
jieba.posseg.cut(seg_str)返回包含 “词汇 + 词性” 的迭代器;- 格式化输出
词汇/词性,如 “先帝 /n”“创业 /v”,可结合词性编码表解读(如 n = 名词、v = 动词、adj = 形容词)。
三、文本特征分析
预处理后的数据可进行词频统计、关键词提取,挖掘文本核心信息。
3.1 词频统计
使用collections.Counter统计词汇出现频率,找出文本中高频词汇。
# 调用统计数量的库和jieba库
from collections import Counter
import jieba
# 输入需要进行词频统计的文档名称
filename = "csb_stop.txt"
with open(filename,encoding='utf-8') as f : mytext = f.read()
# 对整篇文章分词并存入列表
mytext = jieba.lcut(mytext)
# 将分词后的列表转为可计数的对象
c = Counter(mytext)
# 遍历频度最高的10个元素
for k,v in c.most_common(10):
# 统计2字以上短语
if len(k) >= 2:
print(k,v)
代码解释:
Counter(mytext)将分词列表转为 “词汇 - 频次” 的键值对;c.most_common(10)获取频次前 10 的词汇,过滤掉单字(仅统计 2 字及以上),更贴合实际分析需求。
3.2 关键词提取
关键词提取是文本分析的核心,常用TF-IDF和TextRank算法,均封装在jieba.analyse中。
3.2.1 TF-IDF 算法
TF-IDF(词频 - 逆文档频率)衡量词汇在文本中的重要性,适用于多文档对比场景。
# TF-IDF算法 统计关键词
import jieba
import jieba.analyse as analyse
# 输入需要进行关键词提取的文档名称,文本字数越多越好
filename = "csb.txt"
# 打开并读取文档
with open(filename,encoding='utf-8') as f : mytext = f.read()
# 使用jieba进行分词,将分好的词存入字符串中
mytext = ' '.join(jieba.cut(mytext))
# TF-IDF选取前三个主题
# topK=3:返回权重最高的前3个关键词;withWeight=False:只返回关键词列表
print("TF-IDF关键词:", " ".join(jieba.analyse.extract_tags(mytext,topK=3,withWeight=False)))
3.2.2 TextRank 算法
TextRank 基于图模型排序,无需外部语料库,适用于单文本关键词提取。
# textrank算法
import jieba
import jieba.analyse as analyse
# 输入需要进行关键词提取的文档名称,文本字数越多越好
filename = "csb.txt"
# 打开并读取文档
with open(filename,encoding='utf-8') as f : mytext = f.read()
# 使用jieba进行分词,将分好的词存入字符串中
mytext = ' '.join(jieba.cut(mytext))
# textrank选取前三个主题
print("TextRank关键词:", " ".join(jieba.analyse.textrank(mytext,topK=3,withWeight=False)))
代码解释:
- TF-IDF 依赖语料库,更适合多文档场景;TextRank 仅依赖当前文本,单文本分析效果更优;
topK=3指定返回前 3 个关键词,可根据需求调整。
四、词云可视化
词云是文本分析的可视化手段,将高频词汇以视觉化形式呈现,更直观易懂(需安装wordcloud:pip install wordcloud)。
4.1 基础词云生成
from wordcloud import WordCloud
import matplotlib
matplotlib.use('TkAgg') # 解决matplotlib后端配置问题(也可设为'Agg'/'Qt5Agg')
import matplotlib.pyplot as plt
import jieba
# 输入需要进行词云化的文档名称(已删除停用词后的文本)
filename = "csb_stop.txt"
# 打开并读取文档内容
with open(filename,encoding='utf-8') as f : mytext = f.read()
# 使用jieba进行分词,将分好的词存入字符串中
mytext = " ".join(jieba.cut(mytext))
# 根据文本字符串生成词云
# 设置字体(避免中文乱码)、宽度、高度、清晰度、背景颜色
wordcloud = WordCloud(font_path="C:/Windows/Fonts/simsun.ttc",width=400,height=200,scale=32,background_color='white').generate(mytext)
# 显示词云
plt.imshow(wordcloud,interpolation='bilinear') # 双线性插值优化显示效果
plt.axis("off") # 隐藏坐标轴
plt.show()
# 保存词云图片
wordcloud.to_file("出师表词云.png")
代码解释:
font_path指定系统字体路径(如宋体simsun.ttc),解决中文乱码;scale=32提升词云清晰度,background_color='white'设置白色背景;plt.imshow()处理图像,plt.show()显示词云,to_file()保存图片。
4.2 自定义形状词云
结合背景图片生成指定形状的词云,视觉效果更丰富。
from wordcloud import WordCloud,STOPWORDS,ImageColorGenerator
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
import jieba
# 输入需要进行词云化的文档名称
filename = "csb_stop.txt"
# 打开并读取文档内容
with open(filename,encoding='utf-8') as f : mytext_wcl = f.read()
# 使用jieba进行分词,将分好的词存入字符串中
mytext_wcl = " ".join(jieba.cut(mytext_wcl))
# 设置背景图片(1.jpg为自定义形状图片)
photo_coloring = plt.imread('1.jpg')
# 生成词云(mask指定背景形状)
wordcloud = WordCloud(font_path="C:/Windows/Fonts/simsun.ttc",width=400,height=200,mask=photo_coloring,scale=32,background_color='white').generate(mytext_wcl)
# 显示词云
plt.imshow(wordcloud,interpolation='bilinear')
plt.axis("off")
plt.show()
# 保存词云图片
wordcloud.to_file("出师表词云(带形状).png")
代码解释:
mask=photo_coloring指定词云形状为背景图片的轮廓;- 需确保背景图片为清晰的轮廓图(如黑色形状 + 白色背景),效果更佳。
五、词袋模型(BOW)
词袋模型是文本特征表示的基础方法,将文本转为数值向量,便于机器学习建模。
5.1 词袋模型概念
词袋模型忽略文本的语序、语法,仅关注词汇的出现与否或出现频率,将文本抽象为 “词汇集合”,核心是构建词汇表并生成文本向量。
5.2 简单词袋模型实现
# 简单词袋模型案例
# 文本分词
import jieba
# 初始文本
content = [
"机器学习带动人工智能飞速地发展。",
"深度学习带动人工智能飞速地发展。",
"机器学习和深度学习带动人工智能飞速地发展。"
]
# 调用jieba库,使用精确模式对每行句子进行分词,并存入列表
seg_1 = [jieba.lcut(con) for con in content]
# 展示分词后的列表
print(seg_1)
# 建立总词典
BOW = [x for item in seg_1 for x in item] # 两层循环,拼接所有词汇
# 使用set函数去重,转换为列表
BOW = list(set(BOW))
# 展示总词典
print(BOW)
# 生成文本向量(仅标记词汇是否出现:1=出现,0=未出现)
bag_of_word2vec = []
# 遍历分词列表的每一个小列表
for sentence in seg_1:
# 在集合词典中出现就是1,没出现就是0
token = [1 if token in sentence else 0 for token in BOW]
# 将每一句的词袋模型向量存入列表
bag_of_word2vec.append(token)
print(bag_of_word2vec)
代码解释:
- 总词典
BOW包含所有文本的唯一词汇; - 文本向量为二进制向量,仅标记词汇是否出现,未考虑出现频率。
5.3 改进版词袋模型(去停用词)
# 改进词汇表(去除停用词)
import jieba
# 初始文本
content = [
"机器学习带动人工智能飞速地发展。",
"深度学习带动人工智能飞速地发展。",
"机器学习和深度学习带动人工智能飞速地发展。"
]
# 分词
seg_1 = [jieba.lcut(con) for con in content]
print(seg_1)
# 去除停用词
punctuation = set()
stopwords = [line.strip() for line in open('ting.txt','r',encoding='utf-8').readlines()]
punctuation.update(stopwords)
tokenized = []
for sentence in seg_1:
words = []
for word in sentence:
if word not in punctuation:
words.append(word)
tokenized.append(words)
print(tokenized)
# 建立去停用词后的总词典
BOW = [x for item in seg_1 for x in item if x not in punctuation]
BOW = list(set(BOW))
print(BOW)
# 生成去停用词后的文本向量
bag_of_word2vec = []
for sentence in tokenized:
token = [1 if token in sentence else 0 for token in BOW]
bag_of_word2vec.append(token)
print(bag_of_word2vec)
代码解释:
- 去除停用词后,词典更精简,向量更贴合文本核心特征。
5.4 基于 sklearn 的词频词袋模型
sklearn的CountVectorizer可自动分词、去停用词,并统计词汇出现频率,生成词频矩阵。
# 词袋模型显示频率(CountVectorizer)
import jieba
from sklearn.feature_extraction.text import CountVectorizer
# 初始文本
ary = [
"机器学习带动人工智能飞速地发展。",
"深度学习带动人工智能飞速地发展。",
"机器学习和深度学习带动人工智能飞速地发展。"
]
corpus = []
# 遍历初始文本列表的每一句话,分词并拼接为字符串
for title in ary:
corpus.append(' '.join(jieba.cut(title)))
# CountVectorizer()对文本数据进行特征值化
vectorizer = CountVectorizer()
# 训练并转换数据
X = vectorizer.fit_transform(corpus)
# 获取词汇表
word = vectorizer.get_feature_names_out()
# 打印词汇表(|分隔)
print('|'.join(word))
# 打印词频矩阵(每行对应一个文本,每列对应一个词汇,值为出现次数)
print(X.toarray())
代码解释:
CountVectorizer自动过滤停用词(默认英文停用词,中文需结合 jieba 分词);- 词频矩阵直观展示每个词汇在各文本中的出现次数,便于后续建模。
5.5 词袋模型的局限性
- 忽略语序和语法:如 “我吃苹果” 和 “苹果吃我” 的词袋向量完全相同,无法体现语义差异;
- 维度灾难:文本词汇量越大,向量维度越高,计算成本增加;
- 未考虑词汇语义:仅关注词汇出现与否 / 频率,无法体现词汇间的关联(如 “机器学习” 和 “深度学习” 的语义相近,但词袋模型视为独立词汇);
- 对稀疏数据敏感:大部分词汇仅出现在少数文本中,向量稀疏,影响建模效果。
六、总结
本文从网络爬虫获取数据入手,完整讲解了文本数据的预处理(分词、去停用词、词性标注)、特征分析(词频统计、关键词提取)、可视化(词云)及词袋模型的实现。这套流程适用于新闻分析、评论挖掘、文学文本分析等场景,是文本数据处理的基础框架。
更多推荐
所有评论(0)