Open11

自然言語処理で役立つTips

ピン留めされたアイテム
はるはる

ライブラリなどをメモっていきます。
以下目次

  • ja-sentence-segmenterというライブラリ。
  • spacyを用いたときの、ent.label_の一覧を取得する方法
  • spacy.load("hogehoge")のhogehogeをダウンロード
  • sudachipyでユーザー辞書作成
  • 固有表現抽出 GiNZA使用したマスキング
  • mecab-ipadic-NEologdをインストールする
  • neologdのcsvを、Sudachiで使えるようにする(未解決問題あり)
  • spaCy/GiNZAの形態素解析処理 Sudachiの設定ファイルを変更する方法
  • WordNetで類似語検索
  • UserWarning: [W095] Model 'ja_ginza' (5.1.3) was trained with spaCy v3.2.0 and may not be 100% compatible with the current version (3.7.2)
はるはる

spacyを用いたときの、ent.label_の一覧を取得する方法

import spacy
nlp = spacy.load("ja_core_news_md")
nlp.get_pipe('ner').labels

('CARDINAL', 'DATE', 'EVENT', 'FAC', 'GPE', 'LANGUAGE', 'LAW', 'LOC', 'MONEY', 'MOVEMENT', 'NORP', 'ORDINAL', 'ORG', 'PERCENT', 'PERSON', 'PET_NAME', 'PHONE', 'PRODUCT', 'QUANTITY', 'TIME', 'TITLE_AFFIX', 'WORK_OF_ART') ('CARDINAL', 'DATE', 'EVENT', 'FAC', 'GPE', 'LANGUAGE', 'LAW', 'LOC', 'MONEY', 'MOVEMENT', 'NORP', 'ORDINAL', 'ORG', 'PERCENT', 'PERSON', 'PET_NAME', 'PHONE', 'PRODUCT', 'QUANTITY', 'TIME', 'TITLE_AFFIX', 'WORK_OF_ART')

参考

https://stackoverflow.com/questions/53383601/can-you-determine-list-of-labels-for-existing-entityrecognizer-ner

はるはる

spacy.load("hogehoge")のhogehogeをダウンロード

python3 -m spacy download hogehoge

例として、ja_core_news_mdja_ginzaなどがある。

はるはる

sudachipyでユーザー辞書作成

  • WSLでやるには、エクスプローラーのところにwslと入力して、カレントディレクトリをsystem.dicがある場所にします。
  • その後、csvパスや出力先ファイル名を指定します。
略/site-packages/sudachidict_core/resources$
sudachipy ubuild -s "system.dic" -o "出力先ファイル名.dic" "パス/inputするファイル名.csv"

-oや-sなどのオプションは、-hで確認できます。

sudachipy ubuild -h

usage: sudachipy ubuild [-h] [-d string] [-o file] [-s file] file [file ...]
Build User Dictionary
positional arguments:
file source files with CSV format (one or more)
options: -h, --help show this help message and exit -d string description comment to be embedded on dictionary -o file output file (default: user.dic) -s file system dictionary path (default: system core dictionary path)

はるはる

固有表現抽出 GiNZA使用したマスキング

from spacy import displacy
import spacy
nlp = spacy.load('ja_ginza')
filepath = "txtファイルパス"
with open(filepath) as f:
    lines = f.readlines()


chunks = [' '.join(lines[i:i+100]) for i in range(0, len(lines), 100)]

for chunk in chunks:
    doc = nlp(chunk)

# 抽出したエンティティの種類に対して色を指定する
colors = {"COUNTRY": "#00cc00", "CITY": "#00cc00", "GPE_OTHER": "#00cc00", "OCCASION_OTHER": "#00cc00",
          "LOCATION": "#00cc00", "LOCATION_OTHER": "#00cc00", "DOMESTIC_REGION": "#00cc00", "PROVINCE": "#00cc00",
          "STATION": "#00cc00", "CONTINENTAL_REGION": "#00cc00", "THEATER": "#00cc00",

          "TIME": "#adff2f", "DATE": "#adff2f", "DAY_OF_WEEK": "#adff2f",
          "PERIOD_YEAR": "#adff2f", "PERIOD_MONTH": "#adff2f", "PERIOD_DAY": "#adff2f",

          "FLORA": "#adff99", "FLORA_PART": "#adff99",
          "DISH": "#ffeb99", "FOOD_OTHER": "#ffeb99",

          "AGE": "#3385ff", "N_PERSON": "#3385ff", "N_EVENT": "#3385ff", "N_LOCATION_OTHER": "#3385ff", "RANK": "#3385ff",
          "N_PRODUCT": "#3385ff", "": "#3385ff", "": "#3385ff", "": "#3385ff", "MEASUREMENT_OTHER": "#3385ff", "PERCENT": "#3385ff",
          "N_ORGANIZATION": "#3385ff", "ORDINAL_NUMBER": "#3385ff", "N_FACILITY": "#3385ff", "SPEED": "#3385ff",
          "PHONE_NUMBER": "#3385ff",

          "MONEY": "#ffff00",

          "COMPANY": "#99c2ff", "SCHOOL": "#99c2ff", "INTERNATIONAL_ORGANIZATION": "#99c2ff",
          "GOE_OTHER": "#99c2ff", "SHOW_ORGANIZATION": "#99c2ff", "CORPORATION_OTHER": "#99c2ff",

          "CLOTHING": "#ff66a3",
          "PRODUCT_OTHER": "#ff66a3",

          "PERSON": "#c266ff",
          "POSITION_VOCATION": "#ebccff",

          "MUSIC": "#ff7f50", "MOVIE": "#ff7f50", "GAME": "#ff7f50", "SPORT": "#ff7f50", "BOOK": "#ff7f50",
          "BROADCAST_PROGRAM": "#ff7f50",

          "ANIMAL_DISEASE": "#cd5c5c"
          }

options = {"colors": colors}
# docはあなたの解析済みのspaCy Docオブジェクトです
displacy.serve(doc, style="ent", auto_select_port=True)

optionsを以下のようにすると、1000000トークンまでになります。
ただし、表示するトークンの数が多すぎると、ブラウザのパフォーマンスに影響を及ぼす可能性があります。(By BingAI)

options = {"colors": colors, "compact": True, "max_length": 1000000}
displacy.serve(doc, style="ent", options=options, auto_select_port=True)

テキストファイルの途中から最後までしか表示されないので、以下のようにしたら、最後まできちんと実行されるようになりました。

# 全てのチャンクを1つのドキュメントに結合
doc = nlp(' '.join(chunks))

参考サイト

https://www.nogawanogawa.com/entry/ginza#固有表現抽出
https://zenn.dev/hyga2c/articles/ginza5_largetext#3.-一時的解決策
https://spacy.io/usage/visualizers/

自分用メモ

sudachipyに登録しているはずの人名などがちゃんと取得されない
python -m pip install --upgrade pip
pip install -U spacy SudachiPy ginza ja_ginza_electra

のあと、再度実行したら、表示されるようになりました

はるはる

mecab-ipadic-NEologdをインストールする

  1. sudo apt-get update
  2. sudo apt-get -y install aptitude
  3. sudo aptitude update
  4. sudo aptitude upgrade
  5. sudo aptitude install make automake autoconf autotools-dev m4 mecab libmecab-dev mecab-ipadic-utf8 git make curl xz-utils file
  6. sudo sed -i -e 's%/lib/mecab/dic%/share/mecab/dic%' /usr/bin/mecab-config
  7. sudo aptitude install mecab libmecab-dev mecab-ipadic-utf8 git make curl xz-utils file
  8. cd mecab-ipadic-neologd
  9. ./bin/install-mecab-ipadic-neologd -n
    これは結構時間かかるかも??

https://qiita.com/padawan_e15/items/6152144c3411941ced08
10. 以下で、きちんと表示されていれば、成功
echo `mecab-config --dicdir`"/mecab-ipadic-neologd"

エラー

aptitude: command not found

  1. sudo apt-get update
  2. sudo apt-get -y install aptitude

https://www.thegeekdiary.com/aptitude-command-not-found/

はるはる

neologdのcsvを、Sudachiで使えるようにする(未解決問題あり)

git cloneした、mecab-ipadic-neologdのディレクトリに、seedディレクトリがあって、その中に、mecab-user-dict-seed.20200910.csv.xzというファイルがあるので、これを展開します。
ここに入っている、csvファイルを、以下のコードによって、Sudachiに対応した形式にします。

コード
class NeoToSudach:
    '''
    ==================================================
    NEologd 辞書CSV⇒ GiNZA(sudachi)辞書CSV変換クラス
    ==================================================
    '''
    
    def conv(self,input_csv,output_csv):
        '''
        辞書ファイル変換
        
        Parameters
        ----------
          input_csv  str: 変換元CSVのパス
          output_csv str: 出力先CSVのパス
        '''
        
        #出力先の項目を格納するための箱(リスト)を準備
        res = ['*' for x in range(18)]
        
        #出力先を書き込みモードでオープン
        with open(output_csv,'w',encoding='utf-8') as wf:  
            #変換元ファイルを参照モードでオープン
            with open(input_csv,'r',encoding='utf-8') as rf:
                #1行取得
                for line in rf:
                    #処理中の行を表示
                    print(line)
                    #カンマで分解
                    items = line.replace('\n','').split(',')
                    
                    #出力先の箱に変換元の項目を移送
                    res[0] = items[0]               #見出し(TRIE 用)
                    res[1] = self.get_lid(items)    #左接続ID
                    res[2] = self.get_rid(items)    #右接続ID
                    res[3] = items[3]               #コスト
                    res[4] = items[0]               #見出し(解析結果表示用)
                    res[5] = items[4]               #品詞1
                    res[6] = items[5]               #品詞2
                    res[7] = items[6]               #品詞3
                    res[8] = '*'                    #品詞4
                    res[9] = '*'                    #品詞(活用型)
                    res[10] = '*'                   #品詞(活用形)
                    res[11] = items[11]             #読み
                    res[12] = items[12]             #正規化表現
                    res[13] = '*'                   #辞書形ID
                    res[14] = '*'                   #分割タイプ
                    res[15] = '*'                   #A単位分割情報
                    res[16] = '*'                   #B単位分割情報
                    res[17] = '*'                   #未使用
                    
                    #出力先に1行書き込み
                    wf.write(','.join(res) + '\n')
    
    def get_lid(self,items):
        '''
        左接続IDを算出する
        
        Parameters:
        ------------
           imte [str] : 項目のリスト
        '''
        if(items[4] == '名詞' and items[5] == '普通名詞' and items[6] == '一般'):
            return '5146'
        if(items[4] == '名詞' and items[5][:2] == 'サ変'):
            return '5133'
        return items[1]
    
    def get_rid(self,items):
        '''
        右接続IDを算出する
        
        Parameters:
        ------------
           imte [str] : 項目のリスト
        '''
        if(items[4] == '名詞' and items[5] == '固有名詞' and items[6] == '一般'):
            return '4786'
        if(items[4] == '名詞' and items[5] == '固有名詞' and items[6] == '人名'):
            return '4789'
        return items[2]


nts = NeoToSudach()
nts.conv('インプットパス/mecab-user-dict-seed.20200910.csv','アウトプットパス/mecab-user-dict-seed.20200910sudachi.csv')

その後、いつも通り、辞書を作ればOKです。

sudachipy ubuild -s "system.dic" -o "neologd.dic" "mecab-user-dict-seed.20200910sudachi.csv"

発生した問題

参考サイト

コード元
https://resanaplaza.com/2022/10/23/【python】neologdの辞書をginza(sudachi)用に変換して使おう!/

はるはる

UserWarning: [W095] Model 'ja_ginza' (5.1.3) was trained with spaCy v3.2.0 and may not be 100% compatible with the current version (3.7.2)

この警告は、現在使用しているspaCyのバージョン(3.7.2)と、'ja_ginza’モデル(5.1.3)が訓練されたspaCyのバージョン(3.2.0)が完全に互換性がない可能性があることを示しています。
解決するには、

pip uninstall ginza
pip uninstall spacy

で、
その後、

pip install -U ginza

をすると良い。

UserWarning: [W095] Model 'ja_ginza' (5.1.3) was trained with spaCy v3.2.0 and may not be 100% compatible with the current version (3.7.2). If you see errors or degraded performance, download a newer compatible model or retrain your custom model with the current spaCy version. For more details and available updates, run: python -m spacy validate
  warnings.warn(warn_msg)