LoginSignup
0
0

More than 3 years have passed since last update.

言語処理100本ノック-34(pandas使用):「AのB」

Posted at

言語処理100本ノック 2015「第4章: 形態素解析」34本目「「AのB」」記録です。
今回は行情報の組み合わせに対する課題なので、今までのように簡単にはできません。pandasやSQLなどの苦手な部分ですね。ですが、単なるループ処理なので難しくはないです。

参考リンク

リンク 備考
034.「AのB」.ipynb 回答プログラムのGitHubリンク
素人の言語処理100本ノック:34 多くのソース部分のコピペ元
MeCab公式 最初に見ておくMeCabのページ

環境

種類 バージョン 内容
OS Ubuntu18.04.01 LTS 仮想で動かしています
pyenv 1.2.16 複数Python環境を使うことがあるのでpyenv使っています
Python 3.8.1 pyenv上でpython3.8.1を使っています
パッケージはvenvを使って管理しています
Mecab 0.996-5 apt-getでインストール

上記環境で、以下のPython追加パッケージを使っています。通常のpipでインストールするだけです。

種類 バージョン
pandas 1.0.1

第4章: 形態素解析

学習内容

夏目漱石の小説『吾輩は猫である』に形態素解析器MeCabを適用し,小説中の単語の統計を求めます.

形態素解析, MeCab, 品詞, 出現頻度, Zipfの法則, matplotlib, Gnuplot

ノック内容

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

なお,問題37, 38, 39はmatplotlibもしくはGnuplotを用いるとよい.

34. 「AのB」

2つの名詞が「の」で連結されている名詞句を抽出せよ.

回答

回答プログラム 034.「AのB」.ipynb

import pandas as pd

def read_text():
    # 0:表層形(surface)
    # 1:品詞(pos)
    # 2:品詞細分類1(pos1)
    # 7:基本形(base)
    df = pd.read_table('./neko.txt.mecab', sep='\t|,', header=None, 
                       usecols=[0, 1, 2, 7], names=['surface', 'pos', 'pos1', 'base'], 
                       skiprows=4, skipfooter=1 ,engine='python')
    # EOS, 記号, 空白を残す
    return df

df = read_text()

POS_TARGET = '名詞'

for index in df['surface'].index:

    # 1行目・最終行に特別なロジックなし
    if df['surface'][index] == 'の' \
     and df['pos'][index-1] == POS_TARGET \
     and df['pos'][index+1] == POS_TARGET:
        print(index, '\t', df['surface'][index-1] + 'の' + df['surface'][index+1])

    # 多いので制限
    if index > 2000:
        break

回答解説

ファイル読込

前回までのノックとは異なり、EOS・記号・空白行の除去はしていません。文末や記号で明確を含めて「AのB」が連続であることを条件にしたかったためです。

def read_text():
    # 0:表層形(surface)
    # 1:品詞(pos)
    # 2:品詞細分類1(pos1)
    # 7:基本形(base)
    df = pd.read_table('./neko.txt.mecab', sep='\t|,', header=None, 
                       usecols=[0, 1, 2, 7], names=['surface', 'pos', 'pos1', 'base'], 
                       skiprows=4, skipfooter=1 ,engine='python')
    # EOS, 記号, 空白を残す
    return df

「AのB」判断

PandasのSeriesのindexでループします。そして、前後の行が名詞かを判断してます。

for index in df['surface'].index:

    # 1行目・最終行に特別なロジックなし
    if df['surface'][index] == 'の' \
     and df['pos'][index-1] == POS_TARGET \
     and df['pos'][index+1] == POS_TARGET:
        print(index, '\t', df['surface'][index-1] + 'の' + df['surface'][index+1])

出力結果(実行結果)

プログラム実行すると以下の結果が出力されます。多いので2000行までしか見ていないです。

出力結果
118      彼の掌
144      掌の上
151      書生の顔
197      はずの顔
235      顔の真中
248      穴の中
292      書生の掌
294      掌の裏
382      何の事
421      肝心の母親
478      藁の上
484      笹原の中
498      ようやくの思い
516      池の前
658      ようやくの事
729      一樹の蔭
742      垣根の穴
752      隣家の三毛
758      時の通路
806      一刻の猶予
842      家の内
858      彼の書生
861      以外の人間
892      前の書生
958      おさんの隙
1029     おさんの三
1046     胸の痞
1068     家の主人
1089     主人の方
1121     鼻の下
1130     吾輩の顔
1192     自分の住家
1208     吾輩の主人
1249     家のもの
1281     うちのもの
1300     彼の書斎
1326     本の上
1341     皮膚の色
1402     本の上
1411     彼の毎夜
1516     以外のもの
1588     主人の傍
1608     彼の膝
1610     膝の上
1659     経験の上
1665     飯櫃の上
1671     炬燵の上
1700     ここのうち
1702     うちの小供
1704     小供の寝床
1747     彼等の中間
1773     小供の一人
1826     例の神経
1830     性の主人
1839     次の部屋
1919     自分の勝手
1953     吾輩の方
2000     台所の板の間
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0