Skip to content

Instantly share code, notes, and snippets.

@kuczmama
Last active May 16, 2019 03:23
Show Gist options
  • Select an option

  • Save kuczmama/186f785ef67042e4edd2152389106ddd to your computer and use it in GitHub Desktop.

Select an option

Save kuczmama/186f785ef67042e4edd2152389106ddd to your computer and use it in GitHub Desktop.

Revisions

  1. kuczmama revised this gist May 16, 2019. 1 changed file with 54 additions and 76 deletions.
    130 changes: 54 additions & 76 deletions markov_chain.rb
    Original file line number Diff line number Diff line change
    @@ -29,92 +29,70 @@ def present?
    end

    class MarkovChain
    attr_accessor :memory_1, :memory_2, :memory_3
    attr_accessor :memory, :level

    def initialize
    @memory_1 = {}
    @memory_2 = {}
    @memory_3 = {}
    def initialize(level: 1)
    @level = level
    @memory = [].tap{|m| level.times{m.push({})}}
    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
    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 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
    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 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}"
    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

    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
    # Usage
    o = MarkovChain.new(level: 3)
    o.train(path: './training_data/obama.txt')
    o.babble(length: 1000)
  2. kuczmama created this gist May 13, 2019.
    120 changes: 120 additions & 0 deletions markov_chain.rb
    Original 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