开篇
在NLP的前一篇文章,我希望关注的点就是我们文本的表示,说浅显一点就是词语的向量化,前面我们使用了one-hot编码,使用词袋模型,但是词袋模型几乎在现在的NLP任务中是不被使用的,只是作为一个入门的基础,我们是需要慢慢过渡到我们要使用的词向量去,当然在说词向量之前,我们还是要提一下一个比较重要的概念TF-IDF。
TF-IDF
TF-IDF是Text Frequency – Inverse Document Frequency的缩写,很显然从字面意思上,TF-IDF是由两部分组成的,前半部分是词频,后半部分是逆文档频率。TF-IDF是衡量单词重要性的一种指标。
任务
关于任务的介绍可以参照之前的博客词袋模型,里面有详细的解说,这边就明确一下我们的基本任务吧,输入是一条短信的文本,输出是是否是垃圾短信的分类类别。在本文的最后我会放上完整的代码。为了避免数据放置位置的错误,我将数据集的下载和放置直接写在了代码里面,也就是说,代码是可以直接跑的,只要你的环境是没有问题的。
代码
日常的预处理
texts = [x[1] for x in text_data]
target = [x[0] for x in text_data]
# Relabel 'spam' as 1, 'ham' as 0
target = [1. if x=='spam' else 0. for x in target]
# Normalize text
# Lower case
texts = [x.lower() for x in texts]
# Remove punctuation
texts = [''.join(c for c in x if c not in string.punctuation) for x in texts]
# Remove numbers
texts = [''.join(c for c in x if c not in '0123456789') for x in texts]
# Trim extra whitespace
texts = [' '.join(x.split()) for x in texts]
下面就是我们的核心部分,TF-IDF的处理,我们的TensorFlow没有直接处理TF-IDF的函数,所以这边我们调用sklearn这个机器学习库来生成我们每一个单词的tf-idf值,请看代码:
def tokenizer(text):
words = nltk.word_tokenize(text)
return words
# Create TF-IDF of texts
tfidf = TfidfVectorizer(tokenizer=tokenizer, stop_words='english', max_features=max_features)
sparse_tfidf_texts = tfidf.fit_transform(texts)
最上面的那个函数是一个分词函数,使用的是NLTK这个NLP的python库,效果其实就是这样的
In [1]: import nltk
In [2]: a = "my name is tensorflow"
In [3]: a = nltk.word_tokenize(a)
In [4]: a
Out[4]: ['my', 'name', 'is', 'tensorflow']
先解释一下TfidfVectorizer函数里面的几个参数,第一个是分词函数,第二个它会默认去掉一些停用词,第三个是取频率靠前多少的那些词。这里我们取的是频率
下面有一个简单的示例,给你展示一下,这个函数到底是在作用什么?
In [1]: from sklearn.feature_extraction.text import TfidfVectorizer
In [2]: corpus = [
...: 'This is the first document.',
...: 'This is the second second document.',
...: 'And the third one.',
...: 'Is this the first document?',
...: ]
In [3]: vectorizer = TfidfVectorize