はじめに
SnowflakeのCortex AIを試したく、Snowflake Notebooksで顧客レビューから不満点を抽出するPythonを書いた。
1. 顧客レビュー用テーブルを作る(SQL)
CUSATOMER_REVIEWSテーブルを作る
CREATE OR REPLACE TABLE CUSTOMER_REVIEWS (
REVIEW_ID INT,
PRODUCT_NAME STRING,
REVIEW_TEXT STRING,
REVIEW_DATE DATE
);
ダミーデータを入れる
INSERT INTO CUSTOMER_REVIEWS (REVIEW_ID, PRODUCT_NAME, REVIEW_TEXT, REVIEW_DATE)
VALUES
(1, 'モダン・マグカップ',
'5年以上愛用した他社製品から買い替えました。見た目はマットな質感で非常に高級感があり、デスクに置くだけで気分が上がります。ただ、実際に使ってみると持ち手の穴が小さく、男性の指だと少し窮屈に感じます。また、熱い飲み物を入れると本体がかなり熱くなるため、うっかり触れると驚くことがあります。デザインが完璧なだけに、実用面での惜しさが目立ちます。',
'2024-03-01'),
(2, '高性能・ノートPC',
'動画編集をメインにするために購入しましたが、期待以上のスペックでした。4K動画の書き出しもサクサクで、ファンの音も驚くほど静かです。キーボードの打鍵感も心地よく、長時間のタイピングでも疲れにくいのが嬉しい誤算でした。唯一の不満は、電源アダプタが本体のスマートさに反して巨大で重いこと。持ち運びを前提としているので、ここが改善されれば100点満点です。',
'2024-03-02'),
(3, 'ワイヤレス・マウス',
'手にフィットする形状で操作性は抜群です。専用ソフトでのボタンカスタマイズも自由度が高く、事務作業の効率が劇的に上がりました。しかし、クリック音が想像以上に大きく、静かなカフェや図書館で使うにはかなり勇気がいります。また、スリープモードからの復帰時に1秒ほどラグがあるのが地味にストレスです。接続の安定性は良いだけに、この僅かな遅延が非常に惜しいと感じます。',
'2024-03-03'),
(4, 'スマート・デスク',
'リモートワーク環境を整えるために奮発して購入。電動昇降は非常にスムーズで、ミリ単位で高さを調整できるので腰痛が改善しました。ただし、組み立ての難易度が非常に高いです。付属の説明書は図解が分かりにくく、大人2人で作業しても3時間はかかりました。ネジ穴の精度が甘い箇所もあり、力任せに回す必要があったのも不安でした。製品自体は素晴らしいですが、サービス面で課題を感じます。',
'2024-03-04'),
(5, '極上・タオル',
'これまで使ってきたタオルとは次元が違います。一度洗っただけで驚くほどふわふわになり、吸水性も抜群。肌触りが優しすぎて、お風呂上がりが毎日楽しみになりました。友人へのギフトとしても絶対喜ばれると思います。文句なしの星5つです!',
'2024-03-10'),
(6, 'ノイズキャンセリング・ヘッドフォン',
'飛行機での出張が多いので購入しました。エンジン音をほぼ完全に遮断してくれる性能には感動すら覚えます。音質も低音が豊かで、映画鑑賞にも最適です。しかし、長時間装着していると耳の周りが蒸れてしまい、夏場は少し厳しいかもしれません。また、専用アプリのペアリングが不安定で、デバイスを切り替えるたびに再設定が必要になることが多々あります。ハードウェアの完成度に見合うソフトウェアの改善を強く望みます。',
'2024-03-05'),
(7, 'スマート・LEDライト',
'設置が非常に簡単で、スマホアプリとの連携もスムーズでした。時間帯に合わせて自動で色温度が変わる設定にしていますが、生活リズムが整った気がします。デザインもシンプルでどんなインテリアにも馴染みますし、今のところ欠点が見当たりません。',
'2024-03-11');
2. 顧客レビューから不満点を抽出する(Python)
Notebookのパッケージ設定で snowflake-ml を追加した上で実行。
1.で作ったテーブルの、レビュー本文(REVIEW_TEXT)からCOMPLETEで不満点を抽出し、COMPLAINTS列として出力。また、元のレビュー文章も要約して表示させるようにした。
最初はAI_COMPLETE以外にも関数使いたくてSUMMARIZEを使っていたんだけど、あまり要約になっていなかったり英語で出力されたりといった感じだったため、こちらもAI_COMPLETEを使い、プロンプト(lit関数の中の文章)にてアウトプットを細かく指定。
モデルは不満点抽出は小規模モデルのllama3.1-8b、要約は中規模のllama3.3-70bを使用。
要約は小規模モデルだと英語で"Here is the extracted data:~"という前置きが出てきたりあんまり短くなってなかったりで実用に耐えないかなという印象。
注意
モデルは従量課金制なので利用料に注意してください。
Pythonコード
import snowflake.snowpark.functions as F
from snowflake.snowpark.context import get_active_session
# 1. セッションを取得
session = get_active_session()
# 2. テーブル読み込み
df = session.table("CUSTOMER_REVIEWS")
# 3. AI(AICOMPLETE)で不満点抽出
df_ai = df.with_column(
"COMPLAINTS",
F.call_builtin(
"SNOWFLAKE.CORTEX.AI_COMPLETE",
"llama3.1-8b",
F.concat(
F.lit("""
ユーザーレビューから不満点だけを日本語で抽出してください。
[厳守ルール]
- 「不満点:」などのラベルや「・」などの記号、挨拶、改行、英訳は全て禁止。
- 複数の不満点がある場合、全て抽出すること。
- ですます調ではなく、である調で出力すること。
- 不満がない場合は「なし」とだけ出力すること。
レビュー内容:
"""),
F.col("REVIEW_TEXT"),
F.lit("\n不満点の中身:") # AIに「ここから書き始めろ」と誘導する
)
)
)
# 4. AI(AI_COMPLETE)で要約
df_with_summary = df_ai.with_column(
"REVIEW_SUMMARY",
F.call_builtin(
"SNOWFLAKE.CORTEX.AI_COMPLETE",
"llama3.3-70b",
F.concat(
F.lit("以下のレビューを日本語で1行に短く要約してください。英訳や導入文は不要です。レビュー:"),
F.col("REVIEW_TEXT"),
F.lit("\n要約:")
)
)
)
# 5. 結果表示
df_final = df_with_summary.drop("REVIEW_TEXT")
df_final
3. (参考)実行結果
多少レイアウトが崩れているところもあるが、内容はおおむね過不足なし。
ただし1つNo.5の極上タオルのレビューで惜しいところがあって、
本文は「肌触りが優しすぎて、お風呂上がりが毎日楽しみになりました。友人へのギフトとしても絶対喜ばれると思います。文句なしの星5つです!」であるところ、「肌触りが優しすぎて」を不満点(COMPLAINTS)として挙げているところ。
| REVIEW_ID | PRODUCT_NAME | REVIEW_DATE | COMPLAINTS | REVIEW_SUMMARY |
|---|---|---|---|---|
| 1 | モダン・マグカップ | 2024-03-01 | "持ち手の穴が小さく、男性の指だと少し窮屈に感じます。熱い飲み物を入れると本体がかなり熱くなる" | "見た目は高級感があるが、実用面で少し不便な点がある。" |
| 2 | 高性能・ノートPC | 2024-03-02 | "電源アダプタが巨大で重い" | "動画編集に期待以上のスペックで、4K動画の書き出しもサクサクでファンの音も静か。" |
| 3 | ワイヤレス・マウス | 2024-03-03 | "クリック音が大きい。スリープモードからの復帰時にラグがある。" | "操作性は抜群だがクリック音が大きく、スリープ復帰時にラグがある。" |
| 4 | スマート・デスク | 2024-03-04 | "組み立ての難易度が高い。付属の説明書が図解が分かりにくい。ネジ穴の精度が甘い箇所がある。" | "電動昇降デスクは使いやすいが、組み立てが大変でした。" |
| 5 | 極上・タオル | 2024-03-10 | "・肌触りが優しすぎて" | "肌触りが優しく、吸水性が抜群でお風呂上がりが楽しみになるタオルです。" |
| 6 | ノイズキャンセリング・ヘッドフォン | 2024-03-05 | "長時間装着していると耳の周りが蒸れてしまう。専用アプリのペアリングが不安定で、デバイスを切り替えるたびに再設定が必要になる。" | "飛行機のエンジン音を遮断するのに効果的だが、長時間装着すると耳の周りが蒸れてしまい、ソフトウェアの改善が必要。" |
| 7 | スマート・LEDライト | 2024-03-11 | "・なし" | "設置が簡単でスマホアプリとの連携もスムーズで、デザインもシンプルで気に入っている。" |
そこで不満点抽出のモデルも中規模のllama3.3-70bに変えてみると…
| REVIEW_ID | PRODUCT_NAME | REVIEW_DATE | COMPLAINTS | REVIEW_SUMMARY |
|---|---|---|---|---|
| 5 | 極上・タオル | 2024-03-10 | "なし" | "肌触りが優しく、吸水性が抜群でお風呂上がりが楽しみになるタオルです。" |
不満点"なし"になった!
おわりに
テーブルのデータをAIに食わせるのが簡単にできるので、Python/SQL/プロンプトの腕次第でなんでもできそうという感じ。
特化型関数(SUMMARIZE)は出力を日本語にしたいという要件があると(今のところ)使うの厳しいかなという印象だったので、練習以外でCortex AI呼び出すのであればモデルやプロンプト指定ができるAI_COMPLETEを最初に考えたほうがいいかなと思った。