2018年05月10日

言語処理100本ノックでPython入門 #41 - 分節と係り受け


今日は、言語処理100本ノック 2015の問題41です。

■ 問題


夏目漱石の小説『吾輩は猫である』の文章(neko.txt)をCaboChaを使って係り受け解析し,その結果をneko.txt.cabochaというファイルに保存せよ.このファイルを用いて,以下の問に対応するプログラムを実装せよ.

41. 係り受け解析結果の読み込み(文節・係り受け)
40に加えて,文節を表すクラスChunkを実装せよ.このクラスは形態素(Morphオブジェクト)のリスト(morphs),係り先文節インデックス番号(dst),係り元文節インデックス番号のリスト(srcs)をメンバ変数に持つこととする.さらに,入力テキストのCaboChaの解析結果を読み込み,1文をChunkオブジェクトのリストとして表現し,8文目の文節の文字列と係り先を表示せよ.第5章の残りの問題では,ここで作ったプログラムを活用せよ.


■ Pythonのコード
import re

class Morph:
    def __init__(self, surface, base, pos, pos1):
        self.surface = surface
        self.base = base
        self.pos = pos
        self.pos1 = pos1

    def toList(self):
        return [self.surface, self.base, self.pos, self.pos1]

class Chunk:
    def __init__(self, number, dst):
        self.number = number
        self.morphs = []
        self.dst = dst
        self.srcs = []

    def print(self):
        print(self.number)
        print([x.toList() for x in self.morphs])
        print(self.dst, self.srcs)
        print()

def analyze():
    article = []
    sentence = []
    chunk = None
    with open('chap05/neko.txt.cabocha', 'r', encoding='utf8') as fin:
        for line in fin:
            words = re.split(r'\t|,|\n| ', line)
            if line[0] == '*':
                num = int(words[1])
                destNo = int(words[2].rstrip('D'))
                chunk = Chunk(num, destNo)
                sentence.append(chunk)
            elif words[0] == 'EOS':
                if sentence:
                    for index, c in enumerate(sentence, 0):
                        sentence[c.dst].srcs.append(index)
                    article.append(sentence)
                sentence = []
            else:
                chunk.morphs.append(Morph(
                    words[0],
                    words[7],
                    words[1],
                    words[2],
                ))
    return article

def main():
    article = analyze()
    for c in article[8]:
        c.print()

if __name__ == '__main__':
    main()

ソースコードは、GitHubで公開しています。

■ どう解いたか 

この問題を解くのに、文章全体をarticleという変数で表しています。article変数は、以下のような構造になっています。

  • articleは、複数のsentenceから成る -> sentenceのリスト 
  • sentenceは、複数のchunckから成る -> chunckのリスト 
  • chunckは、複数のMorhpから成る -> Morhpのリストをメンバーに持つ

Chunk.srcsの値(係り元文節インデックス番号のリスト)をどう設定するかが悩みましたが、'EOS'の行が現れたら、その直前の文 - つまりsentence変数(リスト)を走査して、各Chunkのsrcsを設定するようにしました。

問題には指定されていませんが、Chunkクラスに勝手に、
self.number = number
を追加しました。このメンバーは表示用なので、無くても問題の本質部分のanalyze関数には影響ないです。

コードの途中に出てくるNoneは、C#のnullのようなものという理解。
chunk = None

Morphクラス、Chunkクラス、analyze関数は、問題42以降使い回すことになると思います。

■ 結果

問題文が求めている表示の形式と違うような気もしますが、本質的な部分ではないと思うので、これで良しとします。

1行目が分節の番号、2行目が分節、3行目が係り先の番号と[]の中は、係り元の番号となっています。
それが、分節の数だけ続きます。最後は、係り先はないので、-1となっています。

0
[['しかし', 'しかし', '接続詞', '*']]
9 []

1
[['その', 'その', '連体詞', '*']]
2 []

2
[['当時', '当時', '名詞', '副詞可能'], ['は', 'は', '助詞', '係助詞']]
5 [1]

3
[['何', '何', '名詞', '代名詞'], ['という', 'という', '助詞', '格助詞']]
4 []

4
[['考', '考', '名詞', '一般'], ['も', 'も', '助詞', '係助詞']]
5 [3]

5
[['なかっ', 'ない', '形容詞', '自立'], ['た', 'た', '助動詞', '*'], ['から', 'から', '助詞', '接続助詞']]
9 [2, 4]

6
[['別段', '別段', '副詞', '助詞類接続']]
7 []

7
[['恐し', '恐い', '形容詞', '自立']]
9 [6]

8
[['いとも', 'いとも', '副詞', '一般']]
9 []

9
[['思わ', '思う', '動詞', '自立'], ['なかっ', 'ない', '助動詞', '*'], ['た', 'た', '助動詞', '*'], ['。', '。', '記号', '句点']]
-1 [0, 5, 7, 8, 9]
  

Posted by gushwell at 21:35Comments(0)Python

2018年05月06日

言語処理100本ノックでPython入門 #40 - cabochaで形態素解析 & クラスの定義



今日から言語処理100本ノック 2015の第5章に入ります。今日はその1問目の問題40です。

■ 問題
夏目漱石の小説『吾輩は猫である』の文章(neko.txt)をCaboChaを使って係り受け解析し,その結果をneko.txt.cabochaというファイルに保存せよ.このファイルを用いて,以下の問に対応するプログラムを実装せよ.

40. 係り受け解析結果の読み込み(形態素)
形態素を表すクラスMorphを実装せよ.このクラスは表層形(surface),基本形(base),品詞(pos),品詞細分類1(pos1)をメンバ変数に持つこととする.さらに,CaboChaの解析結果(neko.txt.cabocha)を読み込み,各文をMorphオブジェクトのリストとして表現し,3文目の形態素列を表示せよ.

■ CaboChaをインストール


まずは、MacにCaboChaをインストールします。
$ brew install cabocha
以下のページを参考にしました。

MeCabとCaboChaをMacに導入してPythonから使ってみる


■ CaboChaを使い、neko.txtを解析


インストールが完了したらneko.txtのあるフォルダに移動し、以下のコマンドを投入します。
$ cabocha -f1 neko.txt -o neko.txt.cabocha

cabochaには、いくつものオプションがあってどれを使ったら良いかわからなかったのですが、デフォルトの出力オプションだとプログラムで扱うのが面倒そうなので、-f1 というオプションをつけました。

これで、以下のようなneko.txt.cabochaというファイルが作成されます。
* 0 -1D 0/0 0.000000
一    名詞,数,*,*,*,*,一,イチ,イチ
EOS
EOS
* 0 2D 0/0 -0.764522
     記号,空白,*,*,*,*, , , 
* 1 2D 0/1 -0.764522
吾輩    名詞,代名詞,一般,*,*,*,吾輩,ワガハイ,ワガハイ
は    助詞,係助詞,*,*,*,*,は,ハ,ワ
* 2 -1D 0/2 0.000000
猫    名詞,一般,*,*,*,*,猫,ネコ,ネコ
で    助動詞,*,*,*,特殊・ダ,連用形,だ,デ,デ
ある    助動詞,*,*,*,五段・ラ行アル,基本形,ある,アル,アル
。    記号,句点,*,*,*,*,。,。,。
EOS
* 0 2D 0/1 -1.911675
名前    名詞,一般,*,*,*,*,名前,ナマエ,ナマエ
は    助詞,係助詞,*,*,*,*,は,ハ,ワ
* 1 2D 0/0 -1.911675
まだ    副詞,助詞類接続,*,*,*,*,まだ,マダ,マダ
* 2 -1D 0/0 0.000000
無い    形容詞,自立,*,*,形容詞・アウオ段,基本形,無い,ナイ,ナイ
。    記号,句点,*,*,*,*,。,。,。
EOS
…以下省略...

EOSは文の終わり、アスタリスクの行は係り受けの情報。そして形態素解析の行は、以下の項目を表しています。
表層形 (Tab区切り)
0. 品詞
1. 品詞細分類1
2. 品詞細分類2
3. 品詞細分類3
4. 活用形
5. 活用型
6. 原形
7. 読み
8. 発音
係り受けの情報については、必要になったら調べます。

■ クラスの定義

やっとクラスを定義する問題が出ました。さっそくMorphクラスを定義します。  
class Morph:
    def __init__(self, surface, base, pos, pos1):
        self.surface = surface
        self.base = base
        self.pos = pos
        self.pos1 = pos1
Pythonもclassキーワードを使ってクラスを定義します。
__init__ は、コンストラクタを表します。
第1引数のselfは必ず必要のようです。これが自身のインスタンスを示します。
これだけで、surfaceやbaseといったメンバーが定義できちゃうのは便利ですね。

メソッドも定義してみました。
def print(self):
    print([self.surface, self.base, self.pos, self.pos1])
メソッドにもselfは必要です。

なんとなく、C#の拡張メソッドみたいです。 C#のようなpublic/privateといったアクセス修飾子はないみたいです。原則公開です。

ただ、
    def __print(self):
        print([self.surface, self.base, self.pos, self.pos1])
とすると、非公開という位置づけになります。

完全な非公開じゃないけど、obj.print() では呼び出せなくなります。先頭に __が付いているから当たり前ですね。

■ インスタンスの生成

インスタンス生成するのにnewキーワードは必要ありません。以下のように書くとインスタンスが生成され、mにインスタンスが代入されます。
m = Morph(
    words[0],
    words[7],
    words[1],
    words[2],
)

■ neko.txt.cabochaの解析

neko.txt.cabochaを読み込み解析する機能は、通常の関数(analyze関数)として定義しました。ちょっと複雑になってしまったかな。

articleは、sentenceが入るリスト。sentenceはMorphが入るリストです。 analyze関数はこのarticleを返しています。

問題には3文目と書いてあります。先頭が0文目から始まると解釈して、article[3]で結果を取り出しています。


■ 出来上がったPythonのコード
import re

class Morph:
    def __init__(self, surface, base, pos, pos1):
        self.surface = surface
        self.base = base
        self.pos = pos
        self.pos1 = pos1

    def print(self):
        print([self.surface, self.base, self.pos, self.pos1])

def analyze():
    article = []
    sentence = []
    with open('chap05/neko.txt.cabocha', 'r', encoding='utf8') as fin:
        for line in fin:
            words = re.split(r'\t|,|\n| ', line)
            if words[0] == '*':
                continue
            elif words[0] == 'EOS':
                if sentence:
                    article.append(sentence)
                sentence = []
            else:
                sentence.append(Morph(
                    words[0],
                    words[7],
                    words[1],
                    words[2],
                ))
    return article

def main():
    article = analyze()
    for morph in article[3]:
        morph.print()

if __name__ == '__main__':
    main()

ソースはGitHubでも公開しています。

■ 結果
['\u3000', '\u3000', '記号', '空白']
['どこ', 'どこ', '名詞', '代名詞']
['で', 'で', '助詞', '格助詞']
['生れ', '生れる', '動詞', '自立']
['た', 'た', '助動詞', '*']
['か', 'か', '助詞', '副助詞/並立助詞/終助詞']
['とんと', 'とんと', '副詞', '一般']
['見当', '見当', '名詞', 'サ変接続']
['が', 'が', '助詞', '格助詞']
['つか', 'つく', '動詞', '自立']
['ぬ', 'ぬ', '助動詞', '*']
['。', '。', '記号', '句点']
  
Posted by gushwell at 21:00Comments(0)Python

2018年04月25日

言語処理100本ノックでPython入門 #39 - matplotlibで散布図を作成



いよいよ言語処理100本ノック 2015の第4章最後の問題39です。

■ 問題


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

39. Zipfの法則
単語の出現頻度順位を横軸,その出現頻度を縦軸として,両対数グラフをプロットせよ.

■ Pythonのコード

import re
import re
import matplotlib.pyplot as plt
 
def analyze():
    lines = []
    sentence = []
    with open('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['surface'] in words.keys():
                words[word['surface']] += 1
            else:
                words[word['surface']] = 1
    return words
 
def getScatterData(words):
    data = [x[1] for x in words.items()]
    data = sorted(data, key=lambda x: x, reverse=True)
    return range(1, len(data)+1), data
 
def plotScatter(x, y):
    plt.rcParams['font.family'] = 'Meiryo'  
    plt.scatter(x, y, s=2)
    plt.xscale("log")
    plt.yscale("log")
 
    plt.xlabel('出現頻度順位')
    plt.ylabel('出現頻度')
    plt.show()
 
def main():
    article = analyze()
    words = getFrequency(article)
    x, y = getScatterData(words)
 
    plotScatter(x, y)
 
if __name__ == '__main__':
    main()

ソースコードは、GitHubで公開しています。

■ 散布図を描く

以下のようにして両対数目盛の散布図を描いています。
plt.scatter(x, y, s=2)
plt.xscale("log")
plt.yscale("log")

軸を対数目盛にするには、xscale('log"0),yscale('log"0) を使います。

散布図は、scatter(x, y, s=2) です。

sは点のサイズを表しています。 Pythonは関数で複数の値を返すのが簡単で良いですね。

ところで、Zipfの法則ってなに?

Wikipediaによると

ジップの法則(ジップのほうそく、Zipf's law)あるいはジフの法則とは、出現頻度が k 番目に大きい要素が全体に占める割合が 1/k に比例するという経験則である。Zipf は「ジフ」と読まれることもある。また、この法則が機能する世界を「ジフ構造」と記する論者もいる。

とのことらしいです。 2番目の出現頻度は、1/2 3番目は1/3, 4番目は、1/4となるという法則ということですね。

■ 結果

nlp39

第4章もこれで終わりです。いよいよ第5章。やっとクラスを使います。
   
Posted by gushwell at 22:30Comments(0)Python

2018年04月22日

言語処理100本ノックでPython入門 #38 - matplotlibでヒストグラム


今日は言語処理100本ノック 2015の問題38です。

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

38. ヒストグラム
単語の出現頻度のヒストグラム(横軸に出現頻度,縦軸に出現頻度をとる単語の種類数を棒グラフで表したもの)を描け.


No37で求めた、単語の出現数のデータをさらに加工して、出現する単語の数を求め、それを元にグラフを描いています。


■ Pythonのコード
import re
import matplotlib.pyplot as plt
 
def analyze():
    lines = []
    sentence = []
    with open('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 getHistogramData(words):
    hist = {}
    for word in words.items():
        if word[1] in hist.keys():
            hist[word[1]] += 1
        else:
            hist[word[1]] = 1
    return words
 
def plotHistgram(data):
    xs = [x[1] for x in data]

    plt.rcParams['font.family'] = 'Meiryo' 
 
    plt.hist(xs, bins=25, range=(1, 25))
    plt.xlim(xmin=1, xmax=25)
    plt.xlabel('単語の出現頻度')
    plt.ylabel('単語の種類数')
    plt.show()
 
def main():
    article = analyze()
    words = getFrequency(article)
    histData = getHistogramData(words)
    sortedData = sorted(histData.items(), key=lambda x: x[1], reverse=True)
    print(sortedData[0:20])

    plotHistgram(sortedData)
 
if __name__ == '__main__':
    main()

ソースコードは、GitHubで公開しています。

■ ヒストグラムの描画

plotHistgram関数が、ヒストグラムを描画している関数です。

最初に書いたコードだと、なんとほとんどの単語が1回しか現れませんでした。 そのため、デフォルト設定のままhistメソッドを呼び出すと、まったく意味のわからないグラフになっていたので、range引数を指定して範囲を上位1-25に限定しました。

X軸は
plt.xlim(xmin=1, xmax=25)
で、範囲を設定できます。

Y軸のタイトルは縦書きにしたかったのですが、やり方がわかりませんでした。

■ 結果
nlp38

グラフ描画とともに、出現頻度の多い単語を20個表示しています。
 
[('の', 9194), ('て', 6868), ('は', 6420), ('に', 6243), ('を', 6071), ('と', 5508), ('が', 5337), ('た', 3988), ('で', 3806), ('も', 2479), ('ない', 2390), ('だ', 2363), ('し', 2322), ('から', 2032), ('ある', 1728), ('な', 1613), ('ん', 1568), ('か', 1530), ('いる', 1249), ('事', 1207)]
  
Posted by gushwell at 22:00Comments(0)Python

2018年04月18日

言語処理100本ノックでPython入門 #37 - matplotlibで棒グラフ作成


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

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

37. 頻度上位10語
出現頻度が高い10語とその出現頻度をグラフ(例えば棒グラフなど)で表示せよ.


■ Pythonのコード
import re
import matplotlib.pyplot as plt

def analyze():
    lines = []
    sentence = []
    with open('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 plotBarChart(sortedwords):
    categories = [x[0] for x in sortedwords]
    xaxis = [x for x in range(10)]
    values = [x[1] for x in sortedwords]

    #plt.rcParams['font.family'] = 'AppleGothic' 
    plt.rcParams['font.family'] = 'Meiryo' 

    plt.bar(xaxis, values)
    plt.xticks(xaxis, categories)
    plt.show()

def main():
    article = analyze()
    words = getFrequency(article)
    sortedwords = sorted(words.items(), key=lambda x: x[1], reverse=True)[0:10]
    print(sortedwords)
    plotBarChart(sortedwords)

if __name__ == '__main__':
    main() 

■ matplotlib.pyplotを使う


まずは、anacondaのcondaコマンドを使って、macに、matplotlibをインストールします。
$ conda install matplotlib

インストールしている途中で、以下のメッセージが出てきたので、y を押します
The following packages will be UPDATED:

    anaconda:   4.3.1-np111py36_0 --> custom-py36_0
    conda:      4.3.14-py36_0     --> 4.3.30-py36h173c244_0
    matplotlib: 2.0.0-np111py36_0 --> 2.0.2-np111py36_0

Proceed ([y]/n)? y

無事インストールできたので、matplotlib.pyplotをimportします。
    import matplotlib.pyplot as plt
これで、pltという名前で利用できるようになります。

実際にグラフを書いているのはplotBarChartメソッド内です。barメソッドでチャートを描いています。 

初めは、以下のように書いてみました。
categories = [x[0] for x in sortedwords]
xaxis = [x for x in range(10)]
values = [x[1] for x in sortedwords]

plt.bar(xaxis, values)
plt.xticks(xaxis, categories)
plt.show()
でも、日本語が文字化けしてしまいます。


■ matplotlibの文字化け対応

matplotlibの環境設定でフォントを日本語にするという方法もあるようですが、ここではコードだけで対応することにします。

まず、
import matplotlib.font_manager as fm
print([f.name for f in fm.fontManager.ttflist])
で、matplotlib利用できるフォント一覧を表示してみます。

僕の環境では’Meiryo’フォントがありますのでこれを使います。 たぶん、Microsoft Officeをインストールしているからかな。
そのほか、AppleGothicというフォントも日本語が表示できるようです。

メイリオフォントが使えることがわかったので、以下のように1行追加するだけで、日本語化することができました。
plt.rcParams['font.family'] =  ‘Meiryo’  // これを追加

plt.bar(xaxis, values)
plt.xticks(xaxis, categories)
plt.show()

どこまで、見た目をカスタマイズできるのかわからないけど、簡単にグラフが書けるのは便利ですね。


■ 結果
nlp37


出現頻度が高い10語とその出現頻度をコンソールにも表示しています。
[('の', 9194), ('て', 6868), ('は', 6420), ('に', 6243), ('を', 6071), ('と', 5508), ('が', 5337), ('た', 3988), ('で', 3806), ('も', 2479)]

  
Posted by gushwell at 22:30Comments(0)Python

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
  
Posted by gushwell at 21:19Comments(0)Python