ランダムっぽい会話をさせてみる

Last-modified: 2018-06-02 (土) 08:27:17

nattoを使ってランダムっぽい会話をさせてみます。
learning.rbに機能を追加して、会話内容をある程度関連性を保持して単語ごとにばらして別ファイルに保存させます。
make_strings_kari.rbで保持した単語を組み立てて、意味の通っているような通っていない文章を返します。

修正したleaning.rb

 require 'yaml'
 require 'pp'
 require 'natto'
 class Learning
   def initialize
     begin
       @dictionary = YAML.load_file'DICTIONARY.yaml'
     rescue
       @dictionary = {}
     end
   end
   def ask
     print '単語> '
     @word=gets.chomp
     print '意味> '
     @mean=gets.chomp
     puts "「#{@word}」とは「#{@mean}」という意味なのね。覚えたわ。"
     @dictionary[@word] = [@dictionary[@word], @mean].flatten.compact
     YAML.dump(@dictionary,File.open('DICTIONARY.yaml', 'w'))
     #### ここからマルコフ連鎖っぽい辞書用
     ## なぜかツンデレっぽい言い方に変換(必須ではない)
     ura_strings = "いいこと?#{@word}ていうのはね#{@mean}という意味なのよ。これくらい常識よ。覚えておきなさい。"
     ## nattoで単語分割
     string_natto = Natto::MeCab.new
     parsed_str = []
     string_natto.parse(ura_strings) do |line|
       parsed_str.push line.surface
     end
     ## マルコフ連鎖用辞書に収録
     begin
       markov_dic = YAML.load_file'MARKOV_DIC.yaml'
     rescue
       markov_dic = []
     end
     cycle = parsed_str.size - 3
     cycle.times do |key1, key2, val|
         key1 = parsed_str[0]
         key2 = parsed_str[1]
         val = parsed_str[2]
         keys = [key1, key2]
         cell_arr = [keys, val]
         markov_dic.push cell_arr
         parsed_str.shift
     end
     markov_dic.uniq!
     YAML.dump(markov_dic,File.open('MARKOV_DIC.yaml', 'w'))
   end
 end
 

make_strings_kari.rb

 require 'yaml'
 require 'natto'
 require 'pp'
 @markov_dic = YAML.load_file'MARKOV_DIC.yaml'
 @yome_strings = ["嫁> え!? そんなこと私に聞くの? 嘘でしょ? もー、信じらんない! "]
 @markov_dic.shuffle!
 def make_stings (keyword)
   @markov_dic.each do |line|
     break if keyword == "。"
     if line[0][0] == keyword
       @yome_strings.push line[0][0]
       @yome_strings.push line[0][1]
       break if line[0][1] == "。"
       keyword = line[1]
       next if keyword != line[0][0]
       make_stings keyword
     end
   end
 end
 puts "嫁> なんでもいいから私に聞いてみなさい。"
 print "俺> "
 str = gets.chomp
 ore_words = []
 parse_ore = Natto::MeCab.new
 parse_ore.parse(str) do |line|
   if line.feature =~ /固有名詞/ || line.feature =~ /名詞,サ変接続/ || line.feature =~ /名詞,一般/
     ore_words.push line.surface
   end
 end
 keyword = ore_words[rand(ore_words.size)]
 make_stings keyword
 puts @yome_strings.join + "わかった?"
 

実行方法

現状、learning.rbは単独で実行できないので、

 $ ruby greeting.rb

から、いくつか言葉を覚え込ませてください。(高い確率でしりとりをさせられる羽目になるかもしれませんが。)
それから、かなりたくさん覚え込ませないと会話っぽくならないので、テーマを絞って教え込むとよいでしょう。
なお、一気に覚え込ませようと、長文を一度に流し込むとDICTIONARY.yamlが壊れたりしますので、注意しましょう。

 

次に

 $ ruby make_strings_kari.rb

を実行すると、嫁が高飛車に何か聞くように要求してきますので、適当な文章を入れてください。
なるべく、先に覚え込ませた単語を含んでいる方がよいです。