实训2—数据集的预处理

为了更好的训练出大模型,我们结合学校提供api生成了15832条训练数据,示例如下:

 {
    "question": "西方艺术史中的巴洛克风格如何影响了现代插花设计?",
    "answer": "巴洛克艺术强调动感、戏剧性和华丽装饰的特点深刻影响了插花。现代巴洛克风格插花常使用大朵花卉如牡丹、大丽花搭配曲线枝条(如龙柳),通过不对称构图和强烈色彩对比(如深红配金色)营造奢华感。典型技巧包括使用S形线条(称'霍格思曲线')和分层堆积手法,在婚礼花艺和酒店装饰中应用广泛。",
    "difficulty": "中级",
    "category": "艺术理论",
    "subcategory": "艺术史对插花的影响",
    "timestamp": "2025-04-26 22:35:20",
    "model": "deepseek-chat",
    "api_type": "deepseek"
  }

接下来对生成数据进行预处理:

一,数据清洗阶段

1.1 重复项检测与处理

基于question字段进行重复检测:


# 基于question字段检测重复
duplicates = df[df.duplicated(subset=['question'], keep=False)]
if len(duplicates) > 0:
    print(f"发现{len(duplicates)}条重复问题,需人工核查:")
    display(duplicates.sort_values('question'))
  • 处理策略:保留最新时间戳的记录,若时间相同则保留较长答案

1.2 缺失值处理

处理逻辑如下所示:

对于难度字段填充:使用预定义的"中级"作为默认值。 

对于类别字段填充:按subcategory分组后取众数,确保同一子类别的样本具有一致的分类。


missing_difficulty = df[df['difficulty'].isnull()]
missing_category = df[df['category'].isnull()]


df['difficulty'].fillna('中级', inplace=True)  
df['category'] = df.groupby('subcategory')['category'].transform(
    lambda x: x.fillna(x.mode()[0]))

1.3 术语标准化

作用如下:

  1. 统一艺术术语的不同表述形式
  2. 建立中英文专业术语对照体系
  3. 提升后续模型训练的术语一致性

示例代码如下:

term_map = {
    'Art Deco': '装饰艺术',
    '新艺术运动': 'Art Nouveau',
    '霍格思曲线': 'Hogarth曲线'
}
df['answer'] = df['answer'].replace(term_map, regex=True)

二、数据格式转换

2.1 构建训练所需的JSONL格式

def convert_to_jsonl(row):
    return {
        "instruction": "作为艺术史与插花专家,请用专业术语回答下列问题。答案需包含:历史背景、核心技法、现代应用案例。",
        "input": f"[难度:{row['difficulty']}][类别:{row['category']}-{row['subcategory']}]\n{row['question']}",
        "output": row['answer']
    }

formatted_data = df.apply(convert_to_jsonl, axis=1).tolist()

字段设计

  • instruction:明确回答要求(角色定位+内容规范)
  • input:结构化输入(元数据+原始问题)
  • output:标准化后的答案文本

2.2 保存中间文件

import json
with open('all_data.jsonl', 'w', encoding='utf-8') as f:
    for item in formatted_data:
        f.write(json.dumps(item, ensure_ascii=False) + '\n')

技术细节

  • JSONL格式:每行独立JSON对象,适合流式读取
  • ensure_ascii=False:保留中文原样存储
  • 文件编码统一为UTF-8,避免乱码问题

三、数据划分策略

3.1 分层抽样准备

from sklearn.model_selection import StratifiedShuffleSplit


df['stratify_key'] = df['difficulty'] + '_' + df['subcategory']


dist = df.groupby('stratify_key').size() / len(df)
print("原始数据分布:\n", dist)

核心原理

  • 分层键 = 难度级别 + 子类别(如"高级_巴洛克建筑")
  • 确保划分后的数据在各个维度保持原始比例

3.2 训练集-验证集-测试集划分


split1 = StratifiedShuffleSplit(n_splits=1, test_size=0.2, random_state=42)
for train_idx, temp_idx in split1.split(df, df['stratify_key']):
    train_set = df.iloc[train_idx]
    temp_set = df.iloc[temp_idx]

split2 = StratifiedShuffleSplit(n_splits=1, test_size=0.5, random_state=42)
for val_idx, test_idx in split2.split(temp_set, temp_set['stratify_key']):
    val_set = temp_set.iloc[val_idx]
    test_set = temp_set.iloc[test_idx]

划分过程

  1. 第一次分割:获得80%训练集 + 20%剩余
  2. 第二次分割:将20%剩余平分(各10%)
  3. 最终比例:80%训练集 / 10%验证集 / 10%测试集

关键参数

  • random_state=42:确保可重复性
  • n_splits=1:单次划分即可满足需求
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值