聚类算法(上):8个常见的无监督聚类方法介绍和比较

news/2024/4/26 8:11:37/文章来源:https://blog.csdn.net/m0_46510245/article/details/129223454

无监督聚类方法的评价指标必须依赖于数据和聚类结果的内在属性,例如聚类的紧凑性和分离性,与外部知识的一致性,以及同一算法不同运行结果的稳定性。

本文将全面概述Scikit-Learn库中用于的聚类技术以及各种评估方法。

本文将分为2个部分,1、常见算法比较 2、聚类技术的各种评估方法

本文作为第一部分将介绍和比较各种聚类算法:

  • K-Means
  • Affinity Propagation
  • Agglomerative Clustering
  • Mean Shift Clustering
  • Bisecting K-Means
  • DBSCAN
  • OPTICS
  • BIRCH

首先我们生成一些数据,后面将使用这些数据作为聚类技术的输入。

 importpandasaspdimportnumpyasnpimportseabornassnsimportmatplotlib.pyplotasplt#Set the number of samples and featuresn_samples=1000n_features=4#Create an empty array to store the datadata=np.empty((n_samples, n_features))#Generate random data for each featureforiinrange(n_features):data[:, i] =np.random.normal(size=n_samples)#Create 5 clusters with different densities and centroidscluster1=data[:200, :] +np.random.normal(size=(200, n_features), scale=0.5)cluster2=data[200:400, :] +np.random.normal(size=(200, n_features), scale=1) +np.array([5,5,5,5])cluster3=data[400:600, :] +np.random.normal(size=(200, n_features), scale=1.5) +np.array([-5,-5,-5,-5])cluster4=data[600:800, :] +np.random.normal(size=(200, n_features), scale=2) +np.array([5,-5,5,-5])cluster5=data[800:, :] +np.random.normal(size=(200, n_features), scale=2.5) +np.array([-5,5,-5,5])#Combine the clusters into one datasetX=np.concatenate((cluster1, cluster2, cluster3, cluster4, cluster5))# Plot the dataplt.scatter(X[:, 0], X[:, 1])plt.show()

结果如下:

我们将用特征值和簇ID创建一个DF。稍后在模型性能时将使用这些数据。

 df=pd.DataFrame(X, columns=["feature_1", "feature_2", "feature_3", "feature_4"])cluster_id=np.concatenate((np.zeros(200), np.ones(200), np.full(200, 2), np.full(200, 3), np.full(200, 4)))df["cluster_id"] =cluster_iddf

现在我们将构建和可视化8个不同的聚类模型:

1、K-Means

K-Means聚类算法是一种常用的聚类算法,它将数据点分为K个簇,每个簇的中心点是其所有成员的平均值。K-Means算法的核心是迭代寻找最优的簇心位置,直到达到收敛状态。

K-Means算法的优点是简单易懂,计算速度较快,适用于大规模数据集。但是它也存在一些缺点,例如对于非球形簇的处理能力较差,容易受到初始簇心的选择影响,需要预先指定簇的数量K等。此外,当数据点之间存在噪声或者离群点时,K-Means算法可能会将它们分配到错误的簇中。

 #K-Meansfromsklearn.clusterimportKMeans#Define function:kmeans=KMeans(n_clusters=5)#Fit the model:km=kmeans.fit(X)km_labels=km.labels_#Print results:#print(kmeans.labels_)#Visualise results:plt.scatter(X[:, 0], X[:, 1], c=kmeans.labels_,      s=70, cmap='Paired')plt.scatter(kmeans.cluster_centers_[:, 0],kmeans.cluster_centers_[:, 1],marker='^', s=100, linewidth=2, c=[0, 1, 2, 3, 4])

2、Affinity Propagation

Affinity Propagation是一种基于图论的聚类算法,旨在识别数据中的"exemplars"(代表点)和"clusters"(簇)。与K-Means等传统聚类算法不同,Affinity Propagation不需要事先指定聚类数目,也不需要随机初始化簇心,而是通过计算数据点之间的相似性得出最终的聚类结果。

Affinity Propagation算法的优点是不需要预先指定聚类数目,且能够处理非凸形状的簇。但是该算法的计算复杂度较高,需要大量的存储空间和计算资源,并且对于噪声点和离群点的处理能力较弱。

 fromsklearn.clusterimportAffinityPropagation#Fit the model:af=AffinityPropagation(preference=-563, random_state=0).fit(X)cluster_centers_indices=af.cluster_centers_indices_af_labels=af.labels_n_clusters_=len(cluster_centers_indices)#Print number of clusters:print(n_clusters_)importmatplotlib.pyplotaspltfromitertoolsimportcycleplt.close("all")plt.figure(1)plt.clf()colors=cycle("bgrcmykbgrcmykbgrcmykbgrcmyk")fork, colinzip(range(n_clusters_), colors):class_members=af_labels==kcluster_center=X[cluster_centers_indices[k]]plt.plot(X[class_members, 0], X[class_members, 1], col+".")plt.plot(cluster_center[0],cluster_center[1],"o",markerfacecolor=col,markeredgecolor="k",markersize=14,)forxinX[class_members]:plt.plot([cluster_center[0], x[0]], [cluster_center[1], x[1]], col)plt.title("Estimated number of clusters: %d"%n_clusters_)plt.show()

3、Agglomerative Clustering

凝聚层次聚类(Agglomerative Clustering)是一种自底向上的聚类算法,它将每个数据点视为一个初始簇,并将它们逐步合并成更大的簇,直到达到停止条件为止。在该算法中,每个数据点最初被视为一个单独的簇,然后逐步合并簇,直到所有数据点被合并为一个大簇。

Agglomerative Clustering算法的优点是适用于不同形状和大小的簇,且不需要事先指定聚类数目。此外,该算法也可以输出聚类层次结构,便于分析和可视化。缺点是计算复杂度较高,尤其是在处理大规模数据集时,需要消耗大量的计算资源和存储空间。此外,该算法对初始簇的选择也比较敏感,可能会导致不同的聚类结果。

 fromsklearn.clusterimportAgglomerativeClustering#Fit the model:clustering=AgglomerativeClustering(n_clusters=5).fit(X)AC_labels=clustering.labels_n_clusters=clustering.n_clusters_print("number of estimated clusters : %d"%clustering.n_clusters_)# Plot clustering resultscolors= ['purple', 'orange', 'green', 'blue', 'red']forindex, metricinenumerate([#"cosine", "euclidean", #"cityblock"]):model=AgglomerativeClustering(n_clusters=5, linkage="ward", affinity=metric)model.fit(X)plt.figure()plt.axes([0, 0, 1, 1])forl, cinzip(np.arange(model.n_clusters), colors):plt.plot(X[model.labels_==l].T, c=c, alpha=0.5)plt.axis("tight")plt.axis("off")plt.suptitle("AgglomerativeClustering(affinity=%s)"%metric, size=20)plt.show()

4、Mean Shift Clustering

Mean Shift Clustering是一种基于密度的非参数聚类算法,其基本思想是通过寻找数据点密度最大的位置(称为"局部最大值"或"高峰"),来识别数据中的簇。算法的核心是通过对每个数据点进行局部密度估计,并将密度估计的结果用于计算数据点移动的方向和距离。算法的核心是通过对每个数据点进行局部密度估计,并将密度估计的结果用于计算数据点移动的方向和距离。

Mean Shift Clustering算法的优点是不需要指定簇的数目,且对于形状复杂的簇也有很好的效果。算法还能够有效地处理噪声数据。他的缺点也是计算复杂度较高,尤其是在处理大规模数据集时,需要消耗大量的计算资源和存储空间,该算法还对初始参数的选择比较敏感,需要进行参数调整和优化。

 fromsklearn.clusterimportMeanShift, estimate_bandwidth# The following bandwidth can be automatically detected usingbandwidth=estimate_bandwidth(X, quantile=0.2, n_samples=100)#Fit the model:ms=MeanShift(bandwidth=bandwidth)ms.fit(X)MS_labels=ms.labels_cluster_centers=ms.cluster_centers_labels_unique=np.unique(labels)n_clusters_=len(labels_unique)print("number of estimated clusters : %d"%n_clusters_)fromitertoolsimportcycleplt.figure(1)plt.clf()colors=cycle("bgrcmykbgrcmykbgrcmykbgrcmyk")fork, colinzip(range(n_clusters_), colors):my_members=labels==kcluster_center=cluster_centers[k]plt.plot(X[my_members, 0], X[my_members, 1], col+".")plt.plot(cluster_center[0],cluster_center[1],"o",markerfacecolor=col,markeredgecolor="k",markersize=14,)plt.title("Estimated number of clusters: %d"%n_clusters_)plt.show()

5、Bisecting K-Means

Bisecting K-Means是一种基于K-Means算法的层次聚类算法,其基本思想是将所有数据点划分为一个簇,然后将该簇分成两个子簇,并对每个子簇分别应用K-Means算法,重复执行这个过程,直到达到预定的聚类数目为止。

算法首先将所有数据点视为一个初始簇,然后对该簇应用K-Means算法,将该簇分成两个子簇,并计算每个子簇的误差平方和(SSE)。然后,选择误差平方和最大的子簇,并将其再次分成两个子簇,重复执行这个过程,直到达到预定的聚类数目为止。

Bisecting K-Means算法的优点是具有较高的准确性和稳定性,能够有效地处理大规模数据集,并且不需要指定初始聚类数目。该算法还能够输出聚类层次结构,便于分析和可视化。缺点是计算复杂度较高,尤其是在处理大规模数据集时,需要消耗大量的计算资源和存储空间。此外该算法对初始簇的选择也比较敏感,可能会导致不同的聚类结果。

 fromsklearn.clusterimportBisectingKMeans#Build and fit model:bisect_means=BisectingKMeans(n_clusters=5).fit(X)BKM_labels=bisect_means.labels_#Print model attributes:#print('Labels: ', bisect_means.labels_)print('Number of clusters: ', bisect_means.n_clusters)#Define varaibles to be included in scatterdot:y=bisect_means.labels_#print(y)centers=bisect_means.cluster_centers_# Visualize the results using a scatter plotplt.scatter(X[:, 0], X[:, 1], c=y)plt.scatter(centers[:, 0], centers[:, 1], c='r', s=100)plt.show()

6、DBSCAN

DBSCAN (Density-Based Spatial Clustering of Applications with Noise)是一种基于密度的聚类算法,其可以有效地发现任意形状的簇,并能够处理噪声数据。DBSCAN算法的核心思想是:对于一个给定的数据点,如果它的密度达到一定的阈值,则它属于一个簇中;否则,它被视为噪声点。

DBSCAN算法的优点是能够自动识别簇的数目,并且对于任意形状的簇都有较好的效果。并且还能够有效地处理噪声数据,不需要预先指定簇的数目。缺点是对于密度差异较大的数据集,可能会导致聚类效果不佳,需要进行参数调整和优化。另外该算法对于高维数据集的效果也不如其他算法

 fromsklearn.clusterimportDBSCANdb=DBSCAN(eps=3, min_samples=10).fit(X)DBSCAN_labels=db.labels_# Number of clusters in labels, ignoring noise if present.n_clusters_=len(set(labels)) - (1if-1inlabelselse0)n_noise_=list(labels).count(-1)print("Estimated number of clusters: %d"%n_clusters_)print("Estimated number of noise points: %d"%n_noise_)unique_labels=set(labels)core_samples_mask=np.zeros_like(labels, dtype=bool)core_samples_mask[db.core_sample_indices_] =Truecolors= [plt.cm.Spectral(each) foreachinnp.linspace(0, 1, len(unique_labels))]fork, colinzip(unique_labels, colors):ifk==-1:# Black used for noise.col= [0, 0, 0, 1]class_member_mask=labels==kxy=X[class_member_mask&core_samples_mask]plt.plot(xy[:, 0],xy[:, 1],"o",markerfacecolor=tuple(col),markeredgecolor="k",markersize=14,)xy=X[class_member_mask&~core_samples_mask]plt.plot(xy[:, -1],xy[:, 1],"o",markerfacecolor=tuple(col),markeredgecolor="k",markersize=6,)plt.title(f"Estimated number of clusters: {n_clusters_}")plt.show()

7、OPTICS

OPTICS(Ordering Points To Identify the Clustering Structure)是一种基于密度的聚类算法,其能够自动确定簇的数量,同时也可以发现任意形状的簇,并能够处理噪声数据。OPTICS算法的核心思想是:对于一个给定的数据点,通过计算它到其它点的距离,确定其在密度上的可达性,从而构建一个基于密度的距离图。然后,通过扫描该距离图,自动确定簇的数量,并对每个簇进行划分。

OPTICS算法的优点是能够自动确定簇的数量,并能够处理任意形状的簇,并能够有效地处理噪声数据。该算法还能够输出聚类层次结构,便于分析和可视化。缺点是计算复杂度较高,尤其是在处理大规模数据集时,需要消耗大量的计算资源和存储空间。另外就是该算法对于密度差异较大的数据集,可能会导致聚类效果不佳。

 fromsklearn.clusterimportOPTICSimportmatplotlib.gridspecasgridspec#Build OPTICS model:clust=OPTICS(min_samples=3, min_cluster_size=100, metric='euclidean')# Run the fitclust.fit(X)space=np.arange(len(X))reachability=clust.reachability_[clust.ordering_]OPTICS_labels=clust.labels_[clust.ordering_]labels=clust.labels_[clust.ordering_]plt.figure(figsize=(10, 7))G=gridspec.GridSpec(2, 3)ax1=plt.subplot(G[0, 0])ax2=plt.subplot(G[1, 0])# Reachability plotcolors= ["g.", "r.", "b.", "y.", "c."]forklass, colorinzip(range(0, 5), colors):Xk=space[labels==klass]Rk=reachability[labels==klass]ax1.plot(Xk, Rk, color, alpha=0.3)ax1.plot(space[labels==-1], reachability[labels==-1], "k.", alpha=0.3)ax1.set_ylabel("Reachability (epsilon distance)")ax1.set_title("Reachability Plot")# OPTICScolors= ["g.", "r.", "b.", "y.", "c."]forklass, colorinzip(range(0, 5), colors):Xk=X[clust.labels_==klass]ax2.plot(Xk[:, 0], Xk[:, 1], color, alpha=0.3)ax2.plot(X[clust.labels_==-1, 0], X[clust.labels_==-1, 1], "k+", alpha=0.1)ax2.set_title("Automatic Clustering\nOPTICS")plt.tight_layout()plt.show()

8、BIRCH

BIRCH(Balanced Iterative Reducing and Clustering using Hierarchies)是一种基于层次聚类的聚类算法,其可以快速地处理大规模数据集,并且对于任意形状的簇都有较好的效果。BIRCH算法的核心思想是:通过对数据集进行分级聚类,逐步减小数据规模,最终得到簇结构。BIRCH算法采用一种类似于B树的结构,称为CF树,它可以快速地插入和删除子簇,并且可以自动平衡,从而确保簇的质量和效率。

BIRCH算法的优点是能够快速处理大规模数据集,并且对于任意形状的簇都有较好的效果。该算法对于噪声数据和离群点也有较好的容错性。缺点是对于密度差异较大的数据集,可能会导致聚类效果不佳,对于高维数据集的效果也不如其他算法。

 importmatplotlib.colorsascolorsfromsklearn.clusterimportBirch, MiniBatchKMeansfromtimeimporttimefromitertoolsimportcycle# Use all colors that matplotlib provides by default.colors_=cycle(colors.cnames.keys())fig=plt.figure(figsize=(12, 4))fig.subplots_adjust(left=0.04, right=0.98, bottom=0.1, top=0.9)# Compute clustering with BIRCH with and without the final clustering step# and plot.birch_models= [Birch(threshold=1.7, n_clusters=None),Birch(threshold=1.7, n_clusters=5),]final_step= ["without global clustering", "with global clustering"]forind, (birch_model, info) inenumerate(zip(birch_models, final_step)):t=time()birch_model.fit(X)print("BIRCH %s as the final step took %0.2f seconds"% (info, (time() -t)))# Plot resultlabels=birch_model.labels_centroids=birch_model.subcluster_centers_n_clusters=np.unique(labels).sizeprint("n_clusters : %d"%n_clusters)ax=fig.add_subplot(1, 3, ind+1)forthis_centroid, k, colinzip(centroids, range(n_clusters), colors_):mask=labels==kax.scatter(X[mask, 0], X[mask, 1], c="w", edgecolor=col, marker=".", alpha=0.5)ifbirch_model.n_clustersisNone:ax.scatter(this_centroid[0], this_centroid[1], marker="+", c="k", s=25)ax.set_ylim([-12, 12])ax.set_xlim([-12, 12])ax.set_autoscaley_on(False)ax.set_title("BIRCH %s"%info)plt.show()

总结

上面就是我们常见的8个聚类算法,我们对他们进行了简单的说明和比较,并且用sklearn演示了如何使用,在下一篇文章中我们将介绍聚类模型评价方法。

https://avoid.overfit.cn/post/e8ecff6dce514fbbbad9c6d6b882fe4e

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

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

相关文章

LearnOpenGL-入门-纹理

本人刚学OpenGL不久且自学,文中定有代码、术语等错误,欢迎指正 我写的项目地址:https://github.com/liujianjie/LearnOpenGLProject LearnOpenGL中文官网:https://learnopengl-cn.github.io/ 文章目录纹理纹理环绕方式纹理过滤多…

【java基础】包装类,自动装箱和自动拆箱

文章目录基本介绍包装类自动装箱自动拆箱包装类注意事项包装类比较包装器内容不可变基本介绍 有时,需要将int这样的基本类型转换为对象。所有的基本类型都有一个与之对应的类。 例如,Integer类对应基本类型int。通常,这些类称为包装器&#…

使用file-selector-button美化原生文件上传

前言 你平时见到的上传文件是下面这样的? 还是下面这种美化过的button样式 还是下面这种复杂的上传组件。 <input type="file" >:只要指定的是type类型的input,打开浏览器就是上面第一种原生的浏览器默认的很丑的样式。 下面的两种是我从ElementUI截的图,…

OpenAPI SDK组件介绍

背景 公司成立以来&#xff0c;积累了数以万计的可复用接口。上层的SaaS业务&#xff0c;原则上要复用这些接口开发自己的业务&#xff0c;为了屏蔽调用接口的复杂性&#xff0c;基础服务开发了apisdk组件&#xff0c;定义了一套声明OpenAPI的注解、注解解析器&#xff0c;实例…

scrapy下载图片

&#x1f431; 个人主页&#xff1a;莎萌玩家&#x1f64b;‍♂️ 作者简介&#xff1a;全栈领域新星创作者、专注于全栈各领域技术&#xff0c;共同学习共同进步&#xff0c;一起加油呀&#xff01;&#x1f4ab;系列专栏&#xff1a;网络爬虫、WEB全栈开发&#x1f4e2; 资料…

你应该知道的ChatGPT提示语

ChatGPT 自上线以来&#xff0c;凭借其优异的自然语言理解和输出能力&#xff0c;仅花 5天就成为了活跃用户过百万的现象级产品。而上一个现象级产品 instagram 花了 2 个半月。到目前为止 ChatGPT 在全球累计用户数量已经过亿&#xff0c;相信现在也有很多人在跟 ChatGPT 聊过…

OKR 与 KPI有何异同?各部门OKR实例【小bu】

OKR 与 KPI&#xff0c;如何本土化是关键 近期公司计划对去年实施的绩效考核方案进行优化&#xff0c;公司以往采用 KPI 绩效考核方式&#xff0c;产生了一些争议。一方面&#xff0c;执行期间部分部门一度忽略指标设置的真实目的&#xff0c;导致出现短视思维和行为&#xff1…

TCP协议原理二

文章目录四、滑动窗口二、流量窗口三、拥塞控制四、滑动窗口 前面我们学习了 确认应答&#xff0c;超时重传&#xff0c;连接管理&#xff0c;这些机制都为我们TCP的可靠性提供了保证&#xff0c;当然在保证TCP的可靠性的同时&#xff0c;传输效率也受到了一定的影响&#xff…

05 DC-AC逆变器(DCAC Converter / Inverter)简介

文章目录0、概述逆变原理方波变换阶梯波变换斩控调制方式逆变器分类逆变器波形指标1、方波变换器A 单相单相全桥对称单脉冲调制移相单脉冲调制单相半桥2、方波变换器B 三相180度导通120度导通&#xff08;线、相的关系与180度相反&#xff09;3、阶梯波逆变器独立直流源二极管钳…

BLIP2-图像文本预训练

文章目录摘要解决问题算法模型结构通过frozen图像编码器学习视觉语言表征图像文本对比学习&#xff08;ITC&#xff09;基于图像文本生成&#xff08;ITG&#xff09;图文匹配&#xff08;ITM&#xff09;从大规模语言模型学习视觉到语言生成模型预训练预训练数据预训练图像编码…

Gehpi的网络布局

Gehpi的网络布局1. 力引导布局2. 辅助布局布局是网络可视化中的重要概念&#xff0c;指将点和边通过某种策略进行排布&#xff0c;应尽可能满足以下4个原则&#xff1a; 节点均匀分布在有限的区域内避免边的交叉和弯曲保持边的长度一致整体布局能反映图内在的特性 Gephi的布局…

Vision Transformer学习了什么-WHAT DO VISION TRANSFORMERS LEARN? A VISUAL EXPLORATION

WHAT DO VISION TRANSFORMERS LEARN? A VISUAL EXPLORATION 文章地址 代码地址 摘要 视觉转换器( Vision Transformers&#xff0c;ViTs )正在迅速成为计算机视觉的事实上的架构&#xff0c;但我们对它们为什么工作和学习什么知之甚少。虽然现有研究对卷积神经网络的机制进…

Bunifu.UI.WinForms 6.0.2 Crack

Bunifu.UI.WinForms为 WinForms创建令人惊叹的UI Bunifu.UI.WinForms我们为您提供了现代化的快速用户界面控件。用于 WinForms C# 和 VB.NET 应用程序开发的完美 UI 工具 简单 Bunifu.UI.WinForms没有臃肿的特征。正是您构建令人惊叹的 WinForms 应用程序所需要的。只需拖放然…

JavaSe第3次笔记

1.String str "hello";字符串类型。 2.两个字符串类型相加意思是拼接&#xff0c;类似于c语言里面的strcat函数。 3.整型变成字符串类型: int a 10; String str String. valueOf(a); 4.当字符串和其他类型进行相加的时候&#xff0c;结果就是字符串。(不完全…

MS9132是一款USB 3 0投屏芯片,内部集成USB 3 0 Device控制器、数据收发模块、音视频处理模块

MS9132是一款USB 3.0投屏芯片&#xff0c;内部集成USB 3.0 Device控制器、数据收发模块、音视频处理模块。MS9132可以通过USB 3.0接口将PC、智能手机、平板电脑上的信息显示或扩展到更大尺寸的显示设备&#xff0c;支持HDMI视频接口输出。 主要功能特征 HDMI 1.4b兼容 支持EDI…

RK3568编译Android11和目录讲解

文章目录 前言一、下载android11源码二、环境搭建1.增加交换内存三、编译瑞芯微原厂源码四、目录讲解总结前言 本文记录在Ubuntu18.04中编译Android11,只有编译了源码,后面才能进行驱动的开发,有兴趣的小伙伴可以和我一起学习吧! 提示:以下是本篇文章正文内容,下面案例可…

【华为OD机试模拟题】用 C++ 实现 - 剩余可用字符集 or @分割可用字符集(2023.Q1)

最近更新的博客 【华为OD机试模拟题】用 C++ 实现 - 获得完美走位(2023.Q1) 文章目录 最近更新的博客使用说明剩余可用字符集 or @分割可用字符集题目输入输出示例一输入输出说明Code使用说明 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,通过率才…

烙铁使用方法

烙铁使用 烙铁是硬件工程师最经常使用的工具之一,一把性能保持良好的烙铁能帮助我们快速进行电路调试。烙铁第一次加热时采用焊锡均匀涂覆在烙铁头上,以便去除包在烙铁头上面的氧化物。在工作中我们需要根据情况选择合适的烙铁头类型,合适的温度进行操作。完成焊接后要在烙铁…

华为OD机试用Python实现 -【贪心的商人 or 最大利润】(2023-Q1 新题)

华为OD机试题 华为OD机试300题大纲贪心的商人 or 最大利润题目描述输入描述输出描述说明示例一输入输出示例二输入输出Python 代码实现华为OD机试300题大纲 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,通过率才会高。 华为 OD 清单查看地址:blog.c…

基于SpringCloud的可靠消息最终一致性01:定理、解决方案和框架

在互联网发展的早期,单体架构是主流的开发模式。因为访问的用户不多,所以整个系统的结构比较简单,就像一口竖井,从上到下,一通到底,如下图所示: 图一:单体应用 随着业务复杂度的不断提升,以及用户需求的不断增加,原来单个的业务系统已经不堪重负了。就好像一个窗口前…