第二,三章(虚拟环境创建)文本表示

第二,三章(虚拟环境创建)文本表示 0.虚拟环境相关pip3 install torch torchvision --index-url https://download.pytorch.org/whl/cu1260词表 vs词典维度词表 Vocabulary词典 Lexicon英文对应Vocabulary / Token ListLexicon / Dictionary信息量少(只有词和ID)多(词性、释义、搭配等)作用编码/解码(文本转数字)知识查询(理解词义和用法)数据结构通常是哈希映射 (Dict[词] - ID)通常是嵌套结构 (Dict[词] - 属性Dict)在模型中的位置必须有的嵌入层Embedding Layer的索引通常作为外部知识库可选注意一般来说词表不是和词典一一对应例如词表中的runs,running对应词典中的run但我们会尽量让词表和词典产生关联1.文本表示的概述2.什么是分词分词将连续的字序按照一定的规范重新组合成词序列的过程英文单词之间是以空格作为自然分界符而中文的词没有一个形式上的分界符分词过程就是找这样分界符的过程2.1英文分词按分词粒度的大小可分为 词级分词字符级分词子词级分词2.1.1词级分词(OOV问题)2.1.2字符级分词2.1.3子词级分词注意语料库就是给的几段几段的文章句子等词汇表就是语料库中不重复的组合并记录频率等当前大模型主流都是子词级分词算法,一个词视作一个token2.2中文分词(jieba的使用)注意在虚拟环境nlpbase中pip的2.2.1三种模式分词# coding:utf-8 import jieba # todo:1.jieba实现精确模式的分词 def dm1_jieba(): # 1.给出需要待切分的文本 content传智教育是一家上市公司旗下有黑马程序员品牌我是在黑马这里学习人工智能 # 2.基于jieba.cut()方法实现文本的切分 jieba.cut是一个分词函数。 content是要分词的文本。 cut_allFalse表示使用精确模式不是全模式,全模式是将所有可能成词的词为一词。 返回值是一个生成器generator可以迭代产生分词后的词语。 生成器不用直接存内存用一个取一个 resultjieba.cut(content,cut_allFalse) # jieba.lcut(content,cut_allFalse) 等价于print(list(result)) print(fresult1:{result}) print(next(result)) print(next(result)) # for a in result: 的本质就是next(result) print(list(result)) # 将生成器内容强转成列表 # todo:2.全模式 def dm2_jieba(): content 传智教育是一家上市公司旗下有黑马程序员品牌我是在黑马这里学习人工智能 resultjieba.lcut(content,cut_allTrue) print(result) # todo:3.搜索引擎模式(在精确模式的基础上进行再分) def dm3_jieba(): content 传智教育是一家上市公司旗下有黑马程序员品牌我是在黑马这里学习人工智能 resultjieba.cut_for_search(content) print(list(result)) if __name____main__: dm1_jieba() dm2_jieba() dm3_jieba()运行结果2.2.2自定义词典# todo:jieba支持自定义词典如果加载了自定义词典那么分词会优先按照词典里面的词进行分词但是要考虑词频 # 词典的格式每行样本word freq cixing def dm4_jieba(): content 传智教育是一家上市公司旗下有黑马程序员品牌我是在黑马这里学习人工智能 # 1.未加入词典实现文本切分 result1 jieba.lcut(content) # cut_all默认False print(f加入词典前{result1}) # 2.使用自定义词典 jieba.load_userdict(./userdict.txt) # 加入词典后实现文本的切分 result2 jieba.lcut(content) print(f加入词典后{result2})运行结果注意随着自创词典词频的增大可以将原来句中没有切分的词给切分开2.1什么是命名实体识别NER2.2什么是词性标注POS2.3语料 vs 词典(表)维度语料 Corpus词典 Lexicon形式连续的文本或语句原始文本。通常是键值对或列表词条属性。内容包含完整的句子、段落、上下文。只包含词元及其相关属性通常不含上下文。规模通常非常庞大GB/TB级别包含海量词汇。相对固定包含有限的词汇条目。动态性动态的随着时间推移可以不断加入新文本。相对静态更新频率较低需要人工修订。作用提供统计证据。模型从中学习语法规则、语义搭配、世界知识。提供先验知识。告诉模型这个词有哪些合法的用法或属性。语料包含重复内容词典是不重复的所有语料中的全部内容词典有两种静态词典语料中冒出新词词典中没有会将新词标注为unk动态词典语料中冒出新词词典会根据特定的算法将新词添加进词典# todo:jieba实现词性标注 def dm5_jieba(): # 1.给出需要带词性标注的文本 content 传智教育是一家上市公司旗下有黑马程序员品牌我是在黑马这里学习人工智能 # 2.实现带词性标注的文本切分 resultpseg.lcut(content) print(f词性标注后的分词切分{result})运行结果返回一个listlist里面存的是元组3.词向量表示3.1概述(文本张量表示)将一段文本转化成数字将一段文本使用张量表示其中一般将词汇表示成向量再由各个词向量按顺序组成矩阵形成文本表示3.2one-hot词向量表示3.3语义化词向量3.3.1Word2Vec概述3.3.2Word2Vec原理(1)数据集Word2Vec不依赖人工标注直接利用大模型原始文本作为数据源从中自动构造训练样本两种模型的输入输出都是词语首先对原始文本进行分词将连续文本转化为token序列模型无法直接处理文本符号训练时仍需将词语转为one-hot编码以便模型进行输入输出计算(2)Skip-Gram中间预测两边反向传播更新Win时其实就更新红色那行相当于用乘坐和上班两个标签对这行进行更新可以理解为用上下文去更新这个向量所以可以将Win红色这一行作为地铁的词向量语料是指所有待输入文本比如有n100个不重复词,但一次输入可能只有n12这是词表是n100,即Win的行是100代表100个不同的词向量one-hot编码长度词表长度语料中不重复的词数≈词典的词数Win的列数就是词向量的维数---即隐藏层的维数3CBOW3.3.3获取Word2Vec词向量pip install gensim(1)公开词向量github.comfrom gensim.models import KeyedVectors # 公开的中文词向量 keyed--键值--词 词的向量 model_path./data/sgns.weibo.word modelKeyedVectors.load_word2vec_format(model_path)# model相当于继承了字典的接口 print(model.vector_size) # 查看词的维度(300) print(len(model.index_to_key)) # 查看文件中多少个词(195202) print(model[地铁]) # 查看某个词的向量 similaritymodel.similarity(地铁,公交) print(地铁 vs 公交 相似度,similarity) # 查看两个词向量的相似度(地铁 vs 公交 相似度 0.65458214) 因为向量 男人-男孩女人-女孩 所以向量 男人-男孩女孩 最相似的是 向量(女人) [(女人, 0.6578881740570068), (女孩子, 0.515068531036377), (女生, 0.45194485783576965), (女人真, 0.4420627951622009), (女人们, 0.43698593974113464)] similar_wordsmodel.most_similar(positive[男人,女孩],negative[男孩],topn5) # 找出与某个词最相近的词 print(similar_words)(2)训练自己的词向量1.准备语料2.训练模型(直接调用Word2Vec)3.保存词向量(只保存Win按词向量格式保存Win)model.wv.save_word2vec_format(my_vectors.kv)4.加载词向量from gensim.models import KeyedVectorsmy_modelKeyedVectors.load_word2vec_format(my_vectors.kv) 第二节 训练自己的词向量 import jieba import pandas as pd from gensim.models import Word2Vec, KeyedVectors 1.准备语料 seq默认,分隔 .dropna 去除有空值null的行 dfpd.read_csv(./data/online_shopping_10_cats.csv,encodingutf-8).dropna() print(df.head()) 只需要第三行数据review 但review中有null数据所以需要去处理一下要不分词不了 如何找出review值为null的行 df[review]取出 DataFrame 中的 review 这一列得到一个 Series。 .isna()判断该 Series 中的每个元素是否为缺失值NaN返回一个布尔类型的 Series其中 True 表示对应位置是缺失值False 表示不是。 df[...]将布尔 Series 作为行索引传入 DataFrame只保留那些在布尔 Series 中对应为 True 的行。 print(df[df[review].isna()]) 但jieba分词会将‘ ’‘/t’等字符也划分但词向量中不需要这些字符 所以要通过.strip()去除特殊字符方法处理jieba.lcut(sentence) sentence[[token for token in jieba.lcut(sentence) if token.strip()!] for sentence in df[review]] # 分词后的二维列表 # 2.模型训练 modelWord2Vec( sentence, # 已分词的句子序列 vector_size100, # 词向量的维度 window5, # 上下文窗口大小 min_count2, # 最小词频(低于将忽略) sg1, # 1:Skip_Gram 0:CBOW workers4 # 并行训练线程数 ) # 3.保存词向量 model.wv.save_word2vec_format(./data/word2vec.txt) # 4.加载词向量 modelKeyedVectors.load_word2vec_format(./data/word2vec.txt) print(model.vector_size) # 词向量维度(100)3.3.4应用Word2Vec词向量 第三节词向量的具体应用 import jieba from gensim.models import KeyedVectors import torch from torch import nn # 1.加载词向量 wvKeyedVectors.load_word2vec_format(./data/word2vec.txt) # 2.准备词向量矩阵 num_embeddingslen(wv.index_to_key) # 词向量个数 embedding_dimwv.vector_size # 词向量维度 embedding_matrixtorch.randn(num_embeddings,embedding_dim) wv.index_to_key 是一个列表里面存的是字符串--词 枚举返回可迭代对象每个元素的元组(索引值) wv[word]类似于字典的值存的是ndarray数组--词向量 将ndarray转成tensor张量存入词向量矩阵 for index,word in enumerate(wv.index_to_key): embedding_matrix[index]torch.tensor(wv[word]) # 3.创建Embedding实际上是创建模型上述第二种初始化 embeddingnn.Embedding.from_pretrained(embedding_matrix) # 4.测试 text我喜欢乘坐地铁 tokensjieba.lcut(text) # 假设 wv 是一个 KeyedVectors 对象包含了 [苹果, 香蕉, 橘子] 三个词 print(wv.key_to_index) 本质是一个字典 # 输出{苹果: 0, 香蕉: 1, 橘子: 2} print(wv.index_to_key) 本质是一个列表 # 输出[苹果, 香蕉, 橘子] 下列将分词转成id input_ids[wv.key_to_index[token] for token in tokens] input_tensortorch.tensor(input_ids) # 这个一个一维张量 embedding(input_tensor) # 输出是4*1004个词每个词向量100维 # 注意一维张量在与嵌入层的Win矩阵乘法时先转为one-hot编码再与Win相乘3.3.5应用W2V(OOV问题) 第四节 处理OOV问题的修改代码 第三节词向量的具体应用 import jieba from gensim.models import KeyedVectors import torch from torch import nn # 1.加载词向量wvself_model wvKeyedVectors.load_word2vec_format(./data/word2vec.txt)# 1.1 处理OOV问题 unk_tokenunk # 当出现新词在老词表中找不到时将新词设为unk index2word[unk_token]wv.index_to_key # 新的词列表 word2index{word:index for index,word in enumerate(index2word)}# 2.准备词向量矩阵 num_embeddingslen(index2word) # 词向量个数 embedding_dimwv.vector_size # 词向量维度 embedding_matrixtorch.randn(num_embeddings,embedding_dim) wv.index_to_key 是一个列表里面存的是字符串--词 枚举返回可迭代对象每个元素的元组(索引值) wv[word]类似于字典的值存的是ndarray数组--词向量 将ndarray转成tensor张量存入词向量矩阵 for index,word in enumerate(index2word): if index !0: # 列表第一个是unk特殊值 embedding_matrix[index]torch.tensor(wv[word]) # 3.创建Embedding实际上是创建模型上述第二种初始化 embeddingnn.Embedding.from_pretrained(embedding_matrix) # 4.测试 text我喜欢乘坐地铁 tokensjieba.lcut(text) # 假设 wv 是一个 KeyedVectors 对象包含了 [苹果, 香蕉, 橘子] 三个词 print(wv.key_to_index) 本质是一个字典 # 输出{苹果: 0, 香蕉: 1, 橘子: 2} print(wv.index_to_key) 本质是一个列表 # 输出[苹果, 香蕉, 橘子] 下列将分词转成id 这是一个字典的 get 方法调用word2index 是一个字典键是词值是对应的索引 .get(token, 0) 表示如果 token 在字典中返回其对应的索引否则返回默认值 0。 input_ids[word2index.get(token,0)for token in tokens] input_tensortorch.tensor(input_ids) # 这个一个一维张量 embedding(input_tensor) # 输出是4*1004个词每个词向量100维 # 注意一维张量在与嵌入层的Win矩阵乘法时先转为one-hot编码再与Win相乘3.4上下文相关词表示(暂时了解)