当前位置:   article > 正文

文本张量的表示方法_文本转换为文本向量

文本转换为文本向量

概念:

  • 将一段文本使用张量进行表示,将词汇表示成向量,成为词向量,再由各个词向量按顺序组成矩阵形成文本表示。

为什么?

  • 因为文本不能够直接被模型计算,所以需要将其转化为向量

作用:

  • 将文本转化为张量表示形式,能够将文本作为计算机程序的输入,然后进行下一步一系列的操作。

把文本转化为向量有两种方法:

  1. one-hot编码

  2. word2vec

  3. word embedding

1. one-hot 编码    【使用稀疏的向量表示文本,占用空间多】

        又称为独热编码,将每个词表示成具有n个元素的向量,这个向量只有一个元素是1,其余的元素都是0,不同词汇的1和0的位置是不同的,其中n的大小是整个语料中不同词汇的总数。

        即:把待处理的文档进行分词或者是N-gram处理,然后进行去重得到词典,例如有一个文档:深度学习,那么进行one-hot处理后的结果如下:

tokenone-hot encoding
1000
0100
0010
0001

one-hot编码实现:

  1. # 导入用于对象保存与加载的joblib
  2. import joblib
  3. # 导入keras中的词汇映射器Tokenizer
  4. from keras.preprocessing.text import Tokenizer
  5. # 假定vocab为语料集所有不同词汇集合
  6. vocab = {"张三", "李四", "王五", "赵六", "孙七"}
  7. # 实例化一个词汇映射器对象
  8. t = Tokenizer(num_words=None, char_level=False)
  9. # 使用映射器拟合现有文本数据
  10. t.fit_on_texts(vocab)
  11. for token in vocab:
  12. zero_list = [0] * len(vocab)
  13. # 使用映射器转化现有文本数据, 每个词汇对应从1开始的自然数
  14. # 返回样式如: [[2]], 取出其中的数字需要使用[0][0]
  15. token_index = t.texts_to_sequences([token])[0][0] - 1
  16. zero_list[token_index] = 1
  17. print(token, "的one-hot编码是:", zero_list)
  18. # 使用joblib工具保存映射器, 以便之后使用
  19. tokenizer_path = "./Tokenizer"
  20. joblib.dump(t, tokenizer_path)

输出结果:

 one-hot编码的使用:

  1. # 导入用于对象保存与加载的joblib
  2. import joblib
  3. # 加载之前保存的Tokenizer, 实例化一个t对象
  4. t = joblib.load(tokenizer_path)
  5. # 编码token为“李四”
  6. token = '李四'
  7. # 使用t获得token_index
  8. token_index = t.texts_to_sequences([token])[0][0] - 1
  9. print(token_index)
  10. # 初始化一个zero_list
  11. zero_list = [0] * len(vocab)
  12. # 令zero_list的对应索引为1
  13. zero_list[token_index] = 1
  14. print(token, '的one-hot编码是:', zero_list)

运行效果:

 one-hot编码的优劣势:

  • 优势:操作简单,容易理解.
  • 劣势:完全割裂了词与词之间的联系,而且在大语料集下,每个向量的长度过大,占据大量内存.

2. word2vec

        将词汇表示成向量的无监督训练方法,将构建神经网络模型,将网络参数作为词汇的向量表示,它包含CBOW和Skipgram两种训练方式。

CBOW(Continuous bag of words)模式:

  • 给定一段用于训练的文本语料, 再选定某段长度(窗口)作为研究对象, 使用上下文词汇预测目标词汇.

  • 图中窗口大小为9, 使用前后4个词汇对目标词汇进行预测.

CBOW模式下的word2vec过程说明:

        假设给定的训练语料只有一句话: Hope can set you free ,窗口大小为3,因此模型的第一个训练样本来自Hope can set,因为是CBOW模式,所以将使用Hope和set作为输入,can作为输出,在模型训练时, Hope,can,set等词汇都使用它们的one-hot编码. 如图所示: 每个one-hot编码的单词与各自的变换矩阵(即参数矩阵3x5, 这里的3是指最后得到的词向量维度)相乘之后再相加, 得到上下文表示矩阵(3x1).

        接着, 将上下文表示矩阵与变换矩阵(参数矩阵5x3, 所有的变换矩阵共享参数)相乘, 得到5x1的结果矩阵, 它将与我们真正的目标矩阵即can的one-hot编码矩阵(5x1)进行损失的计算, 然后更新网络参数完成一次模型迭代.

        最后窗口按序向后移动,重新更新参数,直到所有语料被遍历完成,得到最终的变换矩阵(3x5),这个变换矩阵与每个词汇的one-hot编码(5x1)相乘,得到的3x1的矩阵就是该词汇的word2vec张量表示.

skipgram模式

        给定一段用于训练的文本语料, 再选定某段长度(窗口)作为研究对象, 使用目标词汇预测上下文词汇.

 图中窗口大小为9, 使用目标词汇对前后四个词汇进行预测.

skipgram模式下的word2vec过程说明:

        假设给定的训练语料只有一句话: Hope can set you free ,窗口大小为3,因此模型的第一个训练样本来自Hope can set,因为是skipgram模式,所以将使用can作为输入 ,Hope和set作为输出,在模型训练时, Hope,can,set等词汇都使用它们的one-hot编码. 如图所示: 将can的one-hot编码与变换矩阵(即参数矩阵3x5, 这里的3是指最后得到的词向量维度)相乘, 得到目标词汇表示矩阵(3x1).

        接着, 将目标词汇表示矩阵与多个变换矩阵(参数矩阵5x3)相乘, 得到多个5x1的结果矩阵, 它将与我们Hope和set对应的one-hot编码矩阵(5x1)进行损失的计算, 然后更新网络参数完成一次模型迭代.

        最后窗口按序向后移动,重新更新参数,直到所有语料被遍历完成,得到最终的变换矩阵即参数矩阵(3x5),这个变换矩阵与每个词汇的one-hot编码(5x1)相乘,得到的3x1的矩阵就是该词汇的word2vec张量表示.

第一步: 获取训练数据

  1. # 获取烹饪相关的数据集, 它是由facebook AI实验室提供的演示数据集
  2. # 首先创建一个存储数据的文件夹data
  3. $ mkdir data
  4. # 使用wget下载数据, 存储在data目录中
  5. $ wget https://dl.fbaipublicfiles.com/fasttext/data/cooking.stackexchange.tar.gz -P data
  6. # 解压data目录中的数据
  7. $ tar xvzf ./data/cooking.stackexchange.tar.gz

查看数据的前10条:

$ head cooking.stackexchange.txt 

数据说明:

        cooking.stackexchange.txt中的每一行都包含一个标签列表,后跟相应的文档, 标签列表以类似 "__label__sauce __label__cheese"的形式展现, 代表有两个标签sauce和cheese, 所有标签__label__均以前缀开头,这是fastText识别标签或单词的方式. 标签之后的一段话就是文本信息.如: How much does potato starch affect a cheese sauce recipe?

第二步: 训练集与验证集的划分:

  1. # 查看数据总数
  2. $ wc cooking.stackexchange.txt

  1. # 12404条数据作为训练数据
  2. $ head -n 12404 cooking.stackexchange.txt > cooking.train
  3. # 3000条数据作为验证数据
  4. $ tail -n 3000 cooking.stackexchange.txt > cooking.valid

第三步: 训练词向量:

  1. import fasttext
  2. # 使用fasttext的train_supervised方法进行文本分类模型的训练
  3. # 它的参数是数据集的持久化文件路径'../data/nlp/composition.txt'
  4. model = fasttext.train_unsupervised('../data/nlp/cooking.train')
  5. model
  1. # 通过get_word_vector方法来获得指定词汇的词向量
  2. model.get_word_vector('We')

 第四步: 模型超参数设定​​​:

  1. # 在训练词向量过程中, 我们可以设定很多常用超参数来调节我们的模型效果, 如:
  2. # 无监督训练模式: 'skipgram' 或者 'cbow', 默认为'skipgram', 在实践中,skipgram模式在利用子词方面比cbow更好.
  3. # 词嵌入维度dim: 默认为100, 但随着语料库的增大, 词嵌入的维度往往也要更大.
  4. # 数据循环次数epoch: 默认为5, 但当你的数据集足够大, 可能不需要那么多次.
  5. # 学习率lr: 默认为0.05, 根据经验, 建议选择[0.01,1]范围内.
  6. # 使用的线程数thread: 默认为12个线程, 一般建议和你的cpu核数相同.
  7. model = fasttext.train_unsupervised('../data/nlp/cooking.train', "cbow", dim=300, epoch=1, lr=0.1, thread=8)
  8. model
  1. # 通过get_word_vector方法来获得指定词汇的词向量
  2. model.get_word_vector('We')
  1. array([ 1.8798960e-04, 3.9608974e-04, 1.2488964e-04, -9.2796411e-04,
  2. -6.1711291e-04, -6.2431244e-04, -1.4772391e-04, -3.5378849e-04,
  3. -3.0792586e-04, 5.1501358e-04, 1.6098269e-03, 1.0018016e-03,
  4. 1.6719052e-03, -5.6049239e-04, 7.6037890e-04, 6.1507529e-04,
  5. -1.8648471e-03, -7.2232017e-04, -2.7811489e-04, -4.6330268e-04,
  6. -9.9416811e-04, -2.8092955e-04, -9.3677954e-06, 1.6349037e-03,
  7. 4.3381727e-04, -6.1742309e-04, 9.5424021e-04, -3.5220262e-04,
  8. -2.4382970e-03, -1.9431422e-03, -6.0295616e-04, 6.0434028e-05,
  9. 5.1125861e-04, 2.8696796e-04, -3.2288337e-04, -1.0013091e-03,
  10. -1.0437337e-03, -8.3238486e-04, -4.9110944e-04, 1.1270840e-03,
  11. 8.6425280e-04, -1.9255802e-03, -1.9251168e-03, -1.6462419e-03,
  12. -1.8576446e-03, 7.5667788e-04, 6.6057773e-04, -6.5994063e-05,
  13. -1.6498434e-03, -2.5676386e-04, -4.6431762e-04, 3.8234689e-04,
  14. -6.8796007e-04, 1.0940077e-03, -2.7840986e-04, -3.9451220e-04,
  15. 1.7935492e-03, 4.8564124e-04, -2.9137146e-04, 1.9880496e-03,
  16. 2.9593395e-04, 7.1078213e-04, -5.0951108e-05, -2.1633005e-04,
  17. -5.9387996e-04, 1.3559591e-05, 4.3469830e-04, -1.5066195e-03,
  18. 8.5074385e-04, -1.6271046e-03, -2.6409666e-04, 1.3218648e-03,
  19. -7.4308616e-04, 1.0227414e-03, -1.6490914e-03, -6.4410793e-04,
  20. 6.9497466e-05, 3.5593982e-04, 2.6490851e-03, -5.3268351e-04,
  21. 1.2321163e-03, 1.0681837e-03, -4.7990127e-04, 3.8721034e-04,
  22. 9.9227787e-04, -5.4918707e-04, -1.4470376e-03, 1.2126429e-03,
  23. -4.3907342e-04, -3.9304476e-04, -6.5747555e-04, 3.0149959e-04,
  24. 5.4582942e-04, -5.9078913e-04, -2.3132609e-03, -2.2930815e-03,
  25. 2.5756651e-04, -4.4075365e-04, -1.6666949e-05, 1.4334652e-03,
  26. 1.7858138e-03, 2.2278397e-04, 9.0640283e-04, 3.0442880e-04,
  27. 1.3243086e-03, -7.0690678e-04, -6.4097706e-04, 4.2106956e-05,
  28. -5.3881318e-04, 2.0223754e-03, 8.1660668e-04, 9.3027781e-04,
  29. 8.9407474e-04, 7.0259813e-04, -1.0891645e-03, -1.5033981e-03,
  30. 1.2447413e-03, -5.1550893e-04, 7.8015483e-04, -1.8651132e-04,
  31. -1.5457397e-03, 2.3224749e-04, -7.1424220e-05, 2.5053683e-05,
  32. -5.3998549e-04, 2.8403290e-04, 7.0932624e-04, 1.0760939e-03,
  33. 9.5664262e-04, -1.2577500e-03, -1.3050484e-03, -9.9220476e-04,
  34. -1.1326331e-03, -3.9973820e-04, 1.8455237e-03, -1.2213863e-03,
  35. 4.4848816e-04, 1.1577337e-04, -1.3397774e-04, -1.1544895e-03,
  36. -2.4254384e-04, -1.1866910e-03, 9.7491080e-05, -1.5464274e-03,
  37. -5.7074567e-04, -6.0549628e-05, 4.0644035e-04, -1.9360933e-03,
  38. 8.4747089e-04, 1.4777582e-03, -8.4022677e-04, 5.1099074e-04,
  39. 2.1948041e-04, -1.5321872e-03, 9.0355752e-05, -1.8932702e-04,
  40. -8.6888927e-04, 3.4475196e-04, 1.1358424e-03, 5.9262745e-04,
  41. 1.4131053e-03, -6.2828342e-04, -2.0598862e-03, 3.5489188e-04,
  42. -9.5051492e-04, 5.5754336e-04, 1.5305297e-04, -2.2592241e-04,
  43. -1.2468253e-03, 2.1133265e-03, 2.0393701e-03, -7.5453354e-05,
  44. 2.2464308e-03, -2.7793306e-03, -2.7650670e-04, -5.6757347e-04,
  45. -1.2623724e-03, 2.4185526e-04, -2.1872879e-04, -1.3029057e-03,
  46. 1.2648103e-03, -1.7081172e-04, -5.1090492e-06, 2.0209840e-03,
  47. -4.6539324e-04, -4.3347658e-04, 2.6551257e-03, -4.7769718e-05,
  48. -1.5018480e-03, -2.7433509e-04, -1.1514550e-03, -9.0617285e-04,
  49. 6.4340071e-05, -1.4025187e-04, 1.6628280e-03, -2.0780518e-04,
  50. 1.2190402e-03, -5.0332031e-04, 9.3403400e-04, -2.3752507e-03,
  51. -1.6558596e-03, -2.7870771e-04, -5.1363997e-05, -3.8631755e-04,
  52. -1.2252243e-03, -8.8181972e-05, -8.7797281e-04, 4.6918890e-04,
  53. 2.8892321e-04, -3.6389800e-05, -3.7714560e-04, 1.6713038e-03,
  54. -6.1489409e-06, -9.9299802e-04, 2.9321382e-04, 3.4070999e-04,
  55. -9.1769427e-05, 4.3389792e-04, 2.8307032e-04, 1.8194178e-03,
  56. -2.1896229e-04, -8.7369949e-04, 1.1310980e-03, 2.5185114e-03,
  57. -2.8928742e-05, 3.6371639e-05, -3.4053749e-04, -1.3872653e-03,
  58. 1.9170906e-03, -1.9865986e-03, 2.5991439e-03, 7.5947837e-04,
  59. 4.3592113e-04, 6.6652254e-04, -2.0494119e-04, -9.2760939e-04,
  60. -1.5355994e-04, -9.6773081e-05, -4.9556443e-04, 1.1428313e-03,
  61. 1.4962892e-03, 1.0212720e-03, -3.8397498e-05, 5.6903791e-05,
  62. -5.9897255e-04, -2.0230697e-03, -1.7971732e-05, -2.3715696e-04,
  63. -7.2849606e-04, -9.0493623e-04, 7.3953054e-04, -1.4050563e-03,
  64. -1.4323555e-03, -4.4240867e-04, 5.6989986e-04, 2.5848616e-03,
  65. 4.2838976e-04, -6.8223989e-04, -6.6442939e-05, 6.2906457e-04,
  66. -1.3130277e-03, -2.7790554e-03, 3.0586561e-05, -8.8957418e-04,
  67. -7.8230907e-05, 9.6563809e-04, -8.4480271e-04, 1.8562011e-03,
  68. 4.5768984e-04, -9.2681765e-04, 5.0427485e-04, 1.6942159e-03,
  69. -2.4133138e-04, 1.6701745e-04, -8.1996943e-05, 1.8672661e-04,
  70. -3.0396209e-04, -1.5319184e-03, 6.3104037e-04, 3.0288688e-04,
  71. 9.7920932e-04, 1.0130615e-03, -6.8494043e-04, -1.3638380e-03,
  72. 1.4863213e-03, 9.4224850e-04, 7.5208559e-04, -3.8108899e-04,
  73. -9.1517594e-04, 1.0825705e-03, -6.2862772e-04, -7.2933477e-04,
  74. -1.1180628e-03, 7.0936600e-04, -6.9769856e-04, 1.8013072e-03,
  75. 1.9647011e-03, -2.0243833e-03, -1.0390377e-03, 7.8340177e-04],
  76. dtype=float32)

 第五步: 模型保存与加载​​​:

  1. # 使用save_model保存模型
  2. model.save_model("../data/nlp/cooking.train.bin")
  3. # 使用fasttext.load_model加载模型
  4. model = fasttext.load_model("../data/nlp/cooking.train.bin")
  5. model.get_word_vector("We")

3. word embedding

        word embedding是深度学习中表示文本常用的一种方法。和one-hot编码不同,word embedding使用了浮点型的稠密矩阵来表示token。根据词典的大小,我们的向量通常使用不同的维度,例如100,256,300等。其中向量中的每一个值是一个参数,其初始值是随机生成的,之后会在训练的过程中进行学习而获得。

        如果文本中有20000个词语,如果使用one-hot编码,那么我们会有20000*20000的矩阵,其中大多数的位置都为0,但是如果我们使用word embedding来表示的话,只需要20000* 维度,比如20000*300

形象的表示就是:

tokennumvector
词10[w11,w12,w13...w1N] ,其中N表示维度(dimension)
词21[w21,w22,w23...w2N]
词32[w31,w23,w33...w3N]
...…....
词mm[wm1,wm2,wm3...wmN],其中m表示词典的大小

我们会把所有的文本转化为向量,把句子用向量来表示

但是在这中间,我们会先把token使用数字来表示,再把数字使用向量来表示。

即:token---> num ---->vector

3.1 word embedding API

torch.nn.Embedding(num_embeddings,embedding_dim)

参数介绍:

  1. num_embeddings:词典的大小

  2. embedding_dim:embedding的维度

使用方法:

  1. embedding = nn.Embedding(vocab_size,300) #实例化
  2. input_embeded = embedding(input) #进行embedding的操作 # input传入的只能是数字,字符串无法操作

3.2数据的形状变化

思考:每个batch中的每个句子有10个词语,经过形状为[20,4]的Word emebedding之后,原来的句子会变成什么形状?

        每个词语用长度为4的向量表示,所以,最终句子会变为[batch_size,10,4]的形状。

        增加了一个维度,这个维度是embedding的dim

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

闽ICP备14008679号