Class: JohnDoe::Markov

Inherits:
Object
  • Object
show all
Defined in:
lib/johndoe/markov.rb

Instance Method Summary collapse

Constructor Details

#initializeMarkov

Returns a new instance of Markov.



4
5
6
# File 'lib/johndoe/markov.rb', line 4

def initialize
  @map = {}
end

Instance Method Details

#add(w1, w2, w3) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/johndoe/markov.rb', line 48

def add(w1,w2,w3)
  w12 = w1+" "+w2
  if @map[w12].nil?
    @map[w12] = {:count => 1} 
  else
    @map[w12][:count]+=1
  end
  if @map[w12][w3].nil?
    @map[w12][w3] = 1
  else
    @map[w12][w3]+=1
  end

end

#count_probabilityObject

assume that model is linear so using linear prob



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/johndoe/markov.rb', line 18

def count_probability
  sum = 0
  p_sum = 0
  @map.each{|k,v| sum+=v[:count]}
  @map.each do |k,v|
    v[:p] = p_sum + v[:count]/sum.to_f 
    p_sum = v[:p]

  end
  @map.each do |k,v|
    word_sum = 0
    v.each do |word_key,word_val|
      next unless word_key.class == String
      word_sum += word_val
    end
    v[:word_sum] = word_sum  
  end
end

#gen_from_two(str) ⇒ Object



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/johndoe/markov.rb', line 76

def gen_from_two(str)
  begin
    while true
      found_nil = false
      two_last = two_last_words(str) rescue "I'm still learning"
      return str if @map[two_last].nil? || @map[two_last][:word_sum] == 0
      r = rand(@map[two_last][:word_sum])
      @map[two_last].each do |k,v|
        next if k.class == Symbol
        r -= v
        if r < 0
          found_nil == v.nil?
          str = str + " " + k
          break
        end
      end
    end
  end
  rescue nil
end

#generate_randomObject



63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/johndoe/markov.rb', line 63

def generate_random
  r = rand
  str = ""
  @map.each  do |k,v|
    if r < v[:p]
      str = k
      break
    end
  end
  return gen_from_two(str)

end

#load(filename) ⇒ Object



8
9
10
11
12
13
14
15
# File 'lib/johndoe/markov.rb', line 8

def load(filename)
  file = File.new(filename, "r")
  while (line = file.gets)
    process_line line.downcase
  end
  file.close
  count_probability
end

#process_line(line) ⇒ Object



37
38
39
40
41
42
43
44
45
46
# File 'lib/johndoe/markov.rb', line 37

def process_line(line)
  line.squeeze!(" ")
  words = line.split(" ")
  for i in 0..words.length-2
    word1 = words[i]
    word2 = words[i+1]
    word3 = words[i+2]
    add(word1,word2,word3)
  end
end

#response(str) ⇒ Object



102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/johndoe/markov.rb', line 102

def response(str)
  str.squeeze(" ").split(" ").sort {|x,y| y.size <=> x.size}.each do |s|
    collection = []
    @map.each do |k,v|
      if k.include? s
        collection << k 
      end
    end
    return gen_from_two(@map.keys[rand(@map.keys.size)]) if collection.empty?
    return gen_from_two collection[rand(rand(collection.size))] rescue nil
  end
  return nil
end

#two_last_words(s) ⇒ Object



97
98
99
100
# File 'lib/johndoe/markov.rb', line 97

def two_last_words(s)
  m = /(.* )?([^\s]+) ([^\s]+)$/.match s
  return m[2] + " " + m[3] rescue nil
end