3.1 基于Prompt工程的金融行业项目¶
学习目标¶
- 了解项目背景
- 了解整体项目任务
- 掌握Few-Shot、Zero-Shot的思想
- 完成课程代码开发
一、项目介绍¶
1 项目背景¶
- 当前金融领域信息化发展的时代,金融数据大量激增,许多投资者和研究者试图通过对这些数据进行深度分析而获得一些有效的决策和帮助,尽可能减少决策失误带来的损失。所以,针对金融数据的分析方法研究是目前十分有益且热门的话题。
-
当前人工智能技术在金融行业动态分析领域的应用主要包括:
- 风险评估:通过AI对大数据分析,识别出不同金融风险事件类型、反欺诈行为、信用评分低等风险,帮助金融机构全面评估贷款人的信用状况,从而提高贷款的准确性和风险控制能力。
- 投资决策:通过AI技术对历史数据、财务报表等信息分析,为投资者提供精准的投资决策支持。
- 客户服务:通过AI技术,实现智能客服等功能,进而为客户提供便捷而又准确的答案
-
但是,上述传统应用的实现,通常需要专业的AI技术加持如:NLP、CV、机器学习等知识,对应的就需要专业的算法人员去分析数据、训练模型从实现预测分析。而这对于非专业人员来说要想实现上述应用,可谓是举步维艰。然而,伴随着ChatGPT等大模型问世,使得非专业人员实现上述应用成为可能,应用者不需要特别专业的算法知识,就可以利用大模型来实现金融领域的应用。
- 因此,本项目主要基于大模型来直接实现在金融领域相关任务的应用。重点在于如何对大模型设计prompt,从而激发大模型的"涌现能力",进而给出准确的答案。
2 项目任务与方法介绍¶
- 项目任务(三大业务场景):
- 金融文本分类:将金融文本分成不同类型。
- 金融文本信息抽取:抽取金融文本中的实体。
- 金融文本匹配:判断两个金融文本是否类似。
- 大模型选择:Qwen
- 采用方法:基于Few-Shot+Zero-Shot以及Instrunction的思想,设计prompt, 进而应用大模型完成相应的任务。
3 环境准备¶
本项目运行前请安装相关依赖包:
- openai
二、LLM实现金融文本分类¶
1 需求¶
- 下面几段文本来自某平台发布的金融领域文本:
1."今日,央行发布公告宣布降低利率,以刺激经济增长。这一降息举措将影响贷款利率,并在未来几个季度内对金融市场产生影响。",
2."ABC公司今日发布公告称,已成功完成对XYZ公司股权的收购交易。本次交易是ABC公司在扩大业务范围、加强市场竞争力方面的重要举措。据悉,此次收购将进一步巩固ABC公司在行业中的地位,并为未来业务发展提供更广阔的发展空间。详情请见公司官方网站公告栏",
3."公司资产负债表显示,公司偿债能力强劲,现金流充足,为未来投资和扩张提供了坚实的财务基础。",
4."最新的分析报告指出,可再生能源行业预计将在未来几年经历持续增长,投资者应该关注这一领域的投资机会",
- 我们的目的是期望模型能够帮助我们识别出这4段话中,每一句话描述的是一个什么类型的报告。因此,我们期望模型输出的结果为:
2 项目思路¶
基于提示词进行模型预测,处理流程:
-
加载模型
-
构建提示词 (描述清楚任务及输出格式)
-
模型预测
-
后处理
3 Prompt设计¶
在该任务的 prompt 设计中,我们主要考虑 2 点:
-
需要向模型解释什么叫作「文本分类任务」
-
需要让模型按照我们指定的格式输出
-
为了让模型知道什么叫做「文本分类」,我们借用 In-context Learning 的方式,先给模型展示几个正确的例子:
User: "今日,股市经历了一轮震荡,受到宏观经济数据和全球贸易紧张局势的影响。投资者密切关注美联储可能的政策调整,以适应市场的不确定性。" 是['新闻报道', '公司公告', '财务公告 '分析师报告']里的什么类别? Bot: 新闻报道
User: "本公司年度财务报告显示,去年公司实现了稳步增长的盈利,同时资产负债表呈现强劲的状况。经济环境的稳定和管理层的有效战略执行为公司的健康发展奠定了基础。"是['新闻报道', '公司公告', '财务公告 '分析师报告']里的什么类别? Bot: 财务报告 `
其中,User 代表我们输入给模型的句子,Bot 代表模型的回复内容。
注意:上述例子中 Bot 的部分也是由人工输入的,其目的是希望看到在看到类似 User 中的句子时,模型应当做出类似 Bot 的回答。
4 代码实现¶
方法一:使用Few-Shot方式,将系统提示和示例写到一个prompt中
prompt如下——
你是一个金融专家,需要对输入的金融领域文本进行分析,将类型归类到['新闻报道', '财务报告', '公司公告', '分析师报告'],对于不在这四类中的数据,输出‘不清楚类型’。以下是几个示例分类:
"""今日,股市经历了一轮震荡,受到宏观经济数据和全球贸易紧张局势的影响。投资者密切关注美联储可能的政策调整,以适应市场的不确定性。是['新闻报道', '财务报告', '公司公告', '分析师报告']里的什么类别?""""""新闻报道""""""本公司年度财务报告显示,去年公司实现了稳步增长的盈利,同时资产负债表呈现强劲的状况。经济环境的稳定和管理层的有效战略执行为公司的健康发展奠定了基础。是['新闻报道', '财务报告', '公司公告', '分析师报告']里的什么类别?""""""财务报告""""""本公司高兴地宣布成功完成最新一轮并购交易,收购了一家在人工智能领域领先的公司。这一战略举措将有助于扩大我们的业务领域,提高市场竞争力是['新闻报道', '财务报告', '公司公告', '分析师报告']里的什么类别?""""""公司公告""""""最新的行业分析报告指出,科技公司的创新将成为未来增长的主要推动力。云计算、人工智能和数字化转型被认为是引领行业发展的关键因素,投资者应关注这些趋势是['新闻报道', '财务报告', '公司公告', '分析师报告']里的什么类别?""""""分析师报告"""
代码如下——
# 1 导入必备的工具包
from dotenv import load_dotenv
import openai
import os
# 加载环境变量
load_dotenv()
# 提供所有类别以及每个类别下的样例
class_examples = {
'新闻报道': '今日,股市经历了一轮震荡,受到宏观经济数据和全球贸易紧张局势的影响。投资者密切关注美联储可能的政策调整,以适应市场的不确定性。',
'财务报告': '本公司年度财务报告显示,去年公司实现了稳步增长的盈利,同时资产负债表呈现强劲的状况。经济环境的稳定和管理层的有效战略执行为公司的健康发展奠定了基础。',
'公司公告': '本公司高兴地宣布成功完成最新一轮并购交易,收购了一家在人工智能领域领先的公司。这一战略举措将有助于扩大我们的业务领域,提高市场竞争力',
'分析师报告': '最新的行业分析报告指出,科技公司的创新将成为未来增长的主要推动力。云计算、人工智能和数字化转型被认为是引领行业发展的关键因素,投资者应关注这些趋势'}
sentences = [
"今日,央行发布公告宣布降低利率,以刺激经济增长。这一降息举措将影响贷款利率,并在未来几个季度内对金融市场产生影响。",
"ABC公司今日发布公告称,已成功完成对XYZ公司股权的收购交易。本次交易是ABC公司在扩大业务范围、加强市场竞争力方面的重要举措。据悉,此次收购将进一步巩固ABC公司在行业中的地位,并为未来业务发展提供更广阔的发展空间。详情请见公司官方网站公告栏",
"公司资产负债表显示,公司偿债能力强劲,现金流充足,为未来投资和扩张提供了坚实的财务基础。",
"最新的分析报告指出,可再生能源行业预计将在未来几年经历持续增长,投资者应该关注这一领域的投资机会",
]
# 2 构建函数,进行prompt设计(描述清楚任务及输出格式)
def init_prompts(class_examples):
'''
初始化前置prompt,便于模型做 incontext learning。
:param class_examples:
:return:
'''
class_list = list(class_examples.keys())
pre_prompt = f'你是一个金融专家,需要对输入的金融领域文本进行分析,将类型归类到{class_list},对于不在这四类中的数据,输出‘不清楚类型’。以下是几个示例分类:'
for class_type, example in class_examples.items():
pre_prompt = pre_prompt + f'"""{example}是{class_list}里的什么类别?"""' + f'"""{class_type}。"""'
return {'class_list': class_list, 'pre_prompt': pre_prompt}
# 3 构建推理函数
def model_chat(content: str, history=[]) -> str:
"""
调用大模型对话接口
:param messages: 输入内容
:param model: 模型名称
:return: 大模型输出内容 str
"""
client = openai.OpenAI(
base_url=os.environ.get('DASHSCOPE_BASE_URL', ''),
api_key=os.environ.get('DASHSCOPE_API_KEY', '')
)
messages = [{"role": "user", "content": content}]
response = client.chat.completions.create(
model=os.environ.get('DASHSCOPE_CHAT_MODEL', ''),
messages=history + messages,
stream=False,
)
text = response.choices[0].message.content
return text
# 4 构建后处理函数
# 5 调用推理+后处理():
prompts_info = init_prompts(class_examples)
for sentence in sentences:
content = f"{prompts_info['pre_prompt']}"+f'"""{sentence}是 {prompts_info["class_list"]} 里的什么类别?"""'
print("content: ", content)
resp = model_chat(content, history=[])
print("class result: ", resp)
print('\n')
方法二:将系统提示和示例放到history中,然后将history输给大模型,让大模型进行参考
history示例如下——
[
{'role': 'system', 'content': ”你是一个金融专家,需要对输入的金融领域文本进行分析,将类型归类到['新闻报道', '公司公告', '财务公告 '分析师报告'],对于不在这四类中的数据,输出‘不清楚类型’“},
{'role': 'user', 'content': '今日,央行发布公告宣布降低利率,以刺激经济增长。这一降息举措将影响贷款利率,并在未来几个季度内对金融市场产生影响。'},
{'role': 'assistant', 'content': '新闻报道'},
{'role': 'user', 'content': 'ABC公司今日发布公告称,已成功完成对XYZ公司股权的收购交易。本次交易是ABC公司在扩大业务范围、加强市场竞争力方面的重要举措。据悉,此次收购将进一步巩固ABC公司在行业中的地位,并为未来业务发展提供更广阔的发展空间。详情请见公司官方网站公告栏'},
{'role': 'assistant', 'content': '公司公告'},
{'role': 'user', 'content': '今日,央行发布公告宣布降低利率,以刺激经济增长。这一降息举措将影响贷款利率,并在未来几个季度内对金融市场产生影响。'},
{'role': 'assistant', 'content': '财务公告'},
{'role': 'user', 'content': '最新的分析报告指出,可再生能源行业预计将在未来几年经历持续增长,投资者应该关注这一领域的投资机会'},
{'role': 'assistant', 'content': '分析师报告'},
{'role': 'user', 'content': 'XXXXXXXXXX’},
]
代码如下——
# 1 导入必备的工具包
from dotenv import load_dotenv
import openai
import os
# 加载环境变量
load_dotenv()
# 1 提供所有类别以及每个类别下的样例
class_examples = {
'新闻报道': '今日,股市经历了一轮震荡,受到宏观经济数据和全球贸易紧张局势的影响。投资者密切关注美联储可能的政策调整,以适应市场的不确定性。',
'财务报告': '本公司年度财务报告显示,去年公司实现了稳步增长的盈利,同时资产负债表呈现强劲的状况。经济环境的稳定和管理层的有效战略执行为公司的健康发展奠定了基础。',
'公司公告': '本公司高兴地宣布成功完成最新一轮并购交易,收购了一家在人工智能领域领先的公司。这一战略举措将有助于扩大我们的业务领域,提高市场竞争力',
'分析师报告': '最新的行业分析报告指出,科技公司的创新将成为未来增长的主要推动力。云计算、人工智能和数字化转型被认为是引领行业发展的关键因素,投资者应关注这些趋势'}
sentences = [
"今日,央行发布公告宣布降低利率,以刺激经济增长。这一降息举措将影响贷款利率,并在未来几个季度内对金融市场产生影响。",
"ABC公司今日发布公告称,已成功完成对XYZ公司股权的收购交易。本次交易是ABC公司在扩大业务范围、加强市场竞争力方面的重要举措。据悉,此次收购将进一步巩固ABC公司在行业中的地位,并为未来业务发展提供更广阔的发展空间。详情请见公司官方网站公告栏",
"公司资产负债表显示,公司偿债能力强劲,现金流充足,为未来投资和扩张提供了坚实的财务基础。",
"最新的分析报告指出,可再生能源行业预计将在未来几年经历持续增长,投资者应该关注这一领域的投资机会",
]
# 2 构建函数,进行prompt设计(描述清楚任务及输出格式)
def init_prompts(class_examples):
'''
初始化前置prompt,便于模型做 incontext learning。
:param class_examples:
:return:
'''
class_list = list(class_examples.keys())
pre_history = [{"role": "system",
"content": f'你是一个金融专家,需要对输入的金融领域文本进行分析,将类型归类到{class_list},对于不在这四类中的数据,输出‘不清楚类型’'}]
for class_type, example in class_examples.items():
# pre_history.append((f'{example}是{class_list}里的什么类别?',class_type))
pre_history.append({'role': "user",
'content': f'{example}是{class_list}里的什么类别?'
})
pre_history.append({'role': 'assistant',
'content': class_type
})
return {'class_list': class_list, 'pre_history': pre_history}
# 3 构建推理函数
def model_chat(content: str, history=[]) -> str:
"""
调用大模型对话接口
:param messages: 输入内容
:param model: 模型名称
:return: 大模型输出内容 str
"""
client = openai.OpenAI(
base_url=os.environ.get('DASHSCOPE_BASE_URL', ''),
api_key=os.environ.get('DASHSCOPE_API_KEY', '')
)
messages = [{"role": "user", "content": content}]
response = client.chat.completions.create(
model=os.environ.get('DASHSCOPE_CHAT_MODEL', ''),
messages=history + messages,
stream=False,
)
text = response.choices[0].message.content
return text
# 4 构建后处理函数
# 5 调用推理+后处理():
prompts_info = init_prompts(class_examples)
for sentence in sentences:
content = f"“{sentence}”是 {prompts_info['class_list']} 里的什么类别?"
print("content : ", content)
resp = model_chat(content, history=prompts_info['pre_history'])
print("class result : ", resp)
三、LLM实现金融文本信息抽取¶
1 需求¶
- 下面几段文本来自某平台发布的股票信息:
1.'2023-02-15,寓意吉祥的节日,股票佰笃[BD]美股开盘价10美元,虽然经历了波动,但最终以13美元收盘,成交量微幅增加至460,000,投资者情绪较为平稳。',
2.'2023-04-05,市场迎来轻松氛围,股票盘古(0021)开盘价23元,尽管经历了波动,但最终以26美元收盘,成交量缩小至310,000,投资者保持观望态度。',
- 我们的目的是期望模型能够帮助我们识别出这两段话中的SPO三元组信息。
这里定义的信息抽取Schema如下:
期望抽取的结果如下:
{"日期": ["2023-02-15"], "股票名称": ["佰笃[BD]美股"], "开盘价": ["10美元"], "收盘价": ["13美元"], "成交量": ["460,000"]}
{"日期": ["2023-04-05"], "股票名称": ["盘古(0021)"], "开盘价": ["23元"], "收盘价": ["26美元"], "成交量": ["310,000"]}
2 项目思路¶
基于提示词进行模型预测,处理流程:
- 加载模型
-
构建提示词 (描述清楚任务及输出格式)
-
模型预测
-
后处理
3 Prompt设计¶
在该任务的 prompt 设计中,我们主要考虑 2 点:
-
需要向模型解释什么叫作「信息抽取任务」
-
需要让模型按照我们指定的格式(json)输出
-
为了让模型知道什么叫做「信息抽取」,我们借用 In-context Learning 的方式,先给模型展示几个正确的例子:
User:'2023-01-10,股市震荡。股票古哥-D[EOOE]美股今日开盘价100美元,一度飙升至105美元,随后回落至98美元,最终以102美元收盘,成交量达到520000。'。提取上述句子中“金融”('日期', '股票名称', '开盘价', '收盘价', '成交量')类型的实体,并按照JSON格式输出,上述句子中没有的信息用['原文中未提及']来表示,多个值之间用','分隔。 Bot: {'日期': ['2023-01-10'],'股票名称': ['古哥-D[EOOE]美股'],'开盘价': ['100美元'], '收盘价': ['102美元'],成交量': ['520000']}
其中,User 代表我们输入给模型的句子,Bot 代表模型的回复内容。
注意:上述例子中 Bot 的部分也是由人工输入的,其目的是希望看到在看到类似 User 中的句子时,模型应当做出类似 Bot 的回答。
4 代码实现¶
使用history的方式,代码如下。
# 1导入必备的工具包
from dotenv import load_dotenv
import openai
import json
import os
# 加载环境变量
load_dotenv()
# 定义不同实体下的具备属性
schema = {
'金融': ['日期', '股票名称', '开盘价', '收盘价', '成交量'],
}
IE_PATTERN = "{}\n\n提取上述句子中{}的实体,并按照JSON格式输出,上述句子中不存在的信息用['原文中未提及']来表示,多个值之间用','分隔。"
# 提供一些例子供模型参考
ie_examples = {
'金融': [
{
'content': '2023-01-10,股市震荡。股票古哥-D[EOOE]美股今日开盘价100美元,一度飙升至105美元,随后回落至98美元,最终以102美元收盘,成交量达到520000。',
'answers': {
'日期': ['2023-01-10'],
'股票名称': ['古哥-D[EOOE]美股'],
'开盘价': ['100美元'],
'收盘价': ['102美元'],
'成交量': ['520000'],
}
}
]
}
sentences = [
'2023-02-15,寓意吉祥的节日,股票佰笃[BD]美股开盘价10美元,虽然经历了波动,但最终以13美元收盘,成交量微幅增加至460,000,投资者情绪较为平稳。',
'2023-04-05,市场迎来轻松氛围,股票盘古(0021)开盘价23元,尽管经历了波动,但最终以26美元收盘,成交量缩小至310,000,投资者保持观望态度。',
]
# 2 构建函数,进行prompt设计(描述清楚任务及输出格式)
def build_prompt(ie_examples):
history_list = [{'role': 'system', 'content': "你是信息提取专家,需要需要完成信息抽取任务。我会给你一个句子,你需要提取句子中的实体,并按照JSON格式输出,如果句子中有不存在的信息用['原文中未提及']来表示,多个值之间用','分隔。"}]
# 遍历示例,将样本和实体 添加到history_list中
for type, example_list in ie_examples.items(): # 获取到金融类型
for example in example_list: # 遍历每个样本
sentence = example['content']
entity_type = ','.join(schema[type]) # 获取到金融类型需要抽取的实体
history_list.append({'role': 'user', 'content': IE_PATTERN.format(sentence, entity_type)})
history_list.append({'role': 'assistant', 'content': json.dumps(example['answers'], ensure_ascii=False)})
# print(f'history_list-->{history_list}')
return {'history_list': history_list}
# 3 构建推理函数
def model_chat(content: str, history=[]) -> str:
"""
调用大模型对话接口
:param messages: 输入内容
:param model: 模型名称
:return: 大模型输出内容 str
"""
client = openai.OpenAI(
base_url=os.environ.get('DASHSCOPE_BASE_URL', ''),
api_key=os.environ.get('DASHSCOPE_API_KEY', '')
)
messages = [{"role": "user", "content": content}]
response = client.chat.completions.create(
model=os.environ.get('DASHSCOPE_CHAT_MODEL', ''),
messages=history + messages,
stream=False,
)
text = response.choices[0].message.content
return text
# 4 构建后处理函数
def clean_response(response: str):
# 将模型输出进行清理, 将 ```json清理掉
if '```json' in response:
response = response.split('```json')[1].split('```')[0]
# print('response-->', response)
# 将这个json字符串转为字典
try:
return json.loads(response) # 防止这步转换出错,使用try except
except:
return response
return response
# 5 调用推理+后处理
prompt_dict = build_prompt(ie_examples)
for sentence in sentences:
print(f'sentence-->{sentence}')
result = model_chat(sentence, prompt_dict['history_list'])
final_result = clean_response(result)
print(f'final_result-->{final_result}')
四、LLM实现金融文本匹配¶
1 需求¶
- 下面是几个金融方面的短文本对:
1.('股票市场今日大涨,投资者乐观。', '持续上涨的市场让投资者感到满意。'),
2.('油价大幅下跌,能源公司面临挑战。', '未来智能城市的建设趋势愈发明显。'),
3.('利率上升,影响房地产市场。', '高利率对房地产有一定冲击。'),
-
我们期望模型能够帮我们识别出这 3 对句子中,哪几对描述的是相似的语言。
即期望模型输出的结果为:
2 项目思路¶
基于提示词进行模型预测,处理流程:
- 加载模型
-
构建提示词 (描述清楚任务及输出格式)
-
模型预测
-
后处理
3 Prompt设计¶
在该任务的 prompt 设计中,我们主要考虑 2 点:
-
需要向模型解释什么叫作「文本匹配任务」
-
需要让模型按照我们指定的格式输出
-
为了让模型知道什么叫做「文本匹配任务」,我们借用 In-context Learning 的方式,先给模型展示几个正确的例子:
User: 句子一: 公司ABC发布了季度财报,显示盈利增长。\n句子二: 财报披露,公司ABC利润上升 Bot: 是
User:句子一: 黄金价格下跌,投资者抛售。\n句子二: 外汇市场交易额创下新高 Bot: 不是 ...
其中,User 代表我们输入给模型的句子,Bot 代表模型的回复内容。
注意:上述例子中 Bot 的部分也是由人工输入的,其目的是希望看到在看到类似 User 中的句子时,模型应当做出类似 Bot 的回答。
4 代码实现¶
使用history的方式,代码如下。
# 1 导入必备的工具包
from dotenv import load_dotenv
import openai
import os
# 加载环境变量
load_dotenv()
# 提供相似,不相似的语义匹配例子
examples = {
'是': [
('公司ABC发布了季度财报,显示盈利增长。', '财报披露,公司ABC利润上升。'),
],
'不是': [
('黄金价格下跌,投资者抛售。', '外汇市场交易额创下新高。'),
('央行降息,刺激经济增长。', '新能源技术的创新。')
]
}
sentence_pairs = [
('股票市场今日大涨,投资者乐观。', '持续上涨的市场让投资者感到满意。'),
('油价大幅下跌,能源公司面临挑战。', '未来智能城市的建设趋势愈发明显。'),
('利率上升,影响房地产市场。', '高利率对房地产有一定冲击。'),
]
# 2 构建函数,进行prompt设计(描述清楚任务及输出格式)
def init_prompts(examples):
"""
初始化前置prompt,便于模型做 incontext learning。
"""
pre_history = [{"role": "system",
"content": '现在你需要帮助我完成文本匹配任务,当我给你两个句子时,你需要回答我这两句话语义是否相似。只需要回答是否相似,不要做多余的回答。'}
]
for key, sentence_pairs in examples.items():
for sentence_pair in sentence_pairs:
sentence1, sentence2 = sentence_pair
pre_history.append({
"role": 'user',
"content": f'句子一: {sentence1}\n句子二: {sentence2}\n上面两句话是相似的语义吗?'
})
pre_history.append({
"role": 'assistant',
"content": key
})
return {'pre_history': pre_history}
# 3 构建推理函数
def model_chat(content: str, history=[]) -> str:
"""
调用大模型对话接口
:param messages: 输入内容
:param model: 模型名称
:return: 大模型输出内容 str
"""
client = openai.OpenAI(
base_url=os.environ.get('DASHSCOPE_BASE_URL', ''),
api_key=os.environ.get('DASHSCOPE_API_KEY', '')
)
messages = [{"role": "user", "content": content}]
response = client.chat.completions.create(
model=os.environ.get('DASHSCOPE_CHAT_MODEL', ''),
messages=history + messages,
stream=False,
)
text = response.choices[0].message.content
return text
# 4 构建后处理函数
# 5 调用推理+后处理
prompts_info = init_prompts(examples)
for sentence_pair in sentence_pairs:
sentence1, sentence2 = sentence_pair
sentence_with_prompt = f'句子一: {sentence1}\n句子二: {sentence2}\n上面两句话是相似的语义吗?'
result=model_chat(sentence_with_prompt, history=prompts_info['pre_history'])
print(f'sentence_pair-->{sentence_pair}')
print(f'result-->{result}')
五、本章小结¶
本章节主要介绍了项目开发的背景及意义,采用了Zero-Shot/Few-Shot学习方式,完成了金融文本分类、金融信息抽取以及近似文本匹配。