【文本挖掘】(三)文本表示

文本表示的概念#

  • 核心:将字符串以计算机形式进行表示出来,如向量化。
  • 分类
  • 离散/向量表示:词袋模型(独热编码、TF-IDF、N-gram)
  • 分布式表示:词嵌入word embedding,包括word2vec、Glove、ELMO、GPT、BERT等。
  • 基于矩阵:基于降维表示和基于聚类表示
  • 基于神经网络:CBOW、Skip-gram、NNLM、C&W

文本预处理#

文本预处理的一般过程:
(1)对输入的文本进行删除开始、结尾以及段与段之间的空格等操作。
(2)识别换行符号,对文本进行分段,并用分段标记标识段落。
(3)识别断句符号,如“。”、“!”、“?”、“;”等,并用断句符号标记句子。
(4)对断句出来的句子用分词算法进行分词,并进行词性标注。
(5)处理完成之后,采用一定的策略对之前得到的词汇进行特征词选取。
(6)设置特征词汇的权重。
(7)形成文本的向量空间模型。
image

向量空间模型VSM: vector space model#

权重计算#

  • 布尔权重
  • 词频权重
  • TF-IDF

向量相似度量#

向量内积#

  • 普通形式

Sim(Di,Dj)=kn=1(tik×tjk)

  • 归一化形式

Sim(Di,Dj)=cosθ=kn=1(tik×tjk)k=1ntik×k=1ntjk

向量间的距离#

  • 绝对值距离
  • 欧几里得距离
  • 切比雪夫距离

代码案例#

案例1 计算文档Di=(0.2,0.4,0.11,0.06)和Dj=(0.14,0.21,0.026,0.34)的余弦相似度。

  • 使用内积函数dot()和范式函数linalg.norm()
import numpy as np
di=[0.2,0.4,0.11,0.06]
dj=[0.14,0.21,0.026,0.34]
dist1=np.dot(Di,Dj)/np.linalg.norm(Di)*np.linalg.norm(Dj)
  • 使用scipy
from scipy import spatial
dist1=1-spatial.distance.cosine(Di,Dj)
  • 使用sklearn
dfrom sklarn.metrics.pairwise import cosine_similarity
dist1=cosine_similar(Di.reshape(1,-1),Dj.reshape(1,-1))

案例2 计算两个句子的相似度

D1='我喜欢看电视,不喜欢看电影'
D2='我不喜欢看电视,也不喜欢看电影'

# 分词
split1=[ word for word in jieba.cut(D1) if word not in [',','。']]
split1=[ word for word in jieba.cut(D2) if word not in [',','。']]
# 列出所有的词
wordset=set(split1).union(split2)
# 统计词频
def computeTF(wordSet,split):
	tf=dict.fromkeys(wordSet,0)
	for word in split:
		tf[word]+=1
	return tf

tf1=computeTF(wordSet,split1)
tf2=computeTF(wordSet,split2)
# 词频向量
s1=list(tf1.values())
s2=list(tf2.values())

#计算余弦相似性
dist1=np.dot(s1,s2)/(np.linalg.norm(s1)*np.linalg.norm(s2))

文本表示方法#

离散/向量表示#

TF-IDF#

(TermFrequency)==

(InverseDocumentFrequency)=log+1+10

词袋模型Big of Words#

  • 基于BOW计算文档相似度的gensim实现
1.建立字典
from gensim.corpora import Dictionary
import jieba
str01='大鱼吃小鱼也吃虾米,小鱼吃虾米'
text01=[ [for word in jieba.cut(str,cut_all=Ture) if word note in [",","。""大鱼吃","大鱼吃小鱼"]]]

# Dictionary类用于建立word<->id映射关系,把所有单词取一个set(),并对set中每个单词分配一个id号的map。
dict01=Dictionary(text01)
dict01.dfs          # 字典{单词id,在多少文档中出现}
dict01.num_docs     # 文档数目
dict01.num_nnz      # 每个文件中不重复词个数的和
dict01.num_pos      # 所有词的个数
dict01.token2id     # 字典,{单词,对应id}
dict01.id2token()     #字典,{单词id,对应的单词}
# 向字典添加词条
dict01.add_documents([['猫','爱']])
dict01.token2id.keys()
  • doc2bow转换为BOW稀疏向量
# 转换为BOW稀疏向量
'''allow_update = False : 是否直接更新所用字典
   return_missing = False : 是否返回新出现的(不在字典中的)词'''
print(sum(text01,[]))
dict01_cp=dict01.doc2bow(sum(text01,[]),return_missing=True)

输出结果

[(0, 2), (1, 2)],表明在文档中id0,1的词汇各出现了2次,至于其他词汇则没有出现
return_missing = True时,输出list of (int, int), dict of (str, int)
  • 转换为BOW长向量 doc2idx
# 转换为BOW长向量 doc2idx
#doc2idx( # 转换为list of token_id
#    document : 用于转换的词条list
#    unknown_word_index = -1 : 为不在字典中的词条准备的代码
#输出结果:按照输入list的顺序列出所出现的各词条#ID
str="小鱼吃虾米"
text=[  word for word in jieba.cut(str)]
dict01.doc2idx(text)

输出结果

[3,1,4]
  • Sklearn.CountVectorizer生成文档-词条矩阵
'''
class sklearn.feature_extraction.text.CountVectorizer(

    input = 'content' : {'filename', 'file', 'content'}filename为所需读入的文件列表, file则为具体的文件名称。

    encoding='utf-8' : 文档编码

    stop_words = None : 停用词列表,当analyzer == 'word'时才生效

    min_df / max_df : float in range [0.0, 1.0] or int, default = 1 / 1.0

    词频绝对值/比例的阈值,在此范围之外的将被剔除小数格式说明提供的是百分比,如0.05指的就是5%的阈值)

CountVectorizer.build_analyzer()   # 返回文本预处理和分词的可调用函数
'''

image
image
image

  • 完整案例
    image
    image

分布式表示#

Word2Vec#

CBOW 连续词袋模型#

预测未知词,等同于完形填空,如“easyai 是__ 人工智能 网站”

Skip-Gram跳字模型#

预测上下文,如"_ _ 最好的 _ _"

Doc2Vec#

Doc2Vec是Word2Vec的拓展。

问题思考#

  1. BOW稀疏向量和BOW长向量的区别?
  2. Word2Vec和Doc2Vec的区别?

作者:Gim

出处:https://www.cnblogs.com/Gimm/p/18202533

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   踩坑大王  阅读(37)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示