LoginSignup
6
5

More than 3 years have passed since last update.

Python 日本語WordNetによる単語リスト(csv)からの類義語検索

Last updated at Posted at 2020-04-28

やったこと

日本語WordNetを用いて類義語を検出するコードを実装しました。仕様は単語を用意したcsvファイルを入力として、その単語群から同義語を検索してリスト化しテキストで同義語一覧を出力します。
実装は主にこちらの資料を参考にしています。

WordNetについて

日本語WordNetを知る
ネットワークが可視化されているので直感でイメージしやすいです。WordNetの定義等に興味のある方はご一読ください。

こちらが公式サイトです。
国立研究開発法人情報通信研究機構(NICT)により開発された日本語の意味辞書です。
今回の実装では公式サイトのJapanese Wordnet and English WordNet in an sqlite3 databaseのダウンロードが必要です。
ダウンロードファイル名:wnjpn.db.gz
こちらを解凍すると辞書データのdbファイルが手に入ります。
こちらのdbをPythonで読み込むことで同義語の検出が可能になります。

実装

create_similar_words.py
import sqlite3
import csv
import re
# db接続
conn = sqlite3.connect("wnjpn.db")
# ui
csvfile = 'words.csv'
outfile = 'similar_words.txt'

'''functions
csv_input: csv入力でリスト返却
SearchSimilarWords: 同義語リストを作成し返却
create_similar_wordlst: 同義語リスト整形
save_synonyms: 同義語リスト保存
'''

def csv_input(path_name):
    rows = []
    with open(path_name,encoding='utf-8') as f:
        reader = csv.reader(f)
        for row in reader:
            rows.append(row)
    return rows


def SearchSimilarWords(word):
    word = ','.join(word)
    cur = conn.execute("select wordid from word where lemma='%s'" % word)
    word_id = 99999999  #temp
    for row in cur:
        word_id = row[0]

    # Wordnetに存在する語であるかの判定
    if word_id==99999999:
        return
    cur = conn.execute("select synset from sense where wordid='%s'" % word_id)
    synsets = []
    for row in cur:
        synsets.append(row[0])
    simdict = []
    for synset in synsets:
        cur1 = conn.execute("select name from synset where synset='%s'" % synset)
        cur2 = conn.execute("select def from synset_def where (synset='%s' and lang='jpn')" % synset)
        cur3 = conn.execute("select wordid from sense where (synset='%s' and wordid!=%s)" % (synset,word_id))
        for row3 in cur3:
            target_word_id = row3[0]
            cur3_1 = conn.execute("select lemma from word where wordid=%s" % target_word_id)
            for row3_1 in cur3_1:
                # 類似語をリストに格納
                simdict.append(row3_1[0])
    return simdict


def create_similar_wordlst(full_word):
    parent = []
    child = []
    with open(csvfile, encoding='utf-8') as f:
        reader = csv.reader(f)
        for row in reader:
            child = []
            synonym = SearchSimilarWords(row)
            if not synonym is None:
                row = ','.join(row)
                child.append(row)
                for f_row in full_word:
                    f_row = ','.join(f_row)
                    for syn in synonym:
                        if f_row == syn:
                            child.append(syn)
            if len(child) > 1:
                parent.append(set(child))
    # print(parent)
    return parent


def save_synonyms(lst):
    norlst = []
    for row in lst:
        row = list(row)
        row = ','.join(row)
        norlst.append(row)
    norlst = set(norlst)
    with open(outfile, mode='w') as f:
        for row in norlst:
            f.write(row+'\n')


def main():
    full_word = csv_input(csvfile)
    save_synonyms(create_similar_wordlst(full_word))


if __name__ == "__main__":
    main()

フォルダ構成

create_similar_words.py
wards.csv
wnjpn.db

入力ファイル例

今回は簡易な実装の為、一列のみに文字列が挿入されているケースを想定しています。また、words.csv内にある文字内で類義語を検索する仕組みとなっています。

words.csv
開発
発展
・
・
・
集まる
群がる
たかる

出力ファイル例

similar_words.csv
開発,発展
・
・
・
集まる,群がる,たかる

まとめ

csv内の文字内から同義語を検索しcsvで出力するスクリプトを作成しました。分からない内容や実装の不備があればご指摘よろしくお願いいたします。また、LGTMも歓迎です!
ご一読ありがとうございました。

6
5
1

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
6
5