わさっきhb

大学(教育研究)とか ,親馬鹿とか,和歌山とか,とか,とか.

漢字とカタカナの使用回数

1000日分の日記のXMLファイルを使って,自分でどんな語句を使用してきたか,分布を求めてみました.
形態素解析ではなく,もっと簡単に,1文字単位で見ていって,「2文字以上の漢字,カタカナの並び」を単語として,集計し,漢字・カタカナで別々に上位から並べてみました.

順位 漢字度数 漢字語句 カナ度数 カナ語句
1 919 学生 797 ファイル
2 853 自分 549 プログラム
3 667 関数 506 ポインタ
4 649 問題 485 プログラミング
5 645 授業 341 コード
6 477 変数 291 コマンド
7 460 情報 270 ページ
8 455 研究室 261 インストール
9 444 実行 238 ゼミ
10 403 説明 236 システム
11 385 表現 222 コメント
12 356 文字列 195 サーバ
13 356 研究 187 トリアージ
14 352 大学 186 スライド
15 340 配列 179 レポート
16 316 意味 171 コピー
17 312 文字 169 アドバイス
18 307 時間 159 アクセス
19 299 場合 159 エラー
20 279 必要 159 メール
21 272 最初 151 データ
22 266 先生 144 エントリ
23 265 発表 140 コンパイル
24 256 教員 138 メモ
25 254 以下 128 プレゼン
26 254 引数 127 セキュリティ
27 252 情報教育 127 チェック
28 247 確認 122 ライブラリ
29 246 理解 119 リンク
30 244 課題 118 ノート

情報(計算機,コンピュータ)の分野の,大学の構成員が書いたというのがうかがえるリストとなっています.なお,カタカナ13位の「トリアージ」は,教育とまったく別で,昨年の秋に集中して取り上げたのが影響しています.
集計プログラムは以下のとおり.Rubyプログラミングの練習を兼ねています.

#!/usr/bin/env ruby
# -*- coding: utf-8 -*-

# word-counter.rb

class WordCounter
  def open_inputfile
    (ARGV + %W(ENV['USER'] takehikom)).each do |name|
      @outputfile = "#{name}-word.txt"
      ([""] + %w(.xml .xml.gz .txt)).each do |suffix|
        @inputfile = "#{name}#{suffix}"

        if test(?f, @inputfile)
          puts "open #{@inputfile}"
          if /gz$/ =~ suffix
            io = IO.popen("zcat #{@inputfile}", "r:utf-8")
          else
            io = open(@inputfile, "r:utf-8")
          end
          if block_given?
            return yield(io)
          else
            return io
          end
        end
      end
    end
    puts "input file not found."
    exit
  end

  def read
    open_inputfile do |fin|
      fin.each_line do |line|
        type_w = :none  # one of :none, :kanji, :kata, :hira, :other
        word = ""
        word_size = 0

        # http://www.phppro.jp/qa/122
        # http://code.cside.com/3rdpage/jp/utf-8/Hiragana.html
        # http://code.cside.com/3rdpage/jp/utf-8/Katakana.html
        line.split(//u).each do |c|
          # 文字種別を決める
          type_c = :other
          case c
          when /[一-龠]/u
            type_c = :kanji
          when /[ぁ-ん]/u
            type_c = :hira
          when /[ァ-ヴ]/u
            type_c = :kata
          when /[]/u
            if type_w == :hira || type_w == :kata
              type_c = type_w
            else
              type_c = :kata
            end
          end

          # 語に文字を追加する,ほか
          if type_w == type_c
            word += c
            word_size += 1
          else
            if word_size > 1
              if type_w == :kanji
                @kanji_h[word] += 1
              elsif type_w == :kata
                @kata_h[word] += 1
              end
              if $DEBUG
                if type_w == :kanji
                  print "<#{word}> "
                elsif type_w == :kata
                  print "[#{word}] "
                else
                  print "_#{word}_ "
                end
              end
            elsif $DEBUG
              print "_#{word}_ "
            end
            type_w = type_c
            word = c
            word_size = 1
          end
        end
        puts if $DEBUG
      end
    end
  end

  def write
    puts "open #{@outputfile}"
    open(@outputfile, "w") do |fout|
      [@kanji_h, @kata_h].each do |h|
        order = 6
        max = 10 ** order - 1
        temp1 = "%#{order}d%s"
        temp2 = "%#{order}d\t%s"
        h.keys.sort_by {|k| temp1 % [max - h[k], k]}.each do |k|
          fout.puts temp2 % [h[k], k]
        end
        fout.puts
      end
    end
  end

  def start
    @kanji_h = Hash.new(0)
    @kata_h = Hash.new(0)

    read
    puts "#{@kanji_h.size} kanji words"
    puts "#{@kata_h.size} katakana words"
    write
  end
end

if __FILE__ == $0
  WordCounter.new.start
end

いつものように,Ruby 1.9,1.8両対応を心がけています.Cygwinのパッケージのバージョンは「ruby 1.8.7 (2008-08-11 patchlevel 72) [i386-cygwin]」でしたが,これでもRuby 1.9と同じ出力になりました.なお,WordCounter#open_inputfileの中の「:utf-8」は,書かないと,Ruby 1.9で実行時エラーになります*1
あと,コーディングの際にちょっと力を入れてみたのは,入力ファイル名の選定です.「名前.サフィックス」の形で作り,名前は,Ruby実行時におけるコマンドライン引数(word-counter.rbの後ろに書く),環境変数USERの値,固定文字列 "takehikom" の順です.サフィックスは,.xml,.xml.gz,.txtの順です.と思ったけど,サフィックスなしも可能にしました.
どういうことかというと,「ruby word-counter.rb 任意のファイル名」にすれば,そのファイルが入力となりますし,カレントディレクトリに適切な名前のファイルを置けば,「ruby word-counter.rb」だけで,入力ファイルを決定してくれるというわけです.
WordCounter#readでは,入力を1文字ずつ読み出し,漢字・ひらがな・カタカナ・それ以外に分類しています*2.単語の候補を格納するのがローカル変数のwordで,新たに1文字ずつ読み出したものと,同じ分類なら足していきますが,異なる分類なら,そこまでを単語とみなして,登録なり,wordその他のリセットなりをします.
なお,最長一致をとりますので,「和歌山大学」とあれば,「和歌山大学」のみ1件とし,「和歌山」「大学」としてはカウントしていません.それと,行の終わりには必ず改行文字があるので,1行読み出しを終えたときに,単語が残っているかを判断する処理はしていません.
実行は,以下の手順で.

  1. 自分の日記を見る.
  2. 「管理」をクリックする.(デザインにもよるが,はてなでログインしていれば,ページの上部にあるはず.)
  3. 「日記管理ツール」が出たら,「データの管理」をクリックする.
  4. はてなの日記データ形式」の横の「ダウンロード」から,ファイルに保存する.(自分の場合はtakehikom.xmlになる.)
  5. シェルでgzip takehikom.xmlを実行する.takehikom.xml(3552239バイト)がなくなり,代わりにtakehikom.xml.gz(1211781バイト)が作られる.
  6. takehikom.xml.gzとword-counter.rbを同じディレクトリに置き,シェルのカレントディレクトリもそこに移して,ruby word-counter.rbを実行する.takehikom-word.txtが作られる.

なお,gzipコマンドの実行は省略してもかまいません.それと,XMLファイルをダウンロードして見れば分かりますが,isbn記法などで書籍情報を書いていると,isbn記法のままですので,書籍名の中の単語は一切カウントされません.
私の1000日分は,漢字(熟語)は13517種,カタカナ語は2828種.上位30個ずつは,冒頭の表のとおりです*3

*1:ファイルの文字コードは,UTF-8固定です.それ以外だと,実行時エラーです.

*2:漢字の並びとカタカナの並びのそれぞれについて,String#scanを使ったほうが手短に書けたかなと,少し後悔しています.

*3:表は,「head -n 30 takehikom-word.txt > 1.txt」「sed -n 13519,13548p takehikom-word.txt > 2.txt」「paste 1.txt 2.txt > 3.txt」の順に実行して,3.txtを,表組み記法になるようテキストエディタで整形しました.