$30 off During Our Annual Pro Sale. View Details »

Synapse AnalyticsからCognitive Servicesの感情分析を使ってみた(2022/09)

鍋島千夏
September 15, 2022

Synapse AnalyticsからCognitive Servicesの感情分析を使ってみた(2022/09)

約7千のニュース記事を使って、Synapse AnalyticsのSparkからCognitive Serviceの感情分析機能を使ってみる。
そのうえで、Cognitive Serviceの転送率の制限を超えてAPIが要求されるケースがあるのかを確認する。
感情分析の結果を見て、ポジティブな記事とポジティブな記事を見てみる。

鍋島千夏

September 15, 2022
Tweet

More Decks by 鍋島千夏

Other Decks in Technology

Transcript

  1. Synapse Analyticsから Cognitive Servicesの感情分析を 使ってみた 2022/09/16 エーティーエルシステムズ 鍋島千夏

  2. • Azure Cognitive Service for Language のサービスの制限 > 転送率の制限 https://docs.microsoft.com/ja-jp/azure/cognitive-services/language-service/concepts/data-limits

    調査の背景:Cognitive Serviceの転送率の制限
  3. やってみたこと • 約7千のニュース記事を使って、Synapse AnalyticsのSparkからCognitive Serviceの感情分析機能を使ってみ る。 • そのうえで、Cognitive Serviceの転送率の制限を超えてAPIが要求されるケースがあるのかを確認する。 •

    感情分析の結果を確認して、ポジティブな記事とネガティブな記事を見てみる。 • 前提条件 • 用意するAzureリソース • Synapse Analytics • Spark pool (サイズ: Small (4 仮想コア/32 GB) - 3 - 10 個のノード ) • Cognitive Service for Language (Freeレベル,Sレベル) • KeyVault • Storage Acount(ADLS gen2) 参照:チュートリアル:Cognitive Services を使用した感情分析 https://docs.microsoft.com/ja-jp/azure/synapse-analytics/machine-learning/tutorial-cognitive-services-sentiment
  4. 使ってみてわかったこと • 約7千件の文書の感情解析にかかる時間 (sparkpoolはsmallを使用) Freeレベルで約7分、Sレベルで約4分 • Cognitive Service for Languageの1分あたりの要求数

    Freeレベルで100~120件/分、Sレベル120~160で件/分だった。 • Cognitive Service for Languageの転送率の制限を超えたペースでAPIに要求を送 ることがあるか? • Freeレベルでは、制限を超えたペースで要求してしまい、応答がエラーとなることがあった。 • S レベル では、制限の範囲内で実行され、エラーは起きなかった。
  5. 感情分析を使ってみた環境と処理の流れ 新聞記事コーパス (csv) Azure Storage Account (ADLS gen2) Azure Synapse

    Analytics (Spark) Azure Synapse Analytics (レイクデータベース) Cognitive Service (Text Analytics) データソース 感情分析 加工・分析 蓄積 データフロー図 1. CSV形式の新聞記事コーパスを作成 2. ストレージアカウントにCVSをアップ 3. Sparkで加工して感情分析をする 1. CSVをレイクデータベースに保存。 2. 感情分析機能を呼び出して、結果をレイ クデータベースに保存 3. 感情分析の結果を見やすいように加工 してレイクデータベースに保存 4. 感情分析の結果を確認して、エラー行 のみレイクデータベースに保存
  6. 感情分析を使ってみた環境と処理の流れ 新聞記事コーパス (csv) Azure Storage Account (ADLS gen2) Azure Synapse

    Analytics (Spark) Azure Synapse Analytics (レイクデータベース) Cognitive Service (Text Analytics) データソース 感情分析 加工・分析 蓄積 データフロー図 1. CSV形式の新聞記事コーパスを作る 2. ストレージアカウントにCVSをアップ 3. Sparkで加工して感情分析をする 1. CSVをレイクデータベースに保存。 2. 感情分析機能を呼び出して、結果をレイ クデータベースに保存 3. 感情分析の結果をクエリしやすいように フラット化してレイクデータベースに保存 4. 感情分析の結果を確認して、エラー行のみレ イクデータベースに保存
  7. 1. CSV形式の新聞記事コーパスを作る • 「livedoorニュースコーパス」を利用しました。 • 詳細は以下のリンク先をご確認ください。 • 参照 • [1]

    livedoorニュースコーパスをcsvファイル形式で取得する https://nxdataka.netlify.app/ldncsv/ • [2] livedoor ニュースコーパス https://www.rondhuit.com/download.html#ldcc
  8. 1. CSV形式の新聞記事コーパスを作る livedoorニュースコーパスの内容 • 9ジャンルのニュース 7367記事 • CSVの形式は「記事URL」「記事の日付」「タイトル」「本文」「メディア」 対象記事 •

    トピックニュース http://news.livedoor.com/category/vender/news/ • Sports Watch http://news.livedoor.com/category/vender/208/ • ITライフハック http://news.livedoor.com/category/vender/223/ • 家電チャンネル http://news.livedoor.com/category/vender/kadench/ • MOVIE ENTER http://news.livedoor.com/category/vender/movie_enter/ • 独女通信 http://news.livedoor.com/category/vender/90/ • エスマックスhttp://news.livedoor.com/category/vender/smax/ • livedoor HOMME http://news.livedoor.com/category/vender/homme/ • Peachy http://news.livedoor.com/category/vender/ldgirls/
  9. 感情分析を使ってみた環境と処理の流れ 新聞記事コーパス (csv) Azure Storage Account (ADLS gen2) Azure Synapse

    Analytics (Spark) Azure Synapse Analytics (レイクデータベース) Cognitive Service (Text Analytics) データソース 感情分析 加工・分析 蓄積 データフロー図 1. CSV形式の新聞記事コーパスを作る 2. ストレージアカウントにCVSをアップ 3. Sparkで加工して感情分析をする 1. CSVをレイクデータベースに保存。 2. 感情分析機能を呼び出して、結果をレイ クデータベースに保存 3. 感情分析の結果をクエリしやすいように フラット化してレイクデータベースに保存 4. 感情分析の結果を確認して、エラー行 のみレイクデータベースに保存
  10. • CSVができたら、用意したストレージにアップロード 2.ストレージアカウントにCVSをアップ

  11. 処理の流れ 新聞記事コーパス (csv) Azure Storage Account (ADLS gen2) Azure Synapse

    Analytics (Spark) Azure Synapse Analytics (レイクデータベース) Cognitive Service (Text Analytics) データソース 感情分析 加工・分析 蓄積 データフロー図 1. CSV形式の新聞記事コーパスを作る 2. ストレージアカウントにCVSをアップ 3. Sparkで加工して感情分析をする 1. CSVをレイクデータベースに保存。 2. 感情分析機能を呼び出して、結果をレイ クデータベースに保存 3. 感情分析の結果をクエリしやすいように フラット化してレイクデータベースに保存 4. 感情分析の結果を確認して、エラー行のみレ イクデータベースに保存
  12. 2-1. CSVをレイクデータベースに保存 • SparkにCSVを読み込む livedoorニュースコーパスの読み取り時のちょっとした、コツ。 今回取り扱うCSVは本文中で ”(ダブルクォート) がエスケープされていたり、改行が含まれているので、オプション必須。

  13. 3-1. CSVをレイクデータベースに保存 • 中身を確認します。

  14. 3-1. CSVをレイクデータベースに保存

  15. 感情分析を使ってみた環境と処理の流れ 新聞記事コーパス (csv) Azure Storage Account (ADLS gen2) Azure Synapse

    Analytics (Spark) Azure Synapse Analytics (レイクデータベース) Cognitive Service (Text Analytics) データソース 感情分析 加工・分析 蓄積 データフロー図 1. CSV形式の新聞記事コーパスを作る 2. ストレージアカウントにCVSをアップ 3. Sparkで加工して感情分析をする 1. CSVをレイクデータベースに保存。 2. 感情分析機能を呼び出して、結果をレイ クデータベースに保存 3. 感情分析の結果をクエリしやすいように フラット化してレイクデータベースに保存 4. 感情分析の結果を確認して、エラー行のみレ イクデータベースに保存
  16. 3-2. 感情分析機能を呼び出して、結果をレイクデータベースに保存 • レイク データベースから感情分析のノートブックを生成する

  17. 3-2. 感情分析機能を呼び出して、結果をレイクデータベースに保存 • レイク データベースから感情分析のノートブックを生成する

  18. 3-2. 感情分析機能を呼び出して、結果をレイクデータベースに保存 • レイク データベースから感情分析のPythonコードを生成する

  19. 3-2. 感情分析機能を呼び出して、結果をレイクデータベースに保存 新しいノートブックが開いて、 感情分析を呼び出すコードが 追加されます。 ※コードは8月6日時点では正常に動 作していました。

  20. 3-2. 感情分析機能を呼び出して、結果をレイクデータベースに保存 /home/trusted-service-user/cluster- env/env/lib/python3.8/site-packages/mmlspark/__init__.py:4: UserWarning: The mmlspark namespace has been

    deprecated. Please change import statements to import from synapse.ml warnings.warn( ------------------------------------------------------------- -------------- AttributeError Traceback (most recent call last) <ipython-input-2-1eab35a6> in <module> 6 df = spark.sql("SELECT * FROM default.livedoornewstable") 7 ----> 8 sentiment = (TextSentiment() 9 .setLinkedService("CognitiveService1") 10 .setOutputCol("output") AttributeError: 'TextSentiment' object has no attribute 'setLinkedService' 自動生成されたコードは 9月11日時点動作しません。
  21. 3-2. 感情分析機能を呼び出して、結果をレイクデータベースに保存 • Synapse.ML ライブラリを使うよう書き換え from synapse.ml.cognitive import * #

    Load the data into a Spark DataFrame df = spark.sql("SELECT * FROM default.livedoornews01_source") sentiment_df = (TextSentiment() .setTextCol("body") .setLocation("japaneast") .setSubscriptionKey(“XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX") .setOutputCol("sentiment") .setErrorCol("error") .setLanguage("ja") .transform(df)) display(sentiment_df.limit(10)) #とりあえず感情分析の結果をすぐ保存する sentiment_df.write.mode('overwrite').saveAsTable("livedoornews02_sentiment") from mmlspark.cognitive import * from notebookutils import mssparkutils from pyspark.sql.functions import explode # Load the data into a Spark DataFrame df = spark.sql("SELECT * FROM default.livedoornews01_source") sentiment = (TextSentiment() .setLinkedService("CognitiveService1") .setOutputCol("output") .setErrorCol("error") .setLanguage("ja") .setTextCol("body")) results = sentiment.transform(df) # Show the results display(results¥ .select("body", explode("output").alias("exploded"), "error")¥ .select("body", "exploded.*", "error")¥ .limit(10)) 変更前 変更後 参照:Synapse ML https://microsoft.github.io/SynapseML/
  22. 3-2. 感情分析機能を呼び出して、結果をレイクデータベースに保存 • 感情分析を実行して、結果をレイクデータベースに保存 7367記事を感情分析して、レイクテーブルに保存する時間 • Free レベル :7分30分 •

    S レベル :4分37秒 Free レベル S レベル
  23. 3-2. 感情分析機能を呼び出して、結果をレイクデータベースに保存 • 結果を確認(詳細は後ほど)

  24. 感情分析を使ってみた環境と処理の流れ 新聞記事コーパス (csv) Azure Storage Account (ADLS gen2) Azure Synapse

    Analytics (Spark) Azure Synapse Analytics (レイクデータベース) Cognitive Service (Text Analytics) データソース 感情分析 加工・分析 蓄積 データフロー図 1. CSV形式の新聞記事コーパスを作る 2. ストレージアカウントにCVSをアップ 3. Sparkで加工して感情分析をする 1. CSVをレイクデータベースに保存。 2. 感情分析機能を呼び出して、結果をレイ クデータベースに保存 3. 感情分析の結果をクエリしやすいように フラット化してレイクデータベースに保存 4. 感情分析の結果を確認して、エラー行のみレ イクデータベースに保存
  25. 3-3. 感情分析の結果をクエリしやすいようにフラット化してレイク データベースに保存 • 記事のスコアと記事内の文ごとにスコアが返ってくる ⇒ Azure Synapse Studio で見てみましょう。

  26. 補足:感情分析は「文書そのもの」と「文ごと」のスコアが返されるされる。 参照: Docs Cognitive Services - Text Analytics センチメント >

    Sentiment - Sentiment https://docs.microsoft.com/ja-jp/rest/api/cognitiveservices-textanalytics/3.0/sentiment/sentiment?tabs=HTTP#successful-sentiment-request 文書のスコア 文のスコア
  27. 補足:記事の例 もうすぐジューン・ブライドと呼ばれる6月。独女の中には自分の式はまだなのに呼ばれてばかり……という「お祝い貧乏」状態の人も多いのではないだろうか? さらに出席回数を重ねていくと、 こんなお願いごとをされることも少なくない。 「お願いがあるんだけど……友人代表のスピーチ、やってくれないかな?」 さてそんなとき、独女はどう対応したらいいか? 最近だとインターネット等で検索すれば友人代表スピーチ用の例文サイトがたくさん出てくるので、それらを参考にすれば、無難なものは誰でも作成できる。しかし由利さん(33歳)はネットを 参考にして作成したものの「これで本当にいいのか不安でした。一人暮らしなので聞かせて感想をいってくれる人もいないし、かといって他の友人にわざわざ聞かせるのもどうかと思うし……」 ということで活用したのが、なんとインターネットの悩み相談サイトに。そこに作成したスピーチ文を掲載し「これで大丈夫か添削してください」とメッセージを送ったというのである。 「一晩で3人位の人が添削してくれましたよ。ちなみに自分以外にもそういう人はたくさんいて、その相談サイトには同じように添削をお願いする投稿がいっぱいありました」(由利さん)。ためし

    に教えてもらったそのサイトをみてみると、確かに「結婚式のスピーチの添削お願いします」という投稿が1000件を超えるくらいあった。めでたい結婚式の影でこんなネットコミュニティがあった とは知らなかった。 しかし「事前にお願いされるスピーチなら準備ができるしまだいいですよ。一番嫌なのは何といってもサプライズスピーチ!」と語るのは昨年だけで10万以上お祝いにかかったというお祝い貧 乏独女の薫さん(35歳) 「私は基本的に人前で話すのが苦手なんですよ。だからいきなり指名されるとしどろもどろになって何もいえなくなる。そうすると自己嫌悪に陥って終わった後でもまったく楽しめなくなります ね」 サプライズスピーチのメリットとしては、準備していない状態なので、フランクな本音をしゃべってもらえるという楽しさがあるようだ。しかしそれも上手に対応できる人ならいいが、苦手な人の場 合だと「フランク」ではなく「しどろもどろ」になる危険性大。ちなみにプロの司会者の場合、本当のサプライズではなく式の最中に「のちほどサプライズスピーチとしてご指名させていただきま す」という一言があることも多いようだが、薫さん曰く「そんな何分前に言われても無理!」らしい。要は「サプライズを楽しめる」というタイプの人選が大切ということか。 一方「ありきたりじゃつまらないし、ネットで例文を検索している際に『こんな方法もあるのか!』って思って取り入れました」という幸恵さん(30歳)が行ったスピーチは「手紙形式のスピーチ」 というもの。 「◦◦ちゃんへ みたいな感じで新婦の友人にお手紙を書いて読み上げるやり方です。これなら多少フランクな書き方でも大丈夫だし、何より暗記しないで堂々と読み上げることができますよ ね。読んだものはそのまま友人にあげれば一応記念にもなります」(幸恵さん) なるほど、確かにこれなら読みあげればいいだけなので、人前で話すのが苦手な人でも失敗しないかもしれない。 主役はあくまで新郎新婦ながらも、いざとなると緊張し、内容もあれこれ考えて、こっそりリハーサル……そんな人知れず頑張るスピーチ担当独女たちにも幸あれ(高山惠)
  28. 3-3. 感情分析の結果をフラット化してレイクデータベースに保存 • どのような記事がどのように判定されているか確認したい • どのような文(単語)がポジティブ/中立/ネガティブとされているか 見たい 感情分析の結果をフラットにしてクエリしやすくしよう

  29. 3-3. 感情分析の結果をクエリしやすいようにフラット化してレイク データベースに保存 • 感情分析の結果をテーブル形式にフラット化する。

  30. 3-3. 感情分析の結果をクエリしやすいようにフラット化してレイク データベースに保存 #explode関数はJSON中の配列を行に変換してくれる sentiment_flat_df=sentiment_df.select("url" ,"datetime" ,"title" ,"body" ,col("sentiment").alias("article_sentiment") ,col("sentiment.document.id").alias("articleId")

    ,col("sentiment.document.confidenceScores.positive").alias("article_positive") ,col("sentiment.document.confidenceScores.neutral").alias("article_neutral") ,col("sentiment.document.confidenceScores.negative").alias("article_negative") ,explode("sentiment.document.sentences").alias("exploded"),"error")¥ .select("url","datetime","title","body", "article_sentiment" ,"articleId","article_positive","article_neutral","article_negative“ ,"exploded.*", "error")¥ .select( "url" ,"datetime" ,"title" ,"body" ,"article_sentiment" ,"articleId" ,"article_positive" ,"article_neutral" ,"article_negative" ,"text" ,col("confidenceScores.positive").alias("text_positive") ,col("confidenceScores.neutral").alias("text_neutral") ,col("confidenceScores.negative").alias("text_negative") ,"targets" ,"assessments" ,"offset" ,"length" ,"error") display(sentiment_flat_df.limit(30)) sentiment_flat_df.write.mode('overwrite').saveAsTable("livedoornews03_sentimentflatten")
  31. 3-3. 感情分析の結果をクエリしやすいようにフラット化してレイク データベースに保存

  32. 7367記事で最もポジティブな記事は? 記事URL http://news.livedoor.com/article/detail/5813401/

  33. 7367記事で最もポジティブな記事は? ニュートラルな記事に見える・・・ 関連記事の「うまい」に反応してしまったようだ。

  34. 7367記事で最もネガティブな記事は? http://news.livedoor.com/article/detail/4891140/

  35. 7367記事で最もネガティブな記事は? これは、ネガティブな記事だ!

  36. ポジティブな文

  37. ニュートラルな文

  38. ネガティブな文

  39. 感情分析を使ってみた環境と処理の流れ 新聞記事コーパス (csv) Azure Storage Account (ADLS gen2) Azure Synapse

    Analytics (Spark) Azure Synapse Analytics (レイクデータベース) Cognitive Service (Text Analytics) データソース 感情分析 加工・分析 蓄積 データフロー図 1. CSV形式の新聞記事コーパスを作る 2. ストレージアカウントにCVSをアップ 3. Sparkで加工して感情分析をする 1. CSVをレイクデータベースに保存。 2. 感情分析機能を呼び出して、結果をレイ クデータベースに保存 3. 感情分析の結果をクエリしやすいように フラット化してレイクデータベースに保存 4. 感情分析の結果を確認して、エラー行のみレ イクデータベースに保存
  40. 3-3. 感情分析の結果をフラット化してレイクデータベースに保存 どのようなエラーが記録されているか確認したい。 [エラーコード][エラーメッセージ]毎に件数を数えてみよう。

  41. 4.感情分析の結果を確認して、エラー行のみレイクデータベースに保存

  42. 4.感情分析の結果を確認して、エラー行のみレイクデータベースに保存 from pyspark.sql.types import StructType, StructField, StringType, MapType from pyspark.sql.functions

    import schema_of_json,lit jsonSchema = StructType([ StructField('error', StructType([ StructField('code', StringType(), True), StructField('message', StringType(), True) ])) ]) error_parsed_df = error_df.select("url","datetime","title","body","media"¥ ,col("error.response").alias("response") ,col("error.status.statusCode").alias("statusCode") ,col("error.status.reasonPhrase").alias("reasonPhrase") ,from_json(col("error.response"),jsonSchema).alias("responseParsed"))¥ .select("url","datetime","title","body","media","statusCode","reasonPhrase"¥ ,col("responseParsed.error.code").alias("errorCode") ,col("responseParsed.error.message").alias("message")) display(error_parsed_df) error_parsed_df.write.mode('overwrite').saveAsTable("livedoornews04_error")
  43. 4.感情分析の結果を確認して、エラー行のみレイクデータベースに保存 F0の制限値を超えたからn秒後にアクセスしてね(ステータスコード429) F0のクウォータ(1カ月5000件)を超えたからn日後にアクセスしてね(ステータスコード 403) • エラーの内容

  44. Cognitive Service for Languageのメトリック FreeレベルとSレベルの比較

  45. Total Callは848回 ② 感情分析の解析結果データフレーム全件を レイク データベースに格納 → 1分当たり約100~120件のペースで APIが呼ばれ続ける・・・ Free

    レベル
  46. Total Callは848回 Sレベル

  47. Cognitive Service for Languageのメトリック(実績値) メトリックの種類 F0 プラン S プラン Total

    Call(合計) 848回 848回 Blocked Call(合計) 119回 0回 Data In(合計) 27.7MB 24.9回 Data Out(合計) 46.8MB 47.2回 Latency(平均) 749.15ミリ秒 348.31ミリ秒 Successful Call(合計) 729回 738回 Total Errors(合計) 119件 0件 Processed Text Records 11.97K 件 12.07K 件
  48. 補足:感情分析は1度に10文書要求できる。 Docs Cognitive Services - Text Analytics センチメント > Successful

    Sentiment request https://docs.microsoft.com/ja-jp/rest/api/cognitiveservices-textanalytics/3.0/sentiment/sentiment?tabs=HTTP#successful-sentiment-request 1回のリクエストにつき10文書
  49. 補足:Freeプランの制限を越えても課金されない。 参照:Cognitive Service for Language の価格> よく寄せられる質問https://azure.microsoft.com/ja- jp/pricing/details/cognitive-services/language-service/#faq

  50. 補足:1つ文書の文字数は最大5,120文字

  51. 使ってみてわかったこと • 約7千件の文書の感情解析にかかる時間 (sparkpoolはsmallを使用) Freeレベルで約7分、Sレベルで約4分 • Cognitive Service for Languageの1分あたりの要求数

    Freeレベルで100~120件/分、Sレベル120~160で件/分だった。 • Cognitive Service for Languageの転送率の制限を超えたペースでAPIに要求を送ることがあるか? • Freeレベルでは、制限を超えたペースで要求してしまい、応答がエラーとなることがあった。 • S レベル では、制限の範囲内で実行され、エラーは起きなかった。 • レイクデータベースから感情分析を実行するノートブックを自動生成する機能があるが、非推奨となったライブラリが使わ れていてエラーとなった。Synapse.mlを使うよう書き換えが必要 • 感情分析では「文書」そのものと「文書内に含まれる文」に個別に、ポジティブ、中立、ネガティブのスコアが計算される • 文書の判定は怪しいが、文の判定はそこそこ信頼できそう。(個人の感想です。)
  52. 付録 • 以下、今回の検証で記録したCognitive Serviceのメトリックです。

  53. Total Callは848回 Free レベル

  54. Blocked Call回数は119回 Free レベル

  55. Data Inは27.7MB Free レベル

  56. Data Outは46.8MB Free レベル

  57. Latencyは平均279.15ミリ秒 Free レベル

  58. Successful Callは729回 Free レベル

  59. Total Errorsは119回 Free レベル

  60. Processed Text Recordsは11.97k Free レベル

  61. Total Callは848回 Sレベル

  62. Blocked Callは0回 Sレベル

  63. Data Inは24.9MB Sレベル

  64. Data Outは47.2MB Sレベル

  65. Latency(平均)は348.31ミリ秒 Sレベル

  66. Successful Call(合計)は738 Sレベル

  67. Total Errorsは0 Sレベル

  68. Processed Text Recordsは12.07k Sレベル