赞
踩
仅记录学习过程,有问题欢迎讨论
词向量训练目标:
如果两个词在文本出现,它的前后出现的词相似,则这两个词语义相似
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("输入词不存在")
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()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。