本サイトのデータは生成AIによる香り情報の抽出・画像生成を行っています。誤りなどが含まれる可能性がある点にご注意ください。 詳細はこちら

感情マッピング技術ドキュメント

感情マッピング - プルチックの感情の輪

概要

本ドキュメントでは、源氏物語香りデータベースにおける感情推論システムについて説明します。プルチックの感情の輪(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": "御送り迎えの人の衣の裾から、絶えがたく、まさなき(不快な)匂いがすることもあった。"
}

推論プロセス:

  1. Quality フィールドを分析
  2. 「まさなき」がネガティブキーワードにマッチ
  3. disgust(嫌悪)と annoyance(不快)を推論

出力:

{
  "Emotions": ["disgust", "annoyance"]
}

例2:複合感情の推論

入力データ:

{
  "Smell_Word": "梅のか",
  "Quality": "いとおもしろき(非常に趣深い)",
  "Effect": "あはれにみたてまつる(しみじみと感動する)"
}

推論プロセス:

  1. Quality に「趣深い」→ positiveKeywords にマッチ → joy, serenity
  2. 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.ttlRDF/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

処理フロー

  1. json/[巻番号].json ファイルを読み込み
  2. 各香りエントリに対して suggestEmotionsForSmell() を実行
  3. 推論された感情を Emotions フィールドに追加
  4. ファイルに保存

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. 感情ネットワーク可視化

  • 香り同士を共通感情でつなぐネットワークグラフ
  • 物語の進行に伴う感情の変化の可視化

参考文献