じゃあ、おうちで学べる

本能を呼び覚ますこのコードに、君は抗えるか

Basic Summarization Modelを用いてアイドルのブログの文章をさらっと読むオタク気持ち悪い

概要

僕自身が精神的に追い込まれると何も進捗を生やせなくなるアイドルオタクになる。しかし、怠惰なオタクはいちいちアイドルの意味のない文章を全て読んでいるわけにはいきません。要約する。

前回

アイドルのホームページから画像を自動で取得するオタク気持ち悪い() - じゃあ、おうちで学べる

Multi-document Summarization

複数文書要約とは、同じトピックについて書かれた複数のテキストから情報を抽出することを目的とした自動手続きである。その結果、簡潔で包括的な情報レポートを作成します。大きな文書クラスタに含まれる情報をすばやく理解することができます。非常に大きな文書であっても、単一の文書を要約するよりはるかに複雑であります。この難しさは、大量の文書内での必然的なテーマの多様性から生じる。優れた要約技術は、主要テーマを完全性、可読性、および簡潔さと組み合わせることを目指しています。しかし、今回は複雑さを避けるために単一文章(Document Summarization)について考えます。

Basic Summarization Model

A Study on Position Information in Document Summarizationの3章で紹介されている。Basic Summarization Modelとは位置情報を適用するための単語ベースの要約モデルを提案する。このシステムは、最も顕著な文章を選択することによってターゲット要約を構成する典型的な抽出スタイルに従います。最初の文は最も重要であり、終わりに近づくにつれて文の重要度は減少していく、というsentence position hypothesisに基づいてスコア付けされます。今回はこちらを使います。

要約する文章

www.keyakizaka46.com

タイトル

けやかけのお話し⌄̈⃝

本文

[著作権を配慮して削除予定]

実装

#!/usr/bin/env python3
# -*- coding: utf-8 -*-


import MeCab as mc
import numpy as np

m = mc.Tagger("-Ochasen")

def mecab_senter(text):
    if type(text) is bytes:
        text = text.decode("cp932")
    node = m.parseToNode(text)
    sentences = []
    sentence = []
    while node:
        sentence.append(node.surface)        
        if node.surface in ["(笑)","☆","!","♡","♪","。"]:
            sentences.append(sentence)
            sentence = []
        node = node.next
    return sentences

def get_freqdict(sentences):
    freqdict = {}
    N = 0
    for sentence in sentences:
        for word in sentence:
            freqdict.setdefault(word, 0.)
            freqdict[word] += 1
            N += 1
    return freqdict

def score(sentence, freqdict):
    return np.sum([np.log(freqdict[word]) for word in sentence]) / len(sentence)

def direct_proportion(i, n):
    return float(n-i+1)/n

def inverse_proportion(i, n):
    return 1.0 / i

def geometric_sequence(i, n):
    return 0.5 ** (i-1)

def inverse_entropy(p):
    if p == 1.0 or 0.0:
        return 1.0
    return 1-(-p*np.log(p) - (1-p)*np.log(1-p))

def inverse_entropy_proportion(i, n):
    p = i / n
    return inverse_entropy(p)

def summarize(text, limit=100, **options):
    sentences = mecab_senter(text)
    freqdict = get_freqdict(sentences)
    if options["m"] == 0:
        scores = [score(sentence, freqdict) for sentence in sentences]
    if options["m"] == 1:
        if options["f"] == 0:
            word_features = direct_proportion
        elif options["f"] == 1:
            word_features = inverse_proportion
        elif options["f"] == 2:
            word_features = geometric_sequence
        elif options["f"] == 4:
            word_features = inverse_entropy_proportion

        scores = []
        feature_dict = {}
        for sentence in sentences:
            sent_score = 0.0
            for word in sentence:
                feature_dict.setdefault(word, 0.0)
                feature_dict[word] += 1
                sent_score += np.log(freqdict[word]) * word_features(feature_dict[word], freqdict[word])
            sent_score /= len(sentence)
            scores.append(sent_score)

    topics = []
    length = 0
    for index in sorted(range(len(scores)), key=lambda k: scores[k], reverse=True):
        length += len(sentences[index])
        if length > limit: break
        topics.append(index)
    topics = sorted(topics)
    return "".join(["".join(sentences[topic]) for topic in topics])


def main():
    blog_title = u"けやかけのお話し.txt"
    blog_text = open(blog_title, encoding='utf-8').read().replace('\n','').replace('\r','')
    print("タイトル") 
    print(blog_title)
    print("本文")
    print(blog_text)
    print("#####################################")
    print("basic summarization model")
    print(summarize(blog_text, m=0))
    print("#####################################")
    print("using word position feature and direct proportion")
    print(summarize(blog_text,m=1,f=0))
    print("#####################################")
    print("using word position feature and inverse proportion")
    print(summarize(blog_text, m=1, f=1))
    print("#####################################")
    print("using word position feature and Geometric sequence")
    print(summarize(blog_text, m=1, f=2))   
    print("#####################################")


if __name__ == '__main__':
    main()

出力

タイトル
けやかけのお話し.txt
本文
こんばんは☆今日は紅白歌合戦さんのリハーサルに行って参りました!ドキドキでしたが、やっと出させていただけるという実感が湧きました!本番まであと2日です!みんなで力を合わせて練習していきます!あと2日で1年が終わってしまうなんて、、、早すぎます( ºΔº )残りの2016年、大切に過ごしたいと思います!*☼*―――――*☼*―――――先日の「欅って書けない?」では没アンケートなどを供養する企画でした!私はパパラッチ企画で手鏡をレフ板替わりにして自撮りしていた所をまなかに隠し撮りされてしまいました( ºΔº )恥ずかしいー(´•ω•̥`)実は現在発売中の「B.L.T. 2月号」さんに欅坂46が掲載させていただいていて、その撮影中のひとコマでした!窓から光が入ってきたから、もしかしたら反射するかなって思ったけれど、あまり変わりませんでした(笑)B.L.T.さんは撮影中、くす玉で紅白出場のお祝いをしてくださいました!!とーっても嬉しかったです✧ \( °∀° )/ ✧ありがとうございました!盛りだくさんの内容になっていますのでまだ読んでいないという方はぜひ手に取ってみてくださいね♡ねるが私にバースデーソングを歌ってくれていた動画も紹介されましたね⌄̈⃝HAPPY BIRTHDAY ゆかり〜♪ねるは私のことをゆかりって呼ぶんです(笑)あの動画は私の誕生日の0時過ぎにふーちゃんから送られてきて、爆笑しちゃいました!あと、私がMキャラと紹介されてしまったのですが、普段からいじられキャラという意味で書きました!確かに、レッスンなどで厳しくご指導いただくのは身になるので好きです!でも、やっぱり怒られるより褒められる方が好きなので、握手会などではみなさん優しくしてくださいね(´・ω・`)♡それではまたね♪
#####################################
basic summarization model
今日は紅白歌合戦さんのリハーサルに行って参りました!ドキドキでしたが、やっと出させていただけるという実感が湧きました!みんなで力を合わせて練習していきます!あと、私がMキャラと紹介されてしまったのですが、普段からいじられキャラという意味で書きました!
#####################################
using word position feature and direct proportion
今日は紅白歌合戦さんのリハーサルに行って参りました!ドキドキでしたが、やっと出させていただけるという実感が湧きました!本番まであと2日です!みんなで力を合わせて練習していきます!
#####################################
using word position feature and inverse proportion
今日は紅白歌合戦さんのリハーサルに行って参りました!ドキドキでしたが、やっと出させていただけるという実感が湧きました!本番まであと2日です!みんなで力を合わせて練習していきます!
#####################################
using word position feature and Geometric sequence
今日は紅白歌合戦さんのリハーサルに行って参りました!ドキドキでしたが、やっと出させていただけるという実感が湧きました!本番まであと2日です!みんなで力を合わせて練習していきます!
#####################################

最後に

オタクとしてこのようなことに利用してしまいましたがBasic Summarization Modelはもう少しちゃんとチューニングすれば面白い分野だと感じました。もう少し論文を読み込んでの実装力の部分をどうにかしていきたいです。

参考

A Study on Position Information in Document Summarization
Multi-document summarization - Wikipedia
National Institute of Standards and Technology - Wikipedia