2018年04月15日

言語処理100本ノックでPython入門 #36 - 辞書型の操作

  

言語処理100本ノック 2015
の問題36に挑戦です。


■ 問題


夏目漱石の小説『吾輩は猫である』の文章(neko.txt)をMeCabを使って形態素解析し,その結果をneko.txt.mecabというファイルに保存せよ.このファイルを用いて,以下の問に対応するプログラムを実装せよ. なお,問題37, 38, 39はmatplotlibもしくはGnuplotを用いるとよい.

36. 単語の出現頻度
文章中に出現する単語とその出現頻度を求め,出現頻度の高い順に並べよ.


単語の定義がわかりません。形態素解析で得られた一つ一つが単語ということで良いかな。となると、句点、読点も単語だけど... いちおう、記号だけは除外することにします。


■Pythonのコード

import re

def analyze():
    lines = []
    sentence = []
    with open('chap04/neko.txt.mecab', 'r', encoding='utf8') as fin:
        for line in fin:
            words = re.split(r'\t|,|\n', line)
            if words[0] == 'EOS':
                if sentence:
                    lines.append(sentence)
                    sentence = []
                continue
            sentence.append({
                "surface": words[0],
                "base": words[7],
                "pos": words[1],
                "pos1": words[2],
            })
    return lines

def getFrequency(lines):
    words = {}
    for sentense in lines:
        for word in sentense:
            if word['pos'] == '記号':
                continue
            if word['surface'] in words.keys():
                words[word['surface']] += 1
            else:
                words[word['surface']] = 1
    return words

def main():
    article = analyze()
    words = getFrequency(article)
    sortedwords = sorted(words.items(), key=lambda x: x[1], reverse=True)
    for i in range(0, 100):
        print(i, sortedwords[i][0], sortedwords[i][1])

if __name__ == '__main__':
    main()

■ 辞書の操作

辞書のキーが存在しているかは、in キーワードが使えます。
if word['surface'] in words:

次の書き方でも良いみたいです。
if word['surface'] in words.keys():


辞書の値を使ってのソートは、前にも出てきたような気がするけど、以下のように書けばOKです。
sortedwords = sorted(words.items(), key=lambda x: x[1], reverse=True)
最後の引数で、逆順にソートしています。
このコードでは、words.items() をソートしているので、ソートの結果は辞書ではなくリストになります。

最初の100個を表示してみます。
for i in range(0, 100):
    print(i, sortedwords[i][0], sortedwords[i][1])

■ 結果
0 の 9194
1 て 6868
2 は 6420
3 に 6243
4 を 6071
5 と 5508
6 が 5337
7 た 3988
8 で 3806
9 も 2479
10 ない 2390
11 だ 2363
12 し 2322
13 から 2032
14 ある 1728
15 な 1613
16 ん 1568
17 か 1530
18 いる 1249
19 事 1207
20 へ 1034
21 う 992
22 する 992
23 もの 981
24 君 973
25 です 973
26 云う 937
27 主人 932
28 よう 696
29 ね 683
30 この 649
31 御 636
32 ば 617
33 人 602
34 その 576
35 一 554
36 そう 546
37 何 539
38 なる 531
39 さ 514
40 よ 509
41 なら 483
42 吾輩 481
44 ます 458
45 じゃ 448
46 これ 414
47 なっ 404
48 それ 381
49 来 364
50 れ 356
51 見 350
52 でも 346
53 時 345
54 迷亭 343
55 ませ 330
56 いい 320
57 三 319
58 —— 319
59 まで 313
60 ところ 313
61 方 312
62 二 303
63 ず 299
64 上 294
65 まし 289
66 寒月 286
67 顔 282
68 ぬ 277
69 先生 274
70 見る 273
71 人間 272
72 だろ 270
73 くらい 269
74 僕 268
75 たら 262
76 さん 260
77 なく 258
78 気 250
79 あり 249
80 猫 248
81 だけ 246
82 出 245
83 出来 244
84 云っ 241
85 また 238
86 中 234
87 思っ 232
88 ばかり 231
89 十 231
90 ごとく 225
91 あっ 221
92 どう 220
93 って 216
94 細君 213
95 など 205
96 鼻 199
97 今 195
98 大 195
99 や 194