Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Download to read offline

Ruby-us Hagrid: Writing Harry Potter with Ruby

Download to read offline

We all know that Ruby can give us superpowers, but can we use it do something truly magical - write a brand new Harry Potter completely automatically?
It turns out that Ruby and the dark arts of Natural Language Programming are a match made in heaven! Using some basic NLP techniques, a dash of probability, and a few lines of simple Ruby code, we can create a virtual author capable of generating a very convincing Potter pastiche. And if the life of an author’s not for you, don’t worry. In the last part of the talk, we'll explore how we can apply what we've learned to everyday coding problems.

Related Books

Free with a 30 day trial from Scribd

See all
  • Be the first to like this

Ruby-us Hagrid: Writing Harry Potter with Ruby

  1. 1. Ruby-us Hagrid Writing Harry Potter with Ruby @alexpeattiealexpeattie.com/hp
  2. 2. Why should we do it? What can we achieve? How can we do it? Writing Harry Potter with Ruby
  3. 3. Why should we do it?
  4. 4. Category A The “Potheads” Category B The “Notters” “Ouch, my heart” “Is that Yoda?”
  5. 5. What can we achieve?
  6. 6. (Spoiler!)
  7. 7. Neville, Seamus and Dean were muttering but did not speak when Harry had told Fudge mere weeks ago that Malfoy was crying, actually crying tears, streaming down the sides of their heads. “They revealed a spell to make your bludger” said Harry, anger rising once more.
  8. 8. How can we do it?
  9. 9. “They revealed a spell to make your bludger” said Harry, anger rising once more. Key idea 1: Tell the story word by word Key idea 2: Let’s take inspiration from our phones
  10. 10. After “birthday”, I’ve used the word: - “party” 30 times - “cake” 20 times - “wishes” 10 times
  11. 11. After “golden”, J.K. used the word: - “egg” 13 times - “snitch” 11 times - “plates” 10 times The world “golden” appears in the Harry Potter books 226 times.
  12. 12. After “golden”, J.K. used the word: - “egg” 13 times - “snitch” 11 times - “plates” 10 times The world “golden” appears in the Harry Potter books 226 times. Head Continuations
  13. 13. Step 1 Learn Step 2 Generate Key idea 3
  14. 14. golden egg snitch plates light ⋮ liquid 13 11 10 9 1 goldfish out any bowls above 1 1 1 1 golf balls 2 ⋮ 21,814 words ⋮
  15. 15. { :golden => { :egg => 13, :snitch => 11, :plates => 10, :light => 9, :liquid => 1 }, :goldfish => { :out => 1, :any => 1, :of => 1, :bowls => 1 }, :golf => { :balls => 2 } }
  16. 16. alexpeattie.com/hp
  17. 17. def tokenize(text) text.downcase.split(/[^a-z]+/).reject(&:empty?).map(&:to_sym) end "Mr. and Mrs. Dursley, of number four, Privet Drive, were proud to say that they were perfectly normal" [:mr, :and, :mrs, :dursley, :of, :number, :four, :privet, :drive, :were, :proud, :to, :say, :that, :they, :were, :perfectly, :normal]
  18. 18. text = tokenize "The cat sat on the mat. The cat was happy." stats = {} text.each_cons(2) do |head, continuation| stats[head] ||= Hash.new(0) stats[head][continuation] += 1 end
  19. 19. text = tokenize "The cat sat on the mat. The cat was happy." stats = {} text.each_cons(2) do |head, continuation| stats[head] ||= Hash.new(0) stats[head][continuation] += 1 end [:the, :cat] head continuation { :the => { :cat => 1 } }
  20. 20. text = tokenize "The cat sat on the mat. The cat was happy." stats = {} text.each_cons(2) do |head, continuation| stats[head] ||= Hash.new(0) stats[head][continuation] += 1 end [:cat, :sat] head continuation { :the => { :cat => 1 }, :cat => { :sat => 1 } }
  21. 21. text = tokenize "The cat sat on the mat. The cat was happy." stats = {} text.each_cons(2) do |head, continuation| stats[head] ||= Hash.new(0) stats[head][continuation] += 1 end { :the => { :cat => 2, :mat => 1 }, :cat => { :sat => 1, :was => 1 }, :sat => { :on => 1 }, :on => { :the => 1 }, :mat => { :the => 1 }, :was => { :happy => 1 } }
  22. 22. Step 1 Learn ✅ Step 2 Generate
  23. 23. Greedy algorithm
  24. 24. Pick most frequent continuation
  25. 25. Pick most frequent continuation
  26. 26. def pick_next_word_greedily(head) continuations = stats[head] chosen_word, count = continuations.max_by { |word, count| count } return chosen_word end
  27. 27. story = [stats.keys.sample] # start with a random word from corpus 1.upto(50) do # 50 word story story << pick_next_word_greedily(story.last) end puts story.join(" ")
  28. 28. Drumroll….
  29. 29. “Oh no” said Harry. A few seconds later they were all the door and the door and the door and the door and the door.
  30. 30. Take two….
  31. 31. Surreptitiously, several of the door and the door and the door and the door and the door and the door and the door.
  32. 32. several of the door and
  33. 33. conference enchantingly nasty little more than ever since he was a few seconds later they were all the door and… conference
  34. 34. Greedy algorithm
  35. 35. Let’s get random Uniform random algorithm
  36. 36. Pick randomly w/equal probability
  37. 37. Pick randomly w/equal probability ⅓ ⅓ ⅓
  38. 38. Pick randomly w/equal probability egg snitch plates light ⋮ liquid 1/117 1/117 1/117 1/117 1/117 112 more
  39. 39. def pick_random_next_word(head) continuations = stats[head] return continuations.keys.sample end
  40. 40. Debris from boys or accompany him bodily from Ron, yell the waters. Harry laughing together soon father would then bleated the smelly cloud.
  41. 41. What’s the problem?
  42. 42. house elf 102 times ~1/200 chance prices 1 time ~1/200 chance
  43. 43. Let’s get (a bit less) random Weighted random algorithm
  44. 44. house elf 102 times prices 1 time ~1/200 chance ~1/200 chance 734 times
  45. 45. house elf 102 times prices 1 time ~1/7 chance ~1/700 chance 734 times
  46. 46. Pick randomly w/weighted probabilities ½ ⅓ ⅙
  47. 47. def pick_next_word_weighted_randomly(head) continuations = stats[head] continuations.flat_map { |word, count| [word] * count }.sample end
  48. 48. Springing forward as though they had a bite of the hippogriff, he staggered blindly retorting Harry some pumpkin tart.
  49. 49. One last big idea…
  50. 50. Key idea 4: Improve output by looking at more than just 1 previous word
  51. 51. { :golden => { :egg => 12, :snitch => 11, :plates => 10, :light => 9, :liquid => 1 }, :goldfish => { :out => 1, :any => 1, :of => 1, :bowls => 1 }, :golf => { :balls => 2 } } Two words bi·gram two word
  52. 52. { [:golden, :egg] => { :harry => 1, :very => 1, :and => 2, :which => 1, :upstairs => 1, :does => 1, :he => 2, :said => 1, :still => 1, :fell => 1 }, [:golden, :snitch] => { :and => 1, :had => 1, :said => 1, :it => 1, :a => 1, :with => 1, :was => 1, :where => 1, :worked => 1 } } 321,727 entriestri·gram three word Three words
  53. 53. stats = {}
 n = 3 corpus.each_cons(n) do |*head, continuation| stats[head] ||= Hash.new(0) stats[head][continuation] += 1 end Added splat
  54. 54. [[:the, :cat], :sat] head continuation { [:the, :cat] => { :sat => 1 } } stats = {}
 n = 3 corpus.each_cons(n) do |*head, continuation| stats[head] ||= Hash.new(0) stats[head][continuation] += 1 end
  55. 55. Normally when Dudley found his voice barely louder than before. “Dementors” said Dumbledore steadily, he however found all this mess is utterly worthless. Harry looked at him, put Slughorn into his bag more securely on to bigger and bigger until their blackness swallowed Harry whole and started emptying his drawers. — trigram model
  56. 56. Neville, Seamus and Dean were muttering but did not speak when Harry had told Fudge mere weeks ago that Malfoy was crying, actually crying tears, streaming down the sides of their heads. “They revealed a spell to make your bludger” said Harry, anger rising once more. — 4-gram model
  57. 57. def tokenize(sentence) sentence.downcase.split(/[^a-z]+/).reject(&:empty?).map(&:to_sym) end def pick_next_word_weighted_randomly(head, stats) continuations = stats[head] continuations.flat_map { |word, count | [word] * count }.sample end text = tokenize(IO.read('hp.txt')) stats = {} n = 3 text.each_cons(n) do |*head, continuation| stats[head] ||= Hash.new(0) stats[head][continuation] += 1 end story = stats.keys.sample 1.upto(50) do story << pick_next_word_weighted_randomly(story.last(n - 1), stats) end puts story.join(" ") 20 lines
  58. 58. Harry Potter
  59. 59. Harry Potter Hard Problems
  60. 60. 1. Understand how to break down the ….problem 2. Pay attention to your failures 3. Find the right metaphor
  61. 61. 1. Understand how to break down the ….problem 2. Pay attention to your failures 3. Find the right metaphor
  62. 62. How do you eat an elephant? One bite at a time. — Proverb
  63. 63. Obvious 1 bite = 1 move
  64. 64. Less obvious 1 bite = 1 turn ⏎
  65. 65. Less obvious still 1 bite = 1 landmark
  66. 66. “What are the building blocks for solving this problem?”
  67. 67. 1. Understand how to break down the ….problem 2. Pay attention to your failures 3. Find the right metaphor
  68. 68. several of the door and
  69. 69. “Why didn’t this work?”
  70. 70. 1. Understand how to break down the ….problem 2. Pay attention to your failures 3. Find the right metaphor
  71. 71. Keeps the essential parts of the problem.
  72. 72. Keeps the essential parts of the problem. Can play around with the metaphor, and learn more about the problem.
  73. 73. Harry Potions Hermione Potions Neville Potions Hermione Arithmancy Hermione Ancient Runes Neville Herbology Harry Herbology Harry Divination
  74. 74. Harry Potions Hermione Potions Neville Potions Hermione Arithmancy Hermione Ancient Runes Neville Herbology Harry Herbology Harry Divination Whoops
  75. 75. Herbology Divination Potions Ancient Runes Arithmancy
  76. 76. Herbology Divination Potions Ancient Runes Arithmancy
  77. 77. Herbology Divination Potions Ancient Runes Arithmancy
  78. 78. “What’s a good metaphor for this problem?”
  79. 79. 1. Understand how to break down the ….problem 2. Pay attention to your failures 3. Find the right metaphor Hard Problems
  80. 80. alexpeattie.com/hp Thank you! Slides and notes online at:

We all know that Ruby can give us superpowers, but can we use it do something truly magical - write a brand new Harry Potter completely automatically? It turns out that Ruby and the dark arts of Natural Language Programming are a match made in heaven! Using some basic NLP techniques, a dash of probability, and a few lines of simple Ruby code, we can create a virtual author capable of generating a very convincing Potter pastiche. And if the life of an author’s not for you, don’t worry. In the last part of the talk, we'll explore how we can apply what we've learned to everyday coding problems.

Views

Total views

48

On Slideshare

0

From embeds

0

Number of embeds

0

Actions

Downloads

0

Shares

0

Comments

0

Likes

0

×