分類における確信度と不確実性
モデルに確信度をスコア化させ、曖昧な分類を処理する方法を学びます。
「分類における確信度と不確実性」はCoddyKit上の無料AI Prompt Engineeringレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはAI Prompt Engineering学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 AI Prompt Engineeringコースには全4レッスンが含まれています。
自信過剰なモデルの問題
デフォルトでは、LLMは入力が実際には曖昧であっても、明らかに確信があるように分類タスクへ回答します。モデルにpositive、negative、neutralのいずれかを返すよう指示すると、必ず1つを選び、わかりませんとは決して言いません。
本番システムで、不確かな分類を確実なものとして扱うと、コストの大きいエラーにつながります。たとえば、サポートチケットの誤った振り分け、誤った推奨、不正確なレポートなどです。
分類プロンプトで不確実性を定量化すると、この問題を解決できます。
信頼度スコア(1〜10)
モデルに数値スケールで信頼度を評価させると、後続システムでしきい値を設定できる、きめ細かなシグナルが得られます。
import anthropic, json
client = anthropic.Anthropic(api_key='YOUR_API_KEY')
def classify_with_confidence(text):
prompt = f'''
Classify the sentiment of the text below.
Return JSON:
{{
"sentiment": "positive|negative|neutral",
"confidence": 1-10,
"reason": "brief explanation of confidence level"
}}
Confidence scale: 10=completely certain, 1=total guess, 5=genuinely ambiguous
Text: {text}
'''
r = client.messages.create(
model='claude-opus-4-5', max_tokens=100,
messages=[{'role': 'user', 'content': prompt}]
)
return json.loads(r.content[0].text)
print(classify_with_confidence('I sort of liked it but the wait was too long.'))
print(classify_with_confidence('This product is absolutely outstanding!'))UNCERTAIN応答
分類の信頼度がしきい値を下回った場合に、モデルが明示的にUNCERTAINと返すよう指示すると、positive、negative、UNCERTAINの3種類の出力を作成できます。
def classify_or_uncertain(text, uncertainty_threshold=4):
prompt = f'''
Classify the sentiment of the text: positive, negative, or neutral.
If the sentiment is genuinely ambiguous or you are not confident (confidence below {uncertainty_threshold}/10),
return UNCERTAIN instead of guessing.
Return JSON: {{"sentiment": "positive|negative|neutral|UNCERTAIN", "confidence": 1-10}}
Text: {text}
'''
r = client.messages.create(
model='claude-opus-4-5', max_tokens=80,
messages=[{'role': 'user', 'content': prompt}]
)
result = json.loads(r.content[0].text)
if result['sentiment'] == 'UNCERTAIN' or result['confidence'] < uncertainty_threshold:
print(f'Routing to human review: confidence={result["confidence"]}')
return result
print(classify_or_uncertain('It was fine, I guess. Not bad, not great.'))
print(classify_or_uncertain('Absolutely terrible product. Never buying again.'))カテゴリ確率の順位付け
単一のカテゴリを強制的に選ばせる代わりに、考えられるすべてのカテゴリを尤度の高い順に並べるようモデルに求めます。これにより、上位2つのカテゴリがどれほど拮抗しているかがわかります。
def classify_ranked(text, categories):
cats = ', '.join(categories)
prompt = f'''
Classify this text into one of these categories: {cats}
Return ALL categories ranked by likelihood, highest first.
Return JSON: {{"ranked": [{{"category": str, "probability": 0.0-1.0}}]}}
Probabilities must sum to 1.0.
Text: {text}
'''
r = client.messages.create(
model='claude-opus-4-5', max_tokens=150,
messages=[{'role': 'user', 'content': prompt}]
)
result = json.loads(r.content[0].text)
return result['ranked']
cats = ['billing', 'technical', 'general', 'cancellation']
ranked = classify_ranked('I was charged twice and now my account is locked.', cats)
for item in ranked:
print(f'{item["category"]}: {item["probability"]:.0%}')確率の差を使った曖昧さの検出
順位付けされた上位2つの確率の差は、信頼性の高い曖昧さのシグナルです。差が小さい場合はモデルが不確かで、差が大きい場合は確信を持っています。
def classify_with_ambiguity_detection(text, categories, ambiguity_threshold=0.15):
ranked = classify_ranked(text, categories)
top1_prob = ranked[0]['probability']
top2_prob = ranked[1]['probability'] if len(ranked) > 1 else 0
spread = top1_prob - top2_prob
is_ambiguous = spread < ambiguity_threshold
return {
'primary': ranked[0]['category'],
'secondary': ranked[1]['category'] if len(ranked) > 1 else None,
'confidence_spread': round(spread, 3),
'is_ambiguous': is_ambiguous,
'action': 'human_review' if is_ambiguous else 'auto_classify'
}
result = classify_with_ambiguity_detection(
'My upgrade did not apply and I think I was still charged.', ['billing', 'technical', 'general', 'cancellation']
)
print(result)条件付き不確実性:不明な場合は質問する
会話型アプリケーションでは、UNCERTAINを返す代わりに、モデルへ明確化を求める質問をさせることができます。
SYSTEM_CLARIFY = '''
You are a support ticket classifier.
If the customer message is clear, classify it and respond with JSON:
{"action": "classify", "category": str, "confidence": 1-10}
If the message is ambiguous or you are not sure which category applies, respond with:
{"action": "clarify", "question": "A single clarifying question to ask the customer"}
Categories: billing, technical, account, cancellation
Only ask for clarification when genuinely needed. Prefer classification when possible.
'''
def classify_or_ask(message):
r = client.messages.create(
model='claude-opus-4-5', max_tokens=100,
system=SYSTEM_CLARIFY,
messages=[{'role': 'user', 'content': message}]
)
return json.loads(r.content[0].text)
print(classify_or_ask('It is not working anymore.'))
print(classify_or_ask('Cancel my subscription immediately.'))信頼度のキャリブレーション:Temperatureと一貫性
同じ分類を異なるTemperatureで複数回実行すると、モデルが本当にどの程度不確かなのかがわかります。分散が大きい場合は、入力が実際に曖昧であることを示します。
from collections import Counter
def calibrated_classify(text, n_samples=5):
results = []
for _ in range(n_samples):
r = client.messages.create(
model='claude-opus-4-5', max_tokens=50,
messages=[{'role': 'user', 'content': f'Classify as positive/negative/neutral. Return JSON: {{"sentiment": str}}\n\n{text}'}]
)
results.append(json.loads(r.content[0].text)['sentiment'])
counts = Counter(results)
dominant = counts.most_common(1)[0]
agreement_rate = dominant[1] / n_samples
return {
'classification': dominant[0],
'agreement_rate': agreement_rate,
'is_uncertain': agreement_rate < 0.7,
'all_results': dict(counts)
}
result = calibrated_classify('The product is okay, nothing special.')
print(result)信頼度に基づく振り分け
本番環境の振り分けシステムでは、信頼度のレベルを使って異なるハンドラーへルーティングします。
def route_by_confidence(text, classify_fn, auto_threshold=8, human_threshold=4):
result = classify_fn(text)
confidence = result.get('confidence', 5)
category = result.get('category') or result.get('sentiment', 'unknown')
if confidence >= auto_threshold:
return {'route': 'auto_process', 'category': category, 'confidence': confidence}
elif confidence >= human_threshold:
return {'route': 'auto_process_with_flag', 'category': category, 'confidence': confidence,
'flag': 'Low confidence — monitor output'}
else:
return {'route': 'human_review', 'category': category, 'confidence': confidence,
'flag': 'Very low confidence — human classification required'}
print(route_by_confidence('Hate this product.', classify_with_confidence))
print(route_by_confidence('It is kind of okay but also not really.', classify_with_confidence))構造化された不確実性フィールド
分類結果のための包括的な不確実性スキーマです。
UNCERTAINTY_SCHEMA = '''
Return JSON:
{
"primary_category": "string",
"confidence": 1-10,
"uncertainty_type": "none | ambiguous_input | insufficient_context | boundary_case | none",
"alternative_categories": ["string"] or [],
"uncertainty_explanation": "string or null",
"recommended_action": "auto_classify | human_review | request_more_info"
}
Uncertainty types:
- ambiguous_input: The text could clearly mean multiple things
- insufficient_context: Need more information to classify correctly
- boundary_case: The text sits on the border between two categories
- none: Clear classification, no uncertainty
'''
print(UNCERTAINTY_SCHEMA)
print('Use this schema for any classification task requiring uncertainty quantification.')本番環境での不確実性の追跡
本番環境で不確実性の発生率を監視し、プロンプトの劣化やカテゴリのドリフトを検出します。
class ClassificationMonitor:
def __init__(self, human_review_threshold=0.15):
self.total = 0
self.uncertain = 0
self.threshold = human_review_threshold
self.category_counts = {}
def record(self, result):
self.total += 1
cat = result.get('category', 'unknown')
self.category_counts[cat] = self.category_counts.get(cat, 0) + 1
if result.get('confidence', 10) < 5 or result.get('sentiment') == 'UNCERTAIN':
self.uncertain += 1
def report(self):
uncertain_rate = self.uncertain / self.total if self.total else 0
alert = uncertain_rate > self.threshold
return {
'total': self.total,
'uncertain_rate': round(uncertain_rate, 3),
'alert': alert,
'category_distribution': self.category_counts
}
monitor = ClassificationMonitor()
print('Production monitoring system defined.')高い信頼度を信頼できる場合
モデルの信頼度が高くても、分類が正しいとは限りません。信頼度が高い場合でも、次のような一般的な失敗モードがあります。
- 体系的なバイアス:特定のパターンを、信頼度の高い誤った回答として一貫して分類します
- ドメインシフト:モデルは自信を持っていても、入力の形式が学習時のものと大きく異なります
- 迎合:実際の確信度ではなく、好ましく聞こえる内容に合わせて信頼度を調整します
信頼度のキャリブレーションは、必ずラベル付きテストセットに対して評価してください。精度だけでなく、高信頼度の予測が低信頼度の予測よりも実際に正確かどうかも確認します。
クイックチェック
分類結果で、順位付けされた上位2つのカテゴリ確率の差が小さい場合、何を示していますか?
分類における不確実性 — 重要ポイント
不確実性の定量化により、分類はブラックボックスから管理可能なシステムへと変わります。
- すべての分類で信頼度スコア(1〜10)を求め、出力を同じ信頼性のものとして扱わないようにします
- 本当に曖昧な入力には、カテゴリを無理に選ばせるのではなくUNCERTAIN応答を使います
- すべてのカテゴリを確率順に並べ、上位2つの差を最良の曖昧さのシグナルとして使います
- 信頼度がしきい値を下回る場合は人によるレビューへ、高い場合は自動処理へ振り分けます
- 会話型アプリでは、UNCERTAINを返す代わりに明確化の質問をします
- 本番環境で不確実性の発生率を監視し、上昇した場合はプロンプトの劣化やカテゴリのドリフトを疑います
- 精度だけでなく、ラベル付きデータに対する信頼度のキャリブレーションも必ず評価します
よくある質問
「分類における確信度と不確実性」レッスンは無料ですか?
はい。「分類における確信度と不確実性」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、AI Prompt Engineeringコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 AI Prompt Engineeringコースには全4レッスンが含まれています。
「分類における確信度と不確実性」で何を学びますか?
モデルに確信度をスコア化させ、曖昧な分類を処理する方法を学びます。 ブラウザで直接実行するハンズオンコードでAI Prompt Engineeringを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
AI Prompt Engineeringを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのAI Prompt Engineeringは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「分類における確信度と不確実性」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このAI Prompt Engineeringレッスンでコードを書いて実行できますか?
はい。すべてのAI Prompt Engineeringレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- 固有表現抽出のプロンプト
- スキーマ駆動のデータ抽出
- テキスト分類器としての LLM
- 分類における確信度と不確実性