1. one-hot编码

  1. # 字符集的one-hot编码
  2. import string
  3.  
  4. samples = ['zzh is a pig','he loves himself very much','pig pig han']
  5. characters = string.printable
  6. token_index = dict(zip(range(1,len(characters)+1),characters))
  7.  
  8. max_length =20
  9. results = np.zeros((len(samples),max_length,max(token_index.keys()) + 1))
  10. for i,sample in enumerate(sample):
  11. for j,character in enumerate(sample):
  12. index = token_index.get(character)
  13. results[i,j,index] = 1
  14. results

characters= '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW

XYZ!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c'

  1. # keras实现单词级的one-hot编码
  2. from keras.preprocessing.text import Tokenizer
  3. samples = ['zzh is a pig','he loves himself very much','pig pig han']
  4.  
  5. tokenizer = Tokenizer(num_words = 100)
  6. #创建一个分词器(tokenizer),设置为只考虑前1000个最常见的单词
  7. tokenizer.fit_on_texts(samples)#构建单词索引
  8.  
  9. sequences = tokenizer.texts_to_sequences(samples)
  10.  
  11. one_hot_results = tokenizer.texts_to_matrix(samples,mode='binary')
  12.  
  13. # one_hot_results.shape --> (3, 100)
  14.  
  15. word_index = tokenizer.word_index
  16. print('发现%s个unique标记',len(word_index))
  1. sequences = [[2, 3, 4, 1],
    [5, 6, 7, 8, 9, 10],
    [1, 1, 11]]
  2.  
  1. 发现10unique标记
  2.  
  3. word_index =
  1. {'pig': 1, 'zzh': 2, 'is': 3, 'a': 4, 'he': 5,
    'loves': 6,'himself': 7, 'very': 8, 'much': 9,
    'han': 10}

one-hot 编码的一种办法是 one-hot散列技巧(one-hot hashing trick)

如果词表中唯一标记的数量太大而无法直接处理,就可以使用这种技巧。

这种方法没有为每个单词显示的分配一个索引并将这些索引保存在一个字典中,而是将单词散列编码为固定长度的向量,通常用一个非常简单的散列函数来实现。

优点:节省内存并允许数据的在线编码(读取完所有数据之前,你就可以立刻生成标记向量)

缺点:可能会出现散列冲突

如果散列空间的维度远大于需要散列的唯一标记的个数,散列冲突的可能性会减小

  1. import numpy as np
  2.  
  3. samples = ['the cat sat on the mat the cat sat on the mat the cat sat on the mat','the dog ate my homowork']
  4. dimensionality = 1000#将单词保存为1000维的向量
  5. max_length = 10
  6.  
  7. results = np.zeros((len(samples),max_length,dimensionality))
  8. for i,sample in enumerate(samples):
  9. for j,word in list(enumerate(sample.split()))[:max_length]:
  10. index = abs(hash(word)) % dimensionality
  11. results[i,j,index] = 1
  12.  
 

2. 词嵌入

获取词嵌入的两种方法:

  • 在完成主任务的同时学习词嵌入。在这种情况下,一开始是随机的词向量,然后对这些词向量进行学习,其学习方式与学习神经网络的权重相同。
  • 在不同于待解决的机器学习任务上预计算好词嵌入,然后将其加载到模型中。这些词嵌入叫作预训练词嵌入

实验数据:imdb电影评论,我们添加了以下限制,将训练数据限定为200个样本(打乱顺序)。

(1)使用embedding层学习词嵌入  
  1. # 处理imdb原始数据的标签
  2. # _*_ coding:utf-8 _*_
  3. import os
  4.  
  5. imdb_dir = 'imdb'
  6. train_dir = os.path.join(imdb_dir,'train')
  7.  
  8. labels = []
  9. texts = []
  10.  
  11. for label_type in ['neg','pos']:
  12. dir_name = os.path.join(train_dir,label_type)
  13. for fname in os.listdir(dir_name):
  14. if fname[-4:] == '.txt':
  15. f = open(os.path.join(dir_name,fname),encoding='UTF-8')
  16. texts.append(f.read())
  17. f.close()
  18. if label_type == 'neg':
  19. labels.append(0)
  20. else:
  21. labels.append(1)

len(texts)=25000

len(labels)=25000

  1. # 对imdb原始数据的文本进行分词
  2. from keras.preprocessing.text import Tokenizer
  3. from keras.preprocessing.sequence import pad_sequences
  4.  
  5. max_len = 100 #每句话最大长度不超过100个单词
  6. training_samples = 200
  7. validation_samples = 10000
  8. max_words = 10000 #只考虑数据集中前10000个最常见的单词
  9.  
  10. tokenizer = Tokenizer(num_words=max_len)
  11. tokenizer.fit_on_texts(texts)
  12. sequences = tokenizer.texts_to_sequences(texts)
  13. len(sequences)

sequence[0]

word_index = tokenizer.word_index

#88592个unique单词

word_index

data = pad_sequences(sequences,maxlen=max_len)

data.shape = (25000,100)

data[0]

labels = np.asarray(labels)

  1. #asarray会跟着原labels的改变,算是浅拷贝吧,
    没有新开一片内存 

indices = np.arange(data.shape[0])

np.random.shuffle(indices)

indices

array([ 2501, 4853, 2109, ..., 2357, 22166, 12397])

  1. #将data,label打乱顺序
    data = data[indices]
  2. labels = labels[indices]
  3.  
  4. x_train = data[:training_samples]
  5. y_train = labels[:training_samples]
  6.  
  7. x_val = data[training_samples:training_samples+validation_samples]
  8. y_val = labels[training_samples:training_samples+validation_samples]

  1. x_val.shape,y_val.shape
  1. (10000, 100) (10000,)

  1. #2014年英文维基百科的预计算嵌入:Glove词嵌入(包含400000个单词)
  2. glove_dir = 'glove.6B'
  3. embeddings_index = {}
  4.  
  5. f = open(os.path.join(glove_dir,'glove.6B.100d.txt'),encoding='utf8')
  6. for line in f:
  7. values = line.split()
  8. word = values[0]
  9. coefs = np.asarray(values[1:],dtype='float32')
  10. embeddings_index[word] = coefs
  11. f.close()

  1. len(embeddings_index) 400000
  2. f.readline() #'the -0.038194 -0.24487 ...'
    每个单词对应一个词向量

  1. #准备glove词嵌入矩阵
  2. embedding_dim = 100
  3. # 每个单词都有编号,根据编号得到对应的矩阵
  4. embedding_matrix = np.zeros((max_words,embedding_dim))
  5. for word,i in word_index.items():
  6. # print(word,i)--> the 1
  7. if i < max_words:
  8. embedding_vector = embeddings_index.get(word)
  9. if embedding_vector is not None:
  10. embedding_matrix[i] = embedding_vector
  11.  
  12. # print(embedding_matrix[0])

把数据集里面的单词在glove中找到对应的词向量,组成embedding_matrix,

若在glove中不存在,那就为0向量

  1. #定义模型
  2. from keras.models import Sequential
  3. from keras.layers import Embedding,Flatten,Dense
  4.  
  5. model = Sequential()
  6.  
  7. model.add(Embedding(max_words,embedding_dim,input_length=max_len))
  8.  
  9. model.add(Flatten())
  10. model.add(Dense(32,activation='relu'))
  11. model.add(Dense(1,activation='sigmoid'))
  12.  
  13. model.summary()
  14.  
  15. #将预训练的词嵌入加载到embedding层中,
  16. model.layers[0].set_weights([embedding_matrix]) #embedding_matrix ==>(max_words,embedding_dim)
  17. model.layers[0].trainable = False
 

  1. model.compile(loss='binary_crossentropy',optimizer='rmsprop',metrics=['acc'])
  2. history = model.fit(x_train,y_train,
  3. epochs = 10,
  4. batch_size = 32,
  5. validation_data = (x_val,y_val))
  6. model.save_weights('pre_trained_glove_model.h5')
 

  1. import matplotlib.pyplot as plt
  2.  
  3. acc = history.history['acc']
  4. loss = history.history['loss']
  5. val_acc = history.history['val_acc']
  6. val_loss = history.history['val_loss']
  7.  
  8. epochs = range(1,len(acc)+1)
  9.  
  10. plt.plot(epochs,acc,'bo',label='Training acc')
  11. plt.plot(epochs,val_acc,'b',label='Validation acc')
  12. plt.title('Traning and validation acc')
  13. plt.legend()
  14.  
  15. plt.figure()
  16.  
  17. plt.plot(epochs,loss,'bo',label='Training loss')
  18. plt.plot(epochs,val_loss,'b',label='Validation loss')
  19. plt.title('Traning and validation loss')
  20. plt.legend()
  21.  
  22. plt.show()
 

模型很快就开始过拟合,考虑到训练样本很少,这也很情有可原的

 
(2)下面在不使用预训练词嵌入的情况下,训练相同的模型  
  1. #定义模型
  2. from keras.models import Sequential
  3. from keras.layers import Embedding,Flatten,Dense
  4.  
  5. model = Sequential()
  6.  
  7. model.add(Embedding(max_words,embedding_dim,input_length=max_len))
  8.  
  9. model.add(Flatten())
  10. model.add(Dense(32,activation='relu'))
  11. model.add(Dense(1,activation='sigmoid'))
  12.  
  13. model.summary()
  14.  
  15. model.compile(loss='binary_crossentropy',optimizer='rmsprop',metrics=['acc'])
  16. history = model.fit(x_train,y_train,
  17. epochs = 10,
  18. batch_size = 32,
  19. validation_data = (x_val,y_val))

  1. import matplotlib.pyplot as plt
  2.  
  3. acc = history.history['acc']
  4. loss = history.history['loss']
  5. val_acc = history.history['val_acc']
  6. val_loss = history.history['val_loss']
  7.  
  8. epochs = range(1,len(acc)+1)
  9.  
  10. plt.plot(epochs,acc,'bo',label='Training acc')
  11. plt.plot(epochs,val_acc,'b',label='Validation acc')
  12. plt.title('Traning and validation acc')
  13. plt.legend()
  14.  
  15. plt.figure()
  16.  
  17. plt.plot(epochs,loss,'bo',label='Training loss')
  18. plt.plot(epochs,val_loss,'b',label='Validation loss')
  19. plt.title('Traning and validation loss')
  20. plt.legend()
  21.  
  22. plt.show()
 

  1. #在测试集上评估模型
  2.  
  3. test_dir = os.path.join(imdb_dir,'test')
  4.  
  5. labels = []
  6. texts = []
  7.  
  8. for label_type in ['neg','pos']:
  9. dir_name = os.path.join(test_dir,label_type)
  10. for fname in os.listdir(dir_name):
  11. if fname[-4:] == '.txt':
  12. f = open(os.path.join(dir_name,fname),encoding='UTF-8')
  13. texts.append(f.read())
  14. f.close()
  15. if label_type == 'neg':
  16. labels.append(0)
  17. else:
  18. labels.append(1)
  19.  
  20. sequence = tokenizer.texts_to_sequences(texts)
  21. x_test = pad_sequences(sequences,maxlen = max_len)
  22. y_test = np.asarray(labels)
 

model.load_weights('pre_trained_glove_model.h5')

model.evaluate(x=x_test,y=y_test)

 


 如果增加训练集样本的数量,可能使用词嵌入得到的效果会好很多。

2.keras实现-->字符级或单词级的one-hot编码 VS 词嵌入的更多相关文章

  1. 51nod图论题解(4级,5级算法题)

    51nod图论题解(4级,5级算法题) 1805 小树 基准时间限制:1.5 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 她发现她的树的点上都有一个标号(从1到n),这些树都在空 ...

  2. Linux学习笔记(三):系统执行级与执行级的切换

    1.Linux系统与其它的操作系统不同,它设有执行级别.该执行级指定操作系统所处的状态.Linux系统在不论什么时候都执行于某个执行级上,且在不同的执行级上执行的程序和服务都不同,所要完毕的工作和所要 ...

  3. codewar代码练习1——8级晋升7级

    最近发现一个不错的代码练习网站codewar(http://www.codewars.com).注册了一个账号,花了几天的茶余饭后时间做题,把等级从8级升到了7级.本文的目的主要介绍使用感受及相应题目 ...

  4. [数据库事务与锁]详解五: MySQL中的行级锁,表级锁,页级锁

    注明: 本文转载自http://www.hollischuang.com/archives/914 在计算机科学中,锁是在执行多线程时用于强行限制资源访问的同步机制,即用于在并发控制中保证对互斥要求的 ...

  5. MySQL行级锁,表级锁,页级锁详解

    页级:引擎 BDB. 表级:引擎 MyISAM , 理解为锁住整个表,可以同时读,写不行 行级:引擎 INNODB , 单独的一行记录加锁 表级,直接锁定整张表,在你锁定期间,其它进程无法对该表进行写 ...

  6. 行为级和RTL级的区别(转)

    转自:http://hi.baidu.com/renmeman/item/5bd83496e3fc816bf14215db RTL级,registertransferlevel,指的是用寄存器这一级别 ...

  7. CSS 各类 块级元素 行级元素 水平 垂直 居中问题

    元素的居中问题是每个初学者碰到的第一个大问题,在此我总结了下各种块级 行级 水平 垂直 的居中方法,并尽量给出代码实例. 首先请先明白块级元素和行级元素的区别 行级元素 一块级元素 1 水平居中: ( ...

  8. 【数据库】数据库的锁机制,MySQL中的行级锁,表级锁,页级锁

    转载:http://www.hollischuang.com/archives/914 数据库的读现象浅析中介绍过,在并发访问情况下,可能会出现脏读.不可重复读和幻读等读现象,为了应对这些问题,主流数 ...

  9. MySQL中的行级锁,表级锁,页级锁

    在计算机科学中,锁是在执行多线程时用于强行限制资源访问的同步机制,即用于在并发控制中保证对互斥要求的满足. 在数据库的锁机制中介绍过,在DBMS中,可以按照锁的粒度把数据库锁分为行级锁(INNODB引 ...

随机推荐

  1. 【Web前端开发最佳实践系列】前端代码推荐和建议

    一.常用的前端文件的组织结构: 1.js (放置JavaScript代码) lib(放置框架JavaScript文件) custom.js 2.css(放置CSS样式代码) lib(放置框架CSS文件 ...

  2. source.android.google && developer.android.google

    https://source.android.google.cn/ https://developer.android.google.cn/ https://source.android.com/co ...

  3. [转]redhat7(centos7) not registered to Red Hat Subscription Management

    [root@controller0 ~]# yum install ntp Loaded plugins: fastestmirror, product-id, search-disabled-rep ...

  4. 一个lucene源码分析的博客

    ITpub上的一个lucene源码分析的博客,写的比较全面:http://blog.itpub.net/28624388/cid-93356-list-1/

  5. docker搭建gitlab、Redmine

    本地使用windows,setting里面切换至linux 从Docker图标的右键菜单中选中 “Switch to Linux containers ...” Docker Engine运行在Lin ...

  6. cadence allegro 封装产考原点修改

    打开 dra文件后 在菜单栏 setup - change drawing origin 在命令栏输入 新的参考点位置 如想更改新坐标位置为 1,2 .输入  x 1 2 上面两步操作后即可修改!

  7. myeclipse2016破解过程

    1.安装myeclipse2016 CI 7就不介绍了..只需要注意最后安装完成后取消对号.不要立即运行myeclipse2016. 2.下载破解版工具. 到以下网址下载破解工具:http://dow ...

  8. 【CF757G】Can Bash Save the Day? 可持久化点分树

    [CF757G]Can Bash Save the Day? 题意:给你一棵n个点的树和一个排列${p_i}$,边有边权.有q个操作: 1 l r x:询问$\sum\limits_{i=l}^r d ...

  9. java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException

    启动spring boot项目的时候遇到了报错: -Sep- ::15.513 INFO [main] org.apache.catalina.core.StandardService.startIn ...

  10. npm publish 发布

    前言 我们npm publish发布的时候,一定是本地文件发布到远程仓库,并且登录到http://registry.npmjs.org(即npm adduser或npmlogin)之后,才可以进行发布 ...