感情マッピング技術ドキュメント
感情マッピング - プルチックの感情の輪
概要
本ドキュメントでは、源氏物語香りデータベースにおける感情推論システムについて説明します。プルチックの感情の輪(Plutchik's Wheel of Emotions)を理論的基盤として採用し、香りの記述から関連する感情を自動的に推論します。
理論的基盤:プルチックの感情の輪
8つの基本感情と強度レベル
プルチックの感情の輪は、8つの基本感情をそれぞれ3段階の強度で表現します:
| 基本感情 | 弱(weak) | 中程度(moderate) | 強(strong) |
|---|---|---|---|
| 喜び | 穏やか(serenity) | 喜び(joy) | 歓喜(ecstasy) |
| 信頼 | 受容(acceptance) | 信頼(trust) | 称賛(admiration) |
| 恐れ | 不安(apprehension) | 恐れ(fear) | 恐怖(terror) |
| 驚き | 注意散漫(distraction) | 驚き(surprise) | 驚嘆(amazement) |
| 悲しみ | 物思い(pensiveness) | 悲しみ(sadness) | 深い悲しみ(grief) |
| 嫌悪 | 退屈(boredom) | 嫌悪(disgust) | 憎悪(loathing) |
| 怒り | 不快(annoyance) | 怒り(anger) | 激怒(rage) |
| 期待 | 興味(interest) | 期待(anticipation) | 警戒(vigilance) |
複合感情(Dyad)
基本感情の組み合わせによる複合感情:
- 愛(love): 喜び + 信頼
- 楽観(optimism): 喜び + 期待
- 攻撃性(aggressiveness): 怒り + 期待
- 軽蔑(contempt): 怒り + 嫌悪
- 後悔(remorse): 嫌悪 + 悲しみ
- 不承認(disapproval): 悲しみ + 驚き
- 畏敬(awe): 驚き + 恐れ
- 服従(submission): 恐れ + 信頼
感情推論アルゴリズム
推論方式:キーワードマッチング
本システムでは、ルールベースのキーワードマッチング方式を採用しています。機械学習モデルは使用せず、日本語キーワード辞書に基づいてテキストから感情を検出します。
処理フロー
┌─────────────────┐
│ 香りデータ入力 │
│ (Smell オブジェクト) │
└────────┬────────┘
│
▼
┌─────────────────┐
│ テキストフィールド抽出 │
│ - Effect │
│ - Quality │
│ - Circumstances │
└────────┬────────┘
│
▼
┌─────────────────┐
│ キーワードマッチング │
│ (日本語感情辞書) │
└────────┬────────┘
│
▼
┌─────────────────┐
│ 感情ID配列を出力 │
│ ["disgust", "annoyance"] │
└─────────────────┘
推論対象フィールド
香りデータの以下3つのフィールドからテキストを抽出し、感情を推論します:
| フィールド | 説明 | 例 |
|---|---|---|
| Effect | 香りが与える影響・感情反応 | 「心くるしうおほさるゝ」 |
| Quality | 香りの質的特性 | 「たえかたくまさなき」 |
| Circumstances | 香りが知覚される文脈 | 「春の御殿の様子」 |
日本語感情キーワード辞書
src/lib/emotion-mapping.ts で定義されている主要なキーワードマッピング:
const JAPANESE_EMOTION_KEYWORDS: Record<string, string[]> = {
// 喜び系
joy: ['喜', '嬉', '楽', '幸', '悦'],
serenity: ['穏', '静', '安らか', '心地よ', '快い'],
ecstasy: ['歓喜', '狂喜', '有頂天'],
// 悲しみ系
sadness: ['悲', '哀', '憂', '寂'],
pensiveness: ['物思', '物憂', 'もの思'],
grief: ['嘆', '慟哭', '悲嘆'],
// 嫌悪系
disgust: ['嫌', '厭', '忌'],
boredom: ['退屈', '倦', 'つれづれ'],
loathing: ['憎', '忌み嫌'],
// 怒り系
annoyance: ['不快', '苛立', 'いらだ'],
anger: ['怒', '憤', 'いきどほ'],
rage: ['激怒', '憤怒', '逆上'],
// 恐れ系
fear: ['恐', '怖', '畏'],
apprehension: ['不安', '懸念', '心配'],
terror: ['恐怖', '戦慄', 'おびえ'],
// 驚き系
surprise: ['驚', 'おどろ', 'あさまし'],
amazement: ['驚嘆', '仰天', 'あきれ'],
// 信頼系
trust: ['信', '頼', '任'],
admiration: ['称賛', '敬', '尊'],
// 期待系
anticipation: ['期待', '待', '望'],
interest: ['興味', '関心', '好奇'],
// 複合感情
love: ['愛', '恋', '慕', '思ひ'],
empathy: ['あはれ', '哀れ', 'しみじみ'],
contempt: ['軽蔑', '侮', '蔑'],
awe: ['畏敬', '畏怖', 'かしこ'],
remorse: ['後悔', '悔', '恥'],
};
Quality分析の詳細ロジック
Qualityフィールドには特別な分析ロジックが適用されます:
// ポジティブキーワード → joy, serenity を推論
const positiveKeywords = [
'美しい', '良い', '素晴らしい', '心地よい', '快い',
'優雅', '華やか', '鮮やか', 'かうばし', '芳し'
];
// ネガティブキーワード → disgust, annoyance を推論
const negativeKeywords = [
'不快', '悪い', 'まさなき', '絶えがたく', '忌み嫌',
'くさし', '臭し'
];
具体的な推論例
例1:嫌悪・不快の推論
入力データ:
{
"Smell_Word": "きぬのすそたえ",
"Quality": "たえかたくまさなき",
"Sentence_ModernJapanese": "御送り迎えの人の衣の裾から、絶えがたく、まさなき(不快な)匂いがすることもあった。"
}
推論プロセス:
- Quality フィールドを分析
- 「まさなき」がネガティブキーワードにマッチ
disgust(嫌悪)とannoyance(不快)を推論
出力:
{
"Emotions": ["disgust", "annoyance"]
}
例2:複合感情の推論
入力データ:
{
"Smell_Word": "梅のか",
"Quality": "いとおもしろき(非常に趣深い)",
"Effect": "あはれにみたてまつる(しみじみと感動する)"
}
推論プロセス:
- Quality に「趣深い」→ positiveKeywords にマッチ →
joy,serenity - Effect に「あはれ」→ empathy キーワードにマッチ →
empathy
出力:
{
"Emotions": ["joy", "serenity", "empathy"]
}
例3:源氏物語特有の表現
源氏物語には特有の感情表現があり、これらも辞書に含まれています:
| 古語表現 | 推論される感情 |
|---|---|
| あはれ | empathy, sadness, pensiveness |
| もの哀し | sadness, pensiveness |
| 物憂 | sadness, boredom |
| つれづれ | boredom, pensiveness |
| かしこ | awe, fear |
| なつかし | love, trust |
実装ファイル
| ファイル | 役割 |
|---|---|
src/lib/emotions.ts | 感情語彙データ(TypeScript) |
src/lib/emotion-mapping.ts | 推論ロジック・キーワード辞書 |
public/rdf/plutchik-emotions.ttl | RDF/TTL形式の感情語彙 |
scripts/add-emotions.ts | 一括処理スクリプト |
主要関数
// 香りから感情を推論
function suggestEmotionsForSmell(smell: Smell): string[]
// Effect/Circumstancesフィールドから感情を推論
function suggestEmotionsFromEffect(effectText: string): string[]
// Qualityフィールドから感情を推論
function suggestEmotionsFromQuality(qualityText: string): string[]
// 感情IDからラベル付きオブジェクトを取得
function getSmellEmotions(smell: Smell, locale: 'en' | 'ja'): EmotionWithLabel[]
// 関連感情を取得(感情の輪の隣接関係)
function getRelatedEmotions(emotionKey: string): string[]
一括処理スクリプト
使用方法
# ドライラン(変更をプレビュー)
npx tsx scripts/add-emotions.ts --dry-run
# 特定の巻を処理
npx tsx scripts/add-emotions.ts --volume=01
# 全巻を処理
npx tsx scripts/add-emotions.ts
処理フロー
json/[巻番号].jsonファイルを読み込み- 各香りエントリに対して
suggestEmotionsForSmell()を実行 - 推論された感情を
Emotionsフィールドに追加 - ファイルに保存
RDFスキーマでの感情表現
感情語彙はSKOS(Simple Knowledge Organization System)を使用してRDFで定義されています。
名前空間: http://data.odeuropa.eu/vocabulary/plutchik/
# 嫌悪感情の定義
plu:disgust a skos:Concept ;
dbp:next plu:remorse ;
dbp:prev plu:contempt ;
skos:broader plu:boredom ; # より弱い感情
skos:inScheme plu: ;
skos:narrower plu:loathing ; # より強い感情
skos:prefLabel "disgust"@en, "嫌悪"@ja .
# 不快感情の定義
plu:annoyance a skos:Concept ;
skos:inScheme plu: ;
skos:narrower plu:anger ; # より強い感情
skos:prefLabel "annoyance"@en, "不快"@ja ;
skos:topConceptOf plu: .
関係性プロパティ:
skos:broader: より弱い感情へのリンクskos:narrower: より強い感情へのリンクdbp:next: 感情の輪での次の感情dbp:prev: 感情の輪での前の感情
UIでの表示
香り詳細ページ
src/components/pages/smells/SmellDetail.tsx で感情を表示:
- Effectフィールドの後に感情セクションを表示
- 各感情をバッジとして表示
- ホバー時に強度情報を表示
- 日英両言語でラベルを切り替え
感情フィルタリング
src/components/pages/smells/SmellsSearchClient.tsx で感情フィルタを実装:
- 複数感情の選択が可能(AND条件)
- ファセットとして感情ごとの件数を表示
- リアルタイムでフィルタリング
今後の拡張可能性
1. LLMベースの感情分析
現在のキーワードマッチングに加え、LLM(大規模言語モデル)を活用したより高度な感情分析:
- 文脈を考慮した感情推論
- 古語表現のより正確な解釈
- 複雑な感情の組み合わせの検出
2. キーワード辞書の拡張
JAPANESE_EMOTION_KEYWORDS に新しいキーワードを追加することで、推論精度を向上:
// 新しいキーワードの追加例
JAPANESE_EMOTION_KEYWORDS.joy.push('うれし', 'よろこばし');
3. 感情ネットワーク可視化
- 香り同士を共通感情でつなぐネットワークグラフ
- 物語の進行に伴う感情の変化の可視化
参考文献
- Plutchik's Wheel of Emotions
- Odeuropa Emotion Vocabulary
- Robert Plutchik (1980). "A general psychoevolutionary theory of emotion"
- 英語版ドキュメント: Emotion Mapping Technical Document