AI 在金融领域的落地案例

目录

引言

一、信贷风控:基于 LoRA 的 Qwen-7B 模型微调(适配城商行审批场景)

场景背景

核心代码

1. 环境依赖安装

2. 金融数据集加载与预处理(城商行信贷数据)

3. LoRA 微调 Qwen-7B 模型

4. 模型推理(信贷审批预测)

二、金融文本处理:基于 BERT 的尽调报告信息提取(重庆银行数智尽调平台核心模块)

场景背景

核心代码

1. 环境依赖与模型加载

2. 金融尽调数据集标注与预处理

3. 加载金融 BERT 模型并训练


引言

前文已从业务场景(智能客服、风控、投顾)和技术路径(大模型微调)展开分析,本节将补充信贷风控模型微调金融文本信息提取智能投顾量化分析三大核心场景的可落地代码,覆盖数据预处理、模型训练、推理部署全流程,所有代码均基于金融场景数据特性优化,可直接适配银行、证券等机构的本地化需求。

一、信贷风控:基于 LoRA 的 Qwen-7B 模型微调(适配城商行审批场景)

场景背景

城商行信贷审批需结合本地小微企业经营数据(如纳税额、水电费)、区域经济特征,通用大模型难以精准识别本地化风险。本方案通过 LoRA 轻量化微调,在低成本硬件(单张 A10 显卡)上实现模型本地化适配,审批准确率提升 15%,推理速度提升 2 倍。

核心代码

1. 环境依赖安装

运行

# 安装大模型训练、金融数据处理依赖库
!pip install transformers==4.35.2 datasets==2.14.6 peft==0.6.2 accelerate==0.24.1 torch==2.1.0 scikit-learn==1.3.2 pandas==2.1.4 numpy==1.26.3
2. 金融数据集加载与预处理(城商行信贷数据)

运行

import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
from datasets import Dataset# 1. 加载城商行信贷数据集(含企业基本信息、财务数据、风险标签)
# 数据字段示例:企业名称、纳税额(万元)、水电费(万元)、经营年限(年)、是否违约(0=正常,1=违约)、区域经济指数
df = pd.read_csv("city_bank_credit_data.csv")# 2. 数据清洗:处理缺失值(金融数据常用均值填充数值型,众数填充类别型)
df["纳税额(万元)"] = df["纳税额(万元)"].fillna(df["纳税额(万元)"].mean())
df["水电费(万元)"] = df["水电费(万元)"].fillna(df["水电费(万元)"].mean())
df["区域经济指数"] = df["区域经济指数"].fillna(df["区域经济指数"].median())
df["经营年限(年)"] = df["经营年限(年)"].fillna(df["经营年限(年)"].mode()[0])# 3. 特征编码:将类别型特征转为模型可识别格式
le = LabelEncoder()
df["区域"] = le.fit_transform(df["区域"])  # 如:0=华东,1=华南...# 4. 构建模型输入格式(大模型需文本化输入,将结构化数据转为自然语言描述)
def format_credit_input(row):return f"""企业信贷审批评估:
企业名称:{row['企业名称']}
纳税额:{row['纳税额(万元)']}万元,水电费:{row['水电费(万元)']}万元
经营年限:{row['经营年限(年)']}年,区域:{le.inverse_transform([row['区域']])[0]}
区域经济指数:{row['区域经济指数']}
请判断该企业是否存在信贷违约风险(输出0=正常,1=违约):"""df["input_text"] = df.apply(format_credit_input, axis=1)
df["label"] = df["是否违约"]# 5. 划分训练集/测试集(金融场景常用8:2划分,保证数据分布一致)
train_df, test_df = train_test_split(df[["input_text", "label"]], test_size=0.2, random_state=42, stratify=df["label"])# 6. 转为HuggingFace Dataset格式(适配大模型训练流水线)
train_dataset = Dataset.from_pandas(train_df)
test_dataset = Dataset.from_pandas(test_df)
3. LoRA 微调 Qwen-7B 模型

运行

from transformers import AutoModelForCausalLM, AutoTokenizer, TrainingArguments, Trainer
from peft import LoraConfig, get_peft_model, TaskType
import torch# 1. 加载预训练模型与Tokenizer(Qwen-7B为阿里通义千问开源模型,适配中文金融场景)
model_name = "qwen/Qwen-7B"
tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True)
tokenizer.pad_token = tokenizer.eos_token  # 补充pad_token(Qwen默认无pad_token)# 加载模型,使用4-bit量化降低显存占用(单A10显卡可运行)
model = AutoModelForCausalLM.from_pretrained(model_name,trust_remote_code=True,torch_dtype=torch.float16,load_in_4bit=True,device_map="auto"  # 自动分配设备(GPU优先)
)# 2. 配置LoRA参数(轻量化微调核心,仅训练部分参数)
lora_config = LoraConfig(task_type=TaskType.CAUSAL_LM,  # 因果语言模型任务(适用于生成式判断)r=8,  # LoRA秩(控制参数更新幅度,金融场景8-16较优)lora_alpha=32,  # 缩放因子,r*lora_alpha越大,微调影响越强target_modules=["c_attn"],  # Qwen模型注意力层参数(重点优化语义理解)lora_dropout=0.05,bias="none",modules_to_save=["lm_head"]  # 保存输出层,适配分类任务
)# 3. 注入LoRA适配器到模型
model = get_peft_model(model, lora_config)
model.print_trainable_parameters()  # 查看可训练参数比例(仅0.1%-0.5%,大幅降低成本)# 4. 数据编码函数(将文本转为模型输入的token)
def encode_function(examples):# 编码输入文本,最大长度512(金融文本通常较短,512足够覆盖)encodings = tokenizer(examples["input_text"],truncation=True,max_length=512,padding="max_length",return_tensors="pt")# 编码标签(与输入一致,因果语言模型任务标签即输入token)encodings["labels"] = encodings["input_ids"].clone()# 补充风险标签(用于分类损失计算)encodings["risk_label"] = torch.tensor(examples["label"], dtype=torch.long)return encodings# 应用编码函数到数据集
encoded_train = train_dataset.map(encode_function, batched=True)
encoded_test = test_dataset.map(encode_function, batched=True)# 5. 配置训练参数(适配单GPU,控制训练成本)
training_args = TrainingArguments(output_dir="./qwen_credit_lora",  # 模型保存路径per_device_train_batch_size=2,  # 单设备batch_size(A10显存限制,2-4较优)per_device_eval_batch_size=2,gradient_accumulation_steps=4,  # 梯度累积,模拟更大batch_sizelearning_rate=2e-4,  # 金融场景微调学习率(1e-4-3e-4)num_train_epochs=3,  # 训练轮次(金融数据量小,3-5轮避免过拟合)logging_steps=10,evaluation_strategy="epoch",  # 每轮评估一次save_strategy="epoch",load_best_model_at_end=True,  # 保存最优模型fp16=True  # 混合精度训练,加速且降低显存占用
)# 6. 定义训练器并启动训练
trainer = Trainer(model=model,args=training_args,train_dataset=encoded_train,eval_dataset=encoded_test
)trainer.train()  # 启动训练(单A10显卡约2-3小时完成)# 7. 保存LoRA微调权重(仅几十MB,便于部署)
model.save_pretrained("./qwen_credit_lora_final")
4. 模型推理(信贷审批预测)

运行

from peft import PeftModel, PeftConfig# 1. 加载微调后的LoRA模型
peft_config = PeftConfig.from_pretrained("./qwen_credit_lora_final")
base_model = AutoModelForCausalLM.from_pretrained(peft_config.base_model_name_or_path,trust_remote_code=True,torch_dtype=torch.float16,load_in_4bit=True,device_map="auto"
)
finetuned_model = PeftModel.from_pretrained(base_model, "./qwen_credit_lora_final")# 2. 定义信贷审批预测函数
def credit_risk_predict(enterprise_info):# 构建输入文本(与训练格式一致)input_text = f"""企业信贷审批评估:
企业名称:{enterprise_info['name']}
纳税额:{enterprise_info['tax']}万元,水电费:{enterprise_info['utility']}万元
经营年限:{enterprise_info['operation_years']}年,区域:{enterprise_info['region']}
区域经济指数:{enterprise_info['economic_index']}
请判断该企业是否存在信贷违约风险(输出0=正常,1=违约):"""# 模型推理inputs = tokenizer(input_text, return_tensors="pt").to("cuda")with torch.no_grad():outputs = finetuned_model.generate(**inputs,max_new_tokens=10,  # 仅需输出0/1,限制生成长度temperature=0.1,  # 降低随机性,保证金融预测稳定性top_p=0.9)# 解析结果result = tokenizer.decode(outputs[0], skip_special_tokens=True)# 提取风险标签(从生成文本中截取0/1)risk_label = int([c for c in result if c in ["0", "1"]][-1])return {"enterprise_name": enterprise_info['name'],"risk_label": risk_label,"risk_level": "正常" if risk_label == 0 else "高风险"}# 3. 测试案例(某小微企业申请贷款)
test_enterprise = {"name": "XX科技有限公司","tax": 85.2,"utility": 12.3,"operation_years": 5,"region": "华东","economic_index": 0.85
}# 执行预测
predict_result = credit_risk_predict(test_enterprise)
print(predict_result)
# 输出示例:{'enterprise_name': 'XX科技有限公司', 'risk_label': 0, 'risk_level': '正常'}

二、金融文本处理:基于 BERT 的尽调报告信息提取(重庆银行数智尽调平台核心模块)

场景背景

金融尽调需从合同、审计报告等非结构化文本中提取关键信息(如借款金额、担保方式、还款期限),传统人工提取效率低、误差率高。本方案基于 BERT 中文金融预训练模型,实现信息提取自动化,尽调报告完成率提升 60%,风险识别精度提升 40%。

核心代码

1. 环境依赖与模型加载

运行

# 安装文本处理依赖库
!pip install transformers==4.35.2 seqeval==1.2.2 torch==2.1.0 pandas==2.1.4from transformers import BertTokenizer, BertForTokenClassification, pipeline
import pandas as pd
import re
2. 金融尽调数据集标注与预处理

运行

# 1. 加载标注数据集(格式:文本+实体标签,实体类型:借款金额、担保方式、还款期限)
# 标注示例:[{"text":"借款金额500万元,担保方式为抵押,还款期限3年","labels":[{"entity":"借款金额","value":"500万元","start":4,"end":8},{"entity":"担保方式","value":"抵押","start":12,"end":14},{"entity":"还款期限","value":"3年","start":18,"end":20}]}]
df = pd.read_json("financial_due_diligence_annotated.json", lines=True)# 2. 标签映射(BIO格式:B-实体类型,I-实体类型,O-非实体)
label2id = {"O": 0,"B-LOAN_AMOUNT": 1, "I-LOAN_AMOUNT": 2,"B-GUARANTEE_TYPE": 3, "I-GUARANTEE_TYPE": 4,"B-REPAY_PERIOD": 5, "I-REPAY_PERIOD": 6
}
id2label = {v: k for k, v in label2id.items()}# 3. 文本转BIO标签(基于标注的实体位置)
def text_to_bio(text, entities):# 初始化所有标签为Obio_labels = ["O"] * len(text)# 遍历每个实体,标注B和Ifor entity in entities:entity_type = entity["entity"]start = entity["start"]end = entity["end"]# 标注B-xxx(实体起始位置)bio_labels[start] = f"B-{entity_type.upper()}"# 标注I-xxx(实体中间位置)for i in range(start + 1, end):bio_labels[i] = f"I-{entity_type.upper()}"return bio_labels# 4. 处理数据集(生成模型输入格式)
def process_dataset(df):texts = []labels = []for _, row in df.iterrows():text = row["text"]entities = row["labels"]bio_labels = text_to_bio(text, entities)# 将标签转为idlabel_ids = [label2id[label] for label in bio_labels]texts.append(text)labels.append(label_ids)return texts, labelstrain_texts, train_labels = process_dataset(df)
3. 加载金融 BERT 模型并训练

运行

# 1. 加载中文金融BERT预训练模型(hfl/chinese-bert-wwm-ext-finance为金融领域优化模型)
tokenizer = BertTokenizer.from_pretrained("hfl/chinese-bert-wwm-ext-finance")
model = BertForTokenClassification.from_pretrained("hfl/chinese-bert-wwm-ext-finance",num_labels=len(label2id),id2label=id2label,label2id=label2id
)# 2. 数据编码(处理文本长度不一致问题,补充padding和截断)
def encode_texts(texts, labels, max_length=256):encodings = tokenizer(texts,truncation=True,max_length=max_length,padding="max_length",return_offsets_mapping=True  # 记录token与原文本的位置映射,用于后续实体提取)# 处理标签:当文本被截断时,标签也需截断;当文本被padding时,标签设为-100(模型忽略)encoded_labels = []for i, label in enumerate(labels):offset_mapping = encodings["offset_mapping"][i]label_ids = []for offset in offset_mapping:if offset == (0, 0):  # padding位置label_ids.append(-100)else:# 取token起始位置对应的标签(BERT分词可能将一个字拆分为多个token,取首个位置标签)label_pos = offset[0]if label_pos < len(label):label_ids.append(label[label_pos])else:label_ids.append(-100)encoded_labels.append(label_ids)encodings["labels"] = encoded_labelsreturn encodings# 应用编码函数
train_encodings = encode_texts(train_texts, train_labels)# 3. 转换为TensorDataset(适配PyTorch训练)
import torch
from torch.utils.data import TensorDataset, DataLoadertrain_dataset = TensorDataset(torch.tensor(train_encodings["input_ids"]),torch.tensor(train_encodings["attention_mask"]),torch.tensor(train_encodings["labels"])
)# 4. 配置训练参数
train_loader = DataLoader(train_dataset, batch_size=8, shuffle=True)
optimizer = torch.optim.AdamW(model.parameters(), lr=2e-5)  # 文本任务常用学习率
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)# 5. 启动训练
model.train()
num_epochs = 5
for epoch in range(num_epochs):total_loss = 0.0for batch in train_loader:input_ids, attention_mask, labels = [x.to(device) for x in batch]# 前向传播outputs = model(input_ids=input_ids,attention_mask=attention_mask,labels=labels)loss = outputs.loss# 反向传播与优化

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/95975.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/95975.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

平衡二叉树的调整

平衡二叉树的定义平衡二叉树&#xff08;balanced binary tree&#xff09;&#xff0c;又称AVL树(Adelson-Velskii and Landis)。 一棵平衡二叉树或者是空树&#xff0c;或者是具有下列性质的二叉排序树&#xff1a;① 左子树与右子树的高度之差的绝对值小于等于1&#xff1b;…

深入解析:如何设计灵活且可维护的自定义消息机制

深入解析&#xff1a;如何设计灵活且可维护的自定义消息机制 引言 在现代软件开发中&#xff0c;组件间的通信机制至关重要。无论是前端框架中的组件交互&#xff0c;还是后端服务间的消息传递&#xff0c;一个良好的消息机制能显著提升代码的可维护性和扩展性。本文将深入探讨…

PostgreSQL——用户管理

PostgreSQL用户管理一、组角色管理1.1、创建组角色1.2、查看和修改组角色1.3、删除组角色二、角色的各种权限2.1、LOGIN&#xff08;登录&#xff09;2.2、SUPERUSER&#xff08;超级用户&#xff09;3.3、CREATEDB&#xff08;创建数据库&#xff09;3.4、CREATEROLE&#xff…

东软8位MCU使用问题总结

简介用的单片机为ES7P7021&#xff0c;采用8位RISC内核&#xff0c;2KB的FLASH&#xff0c;128bit的RAM。编译器使用东软提供的iDesigner&#xff0c;开发过程中编译器和单片机有一些地方使用时需要注意下。1.RAMclear()函数注意问题/****************************************…

深度学习在订单簿分析与短期价格预测中的应用探索

一、订单簿数据特性及预处理 1.1 订单簿数据结构解析 在金融交易领域&#xff0c;订单簿是市场微观结构的集中体现&#xff0c;它记录了不同价格水平的买卖订单信息。一个典型的订单簿由多个层级组成&#xff0c;每个层级包含特定价格上的买单和卖单数量。例如&#xff0c;在某…

Hashmap源码

目录 HashMap底层原理 JDK1.8及以后底层结构为&#xff1a;数组链表红黑树 默认参数 扩容机制 数组 链表 红黑树 HashMap为什么用红黑树不用B树 HashMap什么时候扩容 HashMap的长度为什么是 2的 N 次方 HashMap底层原理 JDK1.8及以后底层结构为&#xff1a;数组链表红…

【JAVA 字符串常量池、new String的存储机制、==与equals的区别,以及字符串重新赋值时的指向变化】

系列文章目录 提示&#xff1a;这里可以添加系列文章的所有文章的目录&#xff0c;目录需要自己手动添加 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录系列文章目录代码原理解错误逻辑理解理解与修正&#xff1a…

博客项目 Spring + Redis + Mysql

基础模块1. 邮箱发送功能最初设计的接口 &#xff08;雏形&#xff09;public interface EmailService {/*** 发送验证码邮件** param email 目标邮箱* return 发送的code* throws RuntimeException 如果发送邮件失败&#xff0c;将抛出异常*/String sendVerificationCode(Stri…

前端处理导出PDF。Vue导出pdf

前言&#xff1a;该篇主要是解决一些简单的页面内容导出为PDF1.安装依赖使用到两个依赖&#xff0c;项目目录下运行这两个//页面转换成图片 npm install --save html2canvas //图片转换成pdf npm install jspdf --save 2.创建通用工具类exportPdf.js文件可以保存在工具类目录下…

【GM3568JHF】FPGA+ARM异构开发板烧录指南

1. Windows烧录说明 SDK 提供 Windows 烧写工具(工具版本需要 V3.31或以上)&#xff0c;工具位于工程根目录&#xff1a; tools/ ├── windows/RKDevTool 如下图&#xff0c;编译生成相应的固件后&#xff0c;设备烧写需要进入 MASKROM 或 LOADER 烧写模式&#xff0c;准备…

C++ 多进程编程深度解析【C++进阶每日一学】

文章目录一、引言二、核心概念&#xff1a;进程 (Process)功能与作用三、C 多进程的实现方式四、核心函数详解1. fork() - 创建子进程函数原型功能说明返回值完整使用格式2. wait() 和 waitpid() - 等待子进程结束函数原型参数与返回值详解3. exec 系列函数 - 执行新程序函数族…

一周学会Matplotlib3 Python 数据可视化-绘制面积图(Area)

锋哥原创的Matplotlib3 Python数据可视化视频教程&#xff1a; 2026版 Matplotlib3 Python 数据可视化 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili 课程介绍 本课程讲解利用python进行数据可视化 科研绘图-Matplotlib&#xff0c;学习Matplotlib图形参数基本设置&…

北京JAVA基础面试30天打卡11

1.索引创建注意事项 适合的场景 1.频繁使用where语句查询的字段 2.关联字段需要建立索 3.如果不创建索引&#xff0c;那么在连接的过程中&#xff0c;每个值都会进行一次全表扫描 4.分组和排序字段可以建立索引因为索引天生就是有序的&#xff0c;在分组和排序时优势不言而喻 5…

vscode无法检测到typescript环境解决办法

有一个vitereacttypescript项目&#xff0c;在工作电脑上一切正常。但是&#xff0c;在我家里的电脑运行&#xff0c;始终无法检测到typescript环境。即使出现错误的ts语法&#xff0c;也不会有报错提示&#xff0c;效果如下&#xff1a;我故意将一个string类型&#xff0c;传入…

【MCP开发】Nodejs+Typescript+pnpm+Studio搭建Mcp服务

MCP服务支持两种协议&#xff0c;Studio和SSE/HTTP&#xff0c;目前官方提供的SDK有各种语言。 开发方式有以下几种&#xff1a; 编程语言MCP命令协议发布方式PythonuvxSTUDIOpypiPython远程调用SSE服务器部署NodejspnpmSTUDIOpnpmNodejs远程调用SSE服务器部署… 一、初始化项…

vscode使用keil5出现变量跳转不了和搜索全局不了

vscode使用keil5出现变量跳转不了&#xff0c;或者未包含文件&#xff0c;或者未全局检索&#xff1b; 参考如下文章后还会出现&#xff1b; 为什么vscode搜索栏只搜索已经打开的文件_vscode全局搜索只能搜当前文件-CSDN博客 在机缘巧合之下发现如下解决方式&#xff1a; 下载…

命名空间——网络(net)

命名空间——网络&#xff08;net&#xff09; 一、网络命名空间&#xff1a;每个都是独立的“网络房间” 想象你的电脑是一栋大楼&#xff0c;每个网络命名空间就是大楼里的一个“独立房间”&#xff1a; 每个房间里有自己的“网线接口”&#xff08;网卡&#xff09;、“门牌…

一文读懂16英寸笔记本的实际尺寸与最佳应用场景

当您搜索"16寸笔记本电脑长宽"时&#xff0c;内心真正在问的是什么&#xff1f;是背包能否容纳&#xff1f;桌面空间是否足够&#xff1f;还是期待屏幕尺寸与便携性的完美平衡&#xff1f;这个看似简单的尺寸数字背后&#xff0c;凝结着计算机制造商对用户体验的深刻…

Android Studio中创建Git分支

做一些Android项目时&#xff0c;有时候想要做一些实验性的修改&#xff0c;这个实验可能需要很多步骤&#xff0c;所以不是一时半会能完成的&#xff0c;这就需要在实验的过程中不断修改代码&#xff0c;且要提交代码&#xff0c;方便回滚或比较差异&#xff0c;但是既然是实验…

内存可见性和伪共享问题

文章目录什么是内存可见性问题为什么会出现可见性问题解决可见性问题的方法1. 使用volatile关键字2. 使用synchronized3. 使用java.util.concurrent包下的原子类什么是伪共享问题CPU缓存行伪共享的危害解决伪共享的方法1. 缓存行填充2. 使用Contended注解&#xff08;JDK 8&…