自分で書いた会話シミュレーションだけでは面白くない。そこで、自分も知らない言葉や単語を聞かれたときは、ウィキペディア(wikipedia)の膨大なフリー百科事典で検索してみることにした。例えば、ラピロに質問してみる「外傷って何ですか?」(いや、知っているよ。知っているけれど、サンプルとして聞いただけ)。そしたら、ラピロは、こう答える「外傷とは、身体を構成している組織の生理的な連続性が断たれた状態のこと。機械的外力(力学的外力)による損傷。目視可能な損傷、比較的軽度な損傷などの俗称。の事ですよ」。ね、ラピロのIQが一気に100を超えそうな気がしませんか?

インターネットのウィキペディアを検索するには、wikipediaのpythonライブラリをインストールします。
$ sudo pip install wikipedia # Wikipediaライブラリをインストール Downloading wikipedia-1.4.0.tar.gz
2017年7月時点では、version1.4.9のwikiライブラリがダウンロード、インストールされました。
pythonインタプリタを実行して、コマンドラインでwikiを検索して動作を確認する。ひえええー。本当にこの3行だけでWikiサイトからデータを取得出来ちゃったよ。
pi@raspberrypi:~$ python
>>> import wikipedia
>>> wikipedia.set_lang("ja")
>>> print wikipedia.summary("外傷")
外傷とは
身体を構成している組織の生理的な連続性が断たれた状態のこと。本項で詳述する。
機械的外力(力学的外力)による損傷。目視可能な損傷、比較的軽度な損傷などの俗称。
外傷(がいしょう、英: injury, trauma)とは、外的要因による組織または臓器の損傷の総称。
通常、怪我(けが)と呼ばれ、外傷を負うことを負傷(ふしょう)といい、外傷を負った者を
負傷者(ふしょうしゃ)という。なお、死亡と外傷をあわせて死傷(ししょう)といい、死亡
した者と外傷を負った者とを合せて死傷者(ししょうしゃ)という。精神医学において、心理
的外傷を単に外傷と呼ぶことがある→心的外傷(トラウマ)を参照。身体的外傷の場合、広義
には、物理的あるいは化学的な外的要因による損傷すべてを指すが、通常は機械的外力(力学
的外力)による損傷を指す。
でも説明長い。ラピロに喋らせるには少々面倒です。ここで戻値の文章の数を指定できます。
pi@raspberrypi:~$ python
>>> import wikipedia
>>> wikipedia.set_lang("ja")
>>> print wikipedia.summary("外傷", sentences=1)
外傷とは
身体を構成している組織の生理的な連続性が断たれた状態のこと。
知りたい単語の意味を説明するには不十分なので、2~3文は必要かも。
ラピロのメインスクリプトに組み込む前の最終テストとして、小さいスクリプト(wikitest.py)を書いてみた。例えば「外傷」を聞くなら、[python wikitest.py 外傷]を実行する。すると、ラピロがインターネットのwikipediaで調べた結果を、前回までに作ったjtalkスクリプトで音声合成して喋ってくれる。
▽ スクリプト
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# wikitest.py
import wikipedia
import sys
import os
# Wikiの検索
def main_wiki( strText ):
# 単語のサマリーを取得。
print( strText + "ですね。ちょっとお待ちください。" )
wikipedia.set_lang("ja")
#print wikipedia.summary( strText )
try:
strReturn = wikipedia.summary( strText, sentences=1 ).encode("utf-8")
except:
print( "いっぱい考えたけど、思い出せなかっです。" )
finally:
print( strReturn )
strReturn = strReturn + "の事です。"
strCMD = "./jtalk.sh '" + strReturn + "' 'normal'"
os.system( strCMD )
# タイトルの取得。
#print( "▼タイトル" )
#ny = wikipedia.page( strText )
#print( ny.title )
# 単語の詳細情報を取得。
#print( "▼詳細情報" )
#print( ny.content ) とても口語で喋るには情報量が多すぎるのでコメントアウト。
# 初期設定
if __name__ == '__main__':
if (len(sys.argv) <= 1):
print("Syntax: python wikitest.py '[text]'")
sys.exit()
else:
main_wiki( sys.argv[1] )
▽ 実行結果
# python wikitest.py 外傷 外傷ですね。ちょっとお待ちください。 外傷とは 身体を構成している組織の生理的な連続性が断たれた状態のこと。の事です。
何を聞いても回答してくれる。ラピロが凄く頭良くなった。
Wikipediaの別の使い方として、wikiにはダウンロード用のデータファイルが用意されている。これはwikiのwebサイトをクローリングしてデータを取り出しちゃおうという人が増えてWebサイトの負荷が高まってしまうことを避ける目的と思われる。wikiのデータ(jawiki-latest-pages-articles.xml)は解凍後で10GBを超える巨大なファイルだった。SQLなどで検索するには、XMLファイルをRDBなどに変換した方がいい。下記pythonスクリプトで直接XMLファイルを検索することも出来たが、検索に58秒かかった。
考察の結果としては、簡単にwikiを実装するならインターネットwikiを検索する方が、(1)速い (2)簡単:インストール不要 (3)最新の辞書データを参照できる。ダウンロードした時の利点は、(1)オフラインでも使える (2){あり得ないだろうけれど}将来wikiがサービス終了になったりしても使い続けられる だろうか。
▽ スクリプト
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Wikipediaから記事をパースする
import xml.sax
import xml.sax.handler
import sys
import string
glbTitle = False
glbSearch = False
glbComment = False
glbKeyword = ""
glbCount = 0
class Handler( xml.sax.handler.ContentHandler ):
def startElement(self, name, attrs):
global glbTitle, glbComment
if( name == "title" ):
glbTitle = True
if( name == "text" ):
glbComment = True
def endElement(self, name):
global glbTitle, glbComment
if( name == "title" ):
glbTitle = False
if( name == "text" ):
glbComment = False
if( glbSearch == True and name == "text" ):
sys.exit()
def characters(self, content):
global glbSearch, glbCount
if( glbTitle == True ):
#print "Title:" + content
#if( string.find(content, glbKeyword ) != -1 ):
if( content == glbKeyword ):
glbSearch = True
if( glbSearch == True and glbComment == True ):
if( glbCount < 10 ):
print content
glbCount = glbCount + 1
return
def main( strKeyword ):
global glbKeyword
glbKeyword = strKeyword
print( "<" + strKeyword + ">" )
# SAX XMLReaderオブジェクトを生成する
parser = xml.sax.make_parser()
# XMLReaderにイベントのハンドラーを設定する。
parser.setContentHandler( Handler() )
# XMLReaderが、入力ソースを使ってSAXイベントを発生させる。
parser.parse(open("jawiki-latest-pages-articles.xml","r"))
return
if __name__=="__main__":
if ( len(sys.argv) < 1 ):
print( "Syntax: python try_readxml.py " )
else:
main( sys.argv[1].decode("utf-8") )
▽ 実行結果
# python try_readxml.py 外傷
<外傷>
{{otheruses|身体的外傷|心理的外傷|心的外傷}}
'''外傷'''とは
#身体を構成している組織の生理的な連続性が断たれた状態のこと。本項で詳述する。
#[[機械]]的外力([[力学]]的外力)による損傷。目視可能な損傷、比較的軽度な損傷などの俗称。
----
Pythonのwikipediaライブラリを使うと、最小、僅か3行のスクリプトを追加するだけで、インターネットのフリー百科事典を検索してデータを取得することができた。ラピロに組み込むことで、自分でWikiを検索できる、とっても頭のいいロボットになった。意外なことにインターネットの日本語ブログなどで「Pythonのwikipediaライブラリ」を使った事例が掲載されていないので、ついつい、wiki全項目のデータダウンロードを最初に試してしまい2日間くらい余計な作業をしてしまったけど、オンライン版wiki検索ライブラリはお薦め。
