前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >常见的文本分析大汇总

常见的文本分析大汇总

作者头像
HsuHeinrich
发布2023-08-10 11:04:04
2910
发布2023-08-10 11:04:04
举报
文章被收录于专栏:HsuHeinrichHsuHeinrich

常见的文本分析大汇总

小P:小H,你平时做数据分析的时候,会考虑文本信息吗 小H:会啊,虽然能力一般,但是一些基础的信息还是会尝试挖掘的 小P:都有哪些信息可以挖掘啊 小H:比如词频、关键词提取、情感分析、主题词提取等等

词频与词云图

代码语言:javascript
复制
# pip install wordcloud
# pip install jieba
代码语言:javascript
复制
# 导入库
import re  # 正则表达式库
import collections  # 词频统计库
import numpy as np  # numpy库
import jieba  # 结巴分词
import wordcloud  # 词云展示库
from PIL import Image  # 图像处理库
import matplotlib.pyplot as plt  # 图像展示库
import jieba.analyse  # 导入关键字提取库
import pandas as pd
  • 词频提取

本文所有数据如果有需要的同学可关注公众号HsuHeinrich,回复【数据挖掘-文本分析】自动获取~

代码语言:javascript
复制
# 读取文本文件
with open('article1.txt', encoding='gbk') as fn:
    string_data = fn.read()  # 使用read方法读取整段文本
代码语言:javascript
复制
# 文本预处理
pattern = re.compile(u'\t|\n|\.|-|一|:|;|\)|\(|\?|"')  # 建立正则表达式匹配模式
string_data = re.sub(pattern, '', string_data)  # 将符合模式的字符串替换掉
代码语言:javascript
复制
# 文本分词
seg_list_exact = jieba.cut(string_data, cut_all=False)  # 精确模式分词[默认模式]
remove_words = ['的', ',', '和', '是', '随着', '对于', ' ', '对', '等', '能',
                '都', '。', '、', '中', '与', '在', '其', '了', '可以',
                '进行', '有', '更', '需要', '提供', '多', '能力', '通过',
                '会', '不同', '一个', '这个', '我们', '将', '并', '同时',
                '看', '如果', '但', '到', '非常', '—', '如何', '包括', '这']  # 自定义停用词
object_list = [i for i in seg_list_exact if i not in remove_words] # 将不在停用词列表中的词添加到列表中
代码语言:javascript
复制
Building prefix dict from the default dictionary ...
Loading model from cache /var/folders/5c/cshbhmfd1bg0zfq_52jlszfh0000gn/T/jieba.cache
Loading model cost 0.649 seconds.
Prefix dict has been built successfully.
代码语言:javascript
复制
# 词频统计
word_counts = collections.Counter(object_list)  # 对分词做词频统计
word_counts_top5 = word_counts.most_common(5)  # 获取前5个频率最高的词
for w, c in word_counts_top5:  # 分别读出每条词和出现从次数
    print(w, c)  # 打印输出
代码语言:javascript
复制
数据 113
分析 48
功能 47
Adobe 45
Analytics 37
  • 将词频转为词云图展示
代码语言:javascript
复制
# 词频展示
mask = np.array(Image.open('wordcloud.jpg'))  # 定义词频背景
wc = wordcloud.WordCloud(
    font_path='/Users/heinrich/opt/anaconda3/lib/python3.8/site-packages/matplotlib/mpl-data/fonts/ttf/SimHei.ttf',  # 设置字体格式,不设置将无法显示中文
    mask=mask,  # 设置背景图
    max_words=200,  # 设置最大显示的词数
    max_font_size=100  # 设置字体最大值
)
wc.generate_from_frequencies(word_counts)  # 从字典生成词云
image_colors = wordcloud.ImageColorGenerator(mask)  # 从背景图建立颜色方案
wc.recolor(color_func=image_colors)  # 将词云颜色设置为背景图方案
plt.figure(figsize=(12,8))
plt.imshow(wc)  # 显示词云
plt.axis('off')  # 关闭坐标轴
plt.show()

output_10_0

关键词提取

代码语言:javascript
复制
# 读取文本数据
with open('article1.txt', encoding='gbk') as fn:
    string_data = fn.read()  # 使用read方法读取整段文本
# 关键字提取
tags_pairs = jieba.analyse.extract_tags(string_data, topK=5, withWeight=True, 
                                        allowPOS=['ns', 'n', 'vn', 'v', 'nr'], withFlag=True)  # 提取指定词性
tags_list = [(i[0].word, i[0].flag, i[1]) for i in tags_pairs] 
tags_pd = pd.DataFrame(tags_list, columns=['word', 'flag', 'weight'])  # 创建数据框
tags_pd

word

flag

weight

0

数据

n

0.313395

1

报表

n

0.163367

2

功能

n

0.150263

3

分析

vn

0.134857

4

用户

n

0.126633

情感分析

  1. snownlp[1]是常见的中文分析包,主要功能包括:中文分词、词性标注、情感分析、文本分类、转换成拼音、繁体转简体、提取文本关键词、提取文本摘要、tf,idf、Tokenization(分割成句子)、文本相似。由于自带电商训练数据,支持快速分析。也提供自己训练语料库
  2. 基于标注好的玻森情感词典来计算情感值
代码语言:javascript
复制
# pip install snownlp
代码语言:javascript
复制
from snownlp import SnowNLP
import pandas as pd
import jieba
代码语言:javascript
复制
# 基于snownlp的情感打分
def get_snownlp_score(text):
    s=SnowNLP(text)
    score=s.sentiments
    return score

# 基于玻森情感词典的情感打分
def get_BosonNLP_score(text):
    df = pd.read_table("BosonNLP_sentiment_score.txt",sep= " ",names=['key','score']) # 加载情感词典
    key = df['key'].values.tolist()
    score = df['score'].values.tolist()
    segs = jieba.lcut(text)  # 分词
    score_list  = [score[key.index(x)] for x in segs if(x in key)]
    return  sum(score_list)  # 计算得分
代码语言:javascript
复制
# 数据读取
comment = pd.read_excel('comment.xlsx')
pattern = re.compile(u'\t|\n|\.|-|一|:|;|\)|\(|\?|"')  # 建立正则表达式匹配模式
comment['content'] = comment['content'].map(lambda x: re.sub(pattern, '', x)) # 将符合模式的字符串替换
comment.tail()

image-20230206153630280

代码语言:javascript
复制
# 情感打分
comment['snownlp_score'] = comment['content'].apply(get_snownlp_score)
comment['BosonNLP_score'] = comment['content'].apply(get_BosonNLP_score)
comment.head()

image-20230206153649995

基于LDA的主题词提取

代码语言:javascript
复制
# pip install gensim
代码语言:javascript
复制
import os
import tarfile
import jieba.posseg as pseg
from bs4 import BeautifulSoup
from gensim import corpora, models
import itertools
import matplotlib.pyplot as plt  # 图像展示库
from matplotlib.font_manager import FontProperties  
  • 自定义函数
代码语言:javascript
复制
# 中文分词
def jieba_cut(text):
    '''
    将输入的文本句子根据词性标注做分词
    :param text: 文本句子,字符串型
    :return: 符合规则的分词结果
    '''
    rule_words = ['z', 'vn', 'v', 't', 'nz', 'nr', 'ns', 'n', 'l', 'i', 'j', 'an','a']
    words = pseg.cut(text)
    seg_list = [word.word for word in words if word.flag in rule_words]
    return seg_list

# 文本预处理
def text_pro(words_list, tfidf_object=None, training=True):
    '''
    gensim主题建模预处理过程,包含分词类别转字典、生成语料库和TF-IDF转换
    :param words_list: 分词列表,列表型
    :param tfidf_object: TF-IDF模型对象,该对象在训练阶段生成
    :param training: 是否训练阶段,用来针对训练和预测两个阶段做预处理
    :return: 如果是训练阶段,返回词典、TF-IDF对象和TF-IDF向量空间数据;如果是预测阶段,返回TF-IDF向量空间数据
    '''
    # 分词列表转字典
    dic = corpora.Dictionary(words_list)  # 将分词列表转换为字典形式
#     print('{:*^60}'.format('token & word mapping review:'))
#     for i, w in list(dic.items())[:5]:  # 循环读出字典前5条的每个key和value,对应的是索引值和分词
#         print('token:%s -- word:%s' % (i, w))
    # 生成语料库
    corpus = [dic.doc2bow(words) for words in words_list]  # 用于存储语料库的列表
#     print('{:*^60}'.format('bag of words review:'))
#     print(corpus[0])
    # TF-IDF转换
    if training:
        tfidf = models.TfidfModel(corpus)  # 建立TF-IDF模型对象
        corpus_tfidf = tfidf[corpus]  # 得到TF-IDF向量稀疏矩阵
#         print('{:*^60}'.format('TF-IDF model review:'))
#         print(list(corpus_tfidf)[0])  # 打印第一条向量
        return dic, corpus_tfidf, tfidf
    else:
        return tfidf_object[corpus]
    
# 全角转半角
def str_convert(content):
    '''
    将内容中的全角字符,包含英文字母、数字键、符号等转换为半角字符
    :param content: 要转换的字符串内容
    :return: 转换后的半角字符串
    '''
    strs = []
    for each_char in content:  # 循环读取每个字符
        code_num = ord(each_char)  # 读取字符的ASCII值或Unicode值
        if code_num == 12288:  # 全角空格直接转换
            code_num = 32
        elif 65281 <= code_num <= 65374:  # 全角字符(除空格)根据关系转化
            code_num -= 65248
        strs.append(chr(code_num))
    return ''.join(strs)

# 解析文件内容
def data_parse(data):
    '''
    从原始文件中解析出文本内容数据
    :param data: 包含代码的原始内容
    :return: 文本中的所有内容,列表型
    '''
    raw_code = BeautifulSoup(data, 'lxml')  # 建立BeautifulSoup对象
    content_code = raw_code.find_all('content')  # 从包含文本的代码块中找到content标签
    content_list = [str_convert(each_content.text) for each_content in content_code if len(each_content) > 0]
    return content_list

# 构造主题数寻优函数
def cos(vector1, vector2):  # 余弦相似度函数
    dot_product = 0.0;  
    normA = 0.0;  
    normB = 0.0;  
    for a,b in zip(vector1, vector2): 
        dot_product += a*b  
        normA += a**2  
        normB += b**2  
    if normA == 0.0 or normB==0.0:  
        return(None)  
    else:  
        return(dot_product / ((normA*normB)**0.5))   

# 主题数寻优
def lda_k(x_corpus, x_dict):  
    
    # 初始化平均余弦相似度
    mean_similarity = []
    mean_similarity.append(1)
    
    # 循环生成主题并计算主题间相似度
    for i in np.arange(2,11):
        lda = models.LdaModel(x_corpus, num_topics=i, id2word=x_dict)  # LDA模型训练
        for j in np.arange(i):
            term = lda.show_topics(num_words=50)
            
        # 提取各主题词
        top_word = []
        for k in np.arange(i):
            top_word.append([''.join(re.findall('"(.*)"',i)) \
                           for i in term[k][1].split('+')])  # 列出所有词
            
        # 构造词频向量
        word = sum(top_word,[])  # 列出所有的词   
        unique_word = set(word)  # 去除重复的词
        
        # 构造主题词列表,行表示主题号,列表示各主题词
        mat = []
        for j in np.arange(i):
            top_w = top_word[j]
            mat.append(tuple([top_w.count(k) for k in unique_word]))  
            
        p = list(itertools.permutations(list(np.arange(i)),2))
        l = len(p)
        top_similarity = [0]
        for w in np.arange(l):
            vector1 = mat[p[w][0]]
            vector2 = mat[p[w][1]]
            top_similarity.append(cos(vector1, vector2))
            
        # 计算平均余弦相似度
        mean_similarity.append(sum(top_similarity)/l)
    return(mean_similarity)
  • 数据探索
代码语言:javascript
复制
# 汇总所有新闻
all_content = []  # 总列表,用于存储所有文件的文本内容
for root, dirs, files in os.walk('./news_data'):  # 分别读取遍历目录下的根目录、子目录和文件列表
    for file in files:  # 读取每个文件
        file_name = os.path.join(root, file)  # 将目录路径与文件名合并为带有完整路径的文件名
        with open(file_name, encoding='utf-8') as f:  # 以只读方式打开文件
            data = f.read()  # 读取文件内容
        all_content.extend(data_parse(data))  # 从文件内容中获取文本并将结果追加到总列表
        
print('新闻数量:%d' % len(all_content))
代码语言:javascript
复制
新闻数量:18374
  • 中文分词
代码语言:javascript
复制
words_list = [list(jieba_cut(each_content)) for each_content in all_content]  # 分词列表,用于存储所有文件的分词结果
  • 模型拟合
代码语言:javascript
复制
# 训练集的文本预处理
dic, corpus_tfidf, tfidf = text_pro(words_list)  
代码语言:javascript
复制
# 主题寻优
# 计算主题平均余弦相似度
news_k = lda_k(corpus_tfidf, dic)

# 绘制主题平均余弦相似度图形
#解决中文显示问题
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False  
font = FontProperties(size=14) # 设置字体大小
plt.figure(figsize=(12,8))
plt.plot(news_k)
plt.title('新闻LDA主题数寻优', fontproperties=font)
plt.show()

output_31_0

代码语言:javascript
复制
# 模型训练
num_topics = 3  # 设置主题个数
lda = models.LdaModel(corpus_tfidf, id2word=dic, num_topics=num_topics)  # 通过LDA进行主题建模
lda.print_topics(num_words=5) # 展示每个主题的5个关键词
代码语言:javascript
复制
[(0, '0.003*"小区" + 0.003*"登录" + 0.002*"编号" + 0.002*"户型" + 0.002*"信息"'),
 (1, '0.002*"比赛" + 0.002*"是" + 0.001*"散布" + 0.001*"民族" + 0.001*"稳定"'),
 (2, '0.001*"过客" + 0.001*"正方" + 0.001*"反方" + 0.001*"牛肉" + 0.001*"失事"')]
  • 预测主题
代码语言:javascript
复制
with open('article1.txt', encoding='gbk') as f:  # 打开新的文本
    text_new = f.read()  # 读取文本数据
text_content = data_parse(data)  # 解析新的文本
words_list_new = jieba_cut(text_new)  # 将文本转换为分词列表
corpus_tfidf_new = text_pro([words_list_new], tfidf_object=tfidf, training=False)  # 新文本数据集的预处理
corpus_lda_new = lda[corpus_tfidf_new]  # 获取新的分词列表(文档)的主题概率分布
print('{:*^60}'.format('topic forecast:'))
print(list(corpus_lda_new))
代码语言:javascript
复制
**********************topic forecast:***********************
[[(0, 0.23170891), (1, 0.73669183), (2, 0.0315993)]]

总结

文本分析的核心是自然语言处理,本文只能说是冰山一角,但是对于日常挖掘有用的文本信息也还OK,但是如果想更深层次的挖掘文本信息,还是需要寻求专业算法工程师的帮助,例如NLP实验室的同学们~

共勉~

参考资料

[1]

snownlp: https://github.com/isnowfy/snownlp

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2023-06-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 HsuHeinrich 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 常见的文本分析大汇总
    • 词频与词云图
      • 关键词提取
        • 情感分析
          • 基于LDA的主题词提取
            • 总结
              • 参考资料
          相关产品与服务
          NLP 服务
          NLP 服务(Natural Language Process,NLP)深度整合了腾讯内部的 NLP 技术,提供多项智能文本处理和文本生成能力,包括词法分析、相似词召回、词相似度、句子相似度、文本润色、句子纠错、文本补全、句子生成等。满足各行业的文本智能需求。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档