基于堆叠长短期记忆网络 Stacked LSTM 预测A股股票价格走势

news2024/11/18 14:05:45

Close Price Validation

前言

系列专栏:【深度学习:算法项目实战】✨︎
涉及医疗健康、财经金融、商业零售、食品饮料、运动健身、交通运输、环境科学、社交媒体以及文本和图像处理等诸多领域,讨论了各种复杂的深度神经网络思想,如卷积神经网络、循环神经网络、生成对抗网络、门控循环单元、长短期记忆、自然语言处理、深度强化学习、大型语言模型和迁移学习。

近来,机器学习得到了长足的发展,并引起了广泛的关注,其中语音和图像识别领域的成果最为显著。本研究论文分析了深度学习方法–长短期记忆神经网络(LSTM)–在A股市中的表现。论文显示,虽然这种技术在语音识别等其他领域取得了不错的成绩,但在应用于金融数据时却表现不佳。事实上,金融数据的特点是噪声信号比高,这使得机器学习模型难以找到模式并预测未来价格。

本文不对LSTM模型过多介绍,只探讨Stacked LSTM在A股中的表现,以及模型调参与性能优化。本研究文章的结构如下。第一节介绍金融时间序列数据。第二部分介绍金融时间数据的特征过程。第三部分是构建模型、定义参数空间、损失函数与优化器。第四部分是模型评估与结果可视化。第五部分是预测下一个时间点的收盘价。

目录

  • 1. 金融时间序列数据
    • 1.1 获取股票每日价格数据
    • 1.2 观察股票收盘价格趋势
  • 2. 时间数据特征工程
    • 2.1 构造序列数据
    • 2.2 特征缩放(归一化)
    • 2.3 数据集划分(TimeSeriesSplit)
  • 3. 时间序列模型构建(Stacked LSTM)
    • 3.1 构建模型
    • 3.2 定义参数空间
    • 3.3 验证损失与调参循环
    • 3.4 最佳模型输出与保存
  • 4. 模型评估与可视化
    • 4.1 均方误差
    • 4.2 反归一化
    • 4.3 结果验证(可视化)
  • 5. 模型预测
    • 5.1 预测下一个时间点的收盘价

1. 金融时间序列数据

金融时间序列数据是指按照时间顺序记录的各种金融指标的数值序列,这些指标包括但不限于股票价格、汇率、利率等。这些数据具有以下几个显著特点:

  1. 时间连续性:数据按照时间的先后顺序排列,反映了金融市场的动态变化过程。
  2. 噪声和不确定性:金融市场受到多种复杂因素的影响,因此数据中存在大量噪声和不确定性。
  3. 非线性和非平稳性:金融时间序列数据通常呈现出明显的非线性和非平稳性特征。
import numpy as np
import pandas as pd

from pytdx.hq import TdxHq_API

import plotly.graph_objects as go

from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import TimeSeriesSplit
from sklearn.model_selection import ParameterSampler

from keras.models import Sequential
from keras.layers import Input, Dense, LSTM, Dropout
from keras.metrics import RootMeanSquaredError
from keras.optimizers import Adam

1.1 获取股票每日价格数据

首先,让我们使用 TdxHq_API() 函数获取股票价格

api = TdxHq_API()
with api.connect('119.147.212.81', 7709):
    df = api.to_df(api.get_security_bars(9, 1, '600584', 0, 800))
    print(df)
      open  close   high    low       vol        amount  year  month  day  \
0    41.01  39.60  41.29  39.60  432930.0  1.735115e+09  2021      2   25   
1    38.63  39.56  39.56  38.51  398273.0  1.553533e+09  2021      2   26   
2    39.71  40.47  40.59  39.15  382590.0  1.530225e+09  2021      3    1   
3    41.17  40.30  41.26  39.90  334984.0  1.358569e+09  2021      3    2   
4    40.20  40.80  40.92  39.38  325774.0  1.306173e+09  2021      3    3   
..     ...    ...    ...    ...       ...           ...   ...    ...  ...   
795  29.15  29.05  29.29  28.68  489791.0  1.418345e+09  2024      6   14   
796  29.05  31.28  31.90  28.75  980331.0  2.989219e+09  2024      6   17   
797  31.20  31.40  31.41  30.81  580956.0  1.811908e+09  2024      6   18   
798  31.30  31.75  32.02  31.05  739795.0  2.341768e+09  2024      6   19   
799  31.30  31.08  31.88  30.93  530154.0  1.660881e+09  2024      6   20   

     hour  minute          datetime  
0      15       0  2021-02-25 15:00  
1      15       0  2021-02-26 15:00  
2      15       0  2021-03-01 15:00  
3      15       0  2021-03-02 15:00  
4      15       0  2021-03-03 15:00  
..    ...     ...               ...  
795    15       0  2024-06-14 15:00  
796    15       0  2024-06-17 15:00  
797    15       0  2024-06-18 15:00  
798    15       0  2024-06-19 15:00  
799    15       0  2024-06-20 15:00  

[800 rows x 12 columns]

1.2 观察股票收盘价格趋势

接下来,使用 go.Scatter() 函数绘制股票价格趋势

fig = go.Figure([go.Scatter(x=df['datetime'], y=df['close'])])
fig.update_layout(
    title={'text': 'Close Price History', 'font_size': 24, 'font_family': 'Comic Sans MS', 'font_color': '#454545'},
    xaxis_title={'text': '', 'font_size': 18, 'font_family': 'Courier New', 'font_color': '#454545'},
    yaxis_title={'text': 'Close Price CNY', 'font_size': 18, 'font_family': 'Lucida Console', 'font_color': '#454545'},
    xaxis_tickfont=dict(color='#663300'), yaxis_tickfont=dict(color='#663300'), width=900, height=500,
    plot_bgcolor='#F2F2F2', paper_bgcolor='#F2F2F2',
)
fig.show()

价格趋势

2. 时间数据特征工程

# 设置时间窗口大小
window_size = 180

2.1 构造序列数据

若在收盘之前运行,则最后一个测试price不准确,range中长度最好再减1

# 构造序列数据
def create_dataset(dataset, look_back=1):
    X, Y = [], []
    for i in range(len(dataset)-look_back):
        a = dataset[i:(i+look_back), 0]
        X.append(a)
        Y.append(dataset[i + look_back, 0])
    return np.array(X), np.array(Y)

2.2 特征缩放(归一化)

MinMaxScaler() 函数主要用于将特征数据按比例缩放到指定的范围。默认情况下,它将数据缩放到[0, 1]区间内,但也可以通过参数设置将数据缩放到其他范围。在机器学习中,MinMaxScaler()函数常用于不同尺度特征数据的标准化,以提高模型的泛化能力

# 归一化数据
scaler = MinMaxScaler(feature_range=(0, 1))
scaled_data = scaler.fit_transform(df['close'].values.reshape(-1, 1))
# 创建数据集
X, y = create_dataset(scaled_data, look_back=window_size)
# 重塑输入数据为[samples, time steps, features]
X = np.reshape(X, (X.shape[0], X.shape[1], 1))

2.3 数据集划分(TimeSeriesSplit)

TimeSeriesSplit() 函数与传统的交叉验证方法不同,TimeSeriesSplit 特别适用于需要考虑时间顺序的数据集,因为它确保测试集中的所有数据点都在训练集数据点之后,并且可以分割多个训练集和测试集。

# 使用TimeSeriesSplit划分数据集,根据需要调整n_splits
tscv = TimeSeriesSplit(n_splits=3, test_size=30)
# 遍历所有划分进行交叉验证
for i, (train_index, test_index) in enumerate(tscv.split(X)):
    X_train, X_test = X[train_index], X[test_index]
    y_train, y_test = y[train_index], y[test_index]
    # print(f"Fold {i}:")
    # print(f"  Train: index={train_index}")
    # print(f"  Test:  index={test_index}")

这里我们使用最后一个 fold

X_train.shape, X_test.shape, y_train.shape, y_test.shape
((590, 180, 1), (30, 180, 1), (590,), (30,))

3. 时间序列模型构建(Stacked LSTM)

Stacked LSTM,即堆叠长短期记忆网络,是一种深度学习的模型架构,由多个LSTM层堆叠而成。这种架构使得模型能够学习并提取输入序列数据的不同级别的特征,从而提高预测的准确性。

3.1 构建模型

# 定义模型构建函数
def LSTMRegressor(lstm_units, dropout_rate, learning_rate):
    model = Sequential()
    model.add(Input(shape=(X_train.shape[1], X_train.shape[2])))
    model.add(LSTM(lstm_units, return_sequences=True))
    model.add(Dropout(dropout_rate))
    model.add(LSTM(lstm_units, return_sequences=True))
    model.add(Dropout(dropout_rate))
    model.add(LSTM(lstm_units))
    model.add(Dropout(dropout_rate))
    model.add(Dense(60))
    model.add(Dropout(dropout_rate))
    model.add(Dense(1))  # 线性回归层
    
    opt = Adam(learning_rate=learning_rate)
    model.compile(optimizer=opt, loss='mean_squared_error')
    return model

3.2 定义参数空间

使用 ParameterSampler 可以为随机搜索定义参数的分布,却不像网格搜索那样指定所有可能的参数组合。

# 定义参数空间
param_grid = {
    'lstm_units': [32, 64, 128],
    'dropout_rate': [0.2, 0.3, 0.4],
    'learning_rate': [0.001, 0.0001]
}
# 使用ParameterSampler生成参数组合
param_list = list(
    ParameterSampler(
        param_grid, 
        n_iter=len(
            param_grid['lstm_units']
        ) * 
        len(
            param_grid['dropout_rate']
        ) * 
        len(
            param_grid['learning_rate']
        ), 
        random_state=42
    )
)

3.3 验证损失与调参循环

# 初始化最佳验证损失和最佳模型
best_val_loss = float('inf')
best_model = None
# 调参循环
for params in param_list:
    print(f"Trying parameters: {params}")
    model = LSTMRegressor(**params)
    
    # 训练模型(这里仅使用一部分epoch作为示例)
    history = model.fit(X_train, y_train, epochs=10, batch_size=32, validation_data=(X_test, y_test), verbose=0)
    
    # 计算验证集上的损失
    val_loss = history.history['val_loss'][-1]
    
    # 如果当前模型的验证损失比之前的好,则更新最佳模型和最佳验证损失
    if val_loss < best_val_loss:
        best_val_loss = val_loss
        best_model = model
        print(f"Found better model with validation loss: {best_val_loss}")

# 输出最佳模型的参数
print(f"Best model parameters: {param_list[param_list.index(params)]}")
Trying parameters: {'lstm_units': 32, 'learning_rate': 0.001, 'dropout_rate': 0.2}
Found better model with validation loss: 0.007122963201254606
Trying parameters: {'lstm_units': 64, 'learning_rate': 0.001, 'dropout_rate': 0.2}
Found better model with validation loss: 0.006877976469695568
Trying parameters: {'lstm_units': 128, 'learning_rate': 0.001, 'dropout_rate': 0.2}
Found better model with validation loss: 0.003105488372966647
Trying parameters: {'lstm_units': 32, 'learning_rate': 0.0001, 'dropout_rate': 0.2}
Trying parameters: {'lstm_units': 64, 'learning_rate': 0.0001, 'dropout_rate': 0.2}
Trying parameters: {'lstm_units': 128, 'learning_rate': 0.0001, 'dropout_rate': 0.2}
Trying parameters: {'lstm_units': 32, 'learning_rate': 0.001, 'dropout_rate': 0.3}
Trying parameters: {'lstm_units': 64, 'learning_rate': 0.001, 'dropout_rate': 0.3}
Trying parameters: {'lstm_units': 128, 'learning_rate': 0.001, 'dropout_rate': 0.3}
Trying parameters: {'lstm_units': 32, 'learning_rate': 0.0001, 'dropout_rate': 0.3}
Trying parameters: {'lstm_units': 64, 'learning_rate': 0.0001, 'dropout_rate': 0.3}
Trying parameters: {'lstm_units': 128, 'learning_rate': 0.0001, 'dropout_rate': 0.3}
Trying parameters: {'lstm_units': 32, 'learning_rate': 0.001, 'dropout_rate': 0.4}
Trying parameters: {'lstm_units': 64, 'learning_rate': 0.001, 'dropout_rate': 0.4}
Trying parameters: {'lstm_units': 128, 'learning_rate': 0.001, 'dropout_rate': 0.4}
Trying parameters: {'lstm_units': 32, 'learning_rate': 0.0001, 'dropout_rate': 0.4}
Trying parameters: {'lstm_units': 64, 'learning_rate': 0.0001, 'dropout_rate': 0.4}
Trying parameters: {'lstm_units': 128, 'learning_rate': 0.0001, 'dropout_rate': 0.4}
Best model parameters: {'lstm_units': 128, 'learning_rate': 0.0001, 'dropout_rate': 0.4}

3.4 最佳模型输出与保存

best_model.summary()
Model: "sequential_2"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓
┃ Layer (type)                         ┃ Output Shape                ┃         Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━┩
│ lstm_6 (LSTM)(None, 180, 128)66,560 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ dropout_8 (Dropout)(None, 180, 128)0 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ lstm_7 (LSTM)(None, 180, 128)131,584 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ dropout_9 (Dropout)(None, 180, 128)0 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ lstm_8 (LSTM)(None, 128)131,584 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ dropout_10 (Dropout)(None, 128)0 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ dense_4 (Dense)(None, 60)7,740 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ dropout_11 (Dropout)(None, 60)0 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ dense_5 (Dense)(None, 1)61 │
└──────────────────────────────────────┴─────────────────────────────┴─────────────────┘
 Total params: 1,012,589 (3.86 MB)
 Trainable params: 337,529 (1.29 MB)
 Non-trainable params: 0 (0.00 B)
 Optimizer params: 675,060 (2.58 MB)

使用 .save() 函数保存最佳模型

# 保存最佳模型
# best_model.save('best_model.h5')

4. 模型评估与可视化

4.1 均方误差

使用均方误差 mean_squared_error() 评估模型性能

from sklearn.metrics import mean_squared_error
# 使用最佳模型进行预测
trainPredict = best_model.predict(X_train)
testPredict = best_model.predict(X_test)
mse = mean_squared_error(y_test, testPredict)
print(f"Test MSE: {mse}")
19/19 ━━━━━━━━━━━━━━━━━━━━ 2s 105ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 94ms/step
Test MSE: 0.0031054877469655923

4.2 反归一化

# 反归一化预测结果
trainPredict = scaler.inverse_transform(trainPredict)
y_train = scaler.inverse_transform([y_train])
testPredict = scaler.inverse_transform(testPredict)
y_test = scaler.inverse_transform([y_test])

4.3 结果验证(可视化)

# 计算绘图数据
train = df[:X_train.shape[0]+X_train.shape[1]]
valid = df[X_train.shape[0]+X_train.shape[1]:]
valid = valid.assign(predictions=testPredict)
# 可视化数据
fig = go.Figure([go.Scatter(x=train['datetime'], y=train['close'],name='Train')])
fig.add_trace(go.Scatter(x=valid['datetime'],y=valid['close'],name='Test'))
fig.add_trace(go.Scatter(x=valid['datetime'],y=valid['predictions'], name='Prediction'))
fig.update_layout(
    title={'text': 'Close Price Validation', 'font_size': 24, 'font_family': 'Comic Sans MS', 'font_color': '#454545'},
    xaxis_title={'text': '', 'font_size': 18, 'font_family': 'Courier New', 'font_color': '#454545'},
    yaxis_title={'text': 'Close Price CNY', 'font_size': 18, 'font_family': 'Lucida Console', 'font_color': '#454545'},
    xaxis_tickfont=dict(color='#663300'), yaxis_tickfont=dict(color='#663300'), width=900, height=500,
    plot_bgcolor='#F2F2F2', paper_bgcolor='#F2F2F2',
)
fig.show()

验证可视化
从上图我们可以观察到预测价格存在滞后性,关于如何缓解滞后性请参考连接。1

5. 模型预测

5.1 预测下一个时间点的收盘价

# 使用模型预测下一个时间点的收盘价
# 假设latest_closes是一个包含最新window_size个收盘价的列表或数组
latest_closes = df['close'][-window_size:].values
latest_closes = latest_closes.reshape(-1, 1)
scaled_latest_closes = scaler.fit_transform(latest_closes)
latest_closes_reshape = scaled_latest_closes.reshape(1, window_size, 1)
next_close_pred = best_model.predict(latest_closes_reshape)
next_close_pred = scaler.inverse_transform(next_close_pred)
next_close_pred
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step
array([[30.284128]], dtype=float32)

本文仅用于深度学习科学实验和教育目的,并非投资建议


  1. LSTM从理论基础到代码实战 5 关于lstm预测滞后性的讨论 ↩︎

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

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

相关文章

思看科技冲刺上市疑云:募资用途遭强烈质疑,IPO前突击分红

近日&#xff0c;思看科技&#xff08;杭州&#xff09;股份有限公司&#xff08;下称“思看科技”&#xff09;已更新提交2023年最新财务资料&#xff0c;重启科创板IPO进程。贝多财经了解到&#xff0c;思看科技的上市申请于2023年6月获上交所受理&#xff0c;目前已进入问询…

简鹿文件批量重命名:一款文件批量改名高手都在用的工具

作为 IT 行业的搬砖民工&#xff0c;互联网的数据量爆炸性增长&#xff0c;文件管理成为了一项日益重要的任务。"简鹿文件批量重命名"应运而生&#xff0c;旨在为用户提供一个高效、灵活的解决方案&#xff0c;以应对繁琐的文件命名、排序、创建及属性修改等挑战。 这…

足底筋膜炎吃什么药最管用

足底筋膜炎在使用药物后未见明显改善&#xff0c;但通过使用“古顺、敷堂、筋膜”贴后病情得到了缓解。按疗程使用自愈了&#xff0c;这款筋膜贴通过其药物成分渗透到组织中&#xff0c;从根本上消除炎症&#xff0c;从而快速缓解症状&#xff0c;足底筋膜炎得到了明显的改善。…

【思科】IPv6 过渡技术 - 6to4隧道

【思科】IPv6 过渡技术 - 6to4隧道 实验要求实现思路6 to 4 特点注意点IPv4 转 IPv6 格式小技巧 配置R1基础配置OSPFv3 局域网可达 R2基础配置局域网环境(OSPFv3)&#xff1a;IPv6 网络6 to 4 隧道 R3R4基础配置局域网环境(OSPFv3)&#xff1a;IPv6 网络6 to 4 隧道 R5基础配置…

Apifox 快速入门教程

访问示例项目​ 可访问Apifox官网&#xff0c;下载并打开 Apifox 后&#xff0c;你将会看到由系统自动创建的“示例团队”&#xff0c;其中内含一个“示例项目”。 项目中自动生成了与宠物商店有关的数条接口。 手动新建接口​ 新建接口是开发者们最常用的功能之一。Apifox 能…

Java研学-RBAC权限控制(八)

九 登录登出 1 登录作用 判断员工是否有权限访问&#xff0c;首先得知道现在操作的人是谁&#xff0c;所以必须先实现登录功能 2 登录流程 ① 提供登录页面&#xff0c;可输入用户名与密码信息&#xff0c;并添加执行登录的按钮。&#xff08;登录页面不能被拦截&#xff09;…

微服务、多租户、单点登录、国产化形成的开源Java框架!

一、项目简介 JVS是软开企服构建的一站式数字化的开源框架&#xff0c;支持对接多种账户体系&#xff0c;支持多租户、支持Auth2、统一登录、单点登录等&#xff0c;支持原生开发、低代码/零代码开发应用。 二、框架核心功能 控制台(首页)&#xff1a;采用配置化的方式 用户…

C语言从入门到进阶(15万字总结)

前言&#xff1a; 《C语言从入门到进阶》这本书可是作者呕心沥血之作&#xff0c;建议零售价1元&#xff0c;当然这里开个玩笑。 本篇博客可是作者之前写的所有C语言笔记博客的集结&#xff0c;本篇博客不止有知识点&#xff0c;还有一部分代码练习。 有人可能会问&#xff…

HarmonyOS Next 系列之可移动悬浮按钮实现(六)

系列文章目录 HarmonyOS Next 系列之省市区弹窗选择器实现&#xff08;一&#xff09; HarmonyOS Next 系列之验证码输入组件实现&#xff08;二&#xff09; HarmonyOS Next 系列之底部标签栏TabBar实现&#xff08;三&#xff09; HarmonyOS Next 系列之HTTP请求封装和Token…

Huffman树——AcWing 148. 合并果子

目录 Huffman树 定义 运用情况 注意事项 解题思路 AcWing 148. 合并果子 题目描述 运行代码 代码思路 其它代码 代码思路 Huffman树 定义 它是一种最优二叉树。通过构建带权路径长度最小的二叉树&#xff0c;经常用于数据压缩等领域。 运用情况 在数据压缩中&a…

C语言 while循环1

在C语言里有3种循环&#xff1a;while循环 do while 循环 for循环 while语句 //while语法结构 while&#xff08;表达式&#xff09;循环语句; 比如在屏幕上打印1-10 在while循环中 break用于永久的终止循环 在while循环中&#xff0c;continue的作用是跳过本次循环 …

MySQL的综合运用

MySQL版的葵花宝典&#xff0c;欲练此功&#xff0c;挥刀自。。。呃&#xff0c;&#xff0c;&#xff0c;说错了&#xff0c;是先创建两个表&#xff0c;分别是location表和store_info表 示例表为location表和store_info表&#xff0c;如下图所示&#xff1a; 操作一&#xf…

关于小蛋の编程和小蛋编程为同一作者的说明

小蛋の编程和小蛋编程的作品为同一人制作&#xff0c;因前者为父母的手机号进行注册&#xff0c;现用本人手机号注册了新账号小蛋编程&#xff0c;后续文章将在新账号小蛋编程上进行刊登&#xff0c;同时在小蛋编程上对原账号文章进行转载。此账号不再发布帖子&#xff0c;请大…

算法常见手写代码

1.NMS def py_cpu_nms(dets, thresh):"""Pure Python NMS baseline."""#x1、y1、x2、y2、以及score赋值x1 dets[:, 0]y1 dets[:, 1]x2 dets[:, 2]y2 dets[:, 3]scores dets[:, 4]#每一个检测框的面积areas (x2 - x1 1) * (y2 - y1 1)#按…

运维iptables与firewalld详解

iptables与firewalld 一、iptables 1.1 iptables简介 iptables 是一个在 Linux 系统上用来配置 IPv4 数据包过滤规则的工具。它允许系统管理员控制数据包的流向&#xff0c;实现网络安全、网络地址转换&#xff08;NAT&#xff09;和端口转发等功能。 具体来说&#xff0c;…

如何解决app广告填充率低、广告填充异常,提升广告变现收益?

APP广告变现有助于开发者获得持续的收益来源&#xff0c;由于广告链路的封闭性和复杂化&#xff0c;一旦出现请求配置参数错误、返回广告源信息缺失、素材被拦截等异常&#xff0c;大部分开发者很难及时查清异常情况&#xff0c;导致广告填充率不理想&#xff0c;甚至填充率常常…

Spire.PDF for .NET【文档操作】演示:设置 PDF 文档的 XMP 元数据

XMP 是一种文件标签技术&#xff0c;可让您在内容创建过程中将元数据嵌入文件本身。借助支持 XMP 的应用程序&#xff0c;您的工作组可以以团队以及软件应用程序、硬件设备甚至文件格式易于理解的格式捕获有关项目的有意义的信息&#xff08;例如标题和说明、可搜索的关键字以及…

“开源AI”到底是什么意思

开源与专有软件之间的斗争早已为人所熟知。然而&#xff0c;长期以来弥漫在软件圈的紧张关系已经渗透到了人工智能领域&#xff0c;部分原因在于没有人能在AI背景下就“开源”的真正含义达成一致。 相关阅读&#xff1a;GPT-4o通过整合文本、音频和视觉实现人性化的AI交互&…

上海舆情分析软件的功能和对企业的意义

随着互联网的飞速发展&#xff0c;人们参与讨论、发声的途径与评率也越来越多&#xff0c;在为自己发声的同时&#xff0c;公众舆论也成为企业获取民意&#xff0c;改进发展的重要参考。 上海 舆情分析软件的开发&#xff0c;为企业获取舆论&#xff0c;调查研究提供了便捷化的…

Spring+SpringMVC+MyBatis整合

目录 1.SSM介绍1.1 什么是SSM&#xff1f;1.2 SSM框架1.2.1 Spring1.2.2 SpringMVC1.2.3 MyBatis 2.SSM框架整合2.1 建库建表2.2 创建工程2.3 pom.xml2.4 log4j.properties2.5 db.properties2.6 applicationContext-dao.xml2.7.applicationContext-tx.xml2.8 applicationContex…