(5-5-01)金融市场情绪分析:使用Llama 2 大模型实现财经信息的情感分析微调(1)

5.5  使用Llama 2 大模型实现财经信息的情感分析微调

情感分析在金融和经济领域具有重要意义,可以帮助企业从市场洞察、风险管理和投资决策等方面获得有价值的信息。然而,在金融和经济文本方面的标注数据相对稀缺,因此需要使用自然语言处理技术和预训练模型来解决这一问题。在本节的内容中,将通过具体实例展示使用Llama 2 大模型实现财经信息的情感分析微调的过程。

实例5-6基于Llama 2 大模型财经信息的情感分析微调(源码路径:daima/5/llama-2-sentiment-analysis.ipynb)

5.5.1  项目介绍

本项目展示了如何使用 Llama 2 模型进行金融领域的情感分析微调的方法。通过准备金融新闻标题数据集,并利用微调技术,将 Llama 2 模型优化至金融情感分析任务。最终,项目评估了微调后模型的性能,并与基准模型进行了比较,为金融领域的情感分析提供了有益的实践示例。

本项目的实现流程如下所示:

  1. 数据准备:从金融新闻标题数据集中读取数据,并进行预处理和分割,以供微调和测试使用。
  2. 模型微调:使用 Llama 2 模型对准备好的数据集进行微调,以适应金融领域的情感分析任务。这包括加载预训练的模型、配置微调参数、创建微调训练器,并对模型进行微调训练。
  3. 模型测试:对微调后的模型进行测试,使用测试集进行情感分析预测,并评估模型性能。
  4. 性能比较:将微调后的模型与基准模型进行比较,评估其在准确率、精确度、召回率等指标上的表现差异。
  5. 结果保存和总结:保存模型预测结果,并对整个项目进行总结和展望,提供对项目的简要介绍和结论。

本项目涉及到的技术栈如下:

  1. PyTorch:作为深度学习框架,用于加载、微调和训练大型语言模型。
  2. Hugging Face Transformers:提供了各种预训练的语言模型和自然语言处理工具,用于加载和微调大型语言模型。
  3. 数据集库(如 pandas):用于数据处理和准备,以便用于微调和测试。
  4. Llama 2:作为一个示例,用于情感分析微调任务。Llama 2 是一个基于 Transformer 架构的大型语言模型,具有数十亿的参数量。

5.5.2  准备工作

(1)安装一系列用于实现自然语言处理 (NLP) 和深度学习任务的库,这些库为进行情感分析等自然语言处理任务提供了必要的工具和环境。

!pip install -q -U "torch==1.2.0" tensorboard
!pip install -q -U "transformers==4.36.2" "datasets==2.16.1" "accelerate==0.26.1" "bitsandbytes==0.42.0"
!pip install -q -U git+https://github.com/huggingface/trl@a3c5b7178ac4f65569975efadc97db2f3749c65e
!pip install -q -U git+https://github.com/huggingface/peft@4a1559582281fc3c9283892caea8ccef1d6f5a4f

(2)使用 Python 的 f-string 语法来打印 PyTorch 版本号,如果 PyTorch 已经成功安装,它将打印出当前的 PyTorch 版本号。

print(f"pytorch version {torch.__version__}")

执行后在笔者电脑中输出:

PyTorch version 1.2.0

(3)检查当前系统是否可用 CUDA(即是否有 GPU 可以使用),如果有可用的 CUDA 设备,它将选择在 CUDA 设备上进行运算;否则,它将选择在 CPU 上进行运算。然后,打印输出当前正在使用的设备。

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print(f"working on {device}")

如果 CUDA 可用且有 GPU 设备,则输出类似于以下内容:

Working on cuda:0

(4)准备数据并创建用于微调情感分析模型的训练、评估和测试集,并提供了生成测试数据的提示文本的函数generate_prompt(data_point),这个函数的作用是根据测试数据中的新闻标题生成对应的提示文本,以便输入到模型中进行预测。

filename = "sentiment-analysis-for-financial-news/all-data.csv"

df = pd.read_csv(filename, 
                 names=["sentiment", "text"],
                 encoding="utf-8", encoding_errors="replace")

X_train = list()
X_test = list()
for sentiment in ["positive", "neutral", "negative"]:
    train, test  = train_test_split(df[df.sentiment==sentiment], 
                                    train_size=300,
                                    test_size=300, 
                                    random_state=42)
    X_train.append(train)
    X_test.append(test)

X_train = pd.concat(X_train).sample(frac=1, random_state=10)
X_test = pd.concat(X_test)

eval_idx = [idx for idx in df.index if idx not in list(X_train.index) + list(X_test.index)]
X_eval = df[df.index.isin(eval_idx)]
X_eval = (X_eval
          .groupby('sentiment', group_keys=False)
          .apply(lambda x: x.sample(n=50, random_state=10, replace=True)))
X_train = X_train.reset_index(drop=True)

def generate_prompt(data_point):
    return f"""
            Analyze the sentiment of the news headline enclosed in square brackets, 
            determine if it is positive, neutral, or negative, and return the answer as 
            the corresponding sentiment label "positive" or "neutral" or "negative".

            [{data_point["text"]}] = {data_point["sentiment"]}
            """.strip()

def generate_test_prompt(data_point):
    return f"""
            Analyze the sentiment of the news headline enclosed in square brackets, 
            determine if it is positive, neutral, or negative, and return the answer as 
            the corresponding sentiment label "positive" or "neutral" or "negative".

            [{data_point["text"]}] = """.strip()

X_train = pd.DataFrame(X_train.apply(generate_prompt, axis=1), 
                       columns=["text"])
X_eval = pd.DataFrame(X_eval.apply(generate_prompt, axis=1), 
                      columns=["text"])

y_true = X_test.sentiment
X_test = pd.DataFrame(X_test.apply(generate_test_prompt, axis=1), columns=["text"])

train_data = Dataset.from_pandas(X_train)
eval_data = Dataset.from_pandas(X_eval)

对上述代码的具体说明如下:

  1. 从 CSV文件中读取数据,并将其转换为 pandas DataFrame 格式。
  2. 将数据集分为训练集、测试集和评估集,确保每个集合都包含一定比例的正面、中性和负面情感样本。
  3. 定义函数 generate_prompt(data_point),用于生成训练和评估数据的提示文本。这个函数的作用是根据每个数据点(即每个新闻标题和其对应的情感标签)生成用于微调的提示文本。将生成的提示文本应用于训练数据、评估数据和测试数据,并转换为 Hugging Face 数据集格式。
  4. 定义了函数generate_test_prompt()来评估微调后的情感模型的性能,包括计算准确率、生成准确率报告、生成分类报告和生成混淆矩阵。

5.5.3  评估模型的性能

实现函数evaluate(),功能是评估模型的性能,并提供详细的性能指标报告。它接受两个参数:真实情感标签 (y_true) 和模型预测的情感标签 (y_pred)。

def evaluate(y_true, y_pred):
    labels = ['positive', 'neutral', 'negative']  # 标签列表,包括'positive'、'neutral'和'negative'
    mapping = {'positive': 2, 'neutral': 1, 'none':1, 'negative': 0}  # 情感标签到数字的映射,其中'positive'映射为2,'neutral'和'none'映射为1,'negative'映射为0
    def map_func(x):  # 定义映射函数
        return mapping.get(x, 1)  # 返回情感标签的数字表示,未知标签默认映射为1
    
    y_true = np.vectorize(map_func)(y_true)  # 将真实情感标签映射为数字表示
    y_pred = np.vectorize(map_func)(y_pred)  # 将预测情感标签映射为数字表示
    
    # 计算准确率
    accuracy = accuracy_score(y_true=y_true, y_pred=y_pred)
    print(f'准确率: {accuracy:.3f}')
    
    # 生成准确率报告
    unique_labels = set(y_true)  # 获取唯一标签
    for label in unique_labels:  # 遍历每个唯一标签
        label_indices = [i for i in range(len(y_true)) if y_true[i] == label]  # 获取对应标签的索引
        label_y_true = [y_true[i] for i in label_indices]  # 获取对应标签的真实标签
        label_y_pred = [y_pred[i] for i in label_indices]  # 获取对应标签的预测标签
        accuracy = accuracy_score(label_y_true, label_y_pred)  # 计算对应标签的准确率
        print(f'标签 {label} 的准确率: {accuracy:.3f}')
        
    # 生成分类报告
    class_report = classification_report(y_true=y_true, y_pred=y_pred)  # 生成分类报告,包括精确度、召回率和 F1 值
    print('\n分类报告:')
    print(class_report)
    
    # 生成混淆矩阵
    conf_matrix = confusion_matrix(y_true=y_true, y_pred=y_pred, labels=[0, 1, 2])  # 生成混淆矩阵,显示模型在每个情感标签上的预测结果
    print('\n混淆矩阵:')
    print(conf_matrix)

上述代码的实现流程如下:

  1. 首先,将情感标签映射到数字表示,其中正面情感标签映射为 2,中性情感标签和未知情感标签(如果有的话)映射为 1,负面情感标签映射为 0。这样做是为了方便后续计算准确率。
  2. 然后,计算整体准确率,并打印出该值。整体准确率表示模型在所有样本上预测正确的比例。
  3. 接着,为每个情感标签计算准确率,并打印输出每个情感标签的准确率。这样做可以帮助我们了解模型在每个情感类别上的表现。
  4. 随后,生成分类报告,包括每个情感类别的精确度、召回率和 F1 值。分类报告提供了更详细的性能指标,可以帮助我们更好地理解模型的表现。
  5. 最后,生成混淆矩阵,并打印输出该矩阵。混淆矩阵展示了模型在每个情感类别上的预测结果,有助于我们进一步分析模型的性能和错误分类情况。

综上所述,函数evaluate()提供了全面的性能评估报告,帮助我们深入了解模型在情感分析任务上的表现,并发现模型可能存在的问题和改进空间。

未完待续

  • 34
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农三叔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值