第1章 自然语言处理和深度学习概述

正如章节题目,本章更多是一些基础性的概述,介绍的部分库的一些功能比较有趣。

去除停用词,并分词

from nltk.corpus import stopwords
from nltk.tokenize import word_tokenize

# 需要先nltk.download('punkt')和nltk.download('stopwords')
sent = 'deep learning for natural language processing is very interesting'
stop_words = set(stopwords.words('english'))
word_tokens = word_tokenize(sent)
filtered_sent = [w for w in word_tokens if w not in stop_words] 
print(filtered_sent)
# ['deep', 'learning', 'natural', 'language', 'processing', 'interesting']

计数向量化,生成词向量的one-hot编码

from sklearn.feature_extraction.text import CountVectorizer

texts = ['Ramiess sing classic songs', 'he listens to old pop', 'and rock music']
cv = CountVectorizer()
cv_fit = cv.fit_transform(texts)
print(cv.get_feature_names())
# ['and', 'classic', 'he', 'listens', 'music', 'old', 'pop', 'ramiess', 'rock', 'sing', 'songs', 'to']
print(cv_fit.toarray())
# [[0 1 0 0 0 0 0 1 0 1 1 0]
# [0 0 1 1 0 1 1 0 0 0 0 1]
# [1 0 0 0 1 0 0 0 1 0 0 0]]

TF-IDF分数

TF-IDF(词频和反向文档频率,term frequency–inverse document frequency)是信息检索领域的常用指标,字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降,即如果某个词或短语在一篇文章中出现的频率TF高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。
t f − i d f i = t f i , j ⋅ i d f i tf-idf_i=tf_{i,j} \cdot idf_i tfidfi=tfi,jidfi
t f i , j = n i , j ∑ k n k , j tf_{i,j}=\frac{n_{i,j}}{\sum_k n_{k,j}} tfi,j=knk,jni,j
n i , j n_{i,j} ni,j表示单词 i i i在文档 j j j中出现的次数
n k , j n_{k,j} nk,j表示单词 k k k在文档 j j j中出现的次数
故, t f i , j tf_{i,j} tfi,j计算的是单词 i i i在文档 j j j中的比例,即词频
i d f i = l g ∣ D ∣ ∣ { j : t i ∈ d j } ∣ idf_i=lg\frac{\vert D \vert}{\vert \{j:t_i\in d_j\} \vert} idfi=lg{j:tidj}D
∣ D ∣ \vert D \vert D表示语料库的文档总数
∣ { j : t i ∈ d j } ∣ \vert \{j:t_i\in d_j\} \vert {j:tidj}表示包含单词i的文档j的数量
故,两者相除再取以10为底的对数,即逆文档频率
举个例子:
假设一个文档包含100个单词,单词happy出现了5次,那么词频即为5/100=0.05,假设语料库共有1000万个文档,而单词happy出现在其中1000个文档中,那么逆文档频率为lg(10000000/1000)=4,故tf-idf=0.05×4=0.2

from sklearn.feature_extraction.text import TfidfVectorizer
texts = ['aaa bbb aaa', 'aaa ccc']
vert = TfidfVectorizer()
X = vert.fit_transform(texts)
print(X.todense())
#[[0.81818021 0.57496187 0.        ]
# [0.57973867 0.         0.81480247]]

如果大家测试上面的代码,会发现和上面的公式的计算结果不同,这是因为在sklearn中采用的公式和上面不同,其使用的公式如下:
v i , j = t f i , j ⋅ i d f i v_{i,j}=tf_{i,j} \cdot idf_i vi,j=tfi,jidfi
t f − i d f i = v i , j ∑ k v k , j 2 tf-idf_i=\frac{v_{i,j}}{\sqrt {\sum_k v_{k,j}^2}} tfidfi=kvk,j2 vi,j
分母上求了文档中所有单词的欧氏距离
t f i , j = n i , j tf_{i,j}=n_{i,j} tfi,j=ni,j
t f tf tf的值就是出现的次数
i d f i = l n ∣ D ∣ + 1 ∣ { j : t i ∈ d j } ∣ + 1 + 1 idf_i=ln\frac{\vert D \vert +1} {\vert \{ j:t_i \in d_j\} \vert + 1}+1 idfi=ln{j:tidj}+1D+1+1
使用是以e为底,公式上也有变化
但如果在代码中使用 v e r t = T f i d V e c t o r i z e r ( s m o o t h i d f = F a l s e ) vert=TfidVectorizer(smooth_idf=False) vert=TfidVectorizer(smoothidf=False)
那么
i d f i = l n ∣ D ∣ + 1 ∣ { j : t i ∈ d j } ∣ + 1 idf_i=ln\frac{\vert D \vert+1}{\vert \{ j:t_i \in d_j\}\vert + 1} idfi=ln{j:tidj}+1D+1
就不会在后面加1了,默认的是True,就是上面的加了1的公式
示例代码中的语料库为[‘aaa bbb aaa’, ‘aaa ccc’]
以第一个文档中的bbb为例,程序输出结果为0.57496187
因为在第一个文档中只出现了一次,所以 t f i , j = 1 tf_{i,j}=1 tfi,j=1
语料库中的文档总数为2,出现了bbb的文档数为1,所以 i d f i = l n 3 2 + 1 = 1.4054651081081644 idf_i=ln\frac{3}{2}+1=1.4054651081081644 idfi=ln23+1=1.4054651081081644
所以bbb的 v i , j = 1 × 1.4054651081081644 = 1.4054651081081644 v_{i,j}=1 \times 1.4054651081081644=1.4054651081081644 vi,j=1×1.4054651081081644=1.4054651081081644
同理,计算得第一个文档中的aaa的 v i , j = 2 × ( l n 3 3 + 1 ) = 2 v_{i,j}=2\times (ln\frac{3}{3} + 1)=2 vi,j=2×(ln33+1)=2
所以bbb的 t f − i d f i = 1.4054651081081644 1.405465108108164 4 2 + 2 2 = 0.5749618667993135 tf-idf_i=\frac{1.4054651081081644}{\sqrt{1.4054651081081644^2+2^2}}=0.5749618667993135 tfidfi=1.40546510810816442+22 1.4054651081081644=0.5749618667993135

Keras构建MIP模型的小例子

本例子所用的输血数据集见本文的下载链接
数据集一共有748条数据和4个属性

  • Recency, months since last donation
  • Frequency, total number of donation
  • Monetary, total blood donated in c.c.
  • Time, months since first donation
    和一个二元属性用1或0表示该用户是否在2007年3月献血
    首先对文件进行读取,并提取自变量和因变量
import keras
from keras.layers import Dense
from keras.models import Sequential
import numpy as np

# 根据具体的文件路径进行修改
trans = np.genfromtxt('D:\\py3\\book_dl_for_nlp\\transfusion.csv', delimiter=',', skip_header=1)
X = trans[:, 0:4]
Y = trans[:, 4]

下面,创建网络结构,第一层隐藏层由8个神经元组成,第二层隐藏层由6个神经元组成,均使用ReLU激活函数,输出层使用Sigmoid激活函数进行二元分类。

mlp_keras = Sequential()
mlp_keras.add(Dense(8, input_dim=4, kernel_initializer='uniform', activation='relu'))
mlp_keras.add(Dense(6, kernel_initializer='uniform', activation='relu'))
mlp_keras.add(Dense(1, kernel_initializer='uniform', activation='sigmoid'))

设置学习参数,并输出结果

mlp_keras.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
mlp_keras.fit(X, Y, epochs=200, batch_size=8, verbose=0)
accuracy = mlp_keras.evaluate(X, Y)
print('Accuracy:%0.2f%%' % (accuracy[1]*100))

整体代码如下

import keras
from keras.layers import Dense
from keras.models import Sequential
import numpy as np

#%%
trans = np.genfromtxt('D:\\py3\\book_dl_for_nlp\\transfusion.csv', delimiter=',', skip_header=1)
X = trans[:, 0:4]
Y = trans[:, 4]

#%%
mlp_keras = Sequential()
mlp_keras.add(Dense(8, input_dim=4, kernel_initializer='uniform', activation='relu'))
mlp_keras.add(Dense(6, kernel_initializer='uniform', activation='relu'))
mlp_keras.add(Dense(1, kernel_initializer='uniform', activation='sigmoid'))

#%%
mlp_keras.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
mlp_keras.fit(X, Y, epochs=200, batch_size=8, verbose=0)
accuracy = mlp_keras.evaluate(X, Y)
print('Accuracy:%0.2f%%' % (accuracy[1]*100))
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值