はじめに:レビューは読みきれない
ECサイトを運営していると、商品レビューやアンケートの自由記述が毎日のように増えていきます。
- 「梱包が丁寧で好感が持てました」
- 「届くのが思ったより遅かったです」
- 「サイズ感がちょうどよくて、また買いたい」
- 「写真と色味が少し違って残念」
一件ずつ読めば、お客さまが何を喜び、何に不満を感じたのかがよく分かります。けれど件数が数百、数千と積み上がってくると、すべてに目を通すのは現実的ではなくなってきます。結局、星の数だけをぼんやり眺めて終わり、というのもよくある話です。
もったいないのは、自由記述の中に「次に何を直せば満足度が上がるか」のヒントがぎっしり詰まっていることです。星4つでも本文には不満が書かれていたり、逆に星3つでも文章はとても好意的だったり、点数だけでは見えない温度感がそこにあります。
この記事では、たまっていくレビュー文を Claude Code と Python で感情分析(ポジティブ/ネガティブの自動分類)にかけ、その結果を NPS(顧客推奨度)の予測材料 として使う考え方を紹介します。実装の細部よりも、全体の流れと勘どころを押さえることを目的とした記事として読んでください。
💡 補足 NPS(Net Promoter Score)は「この商品・お店を友人にどのくらいすすめたいか」を0〜10点で聞き、推奨者の割合から批判者の割合を引いて算出する指標です。顧客がどれだけファンになってくれているかをざっくり測るものさし、と考えてください。
レビューを感情分析する流れ
やることはシンプルで、大きく3ステップです。
- レビュー文を一か所に集める(CSVやスプレッドシートでOK)
- 一件ずつAIに渡して「ポジティブ/中立/ネガティブ」を判定してもらう
- 判定結果を集計し、傾向を眺める
ここで Claude Code が役立つのは、「こういうデータを読み込んで、こう分類して、結果をこう書き出すスクリプトを作って」と日本語で頼むだけで、Pythonコードのたたき台を用意してくれる ところです。プログラミングに不慣れでも、出てきたコードを動かしながら少しずつ調整していけます。
まずは分類のイメージをつかむ
感情分析といっても、難しい数式を自分で組む必要はありません。AIに一件ずつ「このレビューはポジティブですか、ネガティブですか」と聞いて、答えを記録していくだけです。
たとえば、次のようなレビューを渡すと、
- 「梱包が丁寧で好感が持てました」 → ポジティブ
- 「届くのが思ったより遅かったです」 → ネガティブ
- 「普通でした」 → 中立
といった具合に、ラベルを付けてもらいます。これを全件くり返せば、「ポジティブが何割、ネガティブが何割」という全体像が見えてきます。
Pythonで分類スクリプトを組む
Claude Code に「レビューのCSVを読み込んで、一行ずつ感情を判定して新しい列に書き出すPythonスクリプトを作って」と頼むと、おおよそ次のような骨組みが出てきます。ここでは AnthropicのAPI(Claude)を使う例で示します。
import os
import csv
import anthropic
# APIキーは環境変数から読み込む(コードに直接書かない)
client = anthropic.Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
def classify_sentiment(review_text: str) -> str:
"""レビュー文を ポジティブ / 中立 / ネガティブ のいずれかに分類する"""
message = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=10,
messages=[
{
"role": "user",
"content": (
"次のECレビューの感情を判定してください。\n"
"出力は「ポジティブ」「中立」「ネガティブ」のいずれか一語のみ。\n\n"
f"レビュー: {review_text}"
),
}
],
)
return message.content[0].text.strip()
# reviews.csv(列: review_id, body)を読み込んで結果を書き出す
with open("reviews.csv", encoding="utf-8") as f_in, \
open("reviews_scored.csv", "w", encoding="utf-8", newline="") as f_out:
reader = csv.DictReader(f_in)
writer = csv.DictWriter(f_out, fieldnames=["review_id", "body", "sentiment"])
writer.writeheader()
for row in reader:
sentiment = classify_sentiment(row["body"])
writer.writerow({
"review_id": row["review_id"],
"body": row["body"],
"sentiment": sentiment,
})
print(f"{row['review_id']}: {sentiment}")
ポイントは2つあります。
ひとつは、APIキーをコードに直接書かないこと です。os.environ から読み込むようにしておけば、スクリプトを誰かに見せたりGitで共有したりしても、鍵が漏れる心配がありません。
もうひとつは、出力フォーマットを指定すること です。「一語のみで答えて」と頼んでおくと、後で集計しやすい揃った結果が返ってきます。指示があいまいだと「これはポジティブですね、なぜなら…」と長文で返ってきて、集計が面倒になります。
💡 補足 モデル名やAPIの細かい仕様は更新されていきます。実際に組むときは公式ドキュメント(Anthropic)で最新の指定方法を確認してください。最初は10件ほどの小さなサンプルで試し、判定が手作業の感覚と合っているかを確かめてから全件に広げると安全です。
集計して傾向を眺める
全件にラベルが付いたら、あとは集計するだけです。これも難しいことはなく、表計算ソフトでピボットしても、Pythonで数えても構いません。
import csv
from collections import Counter
counter = Counter()
with open("reviews_scored.csv", encoding="utf-8") as f:
for row in csv.DictReader(f):
counter[row["sentiment"]] += 1
total = sum(counter.values())
for label, count in counter.most_common():
print(f"{label}: {count}件 ({count / total:.1%})")
「ポジティブ72%、中立18%、ネガティブ10%」のように出れば、まず全体の温度感がつかめます。さらに商品カテゴリ別や月別に分けて集計すると、「この商品だけネガティブが急に増えている」といった変化に気づけるようになります。
問い合わせデータと同じように、レビューも一か所に集めてしまえば分析の幅が広がります。集約の考え方は ECのCS問い合わせデータをBigQueryに集約して商品改善に活かす でも触れているので、あわせて読んでみてください。
NPSとの関係・予測に使う考え方
ここからが本題です。感情分析の結果を、どうやって NPS の予測に結びつけるのか、という話です。
NPS は本来、お客さまに直接「0〜10点でどのくらいすすめたいですか」と聞いて測る指標です。けれど、わざわざアンケートに答えてくれる人は限られます。一方で、レビューは黙っていても集まってきます。そこで、レビューの感情傾向を「アンケートの代わりの手がかり」として使えないか と考えるわけです。
直感的にも、
- ポジティブなレビューが多い時期 → 推奨者が多そう(NPSは高めになりそう)
- ネガティブなレビューが増えた時期 → 批判者が増えていそう(NPSは下がりそう)
という関係はイメージできます。
具体的な使い方として、現実的なのは次のような進め方です。
- 過去に実際にNPSアンケートを取った時期があれば、その時期の レビューのポジティブ比率 と 実際のNPS を並べてみる
- 両者がどのくらい連動しているかをざっくり確認する
- 連動していそうなら、アンケートを取っていない時期も「ポジティブ比率の動き」から NPS のおおよその上下を推し量る
たとえば「ポジティブ比率が70%を切った月は、過去のNPSも低めだった」という関係が見えれば、アンケートを毎月取らなくても、レビューの感情だけで「今月は満足度が落ちているかもしれない」と早めに気づけます。これが予測に使う、ということの中身です。
💡 補足 いきなり精密な予測モデルを組む必要はありません。まずは「ポジティブ比率」と「NPS」を時系列で並べて折れ線グラフにするだけでも十分です。2本の線が似た形で動いていれば、それだけで実用的なヒントになります。
注意点:相関≠因果・サンプルの偏り
便利な反面、レビューの感情分析でNPSを推し量るときには、踏み外しやすい落とし穴がいくつかあります。
⚠️ 注意 「ポジティブ比率とNPSが一緒に動いている」ことと、「ポジティブ比率がNPSを決めている」ことは別物です。両方とも、季節要因やキャンペーンといった第三の要因に動かされているだけかもしれません。相関が見えても、因果と決めつけないようにしてください。
もうひとつ大きいのが サンプルの偏り です。レビューを書く人は、お客さま全体の縮図ではありません。とても満足した人か、とても不満だった人のどちらかに偏りやすく、静かに満足している多数派は黙っていることが多いものです。つまり、レビューの感情比率は「全顧客の気持ち」ではなく「わざわざ書いた人の気持ち」だという前提を忘れてはいけません。
⚠️ 注意 AIによる感情判定も万能ではありません。皮肉(「最高でした(笑)」)や、ポジティブとネガティブが混ざった文(「商品は良いが配送が最悪」)は、ラベルがぶれやすい部分です。重要な判断に使う前に、必ず人の目で何件かサンプルチェックする習慣をつけてください。
これらを踏まえると、レビューの感情分析は「NPSを正確に当てる装置」ではなく、「満足度の変化にいち早く気づくためのアンテナ」 と位置づけるのが健全です。数字が動いたら本当の原因を別途調べる、という使い方であれば、十分に役立ってくれます。
なお、AIにテキストを分類させる仕組みそのものは、レビュー以外にも応用が利きます。BigQuery上で大量のテキストをまとめて分析する方法は BigQueryのAI.GENERATE関数とGeminiでテキストデータを分析する で紹介しているので、件数が増えてきたらこちらも検討してみてください。
まとめ
最後に、この記事の流れを振り返っておきます。
- 増え続けるレビューは読みきれず、星の数だけでは温度感が見えない
- Claude Code に頼めば、レビューを感情分類するPythonスクリプトを手早く用意できる
- APIキーはコードに直書きせず環境変数から読み込み、出力フォーマットを指定して集計しやすくする
- ポジティブ比率の動きを、NPS(顧客推奨度)の変化を早めに察知する手がかりとして使える
- ただし相関は因果ではなく、レビューには書き手の偏りがある。AIの判定も人の目で点検する
完璧な予測を目指すより、まずは「今月はポジティブが減っている気がする」を数字で言えるようになることが第一歩です。小さなサンプルから試して、自分のお店のデータでアンテナを育てていってください。