如何自动生成文本摘要

作者: 不会停的蜗牛 | 来源:发表于2017-05-26 11:47 被阅读3091次

    学习资料:
    https://www.youtube.com/watch?v=ogrJaOIuBx4&list=PL2-dafEMk2A7YdKv4XfKpfbTH5z6rEEj3&index=19
    代码:
    https://github.com/llSourcell/How_to_make_a_text_summarizer/blob/master/vocabulary-embedding.ipynb

    今天学习的是自动生成文本摘要。

    当我们的身边的信息越来越多,数据越来越多,链接越来越多的时候,用一句简单的话就能把最重要的信息给表达出来,变得越来越重要。

    有了这个技能,我们就可以让机器为我们提取一篇文章的重要信息,以后甚至是一本书的重要信息。

    这个技术最早是在气象领域应用起来的,就是用一个固定的格式把预测出来的数据套入进去,后来在金融领域,医疗领域也得到广泛的应用,这样的工具可以很好的帮助从业人员节省一部分时间。

    过去的方法是提取一个子集,而我们的大脑在对一篇文章进行总结的时候,利用的是抽象性思维,现在我们就可以用深度学习来模拟这个过程。


    我们要用的数据是BBC新闻数据集。
    http://mlg.ucd.ie/datasets/bbc.html

    pickle, 可以将python的对象转化成character stream,我们可以很轻松的重建这个对象:

    import cPickle as pickle
    FN0 = 'tokens' # this is the name of the data file which I assume you already have
    with open('data/%s.pkl'%FN0, 'rb') as fp:
        heads, desc, keywords = pickle.load(fp) # keywords are not used in this project
    

    返回的heads就是标题,desc就是相应的文章。

    接着我们需要把整个文章变成一个一个的单词,并且一个词一个词的生成总结。

        from collections import Counter
    from itertools import chain
    def get_vocab(lst):
        vocabcount = Counter(w for txt in lst for w in txt.split())
        vocab = map(lambda x: x[0], sorted(vocabcount.items(), key=lambda x: -x[1]))
        return vocab, vocabcount
    

    接着我们要用词向量来表示每个单词。
    word2vec是一个用大量数据提前训练好的模型,我们可以直接下载。

    词向量的每个维度可以表示一个性质,可以是性别或者是头衔等,词向量在每个维度的投影长度可以看作是这个单词在这个性质上的相关度。

    另一种算法叫做GloVe,它属于 count based的,
    每一行代表一个单词,每一列代表和这个单词出现在同一语境中的频数。
    GloVe 比 word2vec 稍微快一点,

    首先,将提前训练好的 glove 词向量下载到本地,然后用它们来初始化embedding matrix,我们先随机初始化,然后把 training vocabulary 出现的所有单词的 glove 权重复制一下。对于词汇表以外的单词,我们会找到离它最近的一个 glove 向量。

         path = 'glove.6B.zip'
        path = get_file(path, origin="http://nlp.stanford.edu/data/glove.6B.zip")
    
    

    然后我们要用 seq2seq 模型,我们输入一句话。

    encoder,输入就是 vocabulay 集,标签就是相应的一句话标题,embeddings 会在训练过程中不断地优化,loss 是 cross entropy。

    decoder,和encoder一样的 lstm 结构,权重矩阵也是用同样的提前训练好的 glove embeddings,它用来生成 summary。

        model = Sequential()
    model.add(Embedding(vocab_size, embedding_size,
                        input_length=maxlen,
                        W_regularizer=regularizer, dropout=p_emb, weights=[embedding], mask_zero=True,
                        name='embedding_1'))
    for i in range(rnn_layers):
        lstm = LSTM(rnn_size, return_sequences=True, # batch_norm=batch_norm,
                    W_regularizer=regularizer, U_regularizer=regularizer,
                    b_regularizer=regularizer, dropout_W=p_W, dropout_U=p_U,
                    name='lstm_%d'%(i+1)
                      )
        model.add(lstm)
        model.add(Dropout(p_dense,name='dropout_%d'%(i+1)))
    
    

    这里有一个很关键的点,就是我们需要记住这段文字中的哪些部分呢?关于记忆的话,我们会选择用 ltm 模型来做,而在这个问题上另一个重要的理论就是 attention,它可以学到哪些数据是最相关的最需要记忆的。

    decoder 会先生成一个单词,然后把这个单词投入到下一层中,就会生成下一个单词,一直到生成一句标题。

    我们在 decoder 这里会应用 attention 机制,对于每一个输出的单词,会计算每个输入单词的权重,来决定应该在这个单词上投入多少 attention。这些权重会被用来计算最后一个隐藏层的加权平均,然后投入到 softmax中。

    可以看一下训练效果:

        X = "What have you been listening to this year ? If you want to find out using cold , hard evidence , then Spotify 's new Year in Music tool will tell you ."
    Y = "Spotify Will Make You Smarter for Your App"
        
        samples = gensamples(X, skips=2, batch_size=batch_size, k=10, temperature=1)
        
        HEADS:
    12.9753409925 How To Make A <0>^
    
    

    推荐阅读 历史技术博文链接汇总
    http://www.jianshu.com/p/28f02bb59fe5
    也许可以找到你想要的

    相关文章

      网友评论

      • ddef50139312:关键是生成式的东西具有逻辑性吗
      • Coming0524:大神,这个东东绝对好想法,可以分析多国语言就好了
        不会停的蜗牛:@Coming0524 现在芝加哥
        Coming0524:@不会停的蜗牛 大神在那个国家?
        不会停的蜗牛:@Coming0524 中文也有很多相关论文在研究的,基本模型差不多,会做各种改进,感兴趣可以查查arxiv上的论文
      • 维真_dfb9:姐 我觉得应该写一写关于tensorflow serving的文章 因为不能光把模型在本地训练呀 还得部署到服务器上之后才能有价值呀😀
        Elfsong:@维真_dfb9 直接在服务器跑不就可以了

      本文标题:如何自动生成文本摘要

      本文链接:https://www.haomeiwen.com/subject/iuntfxtx.html