Skip to main content
Glama
civilian7

korean-people-persona

by civilian7

korean-people-persona

HuggingFace nvidia/Nemotron-Personas-Korea データセット(約100万行、9つのparquetファイル)をSQLiteに変換・検索するためのツール群。

概要

  • 出典: NVIDIA, Nemotron-Personas-Korea — https://huggingface.co/datasets/nvidia/Nemotron-Personas-Korea

  • ライセンス: 元のデータセットページのライセンス条項に従う

  • DBファイル: database/persona.db

  • 元のparquet: data/train-*-of-*.parquet

  • テーブル: persona (メイン) + persona_fts (FTS5外部コンテンツインデックス)

  • ターゲットSQLite: 3.37+ (FTS5, STRICTテーブル, JSON1使用)

  • Python: 3.10以上 (3.11+ 推奨)

  • 依存関係: pyarrow >= 15.0, huggingface_hub >= 0.24 (requirements.txt 参照)

  • ディスク空き容量: 約 5 GB (parquet ~2GB + DB ~3GB)

Related MCP server: Legal Search MCP

データ出典

項目

値

リポジトリ

nvidia/Nemotron-Personas-Korea

ファイル

train-0000{0..8}-of-00009.parquet (9個)

ファイルあたりの行数

約 111,112

総行数

1,000,000

欠損値

全カラムで0 (NOT NULL保証)

country

すべて 대한민국 (大韓民国) の単一値

*_list

Python repr 形式の文字列 → JSON配列に正規化

フォルダ構造

korean-people-persona/
├── data/                  # 원본 parquet (gitignore — 약 2GB)
│   └── train-*-of-*.parquet
├── database/              # 생성된 SQLite (gitignore — 약 3GB)
│   └── persona.db
├── src/
│   ├── convert/                # parquet → SQLite 변환기
│   │   ├── __init__.py
│   │   └── __main__.py
│   └── mcp_server/             # (예정) MCP 서버
├── build.sh / build.bat / build.ps1
├── requirements.txt
└── README.md

data/ と database/ は容量が大きいため、.gitignore でフォルダごと除外されています。

データセットのダウンロード

3つの方法から1つを選択。結果ファイルは data/ フォルダに train-*-of-*.parquet 形式で配置する必要があります。

1) 変換スクリプトオプション (推奨)

src/convert パッケージが不足している場合は自動的に取得します:

pip install huggingface_hub pyarrow
PYTHONPATH=src python -m convert --download              # 없을 때만 받음
PYTHONPATH=src python -m convert --download --force-download   # 항상 재다운로드

2) huggingface-cli を直接使用

pip install huggingface_hub
huggingface-cli download nvidia/Nemotron-Personas-Korea \
    --repo-type dataset \
    --include "train-*-of-*.parquet" \
    --local-dir ./data

3) git lfs クローン

git lfs install
git clone https://huggingface.co/datasets/nvidia/Nemotron-Personas-Korea
mv Nemotron-Personas-Korea/train-*.parquet ./data/

認証: 非公開またはゲート付きモデルの場合は huggingface-cli login または HF_TOKEN 環境変数が必要です。本データセット(公開時点)は認証なしでもダウンロード可能です。

容量: parquet 9個の合計で約1〜2 GB。

メインテーブル persona

CREATE TABLE persona (
  uuid                       TEXT    PRIMARY KEY,                                  -- 32자 hex 문자열 (대시 없음)
  -- 페르소나 서술 (긴 한국어 텍스트) ----------------------------------------------
  persona                    TEXT    NOT NULL,                                     -- 핵심 1~2문장 요약
  professional_persona       TEXT    NOT NULL,                                     -- 직업/업무 페르소나
  sports_persona             TEXT    NOT NULL,                                     -- 스포츠/운동 페르소나
  arts_persona               TEXT    NOT NULL,                                     -- 예술/문화 페르소나
  travel_persona             TEXT    NOT NULL,                                     -- 여행 페르소나
  culinary_persona           TEXT    NOT NULL,                                     -- 식문화/요리 페르소나
  family_persona             TEXT    NOT NULL,                                     -- 가족 관계 페르소나
  cultural_background        TEXT    NOT NULL,                                     -- 문화·성장 배경 서술
  skills_and_expertise       TEXT    NOT NULL,                                     -- 보유 기술/전문성 서술
  hobbies_and_interests      TEXT    NOT NULL,                                     -- 취미·관심사 서술
  career_goals_and_ambitions TEXT    NOT NULL,                                     -- 향후 목표/포부
  -- 리스트 (JSON 배열로 저장) -----------------------------------------------------
  skills_and_expertise_list  TEXT    NOT NULL CHECK(json_valid(skills_and_expertise_list)),   -- 스킬 키워드 JSON 배열
  hobbies_and_interests_list TEXT    NOT NULL CHECK(json_valid(hobbies_and_interests_list)),  -- 취미 키워드 JSON 배열
  -- 인구통계 ---------------------------------------------------------------------
  sex              TEXT    NOT NULL,                                               -- 성별: 남자 / 여자
  age              INTEGER NOT NULL CHECK(age >= 0),                               -- 나이 (정수)
  marital_status   TEXT    NOT NULL,                                               -- 결혼상태 (4종: 미혼/기혼/이혼/사별 등)
  military_status  TEXT    NOT NULL,                                               -- 병역상태 (군필/해당없음 등)
  family_type      TEXT    NOT NULL,                                               -- 가구 유형 (39종: 1인 가구, 배우자와 자녀 등)
  housing_type     TEXT    NOT NULL,                                               -- 주거 형태 (6종: 아파트, 단독주택 등)
  education_level  TEXT    NOT NULL,                                               -- 최종 학력 (7종: 초등학교 ~ 대학원)
  bachelors_field  TEXT    NOT NULL,                                               -- 학사 전공 분야
  occupation       TEXT    NOT NULL,                                               -- 직업 (자유 텍스트)
  district         TEXT    NOT NULL,                                               -- 시군구 (예: 강남-서초)
  province         TEXT    NOT NULL,                                               -- 시도 (17종)
  country          TEXT    NOT NULL DEFAULT '대한민국'                             -- 국가 (단일값: 대한민국)
) STRICT;

インデックス

名前

カラム

用途

idx_persona_demo

(sex, age)

性別/年齢分布クエリ

idx_persona_region

(province, district)

地域フィルター

idx_persona_edu_occ

(education_level, occupation)

学歴/職業分析

idx_persona_family

(family_type, marital_status)

世帯/結婚分析

カラムの意味

カラム

説明

例

uuid

32文字のhex文字列 (ダッシュなし)。PK

03b4f36a18e6469386d0286dddd513c8

persona

核となる1〜2文の要約

"農村地域で一生農業に従事してきた70代男性で..."

*_persona

領域別の詳細ペルソナ (数文の長さ)

職業/スポーツ/芸術/旅行/食文化/家族

cultural_background

文化・成長背景の記述

skills_and_expertise

保有スキルの記述

skills_and_expertise_list

上記項目のキーワードリスト (JSON配列)

["Excel活用","文書作成"]

hobbies_and_interests

趣味・関心の記述

hobbies_and_interests_list

上記項目のキーワードリスト (JSON配列)

["登山","釣り"]

career_goals_and_ambitions

今後の目標

sex

남자 (男性) / 여자 (女性)

age

整数

marital_status

4種

미혼 (未婚) / 기혼 (既婚) / 이혼 (離婚) / 사별 (死別) 等

military_status

2種

군필 (兵役済み) / 해당없음 (該当なし) 等

family_type

39種

배우자와 자녀 (配偶者と子供), 1인 가구 (単身世帯) 等

housing_type

6種

아파트 (マンション), 단독주택 (戸建て) 等

education_level

7種

초등학교 (小学校) 〜 대학원 (大学院)

bachelors_field

学士専攻分野

occupation

職業 (自由記述)

district

市郡区

강남-서초 (江南-瑞草)

province

市道

서울 (ソウル), 경기 (京畿) 等 17種

country

国

대한민국 (大韓民国) (単一値)

全文検索 — persona_fts (FTS5)

長い韓国語記述カラム10個を外部コンテンツ方式でインデックス化。

CREATE VIRTUAL TABLE persona_fts USING fts5(
  professional_persona,
  sports_persona,
  arts_persona,
  travel_persona,
  culinary_persona,
  family_persona,
  cultural_background,
  skills_and_expertise,
  hobbies_and_interests,
  career_goals_and_ambitions,
  content='persona',
  content_rowid='rowid',
  tokenize='unicode61 remove_diacritics 2',
  prefix='2 3 4'
);

トークナイザー: unicode61 + 2/3/4文字のprefixインデックス。韓国語の助詞処理のため、検索時は 등산* のようなprefixマッチングを推奨。形態素解析が必要な場合は mecab-ko / kiwi ベースのカスタムトークナイザーに置換。

FTS同期: データセットが静的なため、1回 INSERT INTO persona_fts(rowid, ...) SELECT ... でビルド。変更がある場合はトリガーを追加。

AIエージェント活用 (MCPサーバー)

本リポジトリは MCP (Model Context Protocol) サーバー を提供しているため、Claude Desktop、Cursor、ClineなどのMCP互換エージェントがデータを直接検索・サンプリングできます。

実行

PYTHONPATH=src python -m mcp_server          # stdio 서버 시작

エージェント別の登録方法

すべての例において、リポジトリの絶対パス /abs/path/to/korean-people-persona を自身の環境に合わせて変更する必要があります。 仮想環境 (.venv) を作成した場合は、command をvenv内のPythonに指定すると依存関係の競合がありません。 (例: macOS/Linux /abs/path/.venv/bin/python, Windows C:/abs/path/.venv/Scripts/python.exe)

Claude Desktop

設定ファイルの場所:

OS

パス

macOS

~/Library/Application Support/Claude/claude_desktop_config.json

Windows

%APPDATA%\Claude\claude_desktop_config.json

Linux

~/.config/Claude/claude_desktop_config.json

またはアプリ内の Settings → Developer → Edit Config メニュー。

{
  "mcpServers": {
    "korean-persona": {
      "command": "python",
      "args": ["-m", "mcp_server"],
      "env": {
        "PYTHONPATH": "/abs/path/to/korean-people-persona/src",
        "PYTHONIOENCODING": "utf-8"
      }
    }
  }
}

保存後、Claude Desktopを再起動 → チャット画面右下のハンマー(🔨)アイコンから5つのツールが表示されることを確認。

Claude Code (CLI)

CLIコマンドで1行登録:

claude mcp add korean-persona python -m mcp_server \
  -e PYTHONPATH=/abs/path/to/korean-people-persona/src \
  -e PYTHONIOENCODING=utf-8

またはプロジェクトルートの .mcp.json / ユーザー設定 ~/.claude/settings.json に直接記述:

{
  "mcpServers": {
    "korean-persona": {
      "command": "python",
      "args": ["-m", "mcp_server"],
      "env": { "PYTHONPATH": "/abs/path/to/korean-people-persona/src" }
    }
  }
}

確認: claude mcp list → 有効化後 /mcp スラッシュコマンドでツール呼び出し可能。

Cursor

プロジェクト別の .cursor/mcp.json またはユーザーグローバル ~/.cursor/mcp.json:

{
  "mcpServers": {
    "korean-persona": {
      "command": "python",
      "args": ["-m", "mcp_server"],
      "env": { "PYTHONPATH": "/abs/path/to/korean-people-persona/src" }
    }
  }
}

または Settings → MCP → Add new MCP Server UIを使用。Cursor再起動後、@korean-persona で呼び出し。

ChatGPT (Developer Mode / Connectors)

ChatGPTのMCP統合は HTTP/SSEトランスポート ベースで動作します(リモートコネクタ)。本サーバーはstdioサーバーであるため、そのままでは登録できず、HTTPアダプターでラップして公開する必要があります。

  1. mcp SDKのHTTPトランスポートでサーバーを実行:

    PYTHONPATH=src python -m mcp_server --transport sse --port 8765

    (現在、本リポジトリの server.py はstdioのみ呼び出し。HTTP/SSEモードを使うには mcp.run(transport="sse", port=8765) への分岐追加が必要です。)

  2. ngrok / Cloudflare Tunnelなどで外部公開:

    ngrok http 8765
  3. ChatGPT → Settings → Connectors → Developer mode → Add custom connector

    • URL: https://<ngrok>/sse

    • 認証: 必要に応じてBearerトークンヘッダーを追加 (MCP_AUTH_TOKEN)

  4. 新しいチャットの Tools メニューからコネクタを有効にするとツール呼び出しが可能。

セキュリティ上の注意: ChatGPTコネクタはモデル外部にツールを公開するため、公開URLは必ず認証で保護してください。ローカル専用であればstdioベースのClaude Desktop / Cursorの使用を推奨。

Gemini CLI

Google gemini-cli ユーザー設定 ~/.gemini/settings.json:

{
  "mcpServers": {
    "korean-persona": {
      "command": "python",
      "args": ["-m", "mcp_server"],
      "env": { "PYTHONPATH": "/abs/path/to/korean-people-persona/src" },
      "cwd": "/abs/path/to/korean-people-persona"
    }
  }
}

確認: gemini mcp list (またはCLI内の /mcp コマンド) → ツールが自動的に表示。

共通トラブルシューティング

症状

原因 / 解決策

ツールが表示されない

アプリの再起動漏れ。Claude Desktopは完全終了が必要 (トレイアイコンまで)

ModuleNotFoundError: mcp_server

PYTHONPATH が src を指しているか確認 (絶対パス推奨)

文字化け

env.PYTHONIOENCODING=utf-8 を追加 (特にWindows)

python コマンドが見つからない

command を絶対パスに (例: /usr/bin/python3, C:/Python311/python.exe, venvのpython)

権限エラー

Windowsでパスにスペースがある場合 → クォーテーションで囲むかパスを変更

公開ツール

ツール

説明

search_persona(query, fields, filters, limit, full)

FTS5自由テキスト検索 + 人口統計フィルター結合 (BM25ソート)

get_persona(uuid)

uuidで単一ペルソナを全件取得

sample_persona(filters, n, full)

条件付きランダムサンプリング

aggregate(group_by, filters, limit)

人口統計 GROUP BY COUNT

stats()

データセット全体の統計・利用可能カラムの案内

エージェント活用サンプル

1) マーケティングインタビューシミュレーション

"60代以上の女性で登山を楽しむ10人をサンプリングして、新発売の膝サポーターの広告コピーに対する反応をシミュレーションして。"

エージェントは以下のフローで動作:

  1. search_persona(query="등산*", filters={"sex":"여자","age_min":60}, limit=10, full=True)

  2. 各ペルソナをシステムプロンプトに注入 → 広告コピー評価の回答を1人1件ずつ生成

  3. 回答をクラスタリングしてインサイトを要約

2) 地域ベースのキャラクターキャスティング

"釜山影島区に住む50代の自営業者ペルソナを探して、短編小説の主人公として使えるようにまとめて。"

search_persona(
  filters={"province":"부산", "district_like":"%영도%",
           "age_min":50, "age_max":59,
           "occupation_like":"%자영%"},
  limit=5, full=True
)

3) 政策影響分析

"小学校卒業が最終学歴である70代以上の単身世帯が、どの市道に最も多いか分布を分析して。"

aggregate(
  group_by=["province"],
  filters={"education_level":"초등학교", "age_min":70,
           "family_type_like":"%혼자%"},
  limit=20
)

4) 意味ベース検索 + 引用

"農村で育ち、孫がいるペルソナを探して、cultural_backgroundの引用とともに教えて。"

search_persona(
  query='"농촌" AND 손주*',
  fields=["cultural_background", "family_persona"],
  limit=5, full=True
)

5) 合成アンケート調査

"全国の人口分布に比例して100人を層化サンプリングした後、それぞれに『週4日制導入に賛成か』と聞いてみて。"

  1. aggregate(group_by=["province","sex","age"]) → 分布比率を計算

  2. 比率通りに sample_persona を市道×性別×年齢層別に呼び出し

  3. 各ペルソナでLLMに1:1の回答を要求

  4. 結果を集計 → 重み付けを適用した賛否分布を算出

直接使用 (コード)

MCPなしでPythonから直接呼び出し:

import sys; sys.path.insert(0, "src")
from mcp_server import tools

tools.stats()
tools.search_persona(query="용접*", filters={"sex":"남자"}, limit=5)
tools.sample_persona(filters={"province":"제주"}, n=3, full=True)

SQL直接クエリ

-- 1) 등산을 좋아하고 트로트 관련 언급이 있는 60대 여성
SELECT p.uuid, p.age, p.province, p.occupation
FROM persona_fts f
JOIN persona p ON p.rowid = f.rowid
WHERE persona_fts MATCH '등산* AND 트로트*'
  AND p.sex = '여자' AND p.age BETWEEN 60 AND 79
ORDER BY bm25(persona_fts) LIMIT 20;

-- 2) 특정 컬럼 검색 + 스니펫
SELECT p.uuid, snippet(persona_fts, 7, '<b>', '</b>', '...', 10) AS hit
FROM persona_fts f JOIN persona p ON p.rowid = f.rowid
WHERE f.skills_and_expertise MATCH '용접*' LIMIT 10;

-- 3) JSON 리스트 펼치기
SELECT p.uuid, j.value AS hobby
FROM persona p, json_each(p.hobbies_and_interests_list) j
WHERE j.value LIKE '%낚시%' LIMIT 10;

-- 4) 인구통계 분포
SELECT province, sex, COUNT(*) cnt
FROM persona GROUP BY province, sex ORDER BY cnt DESC;

PRAGMA設定 (ロード/運用)

PRAGMA journal_mode = WAL;
PRAGMA synchronous  = NORMAL;
PRAGMA temp_store   = MEMORY;
PRAGMA cache_size   = -262144;   -- 256MB

ビルド手順

1行ビルド (推奨)

OS別のラッパースクリプトが仮想環境作成 → 依存関係インストール → ダウンロード → 変換まで自動実行。

プラットフォーム

コマンド

Linux / macOS

chmod +x build.sh && ./build.sh

Windows (cmd)

build.bat

Windows (PowerShell)

.\build.ps1

再ダウンロードオプションはすべて同様に渡す:

./build.sh --force-download
build.bat --force-download
.\build.ps1 --force-download

PowerShellで実行ポリシーエラーが出る場合: PowerShell -ExecutionPolicy Bypass -File .\build.ps1

手動実行

python -m venv .venv
# Linux/macOS: source .venv/bin/activate
# Windows:     .venv\Scripts\activate
pip install -r requirements.txt
PYTHONPATH=src python -m convert [--download] [--force-download]

内部処理:

  1. (オプション) --download 時、parquetの不足分をHuggingFaceから取得

  2. persona.db を新規作成 (既存ファイル削除)

  3. PRAGMA設定 + スキーマ/インデックス作成

  4. 9つのparquetを順次読み込み、行単位で正規化後に executemany でロード (トランザクション単位: ファイル1個)

  5. *_list カラムは ast.literal_eval → json.dumps(ensure_ascii=False) に変換

  6. FTS5仮想テーブル作成 + INSERT ... SELECT で1回ビルド

  7. INSERT INTO persona_fts(persona_fts) VALUES('optimize') 後に ANALYZE

  8. WALチェックポイント後に終了

ディスク容量の推定

  • メインテーブル + インデックス: 約 1.5 ~ 2.5 GB

  • FTS5 prefix含む: 追加 1 ~ 3 GB

  • 合計 約 3 ~ 5 GB 予想 (実際のロード後に更新)。

Related MCP Connectors

Related MCP Servers