Hpricotでポール・グレアムのエッセイの頻出単語を調べてみる

ハッカー必読と評判も高く、翻訳もされているポール・グレアムのエッセイですが、英語の勉強を兼ねて原文で読んでみたりしています。

でもやっぱり基礎英語力不足というか端的に言って語彙が足りないのでなかなか大変です。それじゃあっていうんでDUO3.0とかで受験対策のように単語を暗記するのは微妙に遠回りな気もします。要は自分の読みたい文章が読みこなせれば良いので、対象となる文章の頻出単語を調べてそれらをピンポイントで学習すれば効率良く読めるようになるのではないかと。

そんなわけで、プログラムを書いてみます。ちょっとしたスクレイピングになるのでHpricotを使うことにします。

#!/usr/bin/ruby
require 'rubygems'
require 'hpricot'
require 'open-uri'

tempfile = "corpus.txt"
outfile  = "count.csv"
urllist = [
        "http://www.paulgraham.com/credentials.html",
        "http://www.paulgraham.com/divergence.html",
        "http://www.paulgraham.com/highres.html",
        "http://www.paulgraham.com/artistsship.html",
        "http://www.paulgraham.com/badeconomy.html",
        "http://www.paulgraham.com/fundraising.html",
        "http://www.paulgraham.com/prcmc.html"
                    # ... etc
       ]

def getContentAsText(url)
  doc = Hpricot(open(url))
  body = (doc/'//body').inner_html
  body = body.gsub(/<script.*\/script>/m, "")
  body = body.gsub(/<[^>]*>/, " ")
  body = body.gsub(/&mdash;/,"-")
  body
end

def downloadToTempfile(filename, list)
  file = File.open(filename,'w')
  list.each {|url|
    puts url
    file.puts getContentAsText(url)
  }
  file.close
end

def countWordsOfLine(h, s)
  s.split(/[^a-zA-Z]+/).each {|word|
    w = word.downcase
    h[w] = 0 if h[w].nil?
    h[w] += 1
  }
end

def countWordsOfFile(file)
  dic = Hash::new
  f = open(file)
  f.each {|line| countWordsOfLine(dic, line)}
  f.close

  dic.to_a.sort{|a, b|
    (b[1] <=> a[1]) * 2 + (a[0] <=> b[0])
  }
end

def writeToCsvFile(filename, ary)
  csv = open(filename, "w")
  csv.puts "word,count\n"
  ary.each {|word, count|
    case word
    when "", "s", "t", "ll", "m", "d"
      next
    end
    csv.printf "%s,%d\n", word, count
  }
  csv.close
end

downloadToTempfile(tempfile, urllist)
ary = countWordsOfFile(tempfile)
writeToCsvFile(outfile, ary)

実はHpricotを使うと目次ページから全URLリストを取得するのも簡単なんですが、サイト丸ごとダウンロードするプログラムというのも道義的にどうかと思うのでここでは自動取得にはしていません。
単語の定義はわりと適当です。don'tがdonになったり、複数形と単数形が別に集計されたり。試しにActiveSuppportのsingularize使ってみたけどthisがthiになったりしたのでやめました。

ちなみに結果ですがこんな感じ(98作について集計)。
 count.zip

startupsが720回も使われてるのはいかにもという感じ。lispやhackersも300回以上とか。でもこうやって見ると意外と平易な単語ばっかり使ってるなあ。特殊な専門用語も少ないし。それでいて広範な話題をフォローしてるってあたりが良いエッセイといわれるゆえんかも。