当前位置:   article > 正文

NLP(11)--词向量

NLP(11)--词向量

前言

仅记录学习过程,有问题欢迎讨论

one-hot 编码 i love u [1,2,3]

词向量训练目标:
如果两个词在文本出现,它的前后出现的词相似,则这两个词语义相似

cbow(基于窗口预测词)缺点
:输出层是vocab_size 会很大
收敛速度会很慢

skipGram --用中间词预测两侧词

哈夫曼树
用词频来构造树,词频最大,在树的层级越小
对词向量输出层级过大的优化

Glove 词向量:
按照词来编写关于前后语义关系的矩阵—共现矩阵

词向量存在的问题:
1)词向量是“静态”的。每个词使用固定向量,没有考虑前后文

2)一词多义的情况。西瓜 - 苹果 - 华为

3)影响效果的因素非常多
维度选择、随机初始化、skip-gram/cbow/glove、分词质量、词频截断、未登录词、窗口大小、迭代轮数、停止条件、语料质量等

4)没有好的直接评价指标。常需要用下游任务来评价

句向量:
对于所有的词加和求平均 得到文本向量 计算其相似性和聚类
Kmeans
KMeans一些使用技巧:
先设定较多的聚类类别
聚类结束后计算类内平均距离
排序后,舍弃类内平均距离较长的类别

总结:
1.质变:将离散的字符转化为连续的数值

2.通过向量的相似度代表语义的相似度

3.词向量的训练基于很多不完全正确的假设,但是据此训练的词向量是有意义的

4.使用无标注的文本的一种好方法

代码

Demo1:使用gensim
pip install gensim
寻找词之间的相似性

"""
实现一个 TFIDF
"""
import gensim
import jieba


def gensim_train(corpus, dim):
    model = gensim.models.Word2Vec(corpus,  # 用于训练的语料数据
                                   vector_size=dim,  # 是指特征向量的维度,默认为100。
                                   window=5,  # 一个句子中当前单词和被预测单词的最大距离。
                                   min_count=1,  # 可以对字典做截断. 词频少于min_count次数的单词会被丢弃掉, 默认值为5。
                                   sg=1)
    model.save("word2vec.w2v")
    return model

def main():
    sentences = []
    with open("D:\\NLP\\test\\week5\\corpus.txt",encoding="utf8") as f:
        for line in f:
            sentences.append(jieba.lcut(line))
    model = gensim_train(sentences, 100)
    return model

if __name__ == '__main__':
    # model = main()
    # 加载模型
    model = gensim.models.Word2Vec.load("word2vec.w2v")

    # print(model.wv.most_similar(positive=["男人", "母亲"], negative=["女人"]))
    while True:  #找相似
        string = input("input:")
        try:
            print(model.wv.most_similar(string))
        except KeyError:
            print("输入词不存在")


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

kmeans Demo
找出平均距离最大的类内中心点,然后去除该中心点

#!/usr/bin/env python3  
# coding: utf-8

# 基于训练好的词向量模型进行聚类
# 聚类采用Kmeans算法
import math
from collections import defaultdict

import gensim
import jieba
import numpy as np
# 基于训练好的词向量模型进行聚类
# 聚类采用Kmeans算法
from gensim.models import Word2Vec
from gensim.models import Word2Vec
from sklearn.cluster import KMeans


# 输入模型文件路径
# 加载训练好的模型
def load_word2vec_model(path):
    model = Word2Vec.load(path)
    return model


def load_sentence(path):
    sentences = set()
    with open(path, encoding="utf8") as f:
        for line in f:
            sentence = line.strip()
            sentences.add(" ".join(jieba.cut(sentence)))
    print("获取句子数量:", len(sentences))
    return sentences


# 将文本向量化
def sentences_to_vectors(sentences, model):
    vectors = []
    for sentence in sentences:
        words = sentence.split()  # sentence是分好词的,空格分开
        vector = np.zeros(model.vector_size)
        # 所有词的向量相加求平均,作为句子向量
        for word in words:
            try:
                vector += model.wv[word]
            except KeyError:
                # 部分词在训练中未出现,用全0向量代替
                vector += np.zeros(model.vector_size)
        vectors.append(vector / len(words))
    return np.array(vectors)


# vec1 = 类别
# vec2 = 该类下的数据
def calculate_distant(vec1, vec2):
    return np.sqrt(sum(np.power(vec1 - vec2, 2)))


def main():
    model = gensim.models.Word2Vec.load("D:\\NLP\\test\\dayPractice\\word2vec.w2v")  # 加载词向量模型
    sentences = load_sentence("titles.txt")  # 加载所有标题
    vectors = sentences_to_vectors(sentences, model)  # 将所有标题向量化

    n_clusters = int(math.sqrt(len(sentences)))  # 指定聚类数量
    print("指定聚类数量:", n_clusters)
    kmeans = KMeans(n_clusters)  # 定义一个kmeans计算类
    kmeans.fit(vectors)  # 进行聚类计算

    sentence_label_dict = defaultdict(list)

    # for list1 in kmeans.cluster_centers_:
    #     print(list1)
    center_list = defaultdict(list)
    sentence_index_label_dict = defaultdict(list)
    index = 0
    # 取出kmeans的聚点,丢弃掉类内平均距离最长的那个聚点
    for sentence, label in zip(sentences, kmeans.labels_):  # 取出句子和标签

        sentence_label_dict[label].append(sentence)  # 同标签的放到一起(分好 一簇的)
        sentence_index_label_dict[label].append(index) # 同标签的放到一起(记录的是句子的index)
        index += 1
    # 记录该组的中心点向量值
    for index, center in enumerate(kmeans.cluster_centers_):
        # 记录该组的中心点向量值
        center_list[index].append(center)

    distant_list = defaultdict(list)
    for label, index_list in sentence_index_label_dict.items():
       # 计算本组所有点到中心点的距离和
        temp_i = []
        for i in index_list:
            temp_i.append(calculate_distant(center_list.get(label), vectors[i]))
        # 记录当前组的组内平均距离
        distant_list[label].append(np.mean(temp_i))

    # 丢弃距离最大的那组
    drop_label = max(distant_list)
    del sentence_label_dict[drop_label]

    for label, sentences in sentence_label_dict.items():

        print("cluster %s :" % label)
        for i in range(min(10, len(sentences))):  # 随便打印几个,太多了看不过来
            print(sentences[i].replace(" ", ""))
        print("---------")


if __name__ == "__main__":
    main()



  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/526924
推荐阅读
相关标签
  

闽ICP备14008679号