是什么? 能做什么? 怎么做的? 优缺点?
一. 文本的表示
文本表示的就是把 文本或者字词, 变换成向量或者 矩阵的形式,以便于机器 更加容易或者方便的处理,同时文本表示是 自然语言处理的 开始的环节。
文本表示分为离散表示和分布式表示,离散表示代表有词袋模型,One-hot向量,TF-IDF,n-gram这些都可以看作词袋子模型,分布式表示也叫做词嵌入,经典的模型有word2vec,包括后来的ELMO,GPT,BERT等。
文本的表示:
力度划分: 分为:字级别 , 词级别,句子级别
按照量级分成: 字力度 (把每个词变成向量),
词力度 (把每个词变成向量),
句力度 (把整个句子直接变成向量)
五款 中文 分词工具: jieba,SnowNLP,PkuSeg,THULAC,HanLP
词汇表的概念 :统计出来的所有不重复的单词
词汇表的作用 :把每个字变成下标
文本表示按照 另一个量级表示 分为:
离散型 的表示: [0,1,0,1,0,0,1,1,....] 20000维度
分布式 的表示: embedding
连续数据:列不完:身高,体重,范围(0,1)
离散数据:列得完
Embedding : 解决高维稀疏 (ihello 有五个不重复字母,embedding就有五行)
随机一张表:词汇表有多大,随机的表就有多少行.(想把一个字变为多少维的向量,那么这个表就有多少列) 通过Emdedding把一个one-hot稀疏的向量,变成一个稠密的向量
用one-hot编码出来的向量是离散的,embedding从离散的变成了分布的
如果用embedding,需要随机一张表,因为是随机的,随机的向量好不好?随机的好,因为这张表可以跟着模型一起训练
one-hot 向量也就独热编码,只有一个位置是 1 ,其他全部是 0.
优点 :简单,快速
缺点 :高维稀疏,不能体现字与字之间没有关系,没有办法体现出来一句话中哪个词是比较重要的.
TF-IDF
TF-IDF: 可以提取出来一句话中词的重要性
tf * idf = 词的重要性: 输出的 值越大,证明这个词对于这个文档的 重要性越大。
tf: 词频 :
idf: 逆文档频率 : 公式: log(总文档数/包含词的文档数+1) = idf
例如:文档数2个,包含[的] 也是2 idf = log(2/2) = 0 tf(的) = 100 tf*idf = 100 * 0 = 0,就把的过滤了
优点:简单快速,结果比较符合实际情况
缺点:高维稀疏,idf算法简单,不能完全体现出词的重要性,
有改进版TF- IWF
TF-IDF算法的不足:
TF-IDF 采用文本逆频率 IDF 对 TF 值加权取权值大的作为关键词,但 IDF 的简单结构并不能有效地反映单词的重要程度和特征词的分布情况,使其无法很好地完成对权值调整的功能,所以 TF-IDF 算法的精度并不是很高,尤其是当文本集已经分类的情况下。
在本质上 IDF 是一种试图抑制噪音的加权,并且单纯地认为文本频率小的单词就越重要,文本频率大的单词就越无用。这对于大部分文本信息,并不是完全正确的。IDF 的简单结构并不能使提取的关键词, 十分有效地反映单词的重要程度和特征词的分布情况,使其无法很好地完成对权值调整的功能。尤其是在同类语料库中,这一方法有很大弊端,往往一些同类文本的关键词被盖。
TF-IDF算法实现简单快速,但是仍有许多不足之处:
(1)没有考虑特征词的位置因素对文本的区分度,词条出现在文档的不同位置时,对区分度的贡献大小是不一样的。
(2)按照传统TF-IDF,往往一些生僻词的IDF(反文档频率)会比较高、因此这些生僻词常会被误认为是文档关键词。
(3)传统TF-IDF中的IDF部分只考虑了特征词与它出现的文本数之间的关系,而忽略了特征项在一个类别中不同的类别间的分布情况。
(4)对于文档中出现次数较少的重要人名、地名信息提取效果不佳。
CountVectorizer类会将文本中的词语转换为词频矩阵。
它通过fit_transform函数计算各个词语出现的次数,
通过get_feature_names()可获取词袋中所有文本的关键字,
通过toarray()可看到词频矩阵的结果。
--------------------------------------------
TfidfTransformer:统计CountVectorizer中每个词语的tf-idf权值.
TF-IDF的主要思想是:如果某个词或短语在一篇文章中出现的频率TF高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。TF-IDF实际上是:TF * IDF。
TfidfVectorizer:其实就是CountVectorizer + TfidfTransformer组合使用.
from sklearn.feature_extraction.text import CountVectorizer,TfidfTransformer
from sklearn.feature_extraction.text import TfidfVectorizer
代码:TensorFlow1.14
# tf_emb
import numpy as np
from collections import Counter
import tensorflow as tf
mstr = '段明伟真帅帅帅帅'
word_counter = Counter() # 统计词汇表
for i in mstr:
# 统计每个字出现的次数
word_counter.update(i)
print(word_counter) # Counter({词:次数,......})
# most_common() 把统计的词变为列表套元组的形式[(词,次数),...],从高到底排列
word_list = [i[0] for i in word_counter.most_common()] # [词,词....]
word_dict = {}
for i,j in enumerate(word_list):
word_dict[j] = i
word_ids = []
for i in mstr: # 把字变为下标
word_ids.append(word_dict[i])
word_ids = np.array([word_ids])
# 字典有5个词,随机embedding向量表
embeddings = tf.Variable(tf.random_normal([5,10],dtype=tf.float32))
X = tf.placeholder(tf.int32,[1,8])
# 生成Embedding词向量
embs = tf.nn.embedding_lookup(embeddings,X)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
embeddings_, embs_ = sess.run([embeddings,embs],feed_dict={X:word_ids})
print('embeddings:',embeddings_)
print('embs:',embs_)
代码:torch
import numpy as np
import torch
import torch.nn as nn
from collections import Counter
mstr = '段明伟真帅帅帅帅'
word_counter = Counter()
for i in mstr:
word_counter.update(i)
word_list = [i[0] for i in word_counter.most_common()]
word_dict = {}
for i,j in enumerate(word_list):
word_dict[j] = i
word_ids = []
for i in mstr:
word_ids.append(word_dict[i])
word_ids = np.array([word_ids])
class Model(nn.Module):
def __init__(self):
super(Model, self).__init__()
self.C = nn.Embedding(5,10)
def forward(self,X):
out = self.C(X)
return out
word_ids_tensor = torch.tensor(word_ids)
model = Model()
out = model(word_ids_tensor)
print(out.data.numpy())
文章中的图片是在网上找到的图,如有侵权请私信删除。本文借鉴了很多文章,仅作个人学习总结,如有总结错误,欢迎留言指正