Persona Survey -- 虚拟人格问卷生成系统
> 输入任意问卷 -> 生成N份虚拟人格答卷 -> 输出带质量报告的Excel
1. 能做什么
| 能力 | 说明 |
|---|---|
| 问卷输入 | 问卷星URL直接抓取 / Excel-CSV转换 / 手写YAML |
| 人格生成 | 内置2套人群预设(老年人/普通成人),支持自定义维度和关键词映射 |
| 答卷生成 | 规则驱动+高斯采样,秒级出100份,零LLM依赖,自然分布有区分度 |
| Excel输出 | 4个sheet: 带文本答案 / 纯数字矩阵 / 人格画像 / 质量报告 |
| 质量验证 | 注意力检查一致性 / 趋同检测 / 维度梯度验证 / 分布统计 |
2. 快速开始
方式A: 问卷星URL直接抓取
# 1. 抓取问卷结构
python scripts/scrape_wjx.py "https://www.wjx.cn/vm/XXXX.aspx" --out surveys/my_survey.yaml
# 2. 生成100份答卷
python scripts/run_survey.py --survey surveys/my_survey.yaml --count 100 --out output/
方式B: Excel/CSV转换
# 1. 准备CSV (列: 题号,题型,题干,选项A,选项B,...)
# 2. 转换
python scripts/survey_from_excel.py input.csv --out surveys/my_survey.yaml --title "问卷标题"
# 3. 生成
python scripts/run_survey.py --survey surveys/my_survey.yaml --count 100 --population general_chinese --out output/
方式C: 手写YAML
参考 surveys/template_product_survey.yaml 模板,或 surveys/wjx_elderly_digital_care.yaml 完整示例。
输出
output/
personas.json # N份人格画像
results_raw.json # 逐题答案(raw)
results_summary.csv # 汇总CSV(人口统计+逐题文本答案,Excel可直接打开)
问卷结果_N份.xlsx # 4-sheet Excel (核心交付物)
differentiation_report.md # 区分度报告(注意力检查/趋同检测/维度梯度/判定)
3. Excel 输出结构 (4个Sheet)
| Sheet | 用途 | 结构 |
|---|---|---|
| 问卷数据 | 人可读 | 每行1份答卷,每题列格式"3.一般"(选项ID+文本) |
| 数字矩阵 | 统计软件(SPSS/R) | 纯数字,choice题=选项ID(1,2,3...),likert题=1-5分 |
| 人格画像 | 标签数据 | 每行1个persona,含性别/年龄/学历/各维度1-5值 |
| 质量报告 | 验证 | 逐题分布/趋同检测/注意力检查/维度梯度验证 |
4. 核心设计: 规则驱动引擎
为什么不用LLM?
实测结论 (2026-08-20):
- qwen2.5:3b: 27次调用1m44s,格式遵守率需few-shot强制,mode collapse严重(大量打4分)
- qwen2.5:7b: 45次调用5m30s,区分度4/9(改善但仍不足),Likert全打4分
- 规则驱动: 100份<1秒,区分度满分(平均4.9/5唯一值),零趋同,维度梯度完美
规则引擎原理:
1. 问卷YAML定义 persona_config -> 人格维度 + keyword_map(关键词->维度)
2. 每题文本与关键词匹配 -> 计算各维度权重
3. persona的维度值(1-5) * 权重 -> 期望base值
4. 高斯权重采样(base附近概率最高) -> 自然分布
5. 负面词检测(焦虑/担心/隐私泄露等) -> 自动反转方向
人群预设
| 预设 | 维度 | 适用 |
|---|---|---|
elderly_chinese |
digital_skill, social, loneliness, risk_aversion, family_support, health_level, tech_attitude | 老年人问卷(60+) |
general_chinese |
tech_savviness, price_sensitivity, openness, risk_aversion, social_active, brand_loyalty | 普通成人问卷(18-65) |
| 自定义 | 在YAML的persona_config中定义 |
任意人群 |
自定义人群示例
persona_config:
population: custom
age_range: [22, 35]
gender_ratio: [0.45, 0.55]
dimensions:
- {name: work_pressure, label: "工作压力", mean: 3.5, std: 1.0}
- {name: job_satisfaction, label: "工作满意度", mean: 3.0, std: 1.0}
- {name: growth_desire, label: "成长欲望", mean: 3.5, std: 1.0}
keyword_map:
work_pressure: ["加班","压力","疲惫","焦虑","KPI","deadline"]
job_satisfaction: ["满意","开心","喜欢","值得","成就感"]
growth_desire: ["晋升","学习","培训","成长","发展","未来"]
personalities: ["卷王","躺平族","稳定型","进取型"]
5. 脚本清单
| 脚本 | 用途 | 依赖 |
|---|---|---|
scripts/run_survey.py |
核心引擎: 加载问卷->生成persona->采样答案->输出5个文件(Excel/JSON/CSV/区分度报告) | yaml, openpyxl |
scripts/scrape_wjx.py |
问卷星URL->YAML (curl抓取+正则解析) | yaml, curl(系统) |
scripts/survey_from_excel.py |
Excel/CSV->YAML (列式转换) | yaml, openpyxl(Excel) |
scripts/survey_runner.py |
LLM模式(备用): 逐题调用Ollama/OpenAI生成 | yaml, requests(可选) |
scripts/deprecated/ |
已弃用旧版脚本(v1规则引擎、LLM一代),仅历史参考 | — |
6. 参数详解
run_survey.py 参数
--survey PATH 问卷YAML路径 (必填)
--count N 生成份数 (默认50)
--out DIR 输出目录 (默认./output)
--seed N 随机种子 (默认42, 保证可复现)
--population KEY 覆盖YAML中的人群预设 (elderly_chinese/general_chinese/custom)
scrape_wjx.py 参数
URL 问卷星填写链接 (必填, 形如 https://www.wjx.cn/vm/XXXX.aspx)
--out PATH 输出YAML路径 (默认./survey.yaml)
--title TEXT 问卷标题覆盖
survey_from_excel.py 参数
INPUT Excel或CSV文件路径 (必填)
--out PATH 输出YAML路径 (默认./survey.yaml)
--title TEXT 问卷标题 (默认从文件名推断)
--sheet NAME Excel工作表名 (默认第一个)
CSV格式要求
题号,题型,题干,选项A,选项B,选项C,选项D,选项E
q1,选择,性别,男,女,,,
q2,选择,年龄段,18-25,26-35,36-45,46-55,56-65
q3,量表,我对新技术产品很感兴趣,,,,,
q4,量表,我担心使用新技术会泄露隐私,,,,,
- 题型:
选择(或单选) /量表(或likert) /填空(或open) - 选项列为空的行自动识别为量表题(1-5分)
- 最多5个选项(A-E)
7. 问卷YAML格式
title: "问卷标题"
persona_config:
population: elderly_chinese # 或 general_chinese / custom
questions:
# 单选题
- id: q1
type: single_choice
prompt: "您的性别"
options:
- {id: q1_1, label: "男"}
- {id: q1_2, label: "女"}
# Likert量表题
- id: q6
type: likert
prompt: "我能熟练使用智能手机"
min_value: 1
max_value: 5
labels: ["完全不符合","不太符合","一般","比较符合","完全符合"]
# 填空题
- id: q99
type: open
prompt: "您对智慧养老有什么建议"
注意力检查题
在问卷YAML中用 attention_check 标记完全相同的两题:
questions:
- id: q6
type: likert
prompt: "我能熟练使用智能手机进行日常操作"
attention_check: q81
- id: q81
type: likert
prompt: "我能熟练使用智能手机进行日常操作"
attention_check: q6
引擎会保证这两题答案完全一致。
8. 质量验证指标
自动验证项
| 指标 | 说明 | 合格标准 |
|---|---|---|
| 注意力检查 | 相同题答案一致性 | 100% |
| 趋同检测 | 100份答案唯一的题数 | <15%为优 |
| 维度梯度 | persona维度值 vs 相关题均值 | 单调递增/递减 |
| 分布合理性 | 全问卷答案分布 | 偏正态,无极端集中 |
| 人口统计一致 | Q1性别/Q2年龄/Q3学历 vs persona属性 | 100% |
区分度报告示例
## 注意力检查
- q6 = q81: 100/100 一致 (100%) ✓
## 趋同检测
- 趋同题数: 0/81 (0%) ✓
- 平均每题唯一值: 4.9/5
## 维度梯度验证 (digital_skill vs 技术能力题)
- DS=1: avg=1.50 (n=18)
- DS=2: avg=2.30 (n=22)
- DS=3: avg=3.10 (n=25)
- DS=4: avg=4.05 (n=20)
- DS=5: avg=4.75 (n=15) ✓ 完美递增
9. 注意事项
问卷星抓取
- 仅支持填写链接 (形如
https://www.wjx.cn/vm/XXXX.aspx),不支持后台管理链接 - 页面结构变化时可能需要更新正则,见
scrape_wjx.py的extract_questions() - 抓取的是题目结构,不会提交真实答案到问卷星 (避免ToS违规和数据污染)
数据用途声明
- 生成的数据为模拟数据,用于问卷设计验证、统计分析练习、原型演示
- 不适用于冒充真实调查数据发表研究或做决策依据
- 使用前应在报告中注明"模拟数据"
硬件要求
- 规则驱动模式: 任意配置,<1秒完成100份
- LLM模式(备用): 需要Ollama(qwen2.5:3b/7b)或OpenAI兼容API,RAM>8GB
10. 扩展方向
| 方向 | 现状 | 建议 |
|---|---|---|
| 更多人群预设 | 老年人+普通成人 | 添加学生/职场白领/农村居民等 |
| 维度关联 | _apply_correlations 待实现 |
维度间相关性(如digital_skill与tech_attitude正相关) |
| 多语言 | 中文 | 添加英文关键词映射 |
| LLM增强 | 备用模式(survey_runner.py) | 对开放题用LLM生成自然语言回答 |
| 问卷星提交 | 不支持(ToS风险) | 如需提交,用户手动操作 |
| SPSS导出 | 数字矩阵sheet可导入 | 添加.sav格式原生导出 |
版本历史
| 版本 | 日期 | 变更 |
|---|---|---|
| 2.1.0 | 2026-08-21 | run_survey.py 补齐 results_summary.csv + differentiation_report.md 生成(此前文档承诺但未实现);弃用脚本移入 scripts/deprecated/;补 EXPERIENCE.md |
| 2.0.0 | 2026-08-20 | 通用化重构:任意问卷+任意人群规则引擎,取代 v1 硬编码引擎与 LLM 生成方案 |
| 1.x | 2026-08-19 | v1 硬编码老年问卷引擎 + LLM 批量生成试验(已弃用,见 scripts/deprecated/) |