Movatterモバイル変換


[0]ホーム

URL:


rochefort's blog

この広告は、90日以上更新していないブログに表示しています。

Re: マルコフ連鎖で日本語をもっともらしく要約する

以前から気になっていたマルコフ連鎖をザリガニさんの記事を元に試してみました。

マルコフ連鎖で日本語をもっともらしく要約する - ザリガニが見ていた...。

マルコフ連鎖とは

マルコフ連鎖を説明してみる。 | 分析のおはなし。
個人的にはこちらの図と確率の話で理解しました。
wikipediaは分かりにくいです。
 

マルコフ連鎖分かち書きで文章を要約っぽくする

(ザリガニさんの記事に書いてありますが)
分かち書きしたデータを元にマルコフ連鎖を適用し文章を生成していきます。
ここで複数候補があった場合は、乱数を用いて選択していくことで
要約っぽいことが出来てしまいます。
結構自然な文章になるんですよね。

補足:マルコフ連鎖のロジック

ザリガニさんの記事内のマルコフ連鎖の記事はリンクが切れていましたが
ググってみると以下のtumblrにURLが変更されているようです。
こちらの記事はとてもわかりやすかったです。
netbookerの貯蔵庫 — 人工無能を作ろう~マルコフ連鎖(2接頭語と1接尾語の場合) ...

書いてみた

ザリガニさんの記事のコードは、今は動かないのでちょっと改良して手元で試してみました。

require'open-uri'# require 'mecab'require'natto'require'nokogiri'moduleAsahicomTOP_URL ='http://www.asahi.com/'classMarkovChainMIN_TEXT_SIZE =80MAX_TEXT_SIZE =180defsummarize_headline      url = scrape_headline_top_url      sleep1# 念のため1s待機      text = scrape_article_body(url)      data = generate_mecab_tagger(text)      result =''loopdo        result = summarize(data)        text_size = result.sizebreakif text_size >=MIN_TEXT_SIZE && text_size <=MAX_TEXT_SIZEend      puts result.gsub(/EOS$/,'')endprivatedefscrape_headline_top_url      doc =Nokogiri::HTML.parse(open(TOP_URL))      first_url = doc.css('.HeadlineTop a')[0][:href]URI.join(TOP_URL, first_url).to_senddefscrape_article_body(url)      doc =Nokogiri::HTML.parse(open(url))      doc.css('.ArticleText').text.tr("\n",'').gsub(/\A /,'')enddefgenerate_mecab_tagger(text)# mecab = MeCab::Tagger.new('-Owakati')      mecab =Natto::MeCab.new('-Owakati')      mecab.parse(text +'EOS').split('').each_cons(3).mapdo |a|        {head: a[0],middle: a[1],end: a[2] }endend# マルコフ連鎖で要約defsummarize(data)      t1 = data[0][:head]      t2 = data[0][:middle]      new_text = t1 + t2loopdo        candidates = data.select { |d| d[:head] == t1 && d[:middle] == t2 }breakif candidates.size ==0        num = rand(candidates.size)# 乱数で次の文節を決定する        new_text << candidates[num][:end]breakif candidates[num][:end] =='EOS'        t1 = candidates[num][:middle]        t2 = candidates[num][:end]end      new_textendendendif$0 ==__FILE__Asahicom::MarkovChain.new.summarize_headlineend

結果

今のTop記事は以下。
佐野氏謝罪「スタッフが第三者デザイン写す」 景品問題:朝日新聞デジタル
 
結果がこちら。
202020年とか、えらいことになってますが、年代とか固有名詞はtuningすればよさそうですね。

202020年東京五輪・パラリンピックのエンブレムを手掛けた佐野研二郎氏がデザインをトレースし、そのまま使用するということ自体が、デザイナーとして決してあってはならない」との共同制作でなく、個人応募だったと強調。ベルギーのデザイナーらが提訴 佐野氏は14日、スタッフが第三者のものと思われるデザインを写して使ったことを明らかにし、謝罪した。

ポイント

乱数で候補の選択をおこなっているため、毎回結果が異なりますが
結構文字数に大きな差が出てきます。
そこで、そこそこの文字数に収まるように、min/max値を設定するようにしたところ
なかなかいい感じに要約っぽくなりました。

余談ffi

gemはmecab でも動くのですが natto というライブラリを使ってみました。
このキラキラネームならぬネバネバネームは気になります。
この実装が面白くffi/ffi を利用してます。
これを機にちょろっとffi 調べてみたのですが、これはすごいですね。
コンパイル不要でCのライブラリが扱えてしまうんですね。

About
id:rochefortid:rochefort

Ruby・Rails・Mac・Web・Tech、時々日々のことについて書いています。

follow
Search
Top Entries
はてなブックマーク数
Categories
Comments

    引用をストックしました

    引用するにはまずログインしてください

    引用をストックできませんでした。再度お試しください

    限定公開記事のため引用できません。

    読者です読者をやめる読者になる読者になる

    [8]ページ先頭

    ©2009-2025 Movatter.jp