Edited at

Excelで誰でも簡単言語処理 (感情推定, 固有表現抽出, キーワード抽出, 文類似度推定 etc...)


3行まとめ


  • Excel関数一発で高度な言語処理を使えるようにしました

  • 感情推定、固有表現抽出など日本語を分析・整理するのにいろいろ使えます

  • Windows + Officeユーザならマクロファイルで誰でも簡単に使えます

※Macだと多分動かないと思います。VBAのHTTPリクエストを有効にできないため。。。


8/6追記: コメント頂きましたが、64bit版OfficeだとjsonParseが動かないようなのでアップデート検討中です。



はじめに

MicrosoftのExcel って使ってますか?:bar_chart:

エンジニアには馬鹿にされがちな気もするExcelですが、

とあるアンケート調査によると国内就業者の実に93.4%もの方が「業務においてExcelは重要」と答えているそうです。1

日本の業務はExcelで回っていると言っても過言ではない割合ではないでしょうか。

今回はそんなExcelで様々な言語処理を扱えるようにしてみました。

WindowsでExcelを使っている方ならファイルをダウンロードすれば(多分)簡単に使えます!!


ユースケース例

例えば、お客様の声がたくさん集まったので分析したい・・・という場面を想像してください。

example4.PNG

こんな感じで沢山のコメント2が集まっているのですが、一つ一つ中身を見て分析するのは面倒です。そんなときは横のセルに、 =easyCotohaSentiment(分析したいセル,$B$3)と入力してみましょう

example3.PNG

あっという間にPositiveかNegativeかをそのスコアとともに判定してくれました!3


他に作ったもの


固有表現抽出

解析したい文をセルに書き、easyCotohaNeという関数でそのセルを引数に指定すると、固有表現を抽出します

easyCotohaNe.PNG


キーワード抽出

上記同様、easyCotohaKeywordという関数でセルを引数に指定すると、キーワードを抽出します。

easyCotohaKeyword.PNG


類似度算出

easyCotohaSimilarityという関数で類似度を比較したいセルを2つ指定すると、類似度を算出します。4

easyCotohaSimilarity.PNG


その他

使い方はやや複雑になりますが、他にも下記リンクの言語処理系の機能は全て使えるようにしています。

COTOHA API

例えば構文解析を使えば以下のように形態素解析+読みがな生成などもできます。

parse.PNG


使い方


1.COTOHA APIに登録する

今回の言語処理はCOTOHA APIを使っているため、まず登録します。

for Deveropersという無料プランがあるのでそちらを申し込みます。5

Developer Client id、Developer Client secretという2つのキーがもらえるので、控えておきます。


2. マクロ入りエクセルファイルをダウンロードする

下記からダウンロード (Downloadと書かれたボタンをクリック)

https://github.com/korinzuz2/excelcotoha/blob/master/COTOHA%E5%85%AC%E9%96%8B%E7%94%A8.xlsm


3. ダウンロードしたブックを開き、マクロを有効化する

開くと警告ウインドウなりでマクロを有効化するか聞かれるので、有効にするをクリック


4. HTTPリクエストを有効にする

Excelを開いた状態でAlt + F11するとウインドウが立ち上がるので

そのツールバーからツール→参照設定で「Microsoft XML v6.0」というものにチェックを入れます。


5. 項番1で得たキーを書き込む

シートのB1, B2セルに項番1で発行されたClient id、Client secretを書き込みます。

書き込むとしばらくして、様々なサンプルの解析結果が表示されます。

※サンプルは色々やってるので時間がかかると思います。適宜削ってお使いください。


中身の解説

やっていることはVBAでCOTOHA APIにPOSTしてレスポンスを解釈しているだけです。


1. アクセストークンを取得する

=getAccessToken(B1,B2)という関数を使って、COTOHA APIにkeyとsecretをPOSTすることでアクセストークンを取得します。(ファイルだとB3セルで実施しています。)

getAccessToken (クリックで展開)

Function getAccessToken(ByVal clientId As String, ByVal clientSecret As String) As String

Dim url As String
url = "https://api.ce-cotoha.com/v1/oauth/accesstokens"

Dim paramStr As String: paramStr = "{""grantType"":""client_credentials"",""clientId"":""" & clientId & """,""clientSecret"":""" & clientSecret & """}"

Dim req As XMLHTTP60: Set req = New XMLHTTP60

With req
.Open "POST", url
.setRequestHeader "Content-Type", "application/json"
.setRequestHeader "charset", "utf-8"
.send paramStr
End With

Dim obj As Object
Dim json As Object

Set obj = CreateObject("ScriptControl")
obj.Language = "JScript"
obj.addcode "function jsonParse(s){ return eval('('+s+')');}"

Set json = obj.CodeObject.jsonParse(req.responseText)

getAccessToken = CallByName(json, "access_token", VbGet)

Set req = Nothing

End Function



2. COTOHAの各APIにPOSTしてjsonを取ってくる

例えば =cotohaSentiment()は、解析したい文と項番1のアクセストークンをCOTOHA APIの感情推定APIにPOSTしてそのレスポンス(json形式)を返します。

cotohaSentiment (クリックで展開)


Function cotohaSentiment(ByVal document As String, ByVal accessToken As String) As String
Dim url As String
url = "https://api.ce-cotoha.com/api/dev/nlp/v1/sentiment"

Dim paramStr As String: paramStr = "{""sentence"":""" & document & """}"

Dim req As XMLHTTP60: Set req = New XMLHTTP60

With req
.Open "POST", url
.setRequestHeader "Content-Type", "application/json"
.setRequestHeader "charset", "utf-8"
.setRequestHeader "Authorization", "Bearer " & accessToken
.send paramStr
End With
cotohaSentiment = req.responseText
Set req = Nothing

End Function



3. 返ってきたjson形式のレスポンスから情報を抽出する

COTOHA APIは様々な解析結果を返してくるので、適宜取捨選択して表示します。

たとえば最初に例として挙げた =easyCotohaSentiment() なら、

"emotional_phrase"という感情を表す語が何か、というのが本来解析結果に含まれるのですが、今回はそれを無視して、感情がPositiveかNegativeか、とそのスコアについてのみ抽出して表示するようにしています。

easyCotohaSentiment (クリックで展開)


Function easyCotohaSentiment(ByVal document As String, ByVal accessToken As String) As String

Dim obj As Object
Dim response As String
Dim json As Object
Dim result As String

' json形式でキーワード抽出結果を取得
response = cotohaSentiment(document, accessToken)

' jsonを解析
Set obj = CreateObject("ScriptControl")
obj.Language = "JScript"
obj.addcode "function jsonParse(s){ return eval('('+s+')');}"
Set json = obj.CodeObject.jsonParse(response)

' sentimentとscore値を取り出しカンマ区切りで連結
result = CallByName(CallByName(json, "result", VbGet), "sentiment", VbGet) + ","
result = result + CStr(CallByName(CallByName(json, "result", VbGet), "score", VbGet))
easyCotohaSentiment = result

End Function


また、これらのeasy〜の関数を使わずとも、前述した構文解析のようにExcelのFIND関数やMID関数を駆使してjsonから無理やり情報抽出することも可能です。

Excelの別シートにそれらの例もいろいろと記載してみたので、よろしければ使ってみてください。


まとめ

以上、Excelで言語処理をやってみました。

エンジニアとして「わざわざExcelでやる必要はないだろ」とはちょっと思うのですが、やってみると意外と結果がわかりやすく表示されるのでこれはこれで楽しかったりします。

また、営業さんだろうがお偉いさんだろうが普段コードを全く書かないという人にも触ってもらえる可能性があるので、言語処理の間口を広げるのには案外良いかなと思ったりもします。

あと、実体験上、業務用のPCだとセキュリティだ何だでコードがまともに書けなかったりインストールができなかったりしますが、Excelのマクロは案外許容されてたりします。インターネットにさえ繋がっていれば言語処理ができるというのは無視できない利点なのかもしれない・・・。

 





  1. Excelに関するアンケート (株式会社わかるとできる 調査期間:2016年1月26日~2016年1月27日 調査方法:インターネット調査 調査対象:現在就業している20~59歳の男女562名 ) 



  2. 「人間失格」 太宰 治 (1948) 青空文庫 



  3. 色は条件付き書式。Positive or Negativeが含まれてたら色変える、としてるだけ。 



  4. 類似度は0.0-1.0で判定。今回は0.87なのでかなり似ている、という意味。詳しくは→類似度算出API 



  5. 1日各API1000回まで。それを超えると翌日までエラーになる。