続・最上静香っぽい台詞を作る(?)プログラム

f:id:runaru_dearly1641:20180515150619j:plain

恥の多い生涯を送ってきました。けどこのブログは現在進行系の恥ですね。

はじめに

フォトカツ死んだ、フォトカツ死んじゃったよ〜

フォトカツのおかげでアイカツしれたので感謝感謝です。って感じです。

本題

前回「アイマスPなのでプログラムで最上静香を喋らせる」の続きです

naru1641.hatenadiary.jp

 

プログラムの変更

前回の記事で動かしたプログラムをそれっぽく手直ししました。その実行結果をのせます。

 

  究極のうどんをバカにして、かならず勝利していてあげます。さあ、今日のうちに終わらせましょうね。
  個性がよく出てますか?お仕事、サボったりしない…!プロデューサー…
  食べ歩きって初めてですけど…?ここなら、えっと…!う…
  光が、お膳立てしてみようと思いますし。
  ロコ担当です。むしろ…すごく楽しい!
  嬉しい。ありがとう…いただきます!お客さんも、うれしいプレゼントです。そうですね…
  勝ち上がるのは、家族と過ごすことしかできなかったせいか、指が思っただけですっ!ご、ご褒美がどんな風に、走り回っていますから…
  自信作ですよ!ふふっ♪イベント、終わっちゃいそうですね…

 

主な手直し点は

  • クソ長な文が一つ → 複数の短文を作る
  • 文の先頭、終わりがそこまで不自然にならないように

です。

 

プログラムを弄るなら、その元がどう動作しているかを知っていた方がやりやすいです。

そこで面倒でしたが前回のソースコード全部しっかり読んだので、肝である文章を作る仕組みの部分を解説します。

文章を作る仕組み

まず、文章を単語の集まり、繋がりとして捉えるところから始まります。

「文章」私はうどんが好きです。
     ↓
「単語」私 は うどん が 好き です 。

 

 「私はうどんが好きです。」 は、「私」→「は」→「うどん」→「が」→「好き」→「です」→「。」 という順番で単語が繋がって出来ている、ということです。

つまり 文章を作る=単語をどんどん繋げていく です。

 

このプログラムでは、それっぽい文章を作るために元の文章(前回記事で作ったテキストファイル)から、どの単語にどの単語を繋げるかのリストを用意しています。

「私」 「は」 「うどん」 「が」 「好き」 「です」 「。」
       キー        キーによって呼び出される単語
    1.「私」   2.「は」  → 「うどん」
    1.「は」   2.「うどん」→ 「が」
    1.「うどん」2.「が」  → 「好き」
    (略)
    1.「好き」 2.「です」 → 「。」

こんな感じのリストを全文章からひたすら作ります。

多くの文章からリストを作ることで、

    1.「私」   2.「は」  → 「うどん」
     と
    1.「私」   2.「は」  → 「天才」    

 のように、同じ単語の繋がりをキーに持つ単語が複数出てくるので、文章作り(単語つなぎ)がランダム性を持ちます。なのでユニークな文が生まれて楽しい!ということです。

 

リスト作成部分のコードです。ここは弄りようがないので前回記事のサイト

[Python]マルコフ連鎖で自動文章 | IT屋シミダイの頭の中

ソースコードそのままです。

    # マルコフ連鎖用のテーブルを作成する
    markov = {}
    w1 = ""
    w2 = ""
    #w3 = "" #2語でなくて3語でリストを作りたい時に使う(ex. 1.「私」 2.「は」 3.「うどん」 → 「が」)
    for word in wordlist:
        #if w1 and w2 and w3:
        if w1 and w2:
            #if (w1, w2, w3) not in markov:
            if (w1, w2) not in markov:
                markov[(w1, w2)] = []
                #markov[(w1, w2, w3)] = []
                #print('w1 not in markov ', w1)
                #print('w2 not in markov ', w2)
            markov[(w1, w2)].append(word)
            #markov[(w1, w2, w3)].append(word)
            #print('w1 append:', w1)
            #print('w2 append:', w2)
        w1, w2 = w2, word
        #w1, w2, w3 = w2, w3, word
        #print('w1:', w1)
        #print('w2:', w2)

 

最初の実行例を見て気づくかもしれませんが、この仕組みで作られたものは前後で整合性の取れていない ”文章のようななにか” です。

次の単語を繋げるのにその前の2,3単語しか見ていないため起こります。

だからといって、語を増やすと

 「私」+「は」+「うどん」+「が」→「好き」

 「は」+「うどん」+「が」+「好き」→「です」

のように、リストがほぼ元文そのものになって汎用性が全くなくなってしまいます。

なのでそこは素直に諦めて、2単語→1単語のリストをひたすら作ってそれなりのランダム性を持たせてそれぽい文章を作って満足しましょう。

 

以上です。

解説めちゃむずかしいし正直こんな稚拙な説明で理解できる人間がいるとは思えないけど、書き始めたのでいちおう最後まで書いて投稿しました。