Google Cloud の cloud shell ターミナル上の julia から、Cloud Natural Language API で感情分析をやってみよう
前の投稿 で動かした Google Cloud の cloud shell ターミナル上の julia から、Cloud Natural Language API で感情分析をやってみようという話しです。 なお、julia の PyCall は `/usr/bin/python3`に継いであります。
前提として、Cloud Natural Language API が python3 から動かないといけません。 この為には、 Cloud Natural Language のドキュメントのクイックスタート: 「 環境変数 GOOGLE_APPLICATION_CREDENTIALS を、サービス アカウント キーが含まれる JSON ファイルのパスに設定します。 」という作業が必要です。 JSON として秘密鍵をダウンロードして、cloud shell のターミナルの右上の ... が縦に並ぶアイコンで、JSON 鍵をアップロードします。この鍵の場所を .bashrc に書き込みます。 例は、 `export GOOGLE_APPLICATION_CREDENTIALS="/home/user/Downloads/service-account-file.json"` のような感じです。 user が伏せ字になっています。 また、デフォルトでは Download フォルダーなるものは有りません。.bashrc を読み込ませ直すのに、ターミナルの再起動などをして下さい。
さて、いよいよ julia さんから PyCall 経由で使ってみます。
下準備から
_
_ _ _(_)_ | Documentation: https://docs.julialang.org
(_) | (_) (_) |
_ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help.
| | | | | | |/ _` | |
| | |_| | | | (_| | | Version 1.5.1 (2020-08-25)
_/ |\__'_|_|_|\__'_| | Official https://julialang.org/ release
|__/ |
julia> using PyCall
julia> argparse = pyimport("argparse");
julia> language = pyimport("google.cloud.language");
julia> enums = language.enums;
julia> types = language.types;
julia> client = language.LanguageServiceClient();
次に、content に感情分析をさせたい文字列を入れて、形式情報を付加した document にして、感情分析器に投入です。
julia> content = "Google Cloud の cloud shell で julia が動くなんて、めちゃくちゃ嬉しい。"
"Google Cloud の cloud shell で julia が動くなんて、めちゃくちゃ嬉しい。"
julia> document = types.Document(
content=content,
language = "ja",
type=enums.Document.Type.PLAIN_TEXT)
PyObject type: PLAIN_TEXT
content: "Google Cloud \343\201\256 cloud shell \343\201\247 julia \343\201\214\345\213\225\343\201\217\343\201\252\343\202\223\343\201\246\343\200\201\343\20
2\201\343\201\241\343\202\203\343\201\217\343\201\241\343\202\203\345\254\211\343\201\227\343\201\204\343\200\202"
language: "ja"
julia> result = client.analyze_sentiment(document=document)
PyObject document_sentiment {
magnitude: 0.8999999761581421
score: 0.8999999761581421
}
language: "ja"
sentences {
text {
magnitude: 0.90, score: 0.90 と、とても強めにポジティブな判定になりました。
もちろん。result の中に、文章全体と、それぞれの文の分析結果も含まれています。 尤も1文構成ですから、結果は同じです。
julia> result.document_sentiment.magnitude
0.8999999761581421
julia> result.document_sentiment.score
0.8999999761581421
# つぎは文の方です。
julia> result.sentences[1].text.content
"Google Cloud の cloud shell で julia が動くなんて、めちゃくちゃ嬉しい。"
julia> result.sentences[1].sentiment.magnitude
0.8999999761581421
julia> result.sentences[1].sentiment.score
0.8999999761581421
では、10個作文をしてみましたので、これを分析して頂きましょう。下準備として、documentの形式にする関数と、分析して magunitude と score を取り出す関数を作っておきます。
julia> arrayText = [
"Google Cloud の cloud shell で julia が動くなんて、めちゃくちゃ嬉しい。",
"作文するなんて、そう簡単にできる作業な訳ではない。",
"作文は、頭の柔らかい小学生でも難しい。",
"今日は暑くて死にそうだった。",
"日記帳みたいになってきたが、例文を一生懸命書いているだけなのである。",
"いったいこのブログに、どの程度の価値があるのだろうか? 皆目検討も付かない。いや、意味など無く、単なる環境負荷でしか無いのではないだろうか?",
"もう、そろそろ、良いかずの文章が出きてきた。",
"昨日のテレビ番組は、面白すぎて、腹が痛くなった。",
"これで、終わり。バンザイ。",
"おじいさんが竹の中を覗き込むと、光かがやく赤ん坊がいた。この世のものとは思えぬ、誠に美しい女の子であった。"
];
julia> function makeDoc(content::String)
document = types.Document(
content=content,
language = "ja",
type=enums.Document.Type.PLAIN_TEXT)
return document
end
makeDoc (generic function with 1 method)
julia> function sentimentAnalysis(content::String)
document = makeDoc(content)
result = client.analyze_sentiment(document=document)
return result.document_sentiment.magnitude, result.document_sentiment.score
end
sentimentAnalysis (generic function with 1 methods)
まずは、for ループで無難に読んで、array の1つずつ10個の magnitude と score を取り出しましょう。
julia> function arrayAnalysis(arrayText::Array{String,1})
arraySentiments = zero(rand(size(arrayText,1),2))
for i in 1:size(arrayText,1)
arraySentiments[i,:] .= collect(sentimentAnalysis(arrayText[i]))
end
return arraySentiments
end
arrayAnalysis (generic function with 1 method)
julia> @time foo = arrayAnalysis(arrayText)
1.476476 seconds (1.07 k allocations: 51.562 KiB)
10×2 Array{Float64,2}:
0.9 0.9
0.2 -0.2
0.3 -0.3
0.1 -0.1
0.1 -0.1
0.9 0.0
0.4 -0.4
0.3 -0.3
0.6 0.0
1.0 0.3
julia> foo[1,1]
0.8999999761581421
表示は四捨五入してありますが、ちゃんと Float64 になっているので心配は無用です。「腹が痛い。」 が negative に評価されていたりしますね。 最も negative なのは、"もう、そろそろ、良いかずの文章が出きてきた。" でした。
では、ブロードキャストしてみましょう。
julia> @time foo2 = sentimentAnalysis.(arrayText)
1.595585 seconds (1.03 k allocations: 49.281 KiB)
10-element Array{Tuple{Float64,Float64},1}:
(0.8999999761581421, 0.8999999761581421)
(0.20000000298023224, -0.20000000298023224)
(0.30000001192092896, -0.30000001192092896)
(0.10000000149011612, -0.10000000149011612)
(0.10000000149011612, -0.10000000149011612)
(0.8999999761581421, 0.0)
(0.4000000059604645, -0.4000000059604645)
(0.30000001192092896, -0.30000001192092896)
(0.6000000238418579, 0.0)
(1.0, 0.30000001192092896)
帰りが tuple ですが、ブロードキャストしてくれるようです。律速が Cloud Natural Language API なのでしょうが、この環境では for ループの方が早いかもしれません。コア数やメモリーなど違うのでしょうか?
というわけで動いたので良しとして下さい。