时空数据时序预测模型: HA、VAR、GBRT、GCN、DCRNN、FCCF、ST-MGCN

在这里插入图片描述

HA (Historical Average)

HA (Historical Average,历史平均模型) 是一种基础的时间序列预测方法,通常用于预测具有周期性或季节性规律的数据。它通过计算历史上同一时间段的平均值来预测未来值,假设数据会遵循某种周期性的变化模式。以下是对HA模型的详细介绍:

1. 模型原理

HA模型假设人群流动(或其他时空数据)具有周期性变化规律,通常以一周为周期。例如,一天中的人群流动模式可能在每周的相同时间段表现出相似的趋势。基于这一假设,模型使用历史上相同时间的平均值作为当前时刻的预测值。

具体方法
  • 数据分割 :将历史数据按照时间周期(如一周)进行分割。对于每天的数据,可以分别计算不同天的数据平均值。例如,周一的流动量会与过去所有周一的流动量进行比较。
  • 平均计算 :对于每个时间点,取历史上相同时间段的数据的平均值作为预测值。例如,要预测本周二某时间段的人群流动量,可以取过去所有历史周二同一时间段的人群流动量的平均值作为预测结果。

2. 应用场景

HA模型适用于那些具有明显周期性规律的时空数据,尤其是存在季节性或每天/每周重复的情况。典型的应用场景包括:

  • 交通流量预测 :许多城市中的交通流量呈现明显的周期性,早晚高峰可能每天基本相同,周末的流量也可能与工作日不同。
  • 人群流动预测 :在城市环境中,不同的工作日或周末可能存在不同的人群流动模式,HA模型可以用来预测特定时间段的流动模式。

3. 优点

  • 简单易懂 :HA模型非常直观且易于实现,只需计算历史数据的平均值即可。它不需要复杂的算法,也不依赖于大量的计算资源。
  • 稳定性强 :对于具有强烈周期性规律的数据,HA模型可以提供相对准确的预测,因为历史数据反映了未来的趋势。

4. 局限性

  • 无法处理非周期性变化 :HA模型假设未来的变化与过去的周期性趋势保持一致,因此无法应对突发的变化、长期趋势变化或随机波动。
  • 忽略了时空相关性 :该模型仅考虑了时间上的周期性,而没有考虑空间上的依赖关系(如不同区域之间的互动),这在复杂的时空数据建模中可能是一个不足之处。
  • 对外部因素不敏感 :HA模型未考虑天气、节假日、政策变动等外部因素对人群流动或交通流量的影响,这可能会导致预测误差。

5. 举例说明

假设我们要预测某个城市中的出租车流量:

  • 对于周二10点的人群流动量预测,HA模型会取过去所有历史上周二10点的出租车流量,然后计算这些流量的平均值,作为本次周二10点的预测结果。

6. 改进方向

虽然HA模型简单有效,但如果想提高预测精度,可以结合以下改进方法:

  • 加入时空依赖 :通过引入其他模型(如GCN或DCRNN),可以结合空间依赖关系,进一步提升预测效果。
  • 引入外部变量 :考虑天气、节日等外部因素对人群流动的影响,结合多变量预测模型如VAR或GBRT,可以增强对不可预测事件的应对能力。

VAR (Vector Auto-Regressive)

VAR (Vector Auto-Regressive, 向量自回归) 是一种用于多元时间序列预测的统计模型。它通过分析多个变量的时间序列,利用每个变量自身的历史值以及其他相关变量的历史值来预测未来的数值。该模型非常适合捕捉变量之间的相互影响和动态变化,尤其在时空数据建模中有广泛应用。

1. 模型原理

VAR模型的核心思想是利用一组时间序列的过去值来共同预测这些序列的未来值。在时空预测中,多个时间序列通常代表不同区域或位置的某个变量(如交通流量、温度等),VAR模型通过回归这些变量之间的历史关系来进行预测。

在这里插入图片描述

VAR模型通过这些滞后步数和回归系数来捕捉时间序列中变量间的相互依赖和动态变化。

2. 应用场景

VAR模型适合用于处理多元时间序列数据,尤其在下列应用场景中表现出色:

  • 宏观经济学预测 :在经济学中,VAR模型经常用于分析GDP、通货膨胀率、利率等多个经济变量的动态关系。
  • 时空数据建模 :在交通、气象、人群流动等领域,VAR模型可以通过分析不同区域的历史数据,捕捉这些区域间的空间和时间相关性,从而进行联合预测。
  • 金融市场分析 :该模型可以同时分析多个资产的价格波动及其相互影响,从而预测未来的价格走势。

3. 模型实现

在Python中,VAR模型可以通过statsmodels库来实现。以下是一个基本的实现步骤:

  • 数据准备 :将多个时间序列数据按时间轴排列,通常需要进行数据预处理,如去掉异常值、填补缺失数据等。
  • 选择滞后步数 :选择合适的滞后步数 ppp,这可以通过信息准则(如AIC、BIC)来确定。
  • 模型拟合 :根据历史数据,训练VAR模型,估计回归系数矩阵。
  • 预测 :利用模型进行未来时刻的预测。
import statsmodels.api as sm
from statsmodels.tsa.api import VAR# 假设 df 是一个包含多个时间序列的DataFramemodel = VAR(df)
results = model.fit(maxlags=10, ic='aic')  # 使用AIC准则选择最佳滞后步数
forecast = results.forecast(df.values[-results.k_ar:], steps=5)  # 预测未来5步model = VAR(df)
results = model.fit(maxlags=10, ic='aic'# 使用AIC准则选择最佳滞后步数
forecast = results.forecast(df.values[-results.k_ar:], steps=5# 预测未来5步import statsmodels.api as sm
from statsmodels.tsa.api import VAR# 假设 df 是一个包含多个时间序列的DataFramemodel = VAR(df)
results = model.fit(maxlags=10, ic='aic')  # 使用AIC准则选择最佳滞后步数
forecast = results.forecast(df.values[-results.k_ar:], steps=5)  # 预测未来5步

4. 优点

  • 捕捉变量间的相互依赖 :VAR模型能够很好地捕捉多个变量之间的相互关系,使得预测不仅依赖于单个变量的历史值,还考虑到其他相关变量的影响。
  • 灵活性高 :VAR模型适用于多种类型的时间序列数据,不要求变量之间有特定的因果关系,能够广泛应用于多元数据建模。

5. 局限性

  • 参数较多 :当变量数量 kkk 和滞后步数 ppp 增加时,VAR模型的参数数量会显著增多,可能导致过拟合。
  • 假设线性关系 :VAR模型假设变量之间的关系是线性的,而在实际应用中,许多时空数据可能表现出非线性关系,VAR模型对此难以处理。
  • 对长周期预测效果有限 :随着时间序列长度增加,VAR模型的预测误差可能会累积,导致长周期预测不够准确。

6. 改进与扩展

  • 非线性扩展 :对于具有复杂非线性关系的数据,可以使用非线性VAR(如VARMA、TVAR等)模型来改进预测精度。
  • 加入外部变量 :为了更好地处理外部冲击或季节性影响,VAR模型可以结合外部变量(如天气、政策等)进行扩展。
  • 稀疏化VAR :为了减轻高维数据带来的参数复杂性,可以通过稀疏化技术减少模型中的参数数量,提升模型的可解释性和计算效率。

7. 举例说明

假设我们有四个区域的交通流量数据,并希望使用VAR模型预测未来的流量:

  • 变量 :每个区域的交通流量构成一个时间序列,总共有四个序列。
  • 滞后步数 :假设选择滞后步数 p=5p=5p=5,即使用过去5个时间点的流量值来预测未来的流量。
  • 预测 :VAR模型会根据这四个区域的历史交通流量,捕捉它们之间的相互影响,预测未来每个区域的交通流量。

GBRT (Gradient Boosting Decision Tree)

GBRT (Gradient Boosting Decision Tree, 梯度提升决策树) 是一种集成学习方法,结合了多个决策树模型以提高预测准确性。它通过逐步构建树模型来减少预测误差,广泛应用于回归和分类问题,尤其在处理复杂数据时表现出色。

1. 模型原理

GBRT采用一种迭代的方法,逐步构建树模型,每次都针对前一次模型的预测错误进行改进。其基本思想是通过梯度下降算法来最小化损失函数,利用每个弱学习器(决策树)的输出,来更新整体模型的预测。

基本步骤
  1. 初始化模型 :选择一个简单的模型(例如均值)作为初始预测。
  2. 计算残差 :对于每个样本,计算当前模型的预测值与真实值之间的差异(残差)。
  3. 拟合新树 :使用残差作为目标值训练新的决策树模型,以预测这些残差。
  4. 更新模型 :将新树的预测结果加到当前模型中,形成一个新的预测模型。
  5. 重复步骤 :重复计算残差和拟合新树的过程,直到达到设定的迭代次数或模型性能不再显著提高。
损失函数

GBRT通过优化损失函数来评估模型的性能,常用的损失函数包括:

  • 均方误差 (MSE):用于回归问题。
  • 对数损失 (Log Loss):用于分类问题。

2. 优点

  • 高准确性 :通过集成多个决策树,GBRT可以显著提高预测的准确性,尤其在处理复杂的非线性数据时。
  • 灵活性 :GBRT支持多种类型的损失函数,能够适应不同的任务需求,包括回归和分类。
  • 特征选择 :GBRT能够自动进行特征选择,识别出对预测影响最大的特征。
  • 防止过拟合 :通过设置树的深度、学习率等超参数,GBRT能够有效防止过拟合,提高模型的泛化能力。

在Python中,可以通过scikit-learn库或XGBoost等库来实现GBRT模型。以下是一个基本的实现步骤:

使用scikit-learn实现GBRT:

from sklearn.ensemble import GradientBoostingRegressor
from sklearn.model_selection import train_test_split# 假设 X 是特征矩阵,y 是目标变量
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)# 创建GBRT模型
model = GradientBoostingRegressor(n_estimators=100, learning_rate=0.1, max_depth=3, random_state=42)# 训练模型
model.fit(X_train, y_train)# 预测
predictions = model.predict(X_test)

使用XGBoost实现GBRT:

import xgboost as xgb
from sklearn.model_selection import train_test_split# 假设 X 是特征矩阵,y 是目标变量
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)# 创建DMatrix
dtrain = xgb.DMatrix(X_train, label=y_train)
dtest = xgb.DMatrix(X_test, label=y_test)# 设置参数
params = {'objective': 'reg:squarederror',  # 回归问题'max_depth': 3,'eta': 0.1,'silent': 1,
}# 训练模型
model = xgb.train(params, dtrain, num_boost_round=100)# 预测
predictions = model.predict(dtest)

4. 超参数调优

GBRT有多个超参数可以调整,以下是一些关键的超参数:

  • n_estimators :决策树的数量,过多可能导致过拟合。
  • learning_rate :学习率,控制每棵树对最终预测的贡献,较小的学习率通常能提高模型的性能,但需要增加树的数量。
  • max_depth :每棵树的最大深度,限制树的复杂性以防止过拟合。
  • min_samples_split :一个节点在划分时所需的最小样本数,增大这个值有助于减少过拟合。

5. 局限性

  • 训练时间长 :GBRT通常比单棵决策树训练时间更长,尤其是在大量数据时。
  • 参数选择敏感 :GBRT对超参数选择较为敏感,调优过程可能需要大量的实验。
  • 对噪声敏感 :GBRT在处理带有噪声的数据时,可能会产生过拟合,需进行适当的正则化。

6. 应用场景

  • 回归问题 :如房价预测、销售预测等。
  • 分类问题 :如二分类和多分类任务,广泛应用于金融欺诈检测、客户分类等。
  • 排名问题 :在信息检索和推荐系统中,GBRT可用于生成排名模型。

7. 总结

GBRT是一种强大的机器学习算法,因其高准确性和灵活性而受到广泛应用。通过集成多个决策树,GBRT能够有效捕捉复杂数据中的模式,适用于各种回归和分类任务。尽管在训练时间和参数调优方面存在一定挑战,但其卓越的预测性能使其成为许多实际应用中的首选模型。

FC-LSTM(Fully Connected Long Short-Term Memory)

**FC-LSTM(Fully Connected Long Short-Term Memory)**是一种基于长短期记忆网络(LSTM)的模型,广泛用于处理时序数据,特别是在需要捕捉长期依赖关系的情况下。FC-LSTM结合了全连接层和LSTM层的优势,适用于各种时序预测任务,如时间序列预测、自然语言处理和视频分析等。

1. 模型原理

LSTM简介

LSTM是一种特殊的递归神经网络(RNN),能够有效解决标准RNN在长序列中训练时常见的梯度消失和梯度爆炸问题。LSTM通过引入 遗忘门输入门输出门来控制信息的流动,从而保留长期信息和删除不必要的信息。

  • 遗忘门 :决定哪些信息需要被丢弃。
  • 输入门 :决定哪些新信息需要加入到细胞状态中。
  • 输出门 :决定输出的内容。
全连接层

全连接层是深度学习中的基础组件,每个神经元与前一层的所有神经元都有连接。FC-LSTM通过在LSTM的基础上添加全连接层,能够实现更复杂的特征学习。

2. 模型结构

FC-LSTM通常由多个LSTM层和全连接层组成,具体结构如下:

  1. 输入层 :接受输入时序数据,通常是三维张量(样本数,时间步,特征数)。
  2. LSTM层 :一个或多个LSTM层,用于提取时序特征。
  3. 全连接层 :将LSTM层的输出连接到一个或多个全连接层,进行最终的预测。
  4. 输出层 :根据具体任务(回归或分类)输出预测结果。
示例结构
  • 输入层:输入数据的维度为 (批大小, 时间步数, 特征维度)
  • LSTM层1:输出维度可以设定为128
  • LSTM层2:输出维度可以设定为64
  • 全连接层:输出维度为目标维度
  • 输出层:输出最终预测结果

3. 模型实现

在Python中,FC-LSTM可以通过深度学习库如TensorFlowPyTorch来实现。以下是使用Keras(TensorFlow的高层API)实现FC-LSTM的基本步骤。

import numpy as np
from keras.models import Sequential
from keras.layers import LSTM, Dense, Dropout# 假设 X_train 是输入数据,y_train 是目标变量
# 输入数据形状为 (样本数, 时间步数, 特征数)
X_train = np.random.rand(1000, 10, 5)  # 示例数据
y_train = np.random.rand(1000, 1)  # 示例目标# 创建FC-LSTM模型
model = Sequential()
model.add(LSTM(128, return_sequences=True, input_shape=(10, 5)))  # 第一层LSTM
model.add(Dropout(0.2))  # Dropout层,防止过拟合
model.add(LSTM(64))  # 第二层LSTM
model.add(Dropout(0.2))  # Dropout层,防止过拟合
model.add(Dense(1))  # 全连接层,输出维度为1# 编译模型
model.compile(optimizer='adam', loss='mean_squared_error')# 训练模型
model.fit(X_train, y_train, epochs=50, batch_size=32)

4. 优点

  • 处理长序列数据 :FC-LSTM能够有效捕捉长时间依赖性,适用于复杂时序预测任务。
  • 高表达能力 :通过引入全连接层,FC-LSTM可以学习更复杂的特征表示。
  • 防止过拟合 :可以通过添加Dropout层来降低模型的过拟合风险。

5. 超参数调优

在训练FC-LSTM模型时,以下超参数可以调整:

  • LSTM单元数 :设置每层LSTM的单元数,通常为64、128或256。
  • 时间步数 :输入序列的时间步数,需根据具体任务设定。
  • 批大小 :每次迭代时用于训练的样本数,常用的设置为32、64或128。
  • 学习率 :优化器的学习率,通常需要调优以获得最佳结果。

6. 局限性

  • 训练时间 :由于LSTM结构的复杂性,FC-LSTM的训练时间通常较长。
  • 参数调整 :需要仔细调整超参数,以避免过拟合或欠拟合。
  • 对长序列的依赖性 :尽管LSTM能捕捉长依赖,但在极长序列情况下仍可能面临困难。

7. 应用场景

  • 时间序列预测 :如股票价格预测、气象预测等。
  • 自然语言处理 :如文本生成、机器翻译等。
  • 视频分析 :如动作识别、视频分类等。

8. 总结

FC-LSTM是一种强大的时序数据处理模型,结合了LSTM的长依赖处理能力和全连接层的特征学习能力。其在时序预测、自然语言处理和视频分析等领域表现出色,适合处理复杂的动态数据。尽管训练和调参过程可能较为复杂,但其卓越的性能使其成为时序数据分析中的重要工具。

其他模型

以下是对 GCN(图卷积网络)、DCRNN(扩散卷积递归神经网络)、FCCF(城市人流预测模型)和 ST-MGCN(时空多图卷积网络)的介绍:

模型(GCN、DCRNN、FCCF和ST-MGCN)在时序数据、图结构数据和城市人流预测等领域表现出色。它们结合了图卷积、递归神经网络及高斯马尔可夫随机场等多种技术,提供了强大的能力以应对复杂的数据分析任务。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

参考

https://www.statsmodels.org/stable/index.html
http://urban-computing.com/pdf/MVGCN_Final_Version.pdf
https://www.ncbi.nlm.nih.gov/pmc/articles/PMC9185130/
https://github.com/underdoc-wang/ST-MGCN
https://dl.acm.org/doi/10.1145/3532611

在这里插入图片描述

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

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

相关文章

智能家居的“眼睛”:计算机视觉如何让家更智能

引言 在不远的未来,当我们走进家门,灯光自动亮起,空调已经调至最舒适的温度,甚至音乐也播放着我们最喜欢的歌曲。 这一切,都得益于智能家居系统的发展。而在这个系统中,计算机视觉技术扮演着至关重要的角色…

SpringBoot车辆管理系统:构建与优化

4系统概要设计 4.1概述 本系统采用B/S结构(Browser/Server,浏览器/服务器结构)和基于Web服务两种模式,是一个适用于Internet环境下的模型结构。只要用户能连上Internet,便可以在任何时间、任何地点使用。系统工作原理图如图4-1所示: 图4-1系统工作原理…

群晖通过 Docker 安装 MySQL

1. 打开 Docker 应用,并在注册表搜索 MySQL 2. 下载 MySQL 镜像,并选择版本 3. 在 Docker 文件夹中创建 MySQL,并创建子文件夹 4. 设置权限 5. 选择 MySQL 映像运行,创建容器 6. 配置 MySQL 容器 6.1 使用高权限执行容器 6.2 启…

scrapy 爬虫学习之【中医药材】爬虫

本项目纯学习使用。 1 scrapy 代码 爬取逻辑非常简单,根据url来处理翻页,然后获取到详情页面的链接,再去爬取详情页面的内容即可,最终数据落地到excel中。 经测试,总计获取 11299条中医药材数据。 import pandas as…

idea 2023 配置 web service

前言 能在网上查到的资料,都是比较老的,搞了一上午才配置好了环境 因此记录一下,服务你我他 我的环境: java 1.8,Idea2023.1 配置web service 服务端 直接新建一个java新项目 下载插件 添加框架支持 启动项目 配置web service 客户端 新建项目,下载三个插件的步骤和上面服务…

JMeter之mqtt-jmeter 插件介绍

前言 mqtt-jmeter插件是JMeter中的一个第三方插件,用于支持MQTT(Message Queuing Telemetry Transport)协议的性能测试。MQTT是一种轻量级的发布/订阅消息传输协议,广泛应用于物联网和传感器网络中。 一、安装插件 mqtt-jmeter项目…

【Hive】6-Hive函数、运算符使用

Hive函数、运算符使用 Hive内置运算符 概述 整体上,Hive支持的运算符可以分为三大类:关系运算、算术运算、逻辑运算。 官方参考文档:https://cwiki.apache.org/confluence/display/Hive/LanguageManualUDF 也可以使用下述方式查看运算符的…

2024年AI 制作PPT新宠儿,3款神器集锦,让你的演示与众不同

咱们今儿聊聊最近超火的AI做PPT的工具。这年头,谁不想省事儿,少熬夜加班,多享受享受生活啊?所以,AI开始帮咱们搞定做PPT这种费时的活儿,我自然得好好研究研究。今天,我就给大家详细说说三款很火…

Linux下的进程解析(level 2)

目录 引言 pid解析 /proc 系统调用 fork :创建子进程 执行流分析 父子进程谁先运行 引言 在当今的信息技术时代,操作系统作为计算机系统的核心组件,承担着资源管理、任务调度等重要职责。Linux作为一种开源、高性能的操作系统&#xf…

第11篇:网络安全协议

目录 引言 11.1 安全套接字层(SSL)和传输层安全(TLS)协议 11.1.1 SSL/TLS 的工作原理 11.1.2 SSL/TLS 的应用场景 11.2 虚拟专用网(VPN)和 IP 安全协议(IPSec) 11.2.1 VPN 的工…

《深度学习》OpenCV EigenFaces算法 人脸识别

目录 一、EigenFaces算法 1、什么是EigenFaces算法 2、原理 3、实现步骤 1)数据预处理 2)特征提取 3)构建模型 4)识别 4、优缺点 1)优点 2)缺点 二、案例实现 1、完整代码 运行结果&#xff…

9.存储过程安全性博客大纲(9/10)

存储过程安全性博客大纲 引言 在数据库系统中,存储过程是一种预先编写好的SQL代码集合,它被保存在数据库服务器上,可以通过指定的名称来调用执行。存储过程可以包含一系列的控制流语句,如IF条件语句、WHILE循环等,使…

「从零开始的 Vue 3 系列」:第十一章——跨域问题解决方案全解析

前言 本系列将从零开始,系统性地介绍 Vue 3 的常用 API,逐步深入每个核心概念与功能模块。通过详尽的讲解与实战演示,帮助大家掌握 Vue 3 的基础与进阶知识,最终具备独立搭建完整 Vue 3 项目的能力。 第十一章:跨域问…

Win32图片库CxImage在vs2022下的编译和使用

一、编译CxImage库 1、下载CxImage_702库的源码:在下面的链接中下载cximage702_full.7z https://sourceforge.net/projects/cximage/files/7.02/ 2、解压到某一目录,vs2022打开CxImageFull_vc10.sln解决方案文件,提示升级点确定 3、先编译下面的这几…

基于SSM+微信小程序的房屋租赁管理系统(房屋2)

👉文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1、项目介绍 基于SSM微信小程序的房屋租赁管理系统实现了有管理员、中介和用户。 1、管理员功能有,个人中心,用户管理,中介管理,房屋信息管理&#xff…

[Linux] 逐层深入理解文件系统 (2)—— 文件重定向

标题:[Linux] 逐层深入理解文件系统 (2)—— 文件重定向 个人主页水墨不写bug (图片来源于网络) 目录 一、文件的读取和写入 二、文件重定向的本质 1.手动模拟重定向的过程——把标准输出重定向到redir.txt 2.重定向…

019_基于python+django食品销售数据分析系统2024_4032ydxt

目录 系统展示 开发背景 代码实现 项目案例 获取源码 博主介绍:CodeMentor毕业设计领航者、全网关注者30W群落,InfoQ特邀专栏作家、技术博客领航者、InfoQ新星培育计划导师、Web开发领域杰出贡献者,博客领航之星、开发者头条/腾讯云/AW…

基于SpringBoot的“社区医院管理服务系统”的设计与实现(源码+数据库+文档+PPT)

基于SpringBoot的“社区医院管理服务系统”的设计与实现(源码数据库文档PPT) 开发语言:Java 数据库:MySQL 技术:SpringBoot 工具:IDEA/Ecilpse、Navicat、Maven 系统展示 系统首页界面图 用户注册界面图 医生界面…

这4款实用的工具简直就是硬盘数据丢失的救星。

硬盘数据丢失的情况有很多种,像误删除,格式化,病毒攻击,硬件故障等等。如果不是物理上的损坏,丢失的数据还是可以通过一些方法进行恢复的。这里就跟大家分享几款可以进行数据恢复的专业数据件,希望可以帮助…

Apache Seatunnel Zeta引擎-启动脚本分析

Apache SeaTunnel Zeta引擎的集群模式启动的第一步是执行bin/seatunnel-cluster.sh脚本,所以先来学习下这个脚本。 脚本执行流程分析 脚本简要注释 #!/bin/bash # # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license a…