2021年3月21日日曜日

Pythonで日本語WordNetから類義語を取得する

WordnNetは英語の概念辞書で、英単語が類義語のグループ(synset)に分類されている。このWordNetの日本語版が日本語WordNetで、sqlite3のデータベース形式で公開されている。今回はこのデータベースを利用して単語の類義語をPythonで取得してみる。


環境


WSL2(Ubuntu20.04)。


Python3ではデフォルトでSqlite3を使用できるが、コマンドラインからも使用したいので、Sqlite3パッケージをインストールしておく。


日本語WordNetデータベースの準備

日本語WordNetのリリース・ダウンロードから「Japanese Wordnet and English WordNet in an sqlite3 database」をダウンロードする。

ダウンロードしたファイルgunzip wnjpn.db.gzを適当な場所において解凍しておく。


WordNetデータベースの確認


まずはWordNetデータベースの中身を確認してみる。データベースに接続してテーブル一覧を表示。

いくつかテーブルがあるが、ここでは今回使うwordテーブルとsenseテーブルを確認する。

「.headers on」でselect文でカラム名を表示するようにして、wordテーブルの中身を確認。wordテーブルには日本語だけでなく英単語の情報も格納されている。


日本語だけに限定して確認。


続いてsenseテーブルの確認。このテーブルで単語と概念(synset)が紐づけられている。こちらも英語と日本語が混在しているので日本語に限定して表示してみる。


Pythonで類義語を取得する

WordNetデータベースから、引数で指定した単語の類義語を取得するPythonコードを作成する。実際のところ、指定した単語の概念(synset)を取得してその概念をもつ単語の一覧を取得するSQLを実行し、その結果を出力するだけ。

import sys
import sqlite3

def main():
    word = sys.argv[1]

    con = sqlite3.connect('./wnjpn.db')
    cur = con.cursor()

    # 指定した単語の概念を取得(IN句)
    # 取得した概念をもつ単語を取得
    # テーブルには英単語も混在しているので日本語単語に限定
    # はじめに指定した単語は除外
    sql="""
SELECT word.lemma 
FROM sense 
INNER JOIN word 
ON sense.wordid = word.wordid 
WHERE sense.synset 
IN (
    SELECT sense.synset 
    FROM word 
    INNER JOIN sense 
    ON word.wordid = sense.wordid 
    WHERE word.lemma = ?
) 
AND sense.lang='jpn' 
AND word.lemma != ?
"""

    cur.execute(sql, (word, word))
    rows = cur.fetchall()

    # 類義語一覧表示
    # 重複があるので省く
    syns = set([r[0] for r in rows])
    print(syns)

    cur.close()
    con.close()

if __name__ == '__main__':
    main()


試しに類義語を取得してみる。


0 件のコメント:

コメントを投稿