基于Spark的传感器数据实时分析与预测

基于Spark的传感器数据实时分析与预测

关键词:Spark、传感器数据、实时分析、预测、大数据处理

摘要:本文主要探讨了如何利用Spark进行传感器数据的实时分析与预测。首先介绍了相关的背景知识,包括Spark的基本概念和传感器数据的特点。接着详细解释了核心概念,如Spark的组件、传感器数据的采集与处理等,并阐述了它们之间的关系。通过数学模型和公式说明分析与预测的原理,给出了项目实战的具体步骤,包括开发环境搭建、源代码实现与解读。最后讨论了实际应用场景、未来发展趋势与挑战,并进行总结和提出思考题。

背景介绍

目的和范围

我们生活在一个充满传感器的时代,从智能手环到工业设备中的各种传感器,它们每时每刻都在产生大量的数据。这些数据蕴含着丰富的信息,如果能及时进行分析和预测,就能为我们的生活和生产带来很大的便利。本文的目的就是介绍如何使用Spark这个强大的大数据处理框架,对传感器数据进行实时分析和预测。我们的范围涵盖了从传感器数据的采集、处理,到利用Spark进行分析和预测的整个流程。

预期读者

本文适合对大数据处理和传感器技术感兴趣的初学者,以及想要了解如何利用Spark进行实时数据分析的开发者。即使你对Spark和传感器数据不太熟悉,也能通过本文逐步了解相关知识。

文档结构概述

本文首先会介绍一些基本的术语和概念,让大家对Spark和传感器数据有一个初步的认识。然后通过一个有趣的故事引出核心概念,并详细解释这些概念以及它们之间的关系。接着会介绍核心算法原理和具体操作步骤,包括相关的数学模型和公式。之后会通过一个项目实战,展示如何在实际中使用Spark进行传感器数据的实时分析与预测。还会讨论实际应用场景、推荐相关工具和资源,以及探讨未来的发展趋势与挑战。最后进行总结,并提出一些思考题供大家进一步思考。

术语表

核心术语定义
  • Spark:是一个快速、通用的集群计算系统,它提供了高级API,支持Java、Scala、Python和R等多种编程语言,可用于大规模数据处理。
  • 传感器数据:传感器是一种检测装置,能感受到被测量的信息,并将检测感受到的信息,按一定规律变换成为电信号或其他所需形式的信息输出。这些输出的信息就是传感器数据。
  • 实时分析:指的是在数据产生的同时就对其进行分析,及时得到分析结果,以便做出快速决策。
  • 预测:根据历史数据和当前数据,使用一定的算法和模型,对未来的数据或事件进行推测。
相关概念解释
  • 分布式计算:将一个大的计算任务分解成多个小的子任务,分布在多个计算节点上同时进行计算,最后将结果汇总。Spark就是基于分布式计算的思想,能高效地处理大规模数据。
  • 流处理:对连续不断产生的数据流进行实时处理,而不是等数据全部收集完再处理。Spark提供了流处理的功能,适合处理传感器产生的实时数据。
缩略词列表
  • RDD:弹性分布式数据集(Resilient Distributed Datasets),是Spark的核心数据结构,它是一个不可变的、可分区的、容错的分布式数据集。
  • DStream:离散化流(Discretized Streams),是Spark Streaming对实时数据流的抽象,它是一系列连续的RDD。

核心概念与联系

故事引入

想象一下,有一个大型的工厂,里面有各种各样的机器设备,每台设备上都安装了很多传感器。这些传感器就像工厂里的小侦探,它们不停地收集机器的各种信息,比如温度、压力、振动等。工厂的管理人员希望能够实时了解这些机器的运行状态,以便及时发现问题并进行处理,避免机器出现故障影响生产。但是,传感器产生的数据量非常大,而且是源源不断地产生,如果靠人工来处理这些数据,那简直是不可能完成的任务。这时候,就需要一个强大的工具来帮助我们处理这些数据,而Spark就是这样一个工具,它就像一个超级智能的管家,能够快速、准确地处理这些传感器数据,为管理人员提供有用的信息。

核心概念解释(像给小学生讲故事一样)

** 核心概念一:Spark **
Spark就像一个超级大的魔法盒子,里面有很多神奇的小精灵(组件)。这些小精灵可以帮助我们快速地处理大量的数据。比如,当我们有很多本书要整理分类时,一个人可能要花很长时间,但是如果有很多小精灵一起帮忙,就能很快完成任务。Spark可以在很多台计算机上同时工作,把大的任务分成很多小的任务,让每台计算机都处理一部分,最后把结果汇总起来,这样处理数据的速度就会非常快。

** 核心概念二:传感器数据 **
传感器数据就像我们身体里的小信使。比如,我们的眼睛可以看到东西,耳朵可以听到声音,这些都是我们身体的传感器。在工厂里,传感器就像机器的眼睛和耳朵,它们会把机器的各种状态信息,像温度、压力等,传递给我们。这些信息就是传感器数据,它们就像一封封信件,里面包含了很多重要的内容。

** 核心概念三:实时分析与预测 **
实时分析就像我们在看一场足球比赛,比赛正在进行中,我们要马上分析球员的表现、比分情况等,以便预测比赛的结果。在处理传感器数据时,实时分析就是在数据产生的那一刻就对它进行分析,看看机器的状态是不是正常。而预测就像是我们根据球员过去的表现和当前的比赛情况,预测这场比赛谁会赢。在传感器数据处理中,预测就是根据过去和现在的传感器数据,推测未来机器的状态,比如会不会出现故障等。

核心概念之间的关系(用小学生能理解的比喻)

** 概念一和概念二的关系:**
Spark和传感器数据就像厨师和食材的关系。传感器数据是食材,Spark是厨师。传感器把数据收集起来,就像把各种食材准备好,然后Spark这个厨师就会用这些食材做出美味的菜肴,也就是对传感器数据进行处理和分析,得到有用的信息。

** 概念二和概念三的关系:**
传感器数据和实时分析与预测就像地图和旅行计划的关系。传感器数据就像地图,它记录了机器的各种状态信息。实时分析和预测就像旅行计划,我们根据地图上的信息,比如距离、路况等,制定旅行计划,预测什么时候能到达目的地。同样,我们根据传感器数据,进行实时分析,预测机器未来的状态。

** 概念一和概念三的关系:**
Spark和实时分析与预测就像赛车和比赛策略的关系。Spark是赛车,它速度非常快,能够快速地处理数据。实时分析与预测是比赛策略,我们根据比赛的情况(传感器数据)制定策略,然后让赛车(Spark)按照策略去跑,最终赢得比赛(得到准确的分析和预测结果)。

核心概念原理和架构的文本示意图

Spark的核心架构主要包括Driver Program、Cluster Manager和Executors。Driver Program是程序的主控制程序,它负责创建SparkContext,向Cluster Manager申请资源,并将任务分配给Executors。Cluster Manager是集群资源管理器,它负责管理集群中的计算资源,比如YARN、Mesos等。Executors是在各个计算节点上运行的进程,它们负责执行具体的计算任务。

传感器数据通过采集设备收集后,传输到Spark集群中。Spark Streaming模块将数据流进行处理,转换为DStream,然后进行实时分析。分析结果可以存储在数据库中,也可以用于预测模型的训练和预测。预测模型根据历史数据和实时数据,对未来的传感器数据或事件进行预测。

Mermaid 流程图

传感器

数据采集

Spark集群

Spark Streaming

实时分析

存储结果

预测模型

预测结果

核心算法原理 & 具体操作步骤

在Spark中,我们可以使用多种算法进行传感器数据的实时分析与预测,这里以线性回归算法为例。线性回归是一种简单而常用的预测算法,它可以根据历史数据建立一个线性模型,然后根据这个模型对未来的数据进行预测。

以下是使用Python和Spark进行线性回归预测的示例代码:

frompyspark.ml.featureimportVectorAssemblerfrompyspark.ml.regressionimportLinearRegressionfrompyspark.sqlimportSparkSession# 创建SparkSessionspark=SparkSession.builder.appName("SensorDataPrediction").getOrCreate()# 加载数据data=spark.read.csv("sensor_data.csv",header=True,inferSchema=True)# 准备特征向量assembler=VectorAssembler(inputCols=["feature1","feature2"],outputCol="features")data=assembler.transform(data)# 划分训练集和测试集train_data,test_data=data.randomSplit([0.8,0.2])# 创建线性回归模型lr=LinearRegression(featuresCol="features",labelCol="target")# 训练模型model=lr.fit(train_data)# 进行预测predictions=model.transform(test_data)# 显示预测结果predictions.select("features","target","prediction").show()

具体操作步骤:

  1. 创建SparkSession:SparkSession是Spark 2.0引入的新API,它是与Spark进行交互的入口点。
  2. 加载数据:使用spark.read.csv方法加载传感器数据。
  3. 准备特征向量:使用VectorAssembler将多个特征列合并为一个特征向量列。
  4. 划分训练集和测试集:使用randomSplit方法将数据划分为训练集和测试集,比例为80%和20%。
  5. 创建线性回归模型:使用LinearRegression类创建线性回归模型,并指定特征列和标签列。
  6. 训练模型:使用fit方法对训练集进行训练,得到模型。
  7. 进行预测:使用transform方法对测试集进行预测,得到预测结果。
  8. 显示预测结果:使用select方法选择需要显示的列,并使用show方法显示结果。

数学模型和公式 & 详细讲解 & 举例说明

线性回归的数学模型可以表示为:
y=β0+β1x1+β2x2+⋯+βnxn+ϵy = \beta_0 + \beta_1x_1 + \beta_2x_2 + \cdots + \beta_nx_n + \epsilony=β0+β1x1+β2x2++βnxn+ϵ
其中,yyy是目标变量,x1,x2,⋯ ,xnx_1, x_2, \cdots, x_nx1,x2,,xn是特征变量,β0,β1,β2,⋯ ,βn\beta_0, \beta_1, \beta_2, \cdots, \beta_nβ0,β1,β2,,βn是模型的系数,ϵ\epsilonϵ是误差项。

线性回归的目标是找到一组最优的系数β0,β1,β2,⋯ ,βn\beta_0, \beta_1, \beta_2, \cdots, \beta_nβ0,β1,β2,,βn,使得预测值与实际值之间的误差最小。通常使用最小二乘法来求解这个问题,即最小化误差平方和:
S(β)=∑i=1m(yi−y^i)2S(\beta) = \sum_{i=1}^{m}(y_i - \hat{y}_i)^2S(β)=i=1m(yiy^i)2
其中,yiy_iyi是第iii个样本的实际值,y^i\hat{y}_iy^i是第iii个样本的预测值。

举例说明:假设我们有一组传感器数据,包含两个特征x1x_1x1x2x_2x2,以及一个目标变量yyy。我们可以使用线性回归模型来建立yyyx1x_1x1x2x_2x2之间的关系。通过最小二乘法求解模型的系数,得到一个线性方程。然后,当我们有新的x1x_1x1x2x_2x2值时,就可以使用这个方程预测yyy的值。

项目实战:代码实际案例和详细解释说明

开发环境搭建

  1. 安装Java:Spark是基于Java开发的,所以需要安装Java开发环境。可以从Oracle官网下载Java JDK,并按照安装向导进行安装。
  2. 安装Spark:从Spark官网下载适合自己系统的Spark版本,解压到指定目录。
  3. 安装Python和相关库:安装Python 3.x版本,并使用pip安装pyspark库。
  4. 配置环境变量:将Java和Spark的安装路径添加到系统的环境变量中。

源代码详细实现和代码解读

以下是一个完整的基于Spark的传感器数据实时分析与预测的代码示例:

frompyspark.streamingimportStreamingContextfrompyspark.ml.featureimportVectorAssemblerfrompyspark.ml.regressionimportLinearRegressionfrompyspark.sqlimportSparkSessionfrompyspark.sql.functionsimportcol# 创建SparkSessionspark=SparkSession.builder.appName("SensorDataStreaming").getOrCreate()# 创建StreamingContext,设置批处理间隔为5秒ssc=StreamingContext(spark.sparkContext,5)# 模拟传感器数据流lines=ssc.socketTextStream("localhost",9999)# 处理数据流defprocess_stream(rdd):ifnotrdd.isEmpty():# 将RDD转换为DataFramedf=spark.createDataFrame(rdd.map(lambdax:x.split(",")).map(lambdax:(float(x[0]),float(x[1]),float(x[2]))),["feature1","feature2","target"])# 准备特征向量assembler=VectorAssembler(inputCols=["feature1","feature2"],outputCol="features")data=assembler.transform(df)# 创建线性回归模型lr=LinearRegression(featuresCol="features",labelCol="target")# 训练模型model=lr.fit(data)# 进行预测predictions=model.transform(data)# 显示预测结果predictions.select("features","target","prediction").show()# 对每个RDD应用处理函数lines.foreachRDD(process_stream)# 启动流处理ssc.start()ssc.awaitTermination()

代码解读与分析

  1. 创建SparkSession和StreamingContext:SparkSession是与Spark进行交互的入口点,StreamingContext用于创建和管理流处理任务。
  2. 模拟传感器数据流:使用socketTextStream方法从本地端口9999接收数据流。
  3. 处理数据流:定义process_stream函数,对每个RDD进行处理。在函数内部,将RDD转换为DataFrame,准备特征向量,创建线性回归模型,训练模型并进行预测,最后显示预测结果。
  4. 启动流处理:使用start方法启动流处理任务,并使用awaitTermination方法等待任务结束。

实际应用场景

  • 工业制造:在工厂中,通过对机器设备上的传感器数据进行实时分析和预测,可以及时发现设备的故障隐患,提前进行维护,避免设备停机造成的损失。
  • 智能家居:智能家居系统中的各种传感器,如温度传感器、湿度传感器、光照传感器等,通过实时分析传感器数据,可以自动调节家居设备的运行状态,提高居住的舒适度。
  • 交通运输:在汽车、飞机等交通工具上安装传感器,实时监测车辆的运行状态,如车速、油耗、轮胎压力等,通过分析和预测数据,可以提前发现安全隐患,保障交通安全。

工具和资源推荐

  • Spark官方文档:Spark官方提供了详细的文档,包括API文档、教程等,是学习Spark的重要资源。
  • Python和Java编程书籍:可以学习Python和Java编程语言,以便更好地使用Spark进行开发。
  • Kafka:Kafka是一个分布式消息队列系统,可以用于收集和传输传感器数据。
  • Hadoop:Hadoop是一个开源的分布式计算平台,与Spark可以很好地集成,用于存储和处理大规模数据。

未来发展趋势与挑战

未来发展趋势

  • 与人工智能的深度融合:将Spark与深度学习、机器学习等人工智能技术相结合,提高传感器数据的分析和预测能力。
  • 边缘计算:随着物联网设备的增多,传感器数据量将急剧增加。边缘计算可以在设备端对数据进行初步处理,减少数据传输量,提高系统的响应速度。
  • 实时性要求更高:在一些对实时性要求极高的场景中,如金融交易、医疗监测等,需要进一步提高Spark的实时处理能力。

挑战

  • 数据质量问题:传感器数据可能存在噪声、缺失值等问题,需要对数据进行清洗和预处理,以提高分析和预测的准确性。
  • 系统性能优化:随着数据量的增加,Spark集群的性能可能会受到影响,需要对系统进行优化,如调整集群配置、优化算法等。
  • 安全与隐私问题:传感器数据往往包含敏感信息,如个人健康数据、企业生产数据等,需要加强数据的安全与隐私保护。

总结:学到了什么?

核心概念回顾:

我们学习了Spark、传感器数据、实时分析与预测等核心概念。Spark是一个强大的大数据处理框架,就像一个超级智能的管家;传感器数据是传感器收集的各种信息,就像一封封包含重要内容的信件;实时分析与预测是在数据产生的同时进行分析,并根据历史数据和当前数据预测未来的情况。

概念关系回顾:

我们了解了Spark和传感器数据、传感器数据和实时分析与预测、Spark和实时分析与预测之间的关系。Spark和传感器数据就像厨师和食材的关系,传感器数据和实时分析与预测就像地图和旅行计划的关系,Spark和实时分析与预测就像赛车和比赛策略的关系。

思考题:动动小脑筋

思考题一:

你能想到生活中还有哪些地方可以使用基于Spark的传感器数据实时分析与预测吗?

思考题二:

如果传感器数据中存在大量的噪声,你会如何处理这些数据,以提高分析和预测的准确性?

思考题三:

如何进一步优化基于Spark的传感器数据实时分析与预测系统的性能?

附录:常见问题与解答

问题一:Spark和Hadoop有什么区别?

Spark和Hadoop都是大数据处理框架,但它们的侧重点不同。Hadoop主要用于数据的存储和批处理,而Spark则更注重数据的实时处理和内存计算,处理速度更快。

问题二:如何安装和配置Spark?

可以从Spark官网下载适合自己系统的Spark版本,解压到指定目录。然后配置系统环境变量,将Spark的安装路径添加到PATH变量中。

问题三:如何处理传感器数据中的缺失值?

可以使用均值、中位数等统计方法填充缺失值,也可以使用机器学习算法进行预测填充。

扩展阅读 & 参考资料

  • 《Spark快速大数据分析》
  • 《Python数据分析实战》
  • Spark官方文档:https://spark.apache.org/docs/latest/
  • Kafka官方文档:https://kafka.apache.org/documentation/

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

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

相关文章

MySQL的一张表使用InnoDB引擎,创建时如果忘记给这张表添加主键,请问这边表有没有聚簇索引?如果有的话聚簇索引是什么样的?

聚簇索引创建的原则:主键存在:如果表中定义了主键,主键即为聚簇索引。没有主键时:如果没有定义主键,InnoDB 会选择第一个唯一且非空的索引作为聚簇索引。既没有主键也没有唯一索引时:如果既没有主键也没有合…

2026年RTO市场新动态:口碑供货商评测指南,旋风除尘器/沸石转轮/沸石转轮+CO/RTO,RTO制造商推荐榜 - 品牌推荐师

在日趋严格的环保法规与“双碳”目标驱动下,工业VOCs(挥发性有机物)治理已成为企业可持续运营的核心环节。作为主流高效治理技术,蓄热式热力焚烧炉(RTO)的性能与可靠性,直接关系到企业的环保合规性、运行成本及…

2026年国内诚信的沸石转轮+CO公司联系电话,沸石转轮/活性炭箱/沸石转轮+CO/除尘器,沸石转轮批发厂家排行榜单 - 品牌推荐师

引言 在化工、涂装、印刷、制药等涉及挥发性有机物(VOCs)排放的工业生产领域,沸石转轮吸附浓缩与催化燃烧(CO)组合工艺,已成为保障企业安全生产、改善作业环境、实现达标排放的核心技术装备之一。该技术凭借高净…

SMS-Activate停止运行

SMS-Activate是什么? SMS‑Activate(有时写作 SMS‑Activate.io / SMS‑Activate.org 等) 是一个在线 虚拟接码(短信接收)平台,用户可以在网站上购买或租用临时手机号码,用来接收 短信验证码(SMS OTP)。这类服…

Java服务入门级耗时/cpu/内存/io分析

1 通过JFR对某时段的cpu/耗时/内存分析 方法1: Async Profiler 下载地址: https://github.com/async-profiler/async-profiler/releases优点:轻量工具, 非侵入式修改字节码 完全避免安全点偏置问题 可直接监控native事…

详细介绍:技术演进中的开发沉思-219 Ajax:样式与事件

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

【计算机毕业设计案例】基于python-CNN卷积神经网络深度学习训练识别不同颜色的裤子识别

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

提示工程架构师:为社会变革注入新动能

提示工程架构师:为社会变革注入新动能 1. 引入与连接 1.1 引人入胜的开场 在当今数字化浪潮汹涌澎湃的时代,想象这样一个场景:一家原本传统的农业企业,面临着农产品滞销、市场渠道狭窄的困境,濒临破产边缘。然而,在一位神秘高手的助力下,这家企业通过一款创新的农产品…

深度学习计算机毕设之基于卷神经网络python-CNN-pytorch训练识别苹果树叶病害识别

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

聚焦用户体验:近期备受推荐的RTO供货商深度解析,旋风除尘器/RTO/滤筒除尘器/除尘器/沸石转轮,RTO厂家怎么选 - 品牌推荐师

在工业废气治理领域,RTO(蓄热式废气焚烧设备)作为核心处理技术,直接影响企业排放达标率与生产连续性。面对环保政策趋严与治理成本攀升的双重压力,如何选择技术可靠、服务完备的RTO供货商成为企业关注的焦点。近期…

【课程设计/毕业设计】基于深度学习python-CNN-pytorch训练识别苹果树叶病害识别

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

全网最全专科生必用TOP10 AI论文工具测评

全网最全专科生必用TOP10 AI论文工具测评 2026年专科生AI论文工具测评:如何选对工具提升写作效率 随着人工智能技术的不断发展,AI论文工具逐渐成为高校学生,尤其是专科生群体的重要辅助工具。然而,市面上的工具种类繁多&#xff0…

20250117 之所思 - 人生如梦

20250117 之所思做的不好的几件事:1. 有点浮躁,很难静下心来去做自己本该计划好的事情,自己给自己安排的几个培训始终没有去做。-- 元旦假期之后又接近春节,心情有点浮动,盼望着春节快点到来好安心的休个长假,有…

深度学习毕设项目:基于python-CNN机器学习卷积神经网络训练识别不同颜色的裤子识别

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

Bug记录:neo4j-java-driver,Cannot coerce FLOAT to Java String

遇到的神必Bug,Neo4j中数据转换为Java中的对象时发生,表面原因是Neo4j中的FLOAT数据无法转换为Java的String类型。 解决办法:把Java实体类中的对应属性换为Double类型,原因是neo4j FLOAT类型 对应java 的Double类型…

英语_听说_连读

在上海中考英语听说测试(机器考试)中,“朗读句子”环节不仅考察单词发音,更看重意群停顿和连读技巧。 连读的核心规律是:辅音 + 元音。当一个单词以辅音结尾,紧接着的单词以元音开头时,这两个音要自然地“拼”在…

《数字图像处理》第 4 章 - 频域滤波

前言频域滤波是数字图像处理的核心技术之一,其核心思想是将图像从空间域转换到频率域,通过修改频率分量实现图像增强、去噪、锐化等操作。本文将按照《数字图像处理》第 4 章的完整目录,用通俗易懂的语言讲解频域滤波的全知识点,并…

深度学习毕设项目:基于python-CNN-pytorch人工智能训练识别苹果树叶病害识别

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026年国内做得好的锻件实地厂家哪家好,船用法兰/法兰/锻件/双相钢法兰/不锈钢管板/高温合金法兰,锻件品牌选哪家 - 品牌推荐师

锻件作为工业生产中连接管道、传递动力的核心部件,其质量直接影响石化、船舶、电力等行业的设备安全与运行效率。据国内机械工业协会及行业白皮书数据显示,2025年国内锻件市场规模突破300亿元,但企业技术水平参差不…