当前位置: 首页 > news >正文

金融数据分析(Python)个人学习笔记(13):自然语言处理

一、导入库和函数

pip install wordcloud
pip install  -i https://pypi.tuna.tsinghua.edu.cn/simple jieba
pip install gensim
import pandas as pd
import numpy as np
import jieba

二、载入新闻数据

sinanews = pd.read_csv('my_sinanews2.csv',encoding='gbk')
sinanews

结果:
在这里插入图片描述
新闻标题

myTitle = sinanews.Title[16]
myTitle

结果:

'分析人士:我国宏观政策有空间和余力 各项货币政策会继续落地'

新闻正文

myArticle = sinanews.Article[6]
myArticle

结果:
在这里插入图片描述

三、利用jieba库 分词

分词:把文本切分为词
英文文本:NLTK库
中文文本:Jieba、Ansj、HanLP、盘古分词
jieba库分词函数:cut、 cut_for_search
中文分词技术:
基于规则或字典、n-gram模型、隐马尔可夫模型(HMM)、条件随机场等

(二)三种模式

data = jieba.cut(myTitle, cut_all = True) # 寻找所有可能的词
print("全模式:", '/' .join(data)) # 将分词结果用斜杠 / 连接成一个字符串
data = jieba.cut(myTitle, cut_all = False) # 默认,将句子拆分,不包含重复内容
print("\n精准模式:", '/' .join(data))
data = jieba.cut_for_search(myTitle) # 在精准模式的基础上,再对长词进行切分
print("\n搜索模式:", '/' .join(data))

结果:

全模式: 分析/人士//我国/宏观/宏观政策/观政/政策/有空/空间//余力// //各项/货币/货币政策/政策//继续/落地精准模式: 分析/人士//我国/宏观政策//空间//余力/ /各项/货币政策//继续/落地搜索模式: 分析/人士//我国/宏观/观政/政策/宏观政策//空间//余力/ /各项/货币/政策/货币政策//继续/落地

(二)输出为 list

data = jieba.cut(myTitle)
print(data) # 输出生成器对象的信息
data = jieba.lcut(myTitle) # 返回一个包含分词结果的列表
print('\n','/' .join(data))

结果:

<generator object Tokenizer.cut at 0x00000231AD5A3E20>分析/人士//我国/宏观政策//空间//余力/ /各项/货币政策//继续/落地

(三)并行分词

不支持 Windows 系统,适用于linux系统
并行分词可以利用多核 CPU 的优势,加快大规模文本的分词速度。

# 开启并行分词模式,参数为并发执行的进程数
jieba.enable_parallel(5)# 关闭并行分词模式
jieba.disable_parallel()

(四)词典操作

进行分词时,建立词典,保证关注的词包含在词典中

1. 添加词典

仅对本次运行有效,不会改变jieba库中的词典

jieba.add_word('分析人士') 
'''
或 jieba.suggest_freq('房地产市场', tune = True)
suggest_freq函数可用于调整某个词汇的词频
tune = True:调整该词汇的词频,从而将对象作为一个整体进行切分
'''
data = jieba.lcut(myTitle)
print('/' .join(data))

添加’分析人士’之后,当使用 jieba 进行分词时,如果遇到这个词汇,就会将其作为一个整体进行切分,而不会拆分成其他词语。
结果:

分析人士//我国/宏观政策//空间//余力/ /各项/货币政策//继续/落地

2. 删除词典

jieba.del_word('分析人士')
data = jieba.lcut(myTitle)
print('/' .join(data))

结果:

分析/人士//我国/宏观政策//空间//余力/ /各项/货币政策//继续/落地

3. 加载自定义字典

jieba.load_userdict('user_dict.txt')

自定义词典文件是一个纯文本文件,每行为一个词汇以及相应的词频和词性(词频和词性为可选项)

4. 词性标注

import jieba.posseg as psg
for w,t in psg.lcut(myTitle):print(w,'/',t)

jieba.posseg模块对myTitle进行分词并标注词性,然后逐词打印出词语及其词性
结果:

分析 / vn
人士 / n
: / x
我国 / r
宏观政策 / n
有 / v
空间 / n
和 / c
余力 / n/ x
各项 / r
货币政策 / n
会 / v
继续 / v
落地 / n

5. 词频统计

import jieba 
from collections import Counter
# Counter:对可哈希对象(如字符串、列表、元组等)进行计数统计def get_words(txt):seg_list=jieba.cut(txt) #对文本进行分词,返回生成器c=Counter() # 创建一个counter对象
# 进行词频统计for x in seg_list: # 遍历每个词if len(x)>1 and x != '\r\n':
# 去除长度为1的词(如标点、语气词等)以及换行符c[x] += 1
'''
将词语x的出现次数加 1。
如果词语x是第一次出现,Counter对象会自动将其初始计数设为1;
若已经出现过,则在原有计数基础上加 1。
'''print('常用词频度统计结果')for (k,v) in c.most_common(20): 
'''
返回Counter对象中出现频率最高的前20个词语及其对应的词频
返回的是一个包含元组的列表,每个元组的第一个元素是词语,第二个元素是该词语的出现次数
'''print('%s%s %s %d' % (' '*(5-len(k)), k, '*'*int(v/2), v))
'''
' '*(5-len(k)):在词语前面添加一定数量的空格
'*' * int(v / 2):根据词频生成相应数量的星号
'''get_words(myArticle)

结果:

常用词频度统计结果货币政策 *********** 22
中国人民银行 ********* 19中国 ********* 19经济 ****** 12可以 ***** 11市场 ***** 11余永定 ***** 10增长 ***** 10影响 ***** 10人民币 ***** 10利率 ***** 10目标 ***** 10理解 **** 9政策 **** 9增速 **** 9财政政策 **** 8如何 **** 8变化 **** 8可能 **** 8压力 *** 7

6. 关键词提取

jieba.analyse 模块提供了关键词提取的功能
TF-IDF(词频 - 逆文档频率)算法,其他文本中出现越少、该本文中出现越多,权值越大

import jieba.analyse as analyseprint(" ".join(analyse.extract_tags(myArticle,topK = 20, withWeight = False, allowPOS = ())))
'''
topK = 20:该参数指定了要提取的关键词的数量
withWeight = False:是否返回关键词的权重。当设置为 False 时,函数只返回关键词本身;若设置为 True,则会返回一个包含关键词及其对应权重的元组列表。
allowPOS = ():筛选指定词性的关键词。这里传入一个空元组,表示不进行词性筛选
" ".join(...):把一个可迭代对象中的元素用空格" "连接起来,形成一个新的字符串。
'''

结果:

中国人民银行 货币政策 余永定 最终目标 择机 2025 利率 中国 财政政策 降息 人民币 增速 理解 关税 目标 降准 扩张性 顺差 经济 增长

7. 停用词

可在分词之后,训练模型之前去掉停用词
停用词展示

Stop_words = []
for line in open('stopword.txt',encoding='UTF-8' ):line = line.strip()Stop_words.append(line)Stop_words
'''
for line in ... :逐行读取文件中的内容
strip():去除字符串首尾的空白字符(如空格、制表符、换行符等)
'''

8. 关键词提取:TextRank

基于 TextRank 算法提取文本中的关键词

print(" ".join(analyse.textrank(myArticle,topK = 20, withWeight = False, allowPOS = ('n','nt','v','vn'))))
# 只提取词性为名词(n)、机构团体名(nt)、动词(v)、动名词(vn)的关键词

结果:

中国人民银行 货币政策 经济 可能 影响 利率 市场 增长 政策 资本 人民币 关税 受到 财政政策 增速 变化 投资 目标 理解 调整中国人民银行 货币政策 经济 可能 影响 利率 市场 增长 政策 资本 人民币 关税 受到 财政政策 增速 变化 投资 目标 理解 调整

9. 画词云图

import wordcloud#ls=jieba.lcut(myArticle) #对文本分词
ls = analyse.extract_tags(myArticle,topK = 20, withWeight = False, allowPOS = ()) # 提取关键词
txt= " ".join(ls) #对文本进行标点空格化
w= wordcloud.WordCloud(font_path = "msyh.ttc",width = 1000,height = 700,background_color = "white") 
'''
font_path = "msyh.ttc":指定字体文件的路径msyh.ttc:微软雅黑字体如果不指定字体路径,中文可能会显示为乱码
background_color = "white":设置词云背景为白色
'''
w.generate(txt) # 生成词云
w.to_file("mywordcloud.png") # 保存词云图print(w)

结果:
在这里插入图片描述
至此,已经可以做一些简单的聚类、分类分析

四、文本向量化

(一)文本离散表达

1. 对正文分词

words  = jieba.lcut(myArticle)
' '.join(words)

结果:
在这里插入图片描述

2. 去掉停词

word = []
stopwords = [line.strip() for line in open('stopword1.txt',encoding='UTF-8').readlines()]
for w in words:if w not in stopwords:word.append(w)
' '.join(word)

结果:
在这里插入图片描述

3. 词袋模型向量化,计数

根据正文建立词典,对标题进行向量化
这里与提取关键词的区别在于,是针对分词后的文本,类似于英文中的空格,进行计数,不限于中、英文

from sklearn.feature_extraction.text import CountVectorizer
'''
CountVectorizer:将文本集合转换为词频矩阵其中每一行代表一个文本,每一列代表一个词汇矩阵中的元素表示该词汇在对应文本中出现的次数。
'''Cvect = CountVectorizer(max_features=10)
# 设置生成器,取出现次数最多的前10个词作为字典
doc = []
doc.append(' '.join(word))
Cvect.fit(doc) # 根据文本建立词典
doc1=[]
doc1.append(' '.join(jieba.lcut(myTitle)))
X = Cvect.transform(doc1)
'''
将doc1中的文本转换为词频向量
X是一个稀疏矩阵其中每一行代表doc1中的一个文本每一列代表词汇表中的一个词汇矩阵中的元素表示该词汇在对应文本中出现的次数
'''print('字典中的词:            ', Cvect.get_feature_names_out())
print('\n标题:                  ', doc1)
print('\n标题中每个词出现的次数:', X.toarray())
'''
Cvect.get_feature_names_out():返回构建的词汇表中的所有词汇
X.toarray():将稀疏矩阵X转换为普通的NumPy数组,方便查看每个词汇在文本中出现的次数
'''

结果:

字典中的词:             ['中国' '中国人民银行' '余永定' '利率' '增长' '市场' '影响' '目标' '经济' '货币政策']标题:                   ['分析 人士 : 我国 宏观政策 有 空间 和 余力   各项 货币政策 会 继续 落地']标题中每个词出现的次数: [[0 0 0 0 0 0 0 0 0 1]]

4. TF-IDF模型向量化,权重

from sklearn.feature_extraction.text import TfidfVectorizer
# TfidfVectorizer:将文本数据转换为TF-IDF(词频 - 逆文档频率)特征矩阵tfidf = TfidfVectorizer(max_features=10)
# 设置生成器,取出现次数最多的前10个词作为字典
tfidf.fit(doc)
# 根据文本建立词典,此处可以多添加几个文本,用于计算IDF
# 所有文本放进一个list中,每个元素是一个经过分词的文本
X = tfidf.transform(doc1)
# 根据词典对文本向量化,字典向量中每个词的权重
print('字典中的词:       ', tfidf.get_feature_names_out())
print('\n标题:             ', doc1)
print('\n标题中每个词权重: ', np.round(X.toarray(),2))

结果:

字典中的词:        ['中国' '中国人民银行' '余永定' '利率' '增长' '市场' '影响' '目标' '经济' '货币政策']标题:              ['分析 人士 : 我国 宏观政策 有 空间 和 余力   各项 货币政策 会 继续 落地']标题中每个词权重:  [[0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]]

5. 将23篇新闻保存至txt文件

import osstopwords = [line.strip() for line in open('stopword1.txt',encoding='UTF-8').readlines()]
# readlines:读取所有行
if not os.path.exists('sinanews1'): os.makedirs('sinanews1')
# 如果文件路径不存在,就创建一个路径
for i in range(9):myArticle = sinanews.Article[i]words  = jieba.lcut(myArticle)word = []   for w in words:if w not in stopwords:word.append(w)filename = 'sinanews1/news'+str(i)+'.txt'with open(filename,'w',encoding = 'utf-8') as f:f.write(' '.join(word))#将上一步的分好词的文本保存为一个TXT文档

6. 读取所有文档,放进一个list中

def load_news():data = []for i in range(9):filename = 'sinanews1/news'+str(i)+'.txt'with open(filename,'r',encoding = 'utf-8') as f:data.append(f.read()) # 使用f.read()方法读取文件的全部内容,并将其添加到data列表中。return datadata = load_news()
data
# 调用函数并打印列表

结果:
在这里插入图片描述

7. 保存data为一个文件

f = open('sinanews1/allnews.txt','w',encoding = 'utf-8')
for text in data:f.write(text + '\n') # 将每个新闻文本写入文件,并在末尾添加换行符
f.close()
from sklearn.feature_extraction.text import TfidfVectorizer
tfidf = TfidfVectorizer(max_features=30)## 设置生成器,取出现次数最多的前30个词作为字典,与CountVectorizer相同
tfidf.fit(data)# 根据文本建立词典
doc1=[]
doc1.append(' '.join(jieba.lcut(myTitle)))
X = tfidf.transform(doc1)# 根据词典对文本向量化,字典向量中每个词的权重
print('字典中的词:       ', tfidf.get_feature_names_out())
print('\n标题:             ', doc1)
print('\n标题中每个词权重: ', np.round(X.toarray(),2))

结果:

字典中的词:        ['12' '2024' '中国' '中国人民银行' '中方' '人民币' '伊朗' '会谈' '关税' '发展' '合作' '品牌' '国家''国际' '增长' '市场' '影响' '政策' '比亚迪' '汇率' '特朗普' '目标' '经济' '美国' '美方' '调整' '谈判''货币政策' '越南' '进一步']标题:              ['分析 人士 : 我国 宏观政策 有 空间 和 余力   各项 货币政策 会 继续 落地']标题中每个词权重:  [[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.0. 0. 0. 1. 0. 0.]]

(二)文本分布式表达

1. 导入gensim库以及Word2Vec模型

import gensim
from gensim.models import Word2Vec
from gensim.models.word2vec import LineSentence
from gensim.models import word2vec
'''
gensim:用于主题建模、文档索引和相似性检索,尤其在自然语言处理领域广泛用于处理文本数据和训练词向量模型
Word2Vec:用于训练词向量模型的核心类通过该类可以创建和训练Word2Vec模型,将文本中的每个词表示为一个固定长度的向量
LineSentence:用于处理文本文件的迭代器它可以逐行读取文本文件,并将每行文本分词后作为一个句子返回,方便用于训练Word2Vec模型
'''

2. 载入数据

Word2Vec函数可识别的格式

sentences = word2vec.Text8Corpus('sinanews/allnews.txt')
sina_news = open('sinanews/allnews.txt','r',encoding = 'utf-8')
sentence = LineSentence(sina_news)
'''
Text8Corpus:期望输入的文本文件是按照text8数据集的格式存储的,即文件内容是一个长字符串,单词之间用空格分隔从sinanews/allnews.txt文件中读取数据,并将其转换为适合Word2Vec模型训练的句子流
sentence:创建的一个可迭代句子对象
'''

3. 模型生成

model = Word2Vec(sentences,vector_size=400, min_count=5, sg=0, window =5)
'''
依据输入的句子数据 sentences 训练一个 Word2Vec 词向量模型vector_size=400:设定每个词向量的维度为 400。维度越高,词向量所包含的信息就可能越丰富但同时也会增加计算量和内存占用min_count=5:指定词频的阈值。只有在训练数据中出现次数不少于 5 次的词才会被纳入模型进行训练这样可以过滤掉一些生僻词,减少噪声的影响sg:选择训练算法1:skip-gramm模型,0:CBOW模型window = 5:确定上下文窗口的大小。在训练过程中,模型会考虑目标词前后各5个词作为上下文信息。窗口大小越大,模型能够捕捉到的词之间的长距离依赖关系就越多,但同时也会增加计算复杂度
'''

4. 保存模型

模型词向量至txt文档,可用于分类、聚类等

model.wv.save_word2vec_format('word2vec.txt',binary=False)
'''
将训练得到的词向量保存到一个文本文件中binary=False:表示以文本格式保存词向量。如果设置为True,则会以二进制格式保存二进制格式的文件通常更小,读写速度更快,但不便于人工查看和编辑。保存的文本文件中,第一行包含两个整数,分别表示词汇表的大小和词向量的维度。接下来的每一行对应一个词及其对应的向量,词和向量之间用空格分隔,向量的每个元素之间也用空格分隔。
'''
model.save('word2vec1.word2vec') 
'''
将整个模型保存到一个文件中。保存的文件包含了模型的所有信息,包括词汇表、词向量、训练参数等。这个文件可以使用Word2Vec.load方法进行加载,方便后续继续训练模型或者进行其他操作。
'''

5. 分析词与词之间的关系

不同词向量的相似性

model.wv.similarity('企业','公司')
'''
计算两个词之间的余弦相似度一种常用的度量方法,用于衡量两个向量在方向上的相似程度取值范围在-1到1之间,值越接近1表明两个词的语义越相似接收要计算的两个词,返回一个浮点数
'''

与某个词最相关的词

model.wv.most_similar('企业')
'''
返回一个列表,列表中每个元素是一个元组元组的第一个元素是相似词,第二个元素是余弦相似度topn:返回词的数量,默认返回10个词
'''

6. 采用173条新闻进行训练

载入新闻

sinanews1 = pd.read_csv("my_sinanews1.csv")

将正文提取、分词、去停用词,并保存至一个txt中

import os
jieba.suggest_freq(("碳中和","房地产市场")) # 添加关键词
stopwords = [line.strip() for line in open('stopword1.txt',encoding='UTF-8').readlines()]
if not os.path.exists('sinanews1'): os.makedirs('sinanews1')
filename = 'sinanews1/allnews1.txt' 
f = open(filename,'w',encoding = 'utf-8')
for article in sinanews1.Article:words  = jieba.lcut(article) # 分词word = []   for w in words: # 去停用词if w not in stopwords:word.append(w) # 此时word为list,每个元素为词字符串f.write(' '.join(word) + '\n')# 将每个word list整合为一个字符串,分段保存至一个txt中
f.close()

利用 Word2Vec 进行向量化训练

sentences = word2vec.Text8Corpus('sinanews1/allnews1.txt')
# txt文件中,每条新闻为一段,均经过分词

训练模型

model1 = Word2Vec(sentences,vector_size=400, min_count=5, sg=0, window =5)

某个词的词向量

model1.wv['经济']

与某个词最相关的词

model1.wv.most_similar('人民银行')

与某词最不相关的词

model1.wv.most_similar(negative=['资金'])

不同词向量的相似性,

model1.wv.similarity('贷款','开户')

加减法:银行 - 贷款 + 存款 = ?

model1.wv.most_similar(positive = ['银行','存款'], negative=['贷款'])

保存模型

model1.save('sinanews_word2vec.model') # 模型
model1.wv.save_word2vec_format('sinanews_word2vec.vector', binary=False) # 词向量
model1.wv.save_word2vec_format('sinanews_word2vec.txt',binary=False) # txt格式的词向量    .bin

加载模型

Word2Vec.load('sinanews_word2vec.model')

有新样本时,可以在原来已经训练好的模型上追加训练,不用从头开始

more_sentence = word2vec.Text8Corpus('新文件')
model1.train(more_sentences)

目录下所有文件均有效,不用把文件整合到一起

sentences = PathLineSentences('文件夹目录')

7. 从Github网站下载训练好的模型,或词向量

Github中文社区
载入一个已经训练好的词向量文件,搜狗新闻语料训练所得,1.2G

from gensim import models
model=models.KeyedVectors.load_word2vec_format('word2vec_779845.bin',binary=True)

人民银行 - 政策 + 贷款

model.most_similar(positive = ['人民银行','贷款'], negative=['政策'])

国王 - 男人 + 女人 = 女王

model.most_similar(positive = ['国王','女人'], negative=['男人'])

计算文本相似度
得到文本中每个词的词向量

testtext = '人民银行 加大 稳健 货币政策 实施 力度 房地产 市场 交易 活跃性 上升'
print(model[testtext.split()])
print(np.shape(model[testtext.split()]))

将每个词的词向量相加,得到文本向量,计算不同文本向量的距离

8. Doc2Vec 向量化

因为Doc2Vec中增加了段落信息,因此需要给文本的每个段落一个标签

filename = 'sinanews1/allnews1.txt' 
docs = []
with open(filename,'r',encoding = 'utf-8') as f:doc = f.readlines()
f.close()     

训练模型

from gensim.models import doc2vec
from gensim.models.doc2vec import Doc2Vec, TaggedDocument
documents = [TaggedDocument(d, [i]) for i, d in enumerate(doc)]
model2 = Doc2Vec(documents, dm = 0,vector_size=100, window=8, min_count=5, workers=6)

训练集中索引段落的向量

d1 = model2.dv[1]
d1

推断文本向量

d2 = model2.infer_vector(doc[1].split())
d2

比较训练向量和推断向量的余弦距离

1 - np.dot(d1,d2)/(np.linalg.norm(d1)*np.linalg.norm(d2))

比较两段文本的相似度,即两向量余弦相似度

model2.similarity_unseen_docs(doc[0].split(),doc[1].split())

载入新闻数据

sinanews = pd.read_csv('my_sinanews2.csv',encoding='gbk')
sinanewswith open('my_sinanews2.csv', 'r', encoding='gbk') as file:content = file.read()content

相关文章:

  • 服务器备份,服务器想要备份文件内容有哪些方法?
  • Arduino 入门学习笔记(五):KEY实验
  • PTA -L1-005 考试座位号
  • WPF-遵循MVVM框架创建图表的显示【保姆级】
  • SpringCloud核心组件Eureka菜鸟教程
  • LaTex、pdfLaTex、XeLaTex和luaLaTex的区别和联系
  • Docker常见命令
  • 关于指针和指针算术
  • 开发常使用的团队协作工具
  • 再谈从视频中学习:从给视频打字幕的Humanoid-X、UH-1到首个人形VLA Humanoid-VLA:迈向整合第一人称视角的通用人形控制
  • 文本向量化
  • FastAPI + Redis Pub/Sub + WebSocket 组合解决方案的详细介绍
  • Redis01-基础-入门
  • 信创系统 sudoers 权限配置实战!从小白到高手
  • 引领印尼 Web3 变革:Mandala Chain 如何助力 1 亿用户迈向数字未来?
  • 刀客独家 | 潘胜接管百度移动生态市场部
  • 【Linux】Centos7 在 Docker 上安装 mysql8.0(最新详细教程)
  • 【嘉立创EDA】如何在更新或转换原理图到PCB时,保留已有布局器件
  • QML中的色彩应用
  • .dep 和.rpm有什么区别?
  • 美媒:受关税政策影响,美国电商平台近千种商品平均涨价29%
  • 四川苍溪县教育局通报“工作人员辱骂举报学生”:停职检查
  • 上海首个航空前置货站落户松江综合保税区,通关效率可提升30%
  • 《不眠之夜》上演8年推出特别版,多业态联动形成戏剧经济带
  • 技术派|“会飞的手榴弹”:微型无人机将深刻改变单兵作战方式
  • 神舟二十号载人飞船与空间站组合体完成自主快速交会对接