AIが商品を厳選!!WatsonのToneAnalyzerで口コミを評価してみた
WatsonのToneAnalyzerで口コミを評価してみたよ
やり方を詳しく紹介しますー💛
1.何故AIで口コミ評価をしたか?
AIで口コミ評価をしようとした理由
結論から先に申すと、多数の候補から本当に良い商品を見つけたかったので、AIで口コミ評価が出来るかを試してみました。
商品の良し悪しを買う前に確認する方法
- 商品比較サイトで最初に見るポイントは値段・機能/特徴・星の数では無いでしょうか?
- 大体同じ値段で機能も似ていたらどれが良いか判断に迷うので、他の人がどう評価しているかを確認するために星の数を確認しませんか?
- 商品を買った人から意見を聞くのは商品を選ぶ有効な方法だと思います。
- 星の数では無く口コミを見た方がより詳細な意見を聞くことが出来ますが、一つ一つの口コミを見ていくのは時間がかかります。
- 短時間でその商品を他の人がどう思っているかを確認するのに星の数を見ることは有効な手段です。
星の数で評価する方法の弱点
- 星の数は過去にその商品を買った人が付けているので、ある程度信憑性があります。
- しかし、過去にその商品を買った人は適切に星を付けるでしょうか?
- 星は自発的につける場合もありますが、その商品を買った時にアンケートを聞かれて受動的に付ける場合もあります。
- そういった場合、相当な不満が無ければ星3とか4という無難な星を付けませんか?
- そう、星を付けている人はあまり真剣にその商品を評価していない場合もあります。
- そういう意味で、星の数は本当に妥当な評価では無い可能性もあります。
星よりも正しく商品を評価する方法
- では星よりも正確に商品の評価を知るにはどうすれば良いでしょうか?
- 答えてとしては口コミを見る方が星の数を見るよりも、商品の評価を知ることが出来ます。
- 口コミを書くということは星を付けることより全然手間のかかる作業です。
- そういった手間なことをしているということは、口コミを書く人は星を付けるよりも真剣に商品の良さ(もしくは悪さ)を他の人に知って欲しいと考えているということでしょう。
- ですので口コミを見るのが商品の評価を知るには星の数を見るより有効と言えます。
口コミを読むのは大変
- 口コミは場合によっては1,000件を超える口コミがある場合もあります。
- それを一つ一つ読んでいたら大変です。
- 大変な作業は機械に任せられるなら任せた方が楽です。
- 最近のAIは優秀で文章の内容がポジティブな文章かネガティブな文章かを判断することが出来ます。
- なので、このAIの文章判定機能を用いて手間のかかる口コミの分析が出来るかを試してみることにしました。
- 補足ですが、口コミも星と同じで適当な回答をしている場合がありますが、そういうものはAIが無視する様に出来るのも口コミを評価することのメリットです
(星の数は適当につけたものか判断できないが、口コミはある程度判断が出来る。)
2.AI(Tone Analyzer)で口コミを評価する方法
IBM WatsonのTone Analyzerとは
IBM WatsonのTone Analyzerは、言語分析を使用して、記述されたテキストから感情トーンと言語トーンを検出するAIサービスです。
このサービスは、ドキュメント(文章全体)とセンテンス(文節)の両方のレベルでトーンを分析できます。
Tone Analyzerを使う準備
IBMクラウドのログインページよりIBMクラウドにログインします。
https://cloud.ibm.com/login
※ アカウントの無い方は新規アカウントを作成して下さい。アカウントは無料で作成できます。
IBM Watsonのサービス選択ページよりTone Analyzerを選択します。
https://cloud.ibm.com/developer/watson/services
Tone Analyzerのライト・プランを選択し作成ボタンを押します。
※ ライト・プランはAPIを1ヶ月2,500件まで無料で利用できます。
※ 上記ハードコピーはライト・プラン登録後に取得したため警告が出ていますが、初回は警告は出ません。
Tone Analyzerのライト・プランサービスのAPIキーとAPI URLを確認します
※ APIキーとAPI URLはAPIを使うのに必要なのでメモして下さい。
※ APIキーはあなたのAPI利用プランを使うための認証情報なので他人には公開しないでください。
Tone AnalyzerをPythonで使う準備
# pipコマンドでIBM WatsonのPythonライブラリをインストールする
pip install ibm_watson
Tone Analyzerの使い方(Pythonの実装例)
from ibm_watson import ToneAnalyzerV3
import json
# Tone Analyzerのインスタンス生成
tone_analyzer = ToneAnalyzerV3(
version = '2019-09-01', # APIバージョン(2019-09-01時点で最新のVERを設定)
iam_apikey = APIKEY_TA, # APIキー
url = APIURL_TA # API URL
)
# Tone Analyzerの実行
tone_analysis = tone_analyzer.tone(
{'text': '分析対象のテキストXXXXXXXXXXXXXXXXXXXXXXXXXX'},
content_type='application/json'
).get_result()
# 実行結果の表示
print(json.dumps(tone_analysis, indent=2))
Tone Analyzerの実行結果サンプル
# 解析テキスト
I used it for my last shopping and shower as my home flight was late at night. The hotel is not available for about six hours, but it was very comfortable in Pratnam's shopping, consolidation, and shower because it was close to the "Ratchaparok" station on the Airport Link. However, the 502 air-conditioner was bad, and 504 wasn't refrigerated. Well, it was a sum of money, and I did not stay in the room, so I laughed.
# 実行結果
{
"document_tone": {
"tones": [
{
"score": 0.564087,
"tone_id": "analytical",
"tone_name": "Analytical"
}
]
},
"sentences_tone": [
{
"sentence_id": 0,
"text": "I used it for my last shopping and shower as my home flight was late at night.",
"tones": []
},
{
"sentence_id": 1,
"text": "The hotel is not available for about six hours, but it was very comfortable in Pratnam's shopping, consolidation, and shower because it was close to the \"Ratchaparok\" station on the Airport Link.",
"tones": [
{
"score": 0.528951,
"tone_id": "joy",
"tone_name": "Joy"
},
{
"score": 0.506763,
"tone_id": "analytical",
"tone_name": "Analytical"
}
]
},
{
"sentence_id": 2,
"text": "However, the 502 air-conditioner was bad, and 504 wasn't refrigerated.",
"tones": [
{
"score": 0.687768,
"tone_id": "analytical",
"tone_name": "Analytical"
}
]
},
{
"sentence_id": 3,
"text": "Well, it was a sum of money, and I did not stay in the room, so I laughed.",
"tones": [
{
"score": 0.697738,
"tone_id": "joy",
"tone_name": "Joy"
}
]
}
]
}
実行結果の説明
document_tone オブジェクト
文章全体のトーン(感情)の解析結果。一つのtonesオブジェクトを持つ。
tonesオブジェクトのtone_idが文章全体のトーンの解析結果で以下の何れかのトーン(感情)が設定される。
- anger:怒り
- fear:恐れ
- joy:喜び
- sadness: 悲しみ
- analytical:分析的
- confident:自信
- tentative:暫定
sentences_toneオブジェクト
文節ごとのトーン(感情)の解析結果。文節のリスト配列で構成され各要素がtonesオブジェクトを持つ。 tonesオブジェクトの要素はdocument_tone と同様。
Tone Analyzerリファレンス
3.Tone Analyzerは日本語対応していない
Tone Analyzerは日本語対応していない
2019年9月現在はTone Analyzerは残念ながら日本語に対応していません。Tone Analyzerの類似のサービスでテキストから性格分析を行うPersonality Insightsは日本語に対応しているので、しばらくすればTone Analyzerも日本語対応されると思いますが、現時点でTone Analyzerは日本語に非対応です。
Tone Analyzerで日本語のテキストを解析する方法
Tone Analyzerが日本語に対応していない以上、日本語をTone Analyzerで解析可能な言語(英語)に変換してからTone Analyzerを使う必要があります。 幸いなことに翻訳も今の時代はAIで簡単に出来ます。Google CloudでもIBM Watsonを使って日本語を英語に翻訳しましょう。個人的な感覚では翻訳はGoogle に軍配が上がる気がしますが、今回はIBM Watsonでコードを統一したかったので、IBM WatsonのLanguage Translatorを使って翻訳をしました。
IBM WatsonのLanguage Translatorの使い方
from ibm_watson import LanguageTranslatorV3
import json
# Language Translatorのインスタンス生成
language_translator = LanguageTranslatorV3(
version = '2019-09-01', # APIバージョン(2019-09-01時点で最新のVERを設定)
iam_apikey = APIKEY_LT, # APIキー
url = APIURL_LT # API URL
)
# 翻訳の実行
translation = language_translator.translate(
text = '翻訳対象のテキストXXXXXXXXXXXXXXXXXXXXXXXXXX',
source = 'ja', # 翻訳元言語(日本語)
target = 'en' # 翻訳先言語(英語)
)
text_en = translation.result['translations'][0]['translation']
# 実行結果の表示
print(text_en)
Language Translatorリファレンス
気になるTone Analyzerの精度は?
AIで翻訳したテキストをTone Analyzerは正しく解析できるのか気になりましたが、結構正確に分析してくれました。
# 例1
# 原文(日本語)
4階の角部屋でしたが、窓が閉まらないしすぐ横に駐車場?があったせいで、部屋の中がずっと変な匂いしてました。 階ごとにwifiが飛んでますが、場所が悪 いせいか部屋の中では全く使えませんでした ですが、この値段ですし、部屋にトイレもシャワーも冷蔵庫もクーラーもあるので、文句はあまり言いません
# Language Translator翻訳(英語)
It was a corner room on the fourth floor, but the window was closed or a parking garage right next to it?I had a strange smell in my room because of the time being. I couldn't use wifi on every floor, but I couldn't use it at all in the room or in the room. But I'm not going to complain about it because there's a room in the room, a shower, a refrigerator and a cooler.
# Tone Analyzerの解析結果の抜粋
{
"sentence_id": 1,
"text": "I couldn't use wifi on every floor, but I couldn't use it at all in the room or in the room.",
"tones": [
{
"score": 0.548768,
"tone_id": "anger",
"tone_name": "Anger"
},
→ angerと判断している。
# 例2
# 原文(日本語)
帰国便が深夜発だったので、最後の買い物とシャワーの為に利用しました。 利用時間約6時間で宿泊はしていませんが、Airport Link のRatchaparok 駅の近 くなので、プラトゥナムでの買い物→整理、シャワーには快適でした。 ただ、502は、エアコンの効きが悪く、504は、冷蔵庫がなかったです。 まぁそこは金額が金額だし、宿泊しないので笑って済ませました。
# Language Translator翻訳(英語)
I used it for my last shopping and shower as my home flight was late at night. The hotel is not available for about six hours, but it was very comfortable in Pratnam's shopping, consolidation, and shower because it was close to the "Ratchaparok" station on the Airport Link. However, the 502 air-conditioner was bad, and 504 wasn't refrigerated. Well, it was a sum of money, and I did not stay in the room, so I laughed.
# Tone Analyzerの解析結果の抜粋
"text": "The hotel is not available for about six hours, but it was very comfortable in Pratnam's shopping, consolidation, and shower because it was close to the \"Ratchaparok\" station on the Airport Link.",
"tones": [
{
"score": 0.528951,
"tone_id": "joy",
"tone_name": "Joy"
},
→ joyと判断している。
4.【実装例】AIでタイの5つ星ホテルをランキングしてみた
AIでタイの5つ星ホテルをランキングしてみた
私はもう一つのブログで旅行の記事を書いていて、ホテルの紹介記事でも書いてみようかなと思ったので、Language TranslatorとTone Analyzerを使ってタイの5つ星ホテルのランキングをしてみました。
travel5.hateblo.jp
実装ソース
# coding: UTF-8
import urllib3
from bs4 import BeautifulSoup
import certifi
import json
from ibm_watson import LanguageTranslatorV3
from ibm_watson import ToneAnalyzerV3
import sys
# 分析対象の口コミサイト(★)
TARGET_DOMAIN = "https://www.tripadvisor.jp"
TARGET_TOPPAGE = "/Hotel_Review-g293916-d1647893-Reviews-Siam_Star_Hotel-Bangkok.html"
APIKEY_LT = "xxxxxここには自分のLanguage TranslatorのAPIキーを入れるxxxxxx"
APIURL_LT = "https://gateway-tok.watsonplatform.net/language-translator/api"
APIKEY_TA = "xxxxxここには自分のTone AnalyzerのAPIキーを入れるxxxxxx"
APIURL_TA = "https://gateway-tok.watsonplatform.net/tone-analyzer/api"
API_VERSION = '2019-09-01'
result_map = {
"url" : "",
"joy" : 0,
"anger" : 0,
"sadness" : 0,
"fear" : 0,
"total" : 0
}
# 口コミ検索処理
def getEvalData(url):
if result_map['total'] > 100:
return
print(url)
# httpsの証明書検証を実行
http = urllib3.PoolManager(cert_reqs='CERT_REQUIRED', ca_certs=certifi.where())
# ページデータ取得
html = http.request('GET', url)
soap = BeautifulSoup(html.data, 'html.parser')
# 口コミ取得
for qs in soap.find_all('q'):
try:
for span in qs.find_all('span'):
text = span.text
print('===================')
print(text)
print('---')
text_en = langTranslate(text)
toneAnalyze(text_en)
break
except:
print('Error')
# ボタンリンク取得
a = soap.find('a', class_='next')
if a is not None:
url = TARGET_DOMAIN + a.attrs['href']
result_map['url'] = url
getEvalData(url)
# 日本語→英語翻訳
def langTranslate(text):
language_translator = LanguageTranslatorV3(
version = API_VERSION,
iam_apikey = APIKEY_LT,
url = APIURL_LT
)
translation = language_translator.translate(
text = text,
source = 'ja',
target = 'en')
text_en = translation.result['translations'][0]['translation']
print(text_en)
return text_en
# 口コミ分析
def toneAnalyze(text):
tone_analyzer = ToneAnalyzerV3(
version = API_VERSION,
iam_apikey = APIKEY_TA,
url = APIURL_TA
)
tone_analysis = tone_analyzer.tone(
{'text': text},
content_type='application/json'
).get_result()
# print(json.dumps(tone_analysis, indent=2))
calcScore(tone_analysis)
# スコア判定
def calcScore(resultMap):
# document_tone
if ('document_tone' in resultMap):
for tones in resultMap['document_tone']['tones']:
tone_id = tones['tone_id']
if (tone_id == 'joy' or tone_id == 'anger' or
tone_id == 'sadness' or tone_id == 'fear'):
result_map[tone_id] = result_map[tone_id] + 1
result_map['total'] = result_map['total'] + 1
print('---')
print(tone_id)
# sentences_tone
if ('sentences_tone' in resultMap):
for sentences in resultMap['sentences_tone']:
print('---')
print(sentences['text'])
for tones in sentences['tones']:
tone_id = tones['tone_id']
if (tone_id == 'joy' or tone_id == 'anger' or
tone_id == 'sadness' or tone_id == 'fear'):
result_map[tone_id] = result_map[tone_id] + 1
result_map['total'] = result_map['total'] + 1
print(tone_id)
if __name__ == '__main__':
args = sys.argv
url = TARGET_TOPPAGE
if (len(args) >= 2):
url = args[1]
getEvalData(TARGET_DOMAIN + url)
print('### reulst ###')
print(result_map)
実行結果
注) 上記のサンプルソースは1ホテルの分析にしか対応していません。以下の一覧は上記ソースの★印の箇所を都度置き換えて作成しましたものです。
ホテル名 | AIの評価 | 口コミサイトの評価 | 備考 |
---|---|---|---|
The Raweekanlaya Bangkok | 97 | 4.5 | |
アカラ ホテル | 95 | 5 | |
エバーグリーン ローレル ホテル | 93 | 4.5 | |
アル メロス ホテル | 90 | 4.5 | |
シャーマレイクビューアソーク | 90 | 4 | |
ザ バークレイ ホテル プラトゥーナム | 90 | 4 | |
センタラ グランド アット セントラル プラザ ラープラオ バンコク | 89 | 4.5 | |
アーバナ サトーン | 88 | 3.5 | |
ドリーム バンコク | 88 | 4.5 | |
アエタス ルンピニ | 88 | 4.5 | |
モンティエン リバーサイド ホテル | 87 | 4 | |
ザ グランド フォーウィングス コンベンション ホテル | 87 | 4 | |
グランド メルキュール アソーク レジデンス | 86 | 4.5 | |
ラマダ プラザ メナム リバーサイド | 85 | 4 | |
プリンス パレス ホテル | 84 | 3.5 | |
ザ イータス バンコク | 83 | 4.5 | |
アマリ アトリウム ホテル | 83 | 4 | |
ジャスミン リゾート ホテル | 81 | 4 | |
ザ イータス レジデンス | 80 | 4.5 | |
The Bazaar Hotel | - | 3 | 口コミ100件以下 |
Prince Suites Residence Managed By Prince Palace | - | 3.5 | 口コミ100件以下 |
The Park Nine Suvarnabhumi | - | 4.5 | 評価材料となる口コミが100件以下 |
試した感想
トップ1と2は確かに良いなーと思いました。たぶん口コミをきちんと評価しています。
5つ星ホテルだからどれも良いんですが・・・。
今回はjoyをポジティブ、 anger、sadness、fearをネガティブと判断したのですが、joy、 anger、fearは正しく判断している様に感じましたが、sadnessが何か違う気もします。
「疲れた時にシャワーが使えて良かった」という文をsadnessと評価していました。恐らく「疲れた」をネガティブな表現と判断したのだと思います。まだ改良は必要かもしれません。何の感情も無い文章はTone Analyzerがjoy、anger、sadness、fearの何れも返さないので評価対象とならないことは良かったです。
それではまたー💛