1
/
5

「その他」の内訳集計を指示されたから後輩に押し付けようとした話(Python + GiNZA / 固有表現抽出)


はじめに

ある日急に集計を依頼されたものの、元のデータがフリーテキストで困ったエンジニアの話をします。

ロジカルスタジオでは独自の日報システムを使用しています。
その日報を入力する際、作業種別をプルダウンから選ぶようになっています。

ある程度の種別を用意しているものの、どうしても「その他」という選択肢も必要になります。

「その他」の内容として入力されたフリーテキストから、
どういった内容が「その他」として登録されているのか集計する
というのが目的になります。

フリーテキストなので助詞や接続詞などで表記が揺れて集計しずらい為、
NLPライブラリを利用して集計しやすいようにします。

茶番が長いので本編までSKIP

茶番

ある日ー…

1週間後ー…

本谷さんの席



STEP1:NLPライブラリの選択

さっそく「日本語 NLP ライブラリ」でgoogle検索しましょう。

GiNZA一択ですね。

公式を軽く読むとPythonの環境が要るらしい。
環境を作っていきましょう。

STEP2:Python環境を作る

茶番に書いたようにPython得意(笑)だったら良かったのですが、
現実には1度触ったことが有るくらいです。

windows上でやるかdockerでやるか。
悩んだ結果dockerを選択しました。 (windowsの場合詰まった時に何が原因か分からんイメージが。。)

「python docker image」でgoogle検索します。

オフィシャルも良いですが、先人の知恵が詰まっていそうなので3つ目のqiitaの記事を参考にしました。
この方は「jupyterlab」を使いたかったようですが、この記述をGiNZAに変更します。
GiNZAの公式を見ると、セットアップは下記のコマンドで良いとの事。

pip install -U ginza https://github.com/megagonlabs/ginza/releases/download/latest/ja_ginza_electra-latest-with-model.tar.gz

Dockerfileはこうなります。
docker-compose.ymlは記事のままで良いでしょう。

FROM python:3
USER root

RUN apt-get update
RUN apt-get -y install locales && \
    localedef -f UTF-8 -i ja_JP ja_JP.UTF-8
ENV LANG ja_JP.UTF-8
ENV LANGUAGE ja_JP:ja
ENV LC_ALL ja_JP.UTF-8
ENV TZ JST-9
ENV TERM xterm

RUN apt-get install -y vim less
RUN pip install --upgrade pip
RUN pip install --upgrade setuptools

RUN pip install -U ginza "https://github.com/megagonlabs/ginza/releases/download/latest/ja_ginza_electra-latest-with-model.tar.gz"

後は普通にdocker-composeでビルドします。

STEP3:抽出処理

pythonのコンテナに入り、~/optへ移動するとそこがマウントディレクトリになっています。
ここでスクリプトを組んでいきます。

今回やりたいのは、フリーテキストがずらっと並んだCSVに1行ずつNLPの処理をかまし、
助詞を取り除いた名詞句を抜き出して集計するという内容です。

元となるCSVはこんな内容。

1.GiNZAライブラリをインポート
2.CSVを読み込む
3.1行づつnlpをかます

という流れなので、
GiNZA公式にある「Pythonコードによる解析処理の実行」という節の内容に従って、
まずは1行だけ試してみます。

コードはこちら。

import spacy
nlp = spacy.load('ja_ginza_electra')

f = open('daily_report_details.csv', 'r')

datalist = f.readlines()
doc = nlp(datalist[0])
for sent in doc.sents:
    for token in sent:
        print(token.i, token.orth_, token.lemma_, token.pos_, token.tag_, token.dep_, token.head.i)
    print('EOS')
f.close()

さっそく実行しましょう。

root@7bc5aff4e1f3:~/opt# python aaaa.py
0 " " PUNCT 補助記号-一般 punct 2
1 # # SYM 補助記号-一般 compound 2
2 日報 日報 NOUN 名詞-普通名詞-一般 nmod 5        
3 へ へ ADP 助詞-格助詞 case 2
4 通知 通知 NOUN 名詞-普通名詞-サ変可能 compound 5
5 テスト テスト NOUN 名詞-普通名詞-サ変可能 ROOT 5
6 " " PUNCT 補助記号-一般 punct 5
EOS
7 
 
 NOUN 空白 ROOT 7
EOS

う~ん、10行目の第4引数の「token.pos_」というのがNOUNになってるものが抽出出来れば良さそうだけども。。
何というか細かく分かれ過ぎている気がします。
出来れば「通知テスト」みたいにまとまったワードが欲しい。

調べてみると、8行目のdoc.sentsの代わりにdoc.noun_chunksというのが使えるらしい。
試してみると、

root@7bc5aff4e1f3:~/opt# python aaaa.py 
"#日報
通知テスト

これじゃぁ~~~!!!

得たい結果の出し方が分かったので、
後はひたすらcsvを1行ずつ読んでnoun_chunksを吐き出していくだけです。
一応、実行前にcsvからダブルクォーテーションや・や#などの要らん記号は削除しておきましょう。

ソース内容はこうなりました。

import spacy
nlp = spacy.load('ja_ginza_electra')

f = open('daily_report_details.csv', 'r')
wf = open('result.txt', 'w')

datalist = f.readlines()
for dataline in datalist:
     doc = nlp(dataline)
     for np in doc.noun_chunks:
          wf.write(str(np) + '\n')
f.close()
wf.close()

で、実行しますが…

GPU使わんなぁ。。
公式にはCUDAを使用する方法が書いてありますが、
会社のPCにCUDAなんか入ってないので仕方ないですね。
15,000行の処理をひたすら待ちます。

待つこと12分。
出力したテキストを小文字→大文字に変換した上でソートしExcelに貼り付けると、
良い感じに同じ作業内容が並ぶ結果になりました。

弊社の社内雑務「その他」のTOP10までを発表します。


うーん納得の結果。
面白いのが、9位に「その他」が再出現している事。
これはもう分からんな。。

ま・と・め

・日本語NLPはGiNZAというライブラリが有名らしい

・GiNZA関係の記事を読むと

nlp = spacy.load('ja_ginza')

というサンプルが良く見つかるが、これは古いバージョンで下記のエラーが起きる。

Can't find model 'ja_ginza'. It doesn't seem to be a shortcut link, a Python packageor a valid pathto a data directory

現行バージョン(v5.x)では、

nlp = spacy.load('ja_ginza_electra')

・下記プロパティで、少しまとまった名詞句を取得できる

doc.noun_chunks

・ロジカルスタジオは朝礼の時間を削減するなど業務改革の必要がある

・ロジカルスタジオでは後輩に仕事を押し付けるとコロコロで殴られる

最後に

さて、弊社ロジカルスタジオでは種類を問わず様々な職種・技術で一緒に働ける方を募集しております。

採用サイトには会社の雰囲気社員インタビューなど、
たくさんの情報が掲載されているのでお気軽に覗いてみてください!

フロントエンドエンジニア
即戦力募集!問題を解決するテクニカルディレクターをWanted!
ロジカルスタジオは、テクノロジーとデザインの視点からクライアントの課題解決をめざす、大阪のクリエイティブプロダクションです。 クライアントの期待を超えて「もっと良くなる、を見つける」のが私たちのスタイル。企画・提案からデザイン制作・システム構築、運用、改善提案をワンストップで行えるのが一番の強みです。近年ではその実績と品質が評価され、案件も急増しています。 代表の古川が掲げる企業理念は「絆を大切に、周りの人を豊かにし、社会に貢献する」。 私たちはこのミッションを推進するため、「新しい技術へのチャレンジ精神」を軸に、「切磋琢磨する仲間」と「働きやすい職場環境」を整え、「成長と可能性を大切にする風土」を育ててきました。 2019年9月に増床し、外部向けのセミナーにも活用できるカンファレンスルームを拡充。スタッフによる公式ブログや、マスコットキャラクター「ロージー&カール」によるTwitterなど、情報発信も強化しています。 可能性の芽をすくい上げられるこの場所を、より大きくしていきたい。 私たちと一緒に、このビジョンを実現しませんか。
株式会社ロジカルスタジオ
株式会社ロジカルスタジオ's job postings
5 Likes
5 Likes

Weekly ranking

Show other rankings
Invitation from 株式会社ロジカルスタジオ
If this story triggered your interest, have a chat with the team?