学习笔记-基于keras实现基于 fasttext 的 IMDB 数据集的文本分类

1、fasttext 核心思想

fastText的核心思想就是:将整篇文档的词及n-gram向量叠加平均得到文档向量,然后使用文档向量做softmax多分类。

2、首先导入数据

from keras.datasets import imdb

max_features = 20000  # 词典最大长度
(x_train, y_train), (x_test, y_test) = imdb.load_data(num_words=max_features)

查看数据集,数据已经是数字形式了。
在这里插入图片描述
设置一些参数:

ngram_range = 2  # 抽取的是二元组,可以自己定
max_features = 20000  # 词典最大长度
max_len = 400  # 刚刚通过 np.mean(list(map(len,x_train))) 查看了句子的平均长度 设置为400合适
batch_size = 32
embedding_dims = 100  # 每个单词的编码长度
epoch = 5  # 训练几个 epoch

3、再进行n元组的统计,生成 元组的 词表

def create_ngram_set(input_list, ngram_value=2):
    '''
    返回 不重复的 n_gram 词组
    :param input_list: 输入的列表,也就是 imdb 数据中的每个样本(list形式)
    :param ngram_value: 几元组
    :return: 返回不重复的 n_gram 词组,用于做元组表
    '''
    return set(zip(*[input_list[i:] for i in range(ngram_value)]))

4、加入多元词组特征

# 判断是否大于 1,大于1 就要加入多元词组特征
if ngram_range > 1:
    ngram_set = set()
    for input_list in x_train:
        for i in range(2, ngram_range + 1):
            # 抽取几元组
            set_of_ngram = create_ngram_set(input_list, ngram_value=i)
            ngram_set.update(set_of_ngram)

    start_index = max_features + 1
    # 将新生成的 n_gram 特征加入字典中
    token_index_dict = {v: k + start_index for k, v in enumerate(ngram_set)}
    index_token_dict = {token_index_dict[k]: k for k in token_index_dict}

    max_features = len(list(token_index_dict.keys())) + 1
	# 这个函数会在后面,就是将n_gram的信息 加入到原有的 字特征里
    x_train = add_ngram(x_train, token_index_dict, ngram_range)
    x_test = add_ngram(x_test, token_index_dict, ngram_range)
	
	# 将数据的长度进行 padding 大于 maxlen 的截断, 小于 maxlen 的进行补全
    x_train = sequence.pad_sequences(x_train, maxlen=max_len)
    x_test = sequence.pad_sequences(x_test, maxlen=max_len)

5、add_ngram 函数

def add_ngram(sequences, token_indice, ngram_range=2):
    '''
    对每一个句子进行 n_gram 特征的加入 生成 所有 token 的字典 和 index 字典
    然后 遍历 sequences ,每一个句子 按照几元组的 形式分割,到 token_indice 中去索引,如果有值就加入
    :param sequences: 【【word1,word2,word3.。。】,【word1,word2,word3.。。】。。。】
    :param token_indice: 生成多元组和原始 token 的字典
    :param ngram_range: n_gram 中的 n
    :return: 返回新的 加入 n_gram 特征的列表中的列表
    '''
    new_sequences = []
    for input_list in sequences:
        # 将 列表 进行复制
        new_list = input_list[:]
        # 抽取几元组特征
        for ngram_value in range(2, ngram_range + 1):
            # 抽取 2 元组就在 len(list) 到 len(list)- 2 上进行选取
            for i in range(len(new_list) - ngram_value + 1):
                n_gram = tuple(input_list[i:i + ngram_value])
                if n_gram in token_indice:
                    new_list.append(token_indice[n_gram])
        new_sequences.append(new_list)
    return new_sequences

6、创建 fasttext 模型

class MyModel(keras.models.Model):
    def __init__(self, max_features, embedding_dims, maxlen, num_class):
        super(MyModel, self).__init__()
        self.embedding1 = Embedding(max_features, embedding_dims,input_length=maxlen)
        self.global_average_pool = GlobalAveragePooling1D()
        self.dropout = Dropout(rate=0.2)
        self.dense1 = Dense(num_class,activation='sigmoid')
        self.dense2 = Dense(200,activation='relu')

    def call(self, input):
        x = self.embedding1(input)
        x = self.global_average_pool(x)
        x = self.dense2(x)
        x = self.dropout(x)
        x = self.dense1(x)
        return x

7、模型实例化、编译、训练

num_class = 1
my_model = MyModel(max_features,embedding_dims,max_len,num_class)
my_model.compile(
    loss='binary_crossentropy',
    metrics=['accuracy'],
    optimizer="adam"
)

my_model.fit(
    x_train,
    y_train,
    batch_size=batch_size,
    epochs=epoch,
    validation_data=(x_test, y_test)
    # , callbacks=call_back_list  这一块可以设置自己的回调函数 去做自己想做的事
)

训练效果图:
学习笔记-基于keras实现基于 fasttext 的 IMDB 数据集的文本分类_第1张图片

END

你可能感兴趣的:(文本分类,keras,分类)