当前位置:   article > 正文

python词嵌入_python 词嵌入

python 词嵌入

一、词嵌入的概念

自然语言处理的突破在2023年震撼世界,chatgpt3出来,之后chatgpt4、Gemini、Claude3等出来,问答越来越智能,非常厉害,其中有个基础性的概念,计算机要如何理解语言,基础工作就在于将词向量化,关键的概念便是词嵌入(word embeddings),之前我觉得这个词读的非常绕口,想为什么不直接叫词向量?其实形成词向量的方法有很多,包括词袋模型(Bag-of-Words model)也是一种方法,而词嵌入很厉害,可以让算法自动的理解一些类似的词,也就是自监督,通过词嵌入的概念就可以方便的构建NLP应用了!当然现在也有人在思考如何改进词嵌入的理解深度。

构建词嵌入的步骤有两步:

1、词嵌入第一步是给所有词构建one-hot向量,形成一个巨大的稀疏矩阵,每个词对应到某一个位置为1的向量。

2、通过深度学习来产生词嵌入,比如skip-grams学习词嵌入矩阵,词嵌入矩阵的格式有点像下面这样,当然每个维度表示什么含义属于自监督的事情,也就是说人是不知道的,一般设置成100~300维,词嵌入实际上属于“辅助产品”。以skip-grams算法为例,核心思想是构建一个监督学习问题:根据已有一个目标词,在多少个词内(自己定)找到另一个词,做成一个合理搭配。本身这个问题也很难解,但转成一个求概率问题之后,定义它的损失函数,经过反向传播算法它便是可以计算的了。

但是上面这个算法的计算复杂度是很高的,一旦数据量增大,计算会变得非常慢。因此就有分级(hierarchical)的softmax分类器负采样(Negative Sampling)分级的思路就是算法中常用的分而治之的思路,这种思路诞生了二分法、动态规划等算法,其实就是在softmax中不用先直接分到某个类,先确定区间,是前50%的分类还是后50%的分类负采样的逻辑也简单,除了给正确词之外,也给不正确词,两者做搭配,从而减少运算量

二、PCA(主成分分析)

主成分分析是一种无监督学习算法,可用于降低数据的维数。这个算法可以来做数据可视化,它试图结合不同特性之间的差异。有句话觉得讲得有道理:Remember that understanding the data is one of the most critical steps in Data Science. 要想做进一步的数据分析,至关重要的一步是理解数据,对于人类而言,高维的数据难以直观理解,主成分分析便发挥了重要作用,尤其是理解词向量,比如将词向量压缩到2维,再来看数据便会有直观的感觉,理解他们之间的联系。

PCA的主要思想是将n维特征映射到k维上,这k维是全新的正交特征也被称为主成分,是在原有n维特征的基础上重新构造出来的k维特征。

PCA的算法总结是四个步骤:

1、数据规范化(Mean normalize your data)规范化有公式,比较简单

2、计算协方差矩阵(Compute the covariance matrix),

3、计算奇异值 Compute SVD on your covariance matrix. This returns . The three matrices U, S, V are drawn above. U is labelled with eigenvectors, and S is labelled with eigenvalues. 

4、获得主成分,You can then use the first n columns of vector , to get your new data by multiplying .

采用numpy实现pca的示例代码如下,

  1. # UNQ_C5 GRADED FUNCTION: compute_pca
  2. def compute_pca(X, n_components=2):
  3. """
  4. Input:
  5. X: of dimension (m,n) where each row corresponds to a word vector
  6. n_components: Number of components you want to keep.
  7. Output:
  8. X_reduced: data transformed in 2 dims/columns + regenerated original data
  9. pass in: data as 2D NumPy array
  10. """
  11. ### START CODE HERE ###
  12. # mean center the data
  13. X_demeaned = X - np.mean(X,axis=0)
  14. # calculate the covariance matrix
  15. covariance_matrix = np.cov(X,rowvar=False)
  16. # calculate eigenvectors & eigenvalues of the covariance matrix
  17. eigen_vals, eigen_vecs = np.linalg.eigh(covariance_matrix)
  18. # sort eigenvalue in increasing order (get the indices from the sort)
  19. idx_sorted = np.argsort(eigen_vals)
  20. # reverse the order so that it's from highest to lowest.
  21. idx_sorted_decreasing = idx_sorted[::-1]
  22. # sort the eigen values by idx_sorted_decreasing
  23. eigen_vals_sorted = eigen_vals[idx_sorted_decreasing]
  24. # sort eigenvectors using the idx_sorted_decreasing indices
  25. eigen_vecs_sorted = eigen_vecs[:,idx_sorted_decreasing]
  26. # select the first n eigenvectors (n is desired dimension
  27. # of rescaled data array, or n_components)
  28. eigen_vecs_subset = eigen_vecs_sorted[:,0:n_components]
  29. # transform the data by multiplying the transpose of the eigenvectors with the transpose of the de-meaned data
  30. # Then take the transpose of that product.
  31. X_reduced = np.dot(eigen_vecs_subset.T, X_demeaned.T).T
  32. ### END CODE HERE ###
  33. return X_reduced
'
运行

三、词嵌入代码示例

正常项目都需要经过数据处理,比如去除html标签、特殊字符,先将数据放入到clean_text中:

  1. # bs4 nltk gensim
  2. import os
  3. import re
  4. import numpy as np
  5. import pandas as pd
  6. from bs4 import BeautifulSoup
  7. from sklearn.feature_extraction.text import CountVectorizer
  8. from sklearn.ensemble import RandomForestClassifier
  9. from sklearn.metrics import confusion_matrix
  10. from sklearn.linear_model import LogisticRegression
  11. import nltk
  12. from nltk.corpus import stopwords
  13. df['clean_review'] = df.review.apply(clean_text)

定义文本清理函数,包括取出html文本中数据等,re.sub表示替换函数、将非a-z、A-Z的字符替换成空格,之后剔除停用词:

  1. def clean_text(text):
  2. text = BeautifulSoup(text, 'html.parser').get_text()
  3. text = re.sub(r'[^a-zA-Z]', ' ', text)
  4. words = text.lower().split()
  5. words = [w for w in words if w not in eng_stopwords]
  6. return ' '.join(words)
'
运行

处理分词,tokenizer是分词器,最后得到单独句子的集合:

  1. review_part = df['clean_review']
  2. # 加载分词器
  3. tokenizer = nltk.data.load('tokenizers/punkt/english.pickle')
  4. def split_sentences(review):
  5. # 将长文本转换成句子的list
  6. raw_sentences = tokenizer.tokenize(review.strip())
  7. sentences = [clean_text(s) for s in raw_sentences if s]
  8. return sentences
  9. sentences = sum(review_part.apply(split_sentences), [])

然后进一步将将句子中的词提出放置到sentences_list中:

  1. sentences_list = []
  2. for line in sentences:
  3. sentences_list.append(nltk.word_tokenize(line))

准备训练word2vec,相关参数说明如下:

  • sentences:可以是一个list

  • sg: 用于设置训练算法,默认为0,对应CBOW算法;sg=1则采用skip-gram算法。

  • size:是指特征向量的维度,默认为100。大的size需要更多的训练数据,但是效果会更好. 推荐值为几十到几百。

  • window:表示当前词与预测词在一个句子中的最大距离是多少

  • alpha: 是学习速率

  • seed:用于随机数发生器。与初始化词向量有关。

  • min_count: 可以对字典做截断. 词频少于min_count次数的单词会被丢弃掉, 默认值为5

  • max_vocab_size: 设置词向量构建期间的RAM限制。如果所有独立单词个数超过这个,则就消除掉其中最不频繁的一个。每一千万个单词需要大约1GB的RAM。设置成None则没有限制。

  • workers参数控制训练的并行数。

  • hs: 如果为1则会采用hierarchica·softmax技巧。如果设置为0(defau·t),则negative sampling会被使用。

  • negative: 如果>0,则会采用negativesamp·ing,用于设置多少个noise words

  • iter: 迭代次数,默认为5

设置参数:

  1. # 设定词向量训练的参数
  2. num_features = 300 # Word vector dimensionality
  3. min_word_count = 40 # Minimum word count
  4. num_workers = 4 # Number of threads to run in parallel
  5. context = 10 # Context window size
  6. model_name = '{}features_{}minwords_{}context.model'.format(num_features, min_word_count, context)
'
运行

进行训练:

  1. from gensim.models.word2vec import Word2Vec
  2. model = Word2Vec(sentences_list, workers=num_workers, \
  3. vector_size=num_features, min_count = min_word_count, \
  4. window = context)
  5. # If you don't plan to train the model any further, calling
  6. # init_sims will make the model much more memory-efficient.
  7. model.init_sims(replace=True)
  8. # It can be helpful to create a meaningful model name and
  9. # save the model for later use. You can load it later using Word2Vec.load()
  10. model.save(os.path.join('..', 'models', model_name))

测试下模型情况:

model.most_similar("boy")

输出结果:

[('girl', 0.7018299698829651),
 ('astro', 0.6647905707359314),
 ('teenage', 0.6317306160926819),
 ('frat', 0.60948246717453),
 ('dad', 0.6011481285095215),
 ('yr', 0.6010577082633972),
 ('teenager', 0.5974895358085632),
 ('brat', 0.5941195487976074),
 ('joshua', 0.5832049250602722),
 ('father', 0.5825375914573669)]

很神奇是不是!数据量大了之后会有更好的效果,词嵌入可以直接从文本中读出关系来!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小桥流水78/article/detail/873951
推荐阅读
相关标签
  

闽ICP备14008679号