LoginSignup
0
0

More than 3 years have passed since last update.

言語処理100本ノック-35(pandas使用):名詞の連接

Posted at

言語処理100本ノック 2015「第4章: 形態素解析」35本目「名詞の連接」記録です。
前回と同様、pandasで簡単に処理できないない内容です。ですが、「名詞の連接」部分は10行程度の難しくはない処理です。

参考リンク

リンク 備考
035.名詞の連接.ipynb 回答プログラムのGitHubリンク
素人の言語処理100本ノック:35 多くのソース部分のコピペ元
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を用いるとよい.

35. 名詞の連接

名詞の連接(連続して出現する名詞)を最長一致で抽出せよ.

課題補足(「」について)

回答

回答プログラム 035.名詞の連接.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')
    return df[df['pos'] == '名詞']

df = read_text()

nouns = []
for index in df['surface'].index:
    nouns.append(df['surface'][index])

    # ひとつ先のインデックスがない場合は名詞連接の終端
    if (index + 1) not in df.index:

        # 複数(連接)の場合
        if len(nouns) > 1:
            print(len(nouns), '\t', index, '\t', ''.join(nouns))
        nouns = []

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

回答解説

ファイル読込

今回は名詞以外は不要なのでファイル読込直後に名詞だけを対象にエントリを絞っています。

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')
    return df[df['pos'] == '名詞']

名詞連接抽出

あとはループでの処理です。次エントリのインデックスが+1かどうかで連接終端判断をしています。連接終端で連接リストの長さが1以上の場合のみ名詞連接を出力します。

nouns = []
for index in df['surface'].index:
    nouns.append(df['surface'][index])

    # ひとつ先のインデックスがない場合は名詞連接の終端
    if (index + 1) not in df.index:

        # 複数(連接)の場合
        if len(nouns) > 1:
            print(len(nouns), '\t', index, '\t', ''.join(nouns))
        nouns = []

出力結果(実行結果)

プログラム実行すると以下の結果が出力されます。

出力結果
2    28      した所
2    66      人間中
2    69      一番獰悪
2    172     時妙
2    190     一毛
2    209     その後猫
2    222     一度
2    688     邸内
2    860     書生以外
3    1001    四五遍
2    1028    この間おさん
2    1031    三馬
2    1106    御台所
2    1150    まま奥
2    1235    終日書斎
2    1255    勉強家
2    1266    勉強家
2    1288    勤勉家
3    1392    二三ページ
2    1515    主人以外
2    1581    限り吾輩
2    1599    朝主人
2    1690    一番心持
2    1733    一つ床
2    1781    最後大変
3    1829    神経胃弱性
2    1913    言語同断
2    1961    しようもの
3    1965    家内総がかり
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