LoginSignup
2

More than 5 years have passed since last update.

素人の言語処理100本ノック:44

Last updated at Posted at 2016-11-30

言語処理100本ノック 2015の挑戦記録です。環境はUbuntu 16.04 LTS + Python 3.5.2 :: Anaconda 4.1.1 (64-bit)です。過去のノックの一覧はこちらからどうぞ。

第5章: 係り受け解析

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

44. 係り受け木の可視化

与えられた文の係り受け木を有向グラフとして可視化せよ.可視化には,係り受け木をDOT言語に変換し,Graphvizを用いるとよい.また,Pythonから有向グラフを直接的に可視化するには,pydotを使うとよい.

出来上がったコード:

main.py
# coding: utf-8
import CaboCha
import re
import pydot_ng as pydot

fname = 'neko.txt.tmp'
fname_parsed = 'neko.txt.cabocha.tmp'


def parse_neko():
    '''「吾輩は猫である」を係り受け解析
    「吾輩は猫である」(neko.txt)を係り受け解析してneko.txt.cabochaに保存する
    '''
    with open(fname) as data_file, \
            open(fname_parsed, mode='w') as out_file:

        cabocha = CaboCha.Parser()
        for line in data_file:
            out_file.write(
                cabocha.parse(line).toString(CaboCha.FORMAT_LATTICE)
            )


class Morph:
    '''
    形態素クラス
    表層形(surface)、基本形(base)、品詞(pos)、品詞細分類1(pos1)を
    メンバー変数に持つ
    '''
    def __init__(self, surface, base, pos, pos1):
        '''初期化'''
        self.surface = surface
        self.base = base
        self.pos = pos
        self.pos1 = pos1

    def __str__(self):
        '''オブジェクトの文字列表現'''
        return 'surface[{}]\tbase[{}]\tpos[{}]\tpos1[{}]'\
            .format(self.surface, self.base, self.pos, self.pos1)


class Chunk:
    '''
    文節クラス
    形態素(Morphオブジェクト)のリスト(morphs)、係り先文節インデックス番号(dst)、
    係り元文節インデックス番号のリスト(srcs)をメンバー変数に持つ
    '''

    def __init__(self):
        '''初期化'''
        self.morphs = []
        self.srcs = []
        self.dst = -1

    def __str__(self):
        '''オブジェクトの文字列表現'''
        surface = ''
        for morph in self.morphs:
            surface += morph.surface
        return '{}\tsrcs{}\tdst[{}]'.format(surface, self.srcs, self.dst)

    def normalized_surface(self):
        '''句読点などの記号を除いた表層形'''
        result = ''
        for morph in self.morphs:
            if morph.pos != '記号':
                result += morph.surface
        return result

    def chk_pos(self, pos):
        '''指定した品詞(pos)を含むかチェックする

        戻り値:
        品詞(pos)を含む場合はTrue
        '''
        for morph in self.morphs:
            if morph.pos == pos:
                return True
        return False


def neco_lines():
    '''「吾輩は猫である」の係り受け解析結果のジェネレータ
    「吾輩は猫である」の係り受け解析結果を順次読み込んで、
    1文ずつChunkクラスのリストを返す

    戻り値:
    1文のChunkクラスのリスト
    '''
    with open(fname_parsed) as file_parsed:

        chunks = dict()     # idxをkeyにChunkを格納
        idx = -1

        for line in file_parsed:

            # 1文の終了判定
            if line == 'EOS\n':

                # Chunkのリストを返す
                if len(chunks) > 0:

                    # chunksをkeyでソートし、valueのみ取り出し
                    sorted_tuple = sorted(chunks.items(), key=lambda x: x[0])
                    yield list(zip(*sorted_tuple))[1]
                    chunks.clear()

                else:
                    yield []

            # 先頭が*の行は係り受け解析結果なので、Chunkを作成
            elif line[0] == '*':

                # Chunkのインデックス番号と係り先のインデックス番号取得
                cols = line.split(' ')
                idx = int(cols[1])
                dst = int(re.search(r'(.*?)D', cols[2]).group(1))

                # Chunkを生成(なければ)し、係り先のインデックス番号セット
                if idx not in chunks:
                    chunks[idx] = Chunk()
                chunks[idx].dst = dst

                # 係り先のChunkを生成(なければ)し、係り元インデックス番号追加
                if dst != -1:
                    if dst not in chunks:
                        chunks[dst] = Chunk()
                    chunks[dst].srcs.append(idx)

            # それ以外の行は形態素解析結果なので、Morphを作りChunkに追加
            else:

                # 表層形はtab区切り、それ以外は','区切りでバラす
                cols = line.split('\t')
                res_cols = cols[1].split(',')

                # Morph作成、リストに追加
                chunks[idx].morphs.append(
                    Morph(
                        cols[0],        # surface
                        res_cols[6],    # base
                        res_cols[0],    # pos
                        res_cols[1]     # pos1
                    )
                )


def graph_from_edges_ex(edge_list, directed=False):
    '''pydot_ng.graph_from_edges()のノード識別子への対応版

    graph_from_edges()のedge_listで指定するタプルは
    識別子とグラフ表示時のラベルが同一のため、
    ラベルが同じだが実体が異なるノードを表現することができない。
    例えば文の係り受けをグラフにする際、文の中に同じ単語が
    複数出てくると、それらのノードが同一視されて接続されてしまう。

    この関数ではedge_listとして次の書式のタプルを受け取り、
    ラベルが同一でも識別子が異なるノードは別ものとして扱う。

    edge_list = [((識別子1,ラベル1),(識別子2,ラベル2)), ...]

    識別子はノードを識別するためのもので表示されない。
    ラベルは表示用で、同じでも識別子が異なれば別のノードになる。

    なお、オリジナルの関数にあるnode_prefixは未実装。

    戻り値:
    pydot.Dotオブジェクト
    '''

    if directed:
        graph = pydot.Dot(graph_type='digraph')

    else:
        graph = pydot.Dot(graph_type='graph')

    for edge in edge_list:

        id1 = str(edge[0][0])
        label1 = str(edge[0][1])
        id2 = str(edge[1][0])
        label2 = str(edge[1][1])

        # ノード追加
        graph.add_node(pydot.Node(id1, label=label1))
        graph.add_node(pydot.Node(id2, label=label2))

        # エッジ追加
        graph.add_edge(pydot.Edge(id1, id2))

    return graph


# 対象文字列を入力してもらい、そのままfnameに保存
with open(fname, mode='w') as out_file:
    out_file.write(input('文字列を入力してください--> '))

# 係り受け解析
parse_neko()

# 1文ずつリスト作成
for chunks in neco_lines():

    # 係り先があるものを列挙
    edges = []
    for i, chunk in enumerate(chunks):
        if chunk.dst != -1:

            # 記号を除いた表層形をチェック、空なら除外
            src = chunk.normalized_surface()
            dst = chunks[chunk.dst].normalized_surface()
            if src != '' and dst != '':
                edges.append(((i, src), (chunk.dst, dst)))

    # 描画
    if len(edges) > 0:
        graph = graph_from_edges_ex(edges, directed=True)
        graph.write_png('result.png')

実行結果:

実行結果をいくつか載せておきます。

端末
文字列を入力してください-->  どこで生れたかとんと見当がつかぬ。

Kobito.4Jss2O.png

端末
文字列を入力してください--> 何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。

Kobito.XJs7SQ.png

端末
文字列を入力してください--> 吾輩はここで始めて人間というものを見た。

Kobito.9krwjh.png

いい感じ!

pydotのインストール

まず、問題に取り組む前に環境構築です。
問題で勧められているpydotですが、Python 3に対応したpydot-ngというものがありましたので今回はこれを利用しました。
pydot-ngにはpyparsingGraphVizが必要なので、今回追加で必要なのは次の3つです。

必要なパッケージ 概要 オフィシャルサイト
pyparsing DOT言語のファイルを解析する際に利用されるライブラリです。DOT言語は、データ構造を表すグラフを表現するためのデータ記述言語です。 pyparsing
GraphViz DOT言語のグラフ情報から画像ファイルを生成するツールです。 Graphviz - Graph Visualization Software
pydot-ng GraphVizをPythonで使うためのライブラリです。pydotと互換があります。 pydot - Python interface to Graphviz's Dot language

pyparsingのインストール

condaで探してみたところ、すでに入っていました。*が付いているのはその印です。どうやらAnacondaでインストールされていたようです。

端末(condaでpyparsingの検索)
segavvy@ubuntu:~$ conda search pyparsing
Fetching package metadata .......
pyparsing                    1.5.6                    py26_0  defaults        
                             1.5.6                    py27_0  defaults        
                             1.5.6                    py33_0  defaults        
                             2.0.1                    py26_0  defaults        
                             2.0.1                    py27_0  defaults        
                             2.0.1                    py33_0  defaults        
                             2.0.1                    py34_0  defaults        
                             2.0.3                    py26_0  defaults        
                             2.0.3                    py27_0  defaults        
                             2.0.3                    py33_0  defaults        
                             2.0.3                    py34_0  defaults        
                             2.0.3                    py35_0  defaults        
                             2.1.1                    py27_0  defaults        
                             2.1.1                    py34_0  defaults        
                             2.1.1                    py35_0  defaults        
                             2.1.4                    py27_0  defaults        
                             2.1.4                    py34_0  defaults        
                          *  2.1.4                    py35_0  defaults 

GraphVizのインストール

続いてGraphVizのインストールです。
condaで見つかったので簡単にインストールできました。ついでにいろいろ新しくしてくれた模様です。いいですね。

端末(condaでGraphVizのインストール)
segavvy@ubuntu:~$ conda search graphviz
Fetching package metadata .......
graphviz                     2.38.0                        2  defaults        
segavvy@ubuntu:~$ conda install graphviz
Fetching package metadata .......
Solving package specifications: ..........

Package plan for installation in environment /home/segavvy/anaconda3:

The following packages will be downloaded:

    package                    |            build
    ---------------------------|-----------------
    conda-env-2.6.0            |                0          502 B
    expat-2.1.0                |                0         365 KB
    libtool-2.4.2              |                0         547 KB
    pixman-0.32.6              |                0         2.4 MB
    glib-2.43.0                |                1         5.4 MB
    ruamel_yaml-0.11.14        |           py35_0         377 KB
    conda-4.2.12               |           py35_0         387 KB
    cairo-1.12.18              |                6         594 KB
    harfbuzz-0.9.39            |                1         1.1 MB
    pango-1.39.0               |                1         668 KB
    graphviz-2.38.0            |                2        12.0 MB
    ------------------------------------------------------------
                                           Total:        23.7 MB

The following NEW packages will be INSTALLED:

    cairo:       1.12.18-6    
    expat:       2.1.0-0      
    glib:        2.43.0-1     
    graphviz:    2.38.0-2     
    harfbuzz:    0.9.39-1     
    libtool:     2.4.2-0      
    pango:       1.39.0-1     
    pixman:      0.32.6-0     

The following packages will be UPDATED:

    conda:       4.1.6-py35_0  --> 4.2.12-py35_0 
    conda-env:   2.5.1-py35_0  --> 2.6.0-0       
    ruamel_yaml: 0.11.7-py35_0 --> 0.11.14-py35_0

Proceed ([y]/n)? y

Fetching packages ...
conda-env-2.6. 100% |################################| Time: 0:00:00 533.05 kB/s
expat-2.1.0-0. 100% |################################| Time: 0:00:00   1.35 MB/s
libtool-2.4.2- 100% |################################| Time: 0:00:00   2.70 MB/s
pixman-0.32.6- 100% |################################| Time: 0:00:01   2.49 MB/s
glib-2.43.0-1. 100% |################################| Time: 0:00:01   2.99 MB/s
ruamel_yaml-0. 100% |################################| Time: 0:00:00   5.87 MB/s
conda-4.2.12-p 100% |################################| Time: 0:00:00   3.74 MB/s
cairo-1.12.18- 100% |################################| Time: 0:00:00   5.90 MB/s
harfbuzz-0.9.3 100% |################################| Time: 0:00:00   6.05 MB/s
pango-1.39.0-1 100% |################################| Time: 0:00:00   2.71 MB/s
graphviz-2.38. 100% |################################| Time: 0:00:01   7.16 MB/s
Extracting packages ...
[      COMPLETE      ]|###################################################| 100%
Unlinking packages ...
[      COMPLETE      ]|###################################################| 100%
Linking packages ...
[      COMPLETE      ]|###################################################| 100%

GraphVizが正しく入るとdotコマンドが使えるようになるので、確認しておきます。

端末(GraphVizのインストール確認)
segavvy@ubuntu:~$ dot -V
dot - graphviz version 2.38.0 (20140413.2041)

pydot-ngのインストール

ここまでは順調でしたがpydot-ngのインストールでつまずきました。環境が合わないというエラーのようです。

端末(condaでのpydot-ngインストールエラー)
segavvy@ubuntu:~$ conda install pydot-ng
Fetching package metadata .......
Solving package specifications: ....


UnsatisfiableError: The following specifications were found to be in conflict:
  - pydot-ng
  - python 3.5*
Use "conda info <package>" to see the dependencies for each package.

言われたとおりconda infoしてみます。

端末(pydot-ngのパッケージ情報確認)
segavvy@ubuntu:~$ conda info pydot-ng
Fetching package metadata .......

pydot-ng 1.0.0.15 py27_0
------------------------
file name   : pydot-ng-1.0.0.15-py27_0.tar.bz2
name        : pydot-ng
version     : 1.0.0.15
build number: 0
build string: py27_0
channel     : defaults
size        : 45 KB
date        : 2015-09-09
fn          : pydot-ng-1.0.0.15-py27_0.tar.bz2
license     : MIT
md5         : 8b81a344723e64ec3545b5f030caca47
priority    : 0
schannel    : defaults
url         : https://repo.continuum.io/pkgs/free/linux-64/pydot-ng-1.0.0.15-py27_0.tar.bz2
dependencies:
    pyparsing
    python 2.7*

pydot-ng 1.0.0.15 py34_0
------------------------
file name   : pydot-ng-1.0.0.15-py34_0.tar.bz2
name        : pydot-ng
version     : 1.0.0.15
build number: 0
build string: py34_0
channel     : defaults
size        : 46 KB
date        : 2015-09-09
fn          : pydot-ng-1.0.0.15-py34_0.tar.bz2
license     : MIT
md5         : 13e3a10b45edfb38d91a51d6b3ccabc7
priority    : 0
schannel    : defaults
url         : https://repo.continuum.io/pkgs/free/linux-64/pydot-ng-1.0.0.15-py34_0.tar.bz2
dependencies:
    pyparsing
    python 3.4*

どうやらPython 3.4用のパッケージはPython 3.5には入れられない、ということのようです。でも世の中Python 3.5で使っている方もいるので、0.1の差で弾かないで欲しい...
condaのサイトの説明(Resolution: Fix the conflicts in the installation request)も見てみましたが、無理やり入れる方法はわかりませんでした。

仕方ないのでcondaでのインストールは諦めて、pipで挑戦です。

端末(pipでpydot-ngを検索)
segavvy@ubuntu:~$ pip search pydot-ng
pypayd-ng (0.0.6)                          - A small daemon for processing
                                             bitcoin payments compatible with
                                             modern HD wallets
maestro-ng (0.4.1)                         - Orchestrator for multi-host
                                             Docker deployments
django-auth-ldap-ng (1.7.6)                - Django LDAP authentication
                                             backend
pydot (1.2.3)                              - Python interface to Graphviz's
                                             Dot
telescope-ng (0.1)                         - Observe SPARQLing RDF
                                             constellations through Python
                                             objects.
django-dajax-ng (0.9.4)                    - Easy to use library to create
                                             asynchronous presentation logic
                                             with django and dajaxice-ng
django-dajaxice-ng (0.7.0.7)               - Agnostic and easy to use ajax
                                             library for django
django-macaddress-ng (1.1.1)               - MAC address model and form fields
                                             for Django apps.
django-rest-hooks-ng (1.1.1)               - A powerful mechanism for sending
                                             real time API notifications via a
                                             new subscription model.
django-ninjapaginator-ng (0.1.6)           - Django application with multiple
                                             type of pagination integrated
cmsplugin-text-ng (0.6)                    - django-cms improved text plugin
ApplianceKit-NG (0.6.2)                    - Tools to programatically create
                                             distribution images from any
                                             distribution
pydot-ng (1.0.0)                           - Python interface to Graphviz's
                                             Dot
suds-ng (0.4.1)                            - Lightweight SOAP client - fork of
                                             suds
leancloud-sdk-ng (2.0.0)                   - LeanCloud Python SDK
django-extra-views-ng (0.3.3)              - Extra class-based views for
                                             Django
django-cas-ng (3.5.6)                      - CAS 1.0/2.0 client authentication
                                             backend for Django (inherited
                                             from django-cas)
booby-ng (0.8.3.post1)                     - Data modeling and validation
                                             Python library
keyserver-ng (0.1.0)                       - PGP keyserver with email and key
                                             validation.
pysensu-ng (0.7.0)                         - This is a client to interact with
                                             the Sensu API
django-crispy-forms-ng (2.0.0)             - Best way to have Django DRY forms
                                             of the next generation.
caffeine-ng (3.3.8)                        - A status bar application able to
                                             temporarily prevent the
django-oauth2-provider-ng (0.2.7.4)        - Provide OAuth2 access to your app
Flask-CDN-NG (1.3.0)                       - Serve the static files in your
                                             Flask app from a CDN.
tlslite-ng (0.7.0-alpha2)                  - Pure python implementation of SSL
                                             and TLS.
python-kyototycoon-ng (0.7.3)              - Python client library for the
                                             Kyoto Tycoon key-value store
brutal-ng (0.3.11)                         - The new generation of brutal, a
                                             multi-network asynchronouschat
                                             bot framework using twisted
django-timezone-field-ng (2.0)             - A Django app providing database
                                             and form fields for pytz timezone
                                             objects.
django-tagging-ng (0.3.3)                  - Enhanced tagging application for
                                             Django, based on django-tagging
cplay-ng (2.1.2)                           - A curses front-end for various
                                             audio players
arrow-ng (0.5.0)                           - Better dates and times for Python
ng-mini (0.1.1)                            - rrdtool based server monitor
                                             tool,and a web interface include
django-filebased-email-backend-ng (2.0.2)  - A better 'file' email backend for
                                             Django
micromodels-ng (0.6.3)                     - Declarative dictionary-based
                                             model classes for Python
iencode-ng (0.9.5)                         - iPhone video encoding tools.
django-polymorphic-ng (0.8.0)              - Seamless Polymorphic Inheritance
                                             for Django Models
django-mockups-ng (0.5.0)                  - Provides tools to auto generate
                                             content.
pytest-datadir-ng (1.1.0)                  - Fixtures for pytest allowing test
                                             functions/methods to easily
                                             retrieve test resources from the
                                             local filesystem.
django-js-utils-ng (0.5.futu)              - Django URL Exposure to Javascript
crontab-ng (0.20.3)                        - Parse and use crontab schedules
                                             in Python
purity-ng (0.1)                            - general purpose purity testing
                                             software
django-tastypie-swagger-ng (0.1.3)         - An adapter to use swagger-ui with
                                             django-tastypie
django-multilingual-ng (0.1.21)            - Multilingual extension for Django
                                             - NG
wymypy-ng (2.1)                            - Simple web interface for
                                             controlling MPD
sinaweibopy-ng (1.1.5)                     - Sina Weibo OAuth 2 API Python SDK
pyLisp-NG (2.0.0)                          - A very simple implementation of
                                             Lisp in Python that is perfectly
                                             suitable for Python projects
                                             needing Lisp-like capabilities.
checkbox-ng (0.29)                         - Checkbox - Command Line Test
                                             Runner
You are using pip version 8.1.2, however version 9.0.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.

なんか検索ノイズだらけですが、10数行目のところにpydot-ngがありました。
最後の2行でpipそのもののアップグレードをお勧めされているので、先にpipをアップグレードします。

端末(pipのアップグレード)
segavvy@ubuntu:~$ pip install --upgrade pip
Collecting pip
  Downloading pip-9.0.1-py2.py3-none-any.whl (1.3MB)
    100% |████████████████████████████████| 1.3MB 827kB/s 
Installing collected packages: pip
  Found existing installation: pip 8.1.2
    Uninstalling pip-8.1.2:
      Successfully uninstalled pip-8.1.2
Successfully installed pip-9.0.1

続いてpydot-ngのインストールです。

端末(pipでpydot-ngのインストール)
segavvy@ubuntu:~$ pip install pydot-ng
Collecting pydot-ng
  Downloading pydot_ng-1.0.0.zip
Requirement already satisfied: pyparsing>=2.0.1 in ./anaconda3/lib/python3.5/site-packages (from pydot-ng)
Building wheels for collected packages: pydot-ng
  Running setup.py bdist_wheel for pydot-ng ... done
  Stored in directory: /home/segavvy/.cache/pip/wheels/4f/09/d5/f96fd2578831e1b9021c634f057ab5306a3e4287efa800de29
Successfully built pydot-ng
Installing collected packages: pydot-ng
Successfully installed pydot-ng-1.0.0

無事インストールできました。
Pythonでimportできることを確認しておきます。なお、Installation:のところにあるように、import時はpydot_ngです。ngの前は-(ハイフン)ではなく_(アンダースコア)なのでご注意ください。

端末
segavvy@ubuntu:~$ python
Python 3.5.2 |Anaconda 4.1.1 (64-bit)| (default, Jul  2 2016, 17:53:06) 
[GCC 4.4.7 20120313 (Red Hat 4.4.7-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pydot_ng
>>> 

これでやっと問題が始められます。ふぅ。

問題42のコードの再利用

今回の問題は「吾輩は猫である」(neko.txt)とは関係なく「与えられた文」を処理するのですが、グラフを書く直前までにやることは問題42とまったく同じです。そこでコードを最大限再利用するために(=最大限手を抜くために^^;)、入力された内容で「吾輩は猫である」の代わりのファイルを作り、これまでの処理をそのまま流す形にしました。
クラスと関数は問題42のままですが、ファイル名はneko.txt.tmpneko.txt.cabocha.tmpに変更しています。

有向グラフとは

ウィキブックスのグラフ理論の解説が分かりやすいです。最初の方を読めば、今回の問題には十分そうでした。

pydotの使い方

pydotはまとまった解説が見つけられず、ちょっと苦戦しました。いろんなサイトから寄せ集めてきた知識をベースに、最終的にシンプルなコードに落ち着きました。

まず最初に、ノード(今回の実行結果の図における丸で囲まれた節の部分)をペアにしたタプルを作って、リストに詰め込んでいきます。このノードのペアがエッジ(実行結果の図における線の部分)で結ばれる形になります。

詰め込み終わったらpydot.graph_from_edges()graph_from_edges_ex()で、pydot.Dotオブジェクトに変換します。この時にdirected=Trueを指定すると有向グラフとなり、エッジが矢印になります。この関数のおかげで、DOT言語を知らなくても簡単にグラフが書けます。問題文にある「Pythonから有向グラフを直接的に可視化するには,pydotを使うとよい.」の「直接的」とは、DOT言語を使わずに済むことを指しているようです。

最後にpydot.Dot.write()でファイルに出力します。この関数はwrite_png()write_pdf()write_ps()といった感じで、関数名によってフォーマットを指定できます。今回はpngにしてみました。

2016/12/25追記
コードを修正しました。当初はpydotに用意されているpydot.graph_from_edges()を使ったシンプルなコードだったのですが、これだと1つの文の中で同じ表記の文節があった場合に、混ざってしまうことに気づきました。
例えば「今日の天気は晴れでしたが、明日の天気は悪くなるそうです。」という文の場合、修正前のコードだと次のようになってしまいます。

Kobito.x0sZW8.png

しかし、文中に出てくる2つの「天気」は別物で、次のように区別する必要があります。

Kobito.kcxARN.png

そこで、stack overflowにあった pydot: is it possible to plot two different nodes with the same string in them? という書き込みとpydot.graph_from_edges()のソースを参考に、graph_from_edges_ex()を作りました。

pydotの仕様の調べ方?

前述のようにpydotについてはまとまった解説が見つけられなかったため、仕様が分からない部分はhelp()で確認しました。

Pythonのモジュールは、docstringという仕組みに従ってソースにコメントが入って入ればhelp()で確認できます。例えばpydot.graph_from_edges()の仕様は、次のような感じで確認できます。

端末(pydot.graph_from_edgesの仕様の確認)
segavvy@ubuntu:~/ドキュメント/言語処理100本ノック2015/44$ python
Python 3.5.2 |Anaconda 4.1.1 (64-bit)| (default, Jul  2 2016, 17:53:06) 
[GCC 4.4.7 20120313 (Red Hat 4.4.7-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pydot_ng as pydot
>>> help(pydot.graph_from_edges)
help(pydot.graph_from_edges)
Help on function graph_from_edges in module pydot_ng:

graph_from_edges(edge_list, node_prefix='', directed=False)
    Creates a basic graph out of an edge list.

    The edge list has to be a list of tuples representing
    the nodes connected by the edge.
    The values can be anything: bool, int, float, str.

    If the graph is undirected by default, it is only
    calculated from one of the symmetric halves of the matrix.

ただ、これでもちょっと説明が足りないので、ソースも覗いてみました。ソースの場所は__file__で確認できます。

端末(pydot_ngのソースの場所の確認)
>>> print(pydot.__file__)
/home/segavvy/anaconda3/lib/python3.5/site-packages/pydot_ng/__init__.py

このファイルを開いてdef graph_from_edgesで検索すると実装部分が確認できます。Pythonで作られているモジュールは、この流れでソースの確認できるみたいです。仕様が良く分からないものはソースを確認するのが良さそうですね。

 
45本目のノックは以上です。誤りなどありましたら、ご指摘いただけますと幸いです。


実行結果には、100本ノックで用いるコーパス・データで配布されているデータの一部が含まれます。この第5章で用いているデータは青空文庫で公開されている夏目漱石の長編小説『吾輩は猫である』が元になっています。

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
2