文本分类实战----数据处理篇

最近在参加kaggle上的一个文本分类的比赛,因为持续时间比较长,有两个月的时间,想在这期间详细的学习一下文本分类的方法和知识,所以会持续更新一些博客来记录参赛的过程。在比赛结束后,我会将参赛过程中使用的代码放到我的Github上面,大家相互学习。主要会包括如何处理数据,参赛中使用的模型,一些重要方法的原理等方面的东西。本篇主要记录数据的处理方法。

任务介绍

首先我们介绍一下这个比赛的任务,是对输入的英文文本做二分类任务。具体来说,输入一个英文的问句,需要我们的模型来判断这个问句是不是有意义的,最后输出对应的标签。“有意义”是指这个问句是一个正常的问题,而不是一个带有感情色彩的声明或者不是基于事实的问题,并且这个问题不涉及低俗*等因素。

数据集

首先我们介绍一下比赛官方给出的数据集。数据集由Excel表格给出。训练集的数据1.31million行,测试集数据有56.4k行。每一条训练数据由[qid, question text, target]组成 ,其中qid是每一条数据的唯一id标识,question text是英文问句文本,target是0/1,0代表正常问句,1则相反。下图是示例。测试数据集是需要提交到后台进行判定的,因此是没有target这一项的。
文本分类实战----数据处理篇

另外,比赛官方还给了embedding好的词向量作为支撑数据。四种词向量:Google-vectors-negative300, glove.84B.300d, paragram_300_sl999, wiki-news-300d-1M。都是300维的词向量。

数据处理
方法一:embedding—三种词向量的串联

这里用的方法是使用了官方给出的词向量,将每一个问句中的单词都转化为词向量的形式。不过,为了更为准确的描述一个词,我们这里同时使用了三个词向量(glove.840B.300d,wiki-news-300d-1M,paragram_300_sl999)标识单词,具体做法是将三个词向量串联到一起,形成一个3*300=900维的向量。下面的代码展示了将单词转化为一个300维向量的过程,我们只要重复这个步骤,就可以得到多个词向量。

EMBEDDING_FILE = '../input/embeddings/glove.840B.300d/glove.840B.300d.txt'
def get_coefs(word,*arr): return word, np.asarray(arr, dtype='float32')
embeddings_index = dict(get_coefs(*o.split(" ")) for o in open(EMBEDDING_FILE))

all_embs = np.stack(embeddings_index.values()) # 二维数组 2096016*300
print(all_embs.shape[0])
emb_mean,emb_std = all_embs.mean(), all_embs.std()  # scalar 均值,标准差
print("mean=",emb_mean)
embed_size = all_embs.shape[1]  # 300

word_index = tokenizer.word_index  # 单词对应的整数编号形成的列表
nb_words = min(max_features, len(word_index))  # 只取两者中较小者的单词数量
# 结合下面的代码。对于embeddings中没有的单词,使用随机初始化的词向量
embedding_matrix_1 = np.random.normal(emb_mean, emb_std, (nb_words, embed_size))
for word, i in word_index.items():
    if i >= max_features: 
        continue
    embedding_vector = embeddings_index.get(word)
    if embedding_vector is not None: 
        embedding_matrix_1[i] = embedding_vector

del embeddings_index; gc.collect() # 内存空间清理

我们对另外两个embeddings使用同样的代码就可以得到所用的另外两个词向量矩阵。代码就不重复贴了。下面的代码将三种词向量串联起来。

embedding_matrix = np.concatenate((embedding_matrix_1, embedding_matrix_2, embedding_matrix_3), axis=1)  
del embedding_matrix_1, embedding_matrix_2, embedding_matrix_3
gc.collect()
np.shape(embedding_matrix)  # (50000, 900)

这样,我们就得到了最终的词向量,每个单词由一个900维的向量表示。