まえがき
R&Dチームの徳田(@dakuton)です。 私の開発業務としては自然言語処理をメインとした業務ではありませんが、必要に応じてテキスト解析に携わることもあります。 今回は、がっつり自然言語処理やらないエンジニアからみたときのテキスト解析の使いどころを簡単にご紹介します。
業務での使いどころ
簡単に申し上げると、分類問題として解けそうなデータか?当たりをつけるためにテキスト解析を利用します。
私の業務では時系列データや定量データのような数値データなどをメインに取り扱っていますが、テキスト解析をあわせて行う必要が出てくる場合があります。 これは解析依頼をいただくデータが、数値情報に加えてテキスト情報が付随されているようなデータであることが多いためです。
例えば故障検知の場合、単に正常稼働時の数値データをもとに異常を定義するのではなく
- 過去レポート(故障時の部品や原因をまとめたテキスト文書)から故障傾向を抽出
- 発生件数や発生したときの影響範囲を整理
- 1,2をもとに対応優先度を決める
ことが求められます。 ただし、1の作業件数が数100件オーダー以上になってくると、人手で整理するところの作業コストが増大します。 よって、ざっくりでもよいので意見抽出(評価表現抽出)を行うことが有効です。
分散表現による意見抽出ではダメなのか?
既存のシステムなどで十分なデータが集まっていなくても、分散表現(Word2vec, fastTextを用いて、Wikipediaの全テキスト情報などをもとに学習して獲得した言語ベクトル)による類似度評価を用いることでもある程度は対応できます。ただし、意味が対立する単語について別の意見としたい(評価を反転させたものとしたい)ような場合は、分散表現だけではうまくいかないことがあります。
- うまくいかない理由
- 多くの分散表現で得られる類似度は文書内での単語の共起性に基づくスコアであるため、類義語だけでなく対義語にあたる内容も類似度が高くなります。
- 例えば、利用した日本語Wikipediaコーパスから獲得したWord2vecモデルにて「大きい」「小さい」の単語類似度は0.9以上となります。
社内創業イベントアンケートの意見抽出
毎年6月にオプティムの創業記念イベントであるOPTiM Dayを開催しています。(本年度の実行委員長を務めてさせていただきました) 本イベント終了後、参加いただいた人からアンケートを記入してもらったものを集計し、同じ意味をもつ回答が集約できるか?試してみました。
- OPTiM Day については、過去記事でもご紹介しておりますので、あわせてご覧ください。
意見抽出処理の流れ
3以降がよく見かける分散表現のテキスト分類から変更を加えた処理になります。 処理の実現にあたって、アンケート分析向けの追加学習などを特に行っていないのがポイントです。
- 形態素解析+係り受け解析による主部・述部検出(MeCab+CaboChaを利用)
- 類義語の検出(gensimによるWord2vecを利用)
- 対義語の検出(日本語 WordNetを利用)
- 意味が反転する述部のスコアリング
- 接頭辞「非」「無」「不」「未」など
- 助動詞「ない」「ず」など
- 2〜4をもとに文章一致度を判定
実行結果
多く寄せられた意見として、「昨年度は映画館を会場にしていたが、今年は会場をホテルに変更したこともありスクリーンが見えづらい席があった」というコメントが挙がっています。 そこで、同種のコメントがどのくらい挙がっているか確認してみましょう。
実際の回答に加えて、意味が反転するテスト用データを加えてみたところ、下記の表現パターンが含まれるコメントについては同じ意見として抽出できることが確認できました。
- 「画面(主部)」+「見える(述部)」の否定表現
- 「スクリーン(主部)」+「小さい(述部)」の肯定表現
- 「スクリーン(主部)」+「大きい(述部)」の否定表現
他意見の確認結果
- 3と逆のコメント(分散表現のみだと一致と誤判定される「スクリーン(主部)」+「大きい(述部)」の肯定表現)については、今回の狙いどおり別意見と判断することができました。
- 懇親会についての意見についても、主部(高い類似性検出)と述部(中程度の類似性検出)から下記2件のコメントが部分的に類似していると判断することができました。
- 「ホテルで立食パーティーは、料理、雰囲気ともに素晴らしかった。」 : 「立食(主部)」「料理(主部)」+「素晴らしい(述部)」
- 「ご飯美味しかったです。」: 「ご飯(主部)」+「美味しい(述部)」
アンケートコメント抜粋
ムービーのスクリーンが少し小さく、画面の下の方が見えなかった。 スクリーンが小さかったのと、位置が低かったので、真ん中あたりからは画面下部が見えなかったのが残念でした。 強いて言えばスクリーンの下側が見えにくかったです。 会場中程の席からでは、映像の下部が見えづらかったです。 画面があまり大きくなかった。 ホテルで立食パーティーは、料理、雰囲気ともに素晴らしかった。 ご飯美味しかったです。
新卒企画のコメント分析結果
なお、先月の記事で紹介した新卒企画についてもアンケート意見抽出してみましたが、システムの完成度が高く、突出して改善すべき課題は検出されませんでした。素敵ですね。
うまく意見抽出されないケース
否定表現以外の評価をいろいろ無視しているため、例えば以下のような文だと誤分類となります。
- 疑問表現
- 「スクリーンが大きかった。」と「スクリーンは大きかったか?」が同義と判定される
- 比較表現
- 「会場よかったです。」と「会場は映画館のほうが良かったです。」が同義と判定される
- 仮定表現
- 「スクリーンが大きかった。」と「大きいスクリーンで観たかった。」が同義と判定される
その他
- 数値+テキストデータではなく、動画+テキストデータの場合でも、ハッシュタグやコメントの類語を同じクラスとみなして分類するといった方法が提案されています。例えば最近だと、ハッシュタグを手がかりに未ラベルの動画データをラベル済み相当データとして利用する(弱教師あり学習による行動認識)といった手法が提案されています。
- ECサイトでのレビューのように、レビュー点数+コメントがペアとなるデータを用いる場合は、高評価(★4〜)と低評価(〜★2)などのグループに分けたときの単語出現頻度をもとに分類する方法なども利用可能です。
- 日本語以外への形態素解析+係り受け解析を考慮する場合はUniversal DependenciesベースであるspaCyを使うと便利です。
- Dependency Visualizerを用いて係り受け解析の関係が可視化されるのはうれしいです。
- なお、spaCyそのものは商用可ですが、spaCyが利用する言語コーパスはその限りではないので商用システムでの組み込みについては注意が必要です。
- MeCab系と比較すると導入手順がシンプル(特に64bit Windows環境)
- MeCab/CaboCha利用時の複雑さをDockerfileで記述すると下記のような依存ライブラリ多数ですが、spaCyの場合はpip1行で利用可能です。
FROM python:3.7-alpine RUN apk update RUN apk --no-cache add git gcc curl bash file sudo openssh build-base openssl swig # Install CRF++ ENV version 0.58 ENV url https://drive.google.com/uc?export=download&id=0B4y35FiV1wh7QVR6VXJ5dWExSTQ RUN cd /tmp \ && curl -L -o CRF++-${version}.tar.gz ${url} \ && tar -zxf CRF++-${version}.tar.gz \ && cd CRF++-${version} \ && ./configure \ && make \ && make install \ && rm -rf /tmp/* # Install MeCab ENV version 0.996 ENV url https://drive.google.com/uc?export=download&id=0B4y35FiV1wh7cENtOXlicTFaRUE RUN cd /tmp \ && curl -L -o mecab-${version}.tar.gz ${url} \ && tar -zxf mecab-${version}.tar.gz \ && cd mecab-${version} \ && ./configure --enable-utf8-only --with-charset=utf8 \ && make \ && make install \ && rm -rf /tmp/* # Install IPA dic ENV version 2.7.0-20070801 ENV url https://drive.google.com/uc?export=download&id=0B4y35FiV1wh7MWVlSDBCSXZMTXM RUN cd /tmp \ && curl -SL -o mecab-ipadic-${version}.tar.gz ${url} \ && tar -zxf mecab-ipadic-${version}.tar.gz \ && cd mecab-ipadic-${version} \ && ./configure --with-charset=utf8 \ && make \ && make install \ && rm -rf /tmp/* # Install mecab-ipadic-NEologd RUN cd /tmp \ && git clone --depth 1 https://github.com/neologd/mecab-ipadic-neologd.git \ && mecab-ipadic-neologd/bin/install-mecab-ipadic-neologd -n -y \ && rm -rf /tmp/* # Install CaboCha ENV version 0.69 ENV url https://drive.google.com/uc?export=download&id=0B4y35FiV1wh7SDd1Q1dUQkZQaUU ENV url2 https://drive.google.com/uc?confirm={}&export=download&id=0B4y35FiV1wh7SDd1Q1dUQkZQaUU ENV CPPFLAGS -I/usr/local/include RUN curl -c cabocha-${version}.tar.bz2 -s -L ${url} \ | grep confirm \ | sed -e "s/^.*confirm=\(.*\)&id=.*$/\1/" \ | xargs -I{} curl -b cabocha-${version}.tar.bz2 -L -o cabocha-${version}.tar.bz2 ${url2} \ && tar -jxf cabocha-${version}.tar.bz2 \ && cd cabocha-${version} \ && ./configure --prefix=/usr/local --with-charset=utf8 \ && make \ && make install \ && rm -rf /tmp/* RUN pip3 install mecab-python3 RUN pip3 install git+https://github.com/kenkov/cabocha RUN pip3 install cabocha-python
- 「うまく意見抽出されないケース」で挙げたような表現パターンが複雑化するようであれば、学習計算コストは非常に高いですがTransformerを使った分類手法を用いるのが無難かと考えています。
- (追記) 取り扱うデータが今回サンプルのように1文のものであればELMoでもよい(BERTを適用すると学習が冗長になる点があり、分類ターゲットの文章の長さに応じて使い分けるべき)のでこちらも記載しておきます。
- ELMo: Word2vecのような単語レベルの類似度ではなく、係り受け解析を行った際に得られる接続関係を含んだ表現を得ることができます。
- BERT: ELMoの学習に加えて、文の前後関係(≒比較したい文が隣接していても違和感ないか?)の学習を行っており、1文の形態素解析/係り受け解析で得られる結果をまたいだ表現を得ることができます。その分計算コストは増大します。
- どちらも係り受け接続関係が得られている、ということはstructural-probes(Github)にまとめられています。
おわりに
今回、アンケートにて集約した意見は、今後のイベント運営改善につなげていきたいと思います。
なお今回は、実験結果としてテキスト分析の取り組みをご紹介しましたが、オプティムでは特定フォーマットのデータにこだわらず様々なデータを新しい価値に変換する活動を推進しています。気になる方は下記をご確認ください。
インターンも募集中です。