Last active
May 16, 2019 03:23
-
-
Save kuczmama/186f785ef67042e4edd2152389106ddd to your computer and use it in GitHub Desktop.
Revisions
-
kuczmama revised this gist
May 16, 2019 . 1 changed file with 54 additions and 76 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -29,92 +29,70 @@ def present? end class MarkovChain attr_accessor :memory, :level def initialize(level: 1) @level = level @memory = [].tap{|m| level.times{m.push({})}} end def train(path: "",raw: "") tokens = nil if path.present? tokens = File.read(path).split(" ") elsif raw.present? tokens = raw.split(" ") end (0...(tokens.length - @level)).each do |i| prev_key = nil prev_value = nil (0...@level).each do |level| value = tokens[i + level + 1] key = (prev_key.present? && prev_value.present?) ? prev_key + [prev_value] : [tokens[i]] # puts "i=#{i}, level=#{level}, key=#{key}, value=#{value}, memory=#{memory}" @memory[level][key] = [] if @memory[level][key].blank? @memory[level][key] = value prev_key = key.dup prev_value = value.dup end end end def next_word(curr_state=[]) puts "next word curr_state: #{curr_state}" result = @memory[0].keys.sample.first if curr_state.blank? if result.present? puts "level 0: #{result}" return result end level = @level - 1 while level >= 0 result = @memory[level][curr_state[0...@level]] if result.present? puts "level #{level + 1}: #{result}" return result end level -= 1 end puts "level 0: #{result}" @memory[0].keys.sample.first end def babble(length: 2) result = next_word (0..length).each do tokens = result.split(" ") range = ((-1 * (@level >= tokens.length ? tokens.length : @level))..-1) state = tokens[range] word = next_word(state) result += " " + word end result end end # Usage o = MarkovChain.new(level: 3) o.train(path: './training_data/obama.txt') o.babble(length: 1000) -
kuczmama created this gist
May 13, 2019 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,120 @@ class String def blank? self.nil? || self.empty? end def present? !self.blank? end end class Array def blank? self.nil? || self.empty? end def present? !self.blank? end end class NilClass def blank? self.nil? || self.empty? end def present? !self.blank? end end class MarkovChain attr_accessor :memory_1, :memory_2, :memory_3 def initialize @memory_1 = {} @memory_2 = {} @memory_3 = {} end def train(path: ) tokens = File.read(path).split(" ") (0...tokens.length - 3).each do |i| one_key = tokens[i] one_value = tokens[i + 1] two_key = [one_key, one_value] two_value = tokens[i + 2] three_key = [one_key, one_value, two_value] three_value = tokens[i + 3] next if one_key.blank? || one_value.blank? || two_value.blank? || three_key.blank? || three_value.blank? @memory_1[one_key] = [] if @memory_1[one_key].blank? @memory_2[two_key] = [] if @memory_2[two_key].blank? @memory_3[three_key] = [] if @memory_3[three_key].blank? @memory_1[one_key] << one_value @memory_2[two_key] << two_value @memory_3[three_key] << three_value end end def level_0 result = @memory_1.keys.sample # puts "level 0: #{result}" result end def level_1(curr_state) return nil unless curr_state.present? curr_state = curr_state.first if curr_state.is_a?(Array) && curr_state.length == 1 values = @memory_1[curr_state] return nil if values.blank? result = values.sample # puts "level 1: #{result}" result end def level_2(curr_state) return nil unless curr_state.present? return nil unless curr_state.is_a?(Array) return nil unless curr_state.length == 2 values = @memory_2[curr_state] return nil if values.blank? result = values.sample # puts "Level 2: #{result}" result end def level_3(curr_state) return nil unless curr_state.present? return nil unless curr_state.is_a?(Array) return nil unless curr_state.length == 3 values = @memory_3[curr_state] return nil if values.blank? result = values.sample # puts "Level 3: #{result}" result end def next_word(curr_state="") level_1_key = curr_state.is_a?(Array) ? curr_state.last : curr_state level_2_key = (curr_state.is_a?(Array) && curr_state.length >= 2) ? curr_state[-2..-1] : curr_state level_3(curr_state) || level_2(level_2_key) || level_1(level_1_key) || level_0 end end def give_speech(markov_chain, length=100) result = "" last_word = markov_chain.level_0 result += markov_chain.level_1(last_word) + " " + last_word (0..length).each do |i| last_word = markov_chain.next_word(result.split(" ")[-3..-1]) result += " " + last_word end result end