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

寻找词之间的相似性

java 复制代码
"""
实现一个 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("输入词不存在")

kmeans Demo

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

python 复制代码
#!/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()
相关推荐
用户6915811416542 分钟前
Ascend Extension for PyTorch的源码解析
人工智能
Chef_Chen43 分钟前
从0开始学习机器学习--Day13--神经网络如何处理复杂非线性函数
神经网络·学习·机器学习
Troc_wangpeng44 分钟前
R language 关于二维平面直角坐标系的制作
开发语言·机器学习
用户691581141651 小时前
Ascend C的编程模型
人工智能
-Nemophilist-1 小时前
机器学习与深度学习-1-线性回归从零开始实现
深度学习·机器学习·线性回归
成富2 小时前
文本转SQL(Text-to-SQL),场景介绍与 Spring AI 实现
数据库·人工智能·sql·spring·oracle
CSDN云计算2 小时前
如何以开源加速AI企业落地,红帽带来新解法
人工智能·开源·openshift·红帽·instructlab
艾派森2 小时前
大数据分析案例-基于随机森林算法的智能手机价格预测模型
人工智能·python·随机森林·机器学习·数据挖掘
hairenjing11232 小时前
在 Android 手机上从SD 卡恢复数据的 6 个有效应用程序
android·人工智能·windows·macos·智能手机
小蜗子2 小时前
Multi‐modal knowledge graph inference via media convergenceand logic rule
人工智能·知识图谱