了解词嵌入

本文详细介绍了词嵌入技术的发展历程,重点讲解了Word2Vec、GloVe、TF-IDF和TextRank算法,展示了如何通过神经网络和统计方法学习词向量,以及如何利用这些模型进行文本摘要和关键词提取。
摘要由CSDN通过智能技术生成

参考:
从0开始词嵌入(Word embedding)
word2vec模型深度解析
词向量经典模型:从word2vec、glove、ELMo到BERT
基于TextRank算法的文本摘要(附Python代码)

1 什么是词嵌入?

  词嵌入是自然语言处理的一项核心技术,由于计算机无法理解人类的语言,词嵌入手段将词语转换成计算机能够理解的向量形式,同时也克服了传统方法中词语表示的稀疏性和高维度问题。

1.1定义

  词嵌入是将自然语言中的词语映射为实数向量的过程。在这个过程中,每个词语都被转换成一个固定长度的稠密向量,这些向量构成了词语的向量空间模型。在该模型中,语义或语法性质相似的词语的向量会彼此靠近。

1.2目的

- 语义捕捉:通过学习词语之间的关系,词嵌入能够捕捉词语的同义性、反义性、上下位关系等语义信息。
- 降维: 相比于传统的词袋模型(Bag of Words)或One–hot编码,词嵌入生成的向量维度远低于词汇表的大小,有效缓解了维度灾难问题。
- 稠密表示: 词嵌入向量是稠密的,每个维度通常都有实际的数值,这与稀疏的One-hot向量形成对比。

2 发展历程

2.1 早期尝试

  最早的词表示方法包括One-hot编码和基于统计的方法,如词共现矩阵(Co-occurrence Matrix)和点互信息(PMI)等,但这些方法存在维度高、无法有效捕捉词义等缺点。

2.2 神经网络方法

  随着神经网络的发展,研究者开始使用浅层神经网络学习词嵌入,如Bengio等人提出的神经概率语言模型(NNLM)。

2.3 Word2Vec

  2013年,Mikolov等人提出了Word2Vec,一个高效的词嵌入学习方法,包括Skip-gram和CBOW两种模型。Word2Vec的提出标志着词嵌入技术的一个重要发展阶段。

2.4 后续发展

  随后,更多的模型和方法被提出,如GloVe(基于全局词共现统计的模型)和FastText(能够考虑词内字符级别信息的模型)。

3 实现方法

3.1 Word2Vec 模型

  这是Google在2013年推出的NLP工具,它能够将所有词向量化,这样词与词之间就可以定量的去度量他们之间的关系。
  相比于One-Hot方法,它的思路是通过训练将每个词都映射到较为短的词向量上,这些词向量就组成了向量空间。
  Word2Vec具体的训练方法包含两个部分:CBOW模型和Skip-gram模型。

  1. CBOW模型:这是一个三层的神经网络,特点是输入已知的上下文,输出对当前单词的预测。
  2. Skip-Gram模型:与CBOW模型正好相反,可以由当前的词预测上下文,
    请添加图片描述

3.2 N-gram 模型

  它通过将文本分割成n个连续的项(可以是字母、音节或单词),来预测或识别语言中的一系列元素。这种模型的核心思想是,一个项的出现概率不仅取决于它自身,还取决于它前面的n-1个项。

N-gram定义

  N-gram是一种基于统计的语言模型,用于建立一个项与其前面项序列之间的关联。在N-gram模型中,“N”指的是项的数量,表示在当前项出现的条件下,考虑前面多少个项。例如,一个2-gram(或bigram)模型会考虑当前项之前的1个项,3-gram(或trigram)模型会考虑当前项之前的2个项,以此类推。

N-gram类型

  • Unigram(1-gram):模型中每个项都是独立的,不考虑任何上下文信息。
  • Bigram(2-gram):模型中每个项的出现概率取决于它前面的一个项。
  • Trigram(3-gram)及更高阶:模型中每个项的出现概率取决于它前面的两个或更多项。

代码演示 bigram

# 示例文本数据
text_data = [
    "I feel happy because I am learning",
    "learning is a joyful process",
    "I am happy with my learning progress"
]
from collections import defaultdict, Counter
import numpy as np


def preprocess_text(text_data):
    """
    简单的文本预处理:分词并小写化。
    """
    return [sentence.lower().split() for sentence in text_data]


def build_bigram_model(text_data):
    """
    构建Bigram模型,计算每个Bigram的概率。
    """
    # 预处理文本数据
    processed_text = preprocess_text(text_data)

    # 构建Bigram计数
    #可以创建一个自动初始化的字典,适合用来计数
    bigram_counts = defaultdict(Counter)

    for sentence in processed_text:
        for i in range(len(sentence) - 1):
            first_word, second_word = sentence[i], sentence[i + 1]
            bigram_counts[first_word][second_word] += 1

    # 转换计数为概率
    bigram_model = defaultdict(dict)
    for first_word, next_words in bigram_counts.items():
        total_count = sum(next_words.values())
        for second_word, count in next_words.items():
            bigram_model[first_word][second_word] = count / total_count

    return bigram_model


# 构建模型
bigram_model = build_bigram_model(text_data)
def predict_next_word(bigram_model, word):
    """
    根据给定的单词,预测下一个单词的概率。
    """
    next_words = bigram_model.get(word.lower(), {})
    if not next_words:
        return "No predictions available."
    return next_words

# 示例预测
word = "I"
print(f"Given the word '{word}', the next word probabilities are:")
print(predict_next_word(bigram_model, word))
print('so the following word is ',end='')
max_key = max(predict_next_word(bigram_model, word), key=lambda k: predict_next_word(bigram_model, word)[k]) #获取最大值所对应的键
print(f'"{max_key}"') 

3.3 GloVe模型

  Word2Vec模型仅仅只能考虑于该词相临近窗口的局部信息,没有考虑到窗口外的其他信息,而glove模型利用共现矩阵考虑了全局信息

GloVe工作原理

该模型的核心思想是基于一个假设:单词的共现概率(两个单词同时出现的概率)能够反应单词之间的语义关系。模型训练主要包含以下几个步骤:

  1. 构建共现矩阵:首先,对一个大型语料库进行遍历,构建一个共现矩阵 X X X,矩阵中的元素 X i j X_{ij} Xij代表单词 i i i j j j在特定大小的上下文窗口内共同出现的次数。
  2. 定义目标函数:GloVe模型的目标是让单词向量的点积等于它们共现概率的对数值。具体来说,定义损失函数为所有单词对的权重函数 f ( X i j ) f(X_{ij}) f(Xij)与单词向量点积与 log ⁡ ( X i j ) \log(X_{ij}) log(Xij)之间差的平方和,通过最小化这个损失函数来训练词向量。
  3. 权重函数 f ( X i j ) f(X_{ij}) f(Xij):为了解决稀疏性和频率差异大的问题,GloVe模型引入了一个权重函数 f ( X i j ) f(X_{ij}) f(Xij),它赋予低频单词对较高的权重,而对于高频的单词对则通过一个截断操作来限制它们的权重。
  4. 优化:通过梯度下降等优化算法调整每个单词的向量,以最小化上述损失函数。

3.4 TF-IDF 模型

  当目标文本经过文本清洗和停用词的去除后,一般可以认为剩下的均为有着目标含义的词。下面如果需要对其特征进行更进一步的提取,那么提取的应该是那些能代表文章的元素,包括词、短语、句子、标点以及其他信息的词。从词的角度考虑,需要提取对文章表达贡献度大的词。有些对于文章意义不大的词相反会影响模型的性能,因此需要有一种方法来评估文章中词句的重要性。

TF-IDF模型基本原理

  • TF (Term Frequency):词频,表示词语在文档中出现的频率。这反映了词语在文档中的重要性,但未考虑词语在语料库中的分布情况。
  • IDF (Inverse Document Frequency):逆文档频率,用来衡量一个词语是否具有很好的类别区分能力。计算方式是语料库中的文档总数除以包含该词语之文档的数目,再将得到的商取对数。

  TF-IDF=TF×IDF

3.5 TextRank算法

  该算法的核心思想是来自著名的网页排名算啊PageRank。
PageRank:

  • 当一个网页被越多网页所链接时,其排名会越靠前
  • 排名高的网页应具有更大的表决权,即当一个网页被排名高的网页所链接时,其重要性也会对应提高。

TextRank算法步骤:

  1. 把给定的文本T安装完整句子进行分割。
  2. 对于每个句子,进行分词和词性标注,并且过滤掉停用词,值保留指定词性的单词,如名词,动词,形容词等。
  3. 构建候选关键词图G=(V,E),其中V为节点集,每个词之间的相似度作为连接的边值。
  4. 根据以下公式,迭代传播各节点的权重,直至收敛。
    W S ( V i ) = ( 1 − d ) + d × ∑ V j ∈ ln ⁡ ( V i ) w j i ∑ V k ∈ Out ⁡ ( V j ) w j k W S ( V j ) W S\left(V_{i}\right)=(1-d)+d \times \sum_{V_{j} \in \ln \left(V_{i}\right)} \frac{w_{j i}}{\sum_{V_{k} \in \operatorname{Out}\left(V_{j}\right)} w_{j k}} W S\left(V_{j}\right) WS(Vi)=(1d)+d×Vjln(Vi)VkOut(Vj)wjkwjiWS(Vj)
    对节点按权重进倒排序,作为安重要程度排序的关键词

算法实现

#导入需要的包
import numpy as np
import pandas as pd
import nltk# 自然语言处理包
import re
#需要下载安装punkt模块
#nltk.download('punkt')

#获得数据集  链接:https://s3-ap-south-1.amazonaws.com/av-blog-media/wp-content/uploads/2018/10/tennis_articles_v4.csv
df=pd.read_csv(r".\tennis_articles_v4.csv")

#选择对所有文章进行内容摘要
from nltk.tokenize import sent_tokenize
sentences=[]
for s in df['article_text']:
    #使用sent_tokenize 函数对文本分割成单个句子
    sentences.append(sent_tokenize(s))
print(sentences[:5])
sentences=[y for x in sentences for y in x] #平整list,多维转低维度

#获得embeddding
'''
我们将使用预训练好的Wikipedia 2014 + Gigaword 5 (补充链接)GloVe向量,文件大小是822 MB。
GloVe词向量下载链接:

https://nlp.stanford.edu/data/glove.6B.zip 
 '''
 
word_embeddings={}
f=open(r".\glove.6B.100d.txt",encoding='utf-8')
for line in f:
    values=line.split()
    word=values[0]
    coefs=np.asarray(values[1:],dtype='float32')
    word_embeddings[word]=coefs
f.close()

#文本预处理
#移除标点符号、数字、特殊字符
clean_sentences=pd.Series(sentences).str.replace('[^a-zA-Z]'," ")

#统一成小字母
clean_sentences=[s.lower() for s in clean_sentences]

 #除去常用的停用词如 is am of in 等,需要下载停用词
#nltk.download('stopwords')

from nltk.corpus import stopwords
stop_words=stopwords.words('english')

#定义移除数据集中的停用词的函数
def remove_stopwords(sen):
    sen_new=' '.join([i for i in sen if i not in stop_words])
    return sen_new
    
#移除停用词
clean_sentences=[remove_stopwords(r.split()) for r in clean_sentences]

#利用GloVe词向量为数据集生成特征向量
sentence_vectors=[]
for i in clean_sentences:
    if len(i)!=0:
        v=sum([word_embeddings.get(w,np.zeros((100,))) for w in i.split()])/(len(i.split())+0.001)
        #防止分母为0
    else:
        v=np.zeros((100,))
    sentence_vectors.append(v)

#利用余弦相似度来计算两个句子之间的相似度
from sklearn.metrics.pairwise import cosine_similarity
for i in range(len(sentences)):
    for j in range(len(sentences)):
        if i != j:
            sim_mat[i][j]=cosine_similarity(sentence_vectors[i].reshape(1,100),sentence_vectors[j].reshape(1,100))[0,0]

#应用PageRank算法
import networkx as nx
#先转换成图结构
nx_graph=nx.from_numpy_array(sim_mat)
scores=nx.pagerank(nx_graph)

#摘要提取
ranked_sentences=sorted(((scores[i],s) for i,s in enumerate(sentences)),reverse=True)
for i in range(10):
    print(ranked_sentences[i][1])
  • 39
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值