【机器学习】文本数据简单向量化

来源:互联网 发布:华为网络机顶盒密码 编辑:程序博客网 时间:2024/06/04 20:14

一个文本数据指的是一篇文章,或者一段话,或者一句话。这个文本数据通常称为document,或者text。我们平常的文本都是以人的表达方式展现的,是一个流数据,时间序列数据。我们如果要用计算机对文本数据进行处理,就必须将文本数据表示为计算机能理解的方式。这篇博客就讲解给定一个已经分词、去除停用词后的文本数据集,如何将其向量化的方法。

one-hot表示法

one-hot表示法先将文本数据集中不重复的单词提取出来,得到一个大小为V的词汇表。然后用一个V维的向量来表示一个文章,向量中的第d个维度上的1表示词汇表中的第d个单词出现在这篇文章中。比如给定一个数据集
这里写图片描述

首先提取出其中的不重复单词(不考虑单词在文本中出现的先后顺序),得到一个含有7个单词的词汇表:
这里写图片描述

那么文本数据集就转化为one-hot矩阵:
这里写图片描述

vocab = sorted(set(words), key=words.index)def doc2onehot_matrix(vocab, docs):    '''       transform a document to onehot vector    '''    M = len(docs)    V = len(vocab)    onehot = np.zeros((M, V))    for d, doc in enumerate(docs):        for word in doc:            if word in vocab:                pos = vocab.index(word)                onehot[d][pos] = 1    return onehot

如果文本数据集太大,那么得到的词汇表中可能存在几千个单词,这样会文本的维度太大,不仅会导致计算时间增加,而且带来了稀疏问题(one-hot矩阵中大多数元素都是0)。因此,我们通常在计算词汇表的时候,会排除那些出现次数太少的单词,从而降低文本维度。

tf 表示法

不同于one-hot表示法只关心单词是否出现,tf (term-frequency)表示法还关心单词出现的次数,因此tf矩阵中每个元素表示其对应的单词在文章中出现的次数/文章中的总次数,即单词在文章中的频率。

tfi,j=ni,jknik,j

对于上述的文本数据集,如果用tf矩阵表示就是:
这里写图片描述

tf-idf 表示法

tf-idf (term frequency–inverse document frequency),不仅考虑了单词在文章中的出现次数,还考虑了其在整个文本数据集中的出现次数。TF-IDF的主要思想是:如果某个词或短语在一篇文章中出现的频率TF高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力。idf就是用来衡量一个单词在所有文本中的出现频率,其计算公式为:

idfi=log|D||{j:tidj}|

期中,|D|表示总文章数,分母表示包含词i的文章数。通常,为了防止分母为0会在分母加1,即
idfi=log|D|1+|{j:tidj}|

在idf的计算公式中使用了log,是因为如果某个词在这个文本中的出现次数太少,就会使得|D|除以这个次数得到的值非常大,直接乘以tf会使得idf对计算结果的影响非常大,因此取对数来抑制idf的影响。那么对数应该以什么为底呢?其实任何正数都是可以的,底的取值跟文本数据集没有关系的,因为底的取之不同,并不会改变每个单词的相对重要性。不过一般的取值是10。

def doc2onehot_tf_matrix(vocab, docs):    '''       transform document to onehot vector    '''    M = len(docs)    V = len(vocab)    onehot = np.zeros((M, V))    tf = np.zeros((M, V))    for d, doc in enumerate(docs):        for word in doc:            if word in vocab:                pos = vocab.index(word)                onehot[d][pos] = 1                tf[d][pos] += 1    # normalize to get term frequency    row_sum = tf.sum(axis=1)    tf = tf / row_sum[:, np.newaxis]    return onehot, tfdef doc2tfidf_matrix(onehot, tf):    '''      transform document to tf-idf    '''    M = onehot.shape[0]    ndw = onehot.sum(axis=0) # number of documents contain word     idf = list(map(lambda x: log10(M) / (x+1), ndw))    tfidf = tf * np.array(idf)    return tfidf

其他方法

上述方法都以一定的合理性将文本转化为了向量,但是却存在“语义鸿沟”问题。比如one-hot表示法,假设一个文本中只存在一个词麦克,另外一个文本中只存在一个词话筒,那么可以将这两个文章分别表示为[0,0,0,0,1,0,0,0],[1,0,0,0,0,0,0,0],这样虽然两个文本中的单词相似,但是得到的距离却很远。因此一些深度学习方法将文本将单词表示为n维的实值向量,类似[0.792, −0.177, −0.107, 0.109, −0.542, …]形式。那么每个文本可以基于这些词向量,通过某种方式提取为m维的实值向量。通过这种方法表示的文本,再通过欧氏距离或者余弦距离方法计算得到的距离,就能使得语义相似的词得到的距离相近。

0 0
原创粉丝点击