机器学习实战-聚类算法

聚类算法是一种无监督学习的算法,用于将数据集中的数据分成不同的聚类或组。聚类算法是数据挖掘和机器学习领域中常见的技术之一,具有广泛的应用。 以下是聚类算法的一些知识点:

  1. 聚类算法的目的是将数据集划分为不同的组,使得组内的数据点相似度高,组间的相似度低。
  2. 聚类算法可以分为层次聚类和非层次聚类两种。层次聚类可以分为聚合聚类和分裂聚类两种。
  3. 常用的聚类算法包括K均值聚类、层次聚类、DBSCAN聚类等。其中,K均值聚类是最常见的聚类算法之一,它将数据集分为K个簇,每个簇的中心点被称为质心。
  4. 聚类算法的评价指标包括轮廓系数、Calinski-Harabasz指数、Davies-Bouldin指数等。
  5. 聚类算法的应用包括客户分群、文本聚类、图像分割等。
  6. 聚类算法的优化方法包括选择合适的聚类算法、确定合适的聚类簇数、选择合适的相似度度量等。
  7. 聚类算法的局限性包括需要事先确定聚类簇数、对初始质心的选择敏感、对异常值敏感等。

基于划分的聚类算法

K-Means 聚类算法

K-Means 聚类算法是一种非层次聚类算法,它将数据集分为K个簇,每个簇的中心点被称为质心。K-Means 算法的基本思想是通过不断迭代,将数据点划分到最近的质心所在的簇中,然后重新计算每个簇的质心,直到簇中心不再发生变化或达到最大迭代次数为止。

步骤:

  1. 随机的选取K个中心点,代表K个类别;
  2. 计算N个样本点和K个中心点之间的欧氏距离;
  3. 将每个样本点划分到最近的(欧氏距离最小的)中心点类别中——迭代1;
  4. 计算每个类别中样本点的均值,得到K个均值,将K个均值作为新的中心点——迭代2;
  5. 重复步骤2、3、4;
  6. 满足收敛条件后,得到收敛后的K个中心点(中心点不再变化)。

K-Means 聚类可以用欧式距离,欧式距离很简单,二维平面就是两个点的距离公式,在多维空间里,假设两个样本为 𝑎(𝑥1,𝑥2,𝑥3,𝑥4...𝑥𝑛) , 𝑏(𝑦1,𝑦2,𝑦3,𝑦4...𝑦𝑛) ,求两个样本的欧式距离。

欧式距离是两个样本之间的距离度量,它是最常用的距离度量方式之一。欧式距离指的是两个样本在 n 维空间中的坐标差的平方和的开方,即:

𝑑(𝑥,𝑦)=∑𝑖=1𝑛(𝑥𝑖−𝑦𝑖)2

其中, 和𝑥和𝑦 分别表示两个样本在 n 维空间中的坐标, 和𝑥𝑖和𝑦𝑖 分别表示两个样本在第 i 个维度上的坐标。

python代码实现:

#生成随机点
import matplotlib.pyplot as plt
import numpy as np
from sklearn.datasets.samples_generator import make_blobs
X, y_true = make_blobs(n_samples=300, centers=4,cluster_std=0.60, random_state=0)
plt.scatter(X[:, 0], X[:, 1], s=50)
plt.show()#K-Means 聚类算法
from sklearn.cluster import KMeans
"""KMeans(n_clusters=8, init='k-means++', n_init=10, max_iter=300,tol=0.0001, precompute_distances='auto', verbose=0, random_state=None, copy_x=True, n_jobs=1, algorithm='auto')Parameters:n_clusters: 聚类个数max_iter:  最大迭代数n_init:    用不同的质心初始化值运行算法的次数init:      初始化质心的方法precompute_distances:预计算距离tol:       关于收敛的参数n_jobs:    计算的进程数random_state: 随机种子copy_x:是否修改原始数据algorithm:“auto”, “full” or “elkan””full”就是我们传统的K-Means算法, “elkan”elkan K-Means算法。默认的”auto”则会根据数据值是否是稀疏的,来决定如何选择”full”和“elkan”,稠密的选 “elkan”,否则就是”full”Attributes:cluster_centers_:质心坐标Labels_: 每个点的分类 inertia_:每个点到其簇的质心的距离之和。 
"""
m_kmeans = KMeans(n_clusters=4)
from sklearn import metricsdef draw(m_kmeans,X,y_pred,n_clusters):centers = m_kmeans.cluster_centers_print(centers)plt.scatter(X[:, 0], X[:, 1], c=y_pred, s=50, cmap='viridis')#中心点(质心)用红色标出plt.scatter(centers[:, 0], centers[:, 1], c='red', s=200, alpha=0.5)print("Calinski-Harabasz score:%lf"%metrics.calinski_harabasz_score(X, y_pred) )plt.title("K-Means (clusters = %d)"%n_clusters,fontsize=20)plt.show()
m_kmeans.fit(X)
KMeans(algorithm='auto', copy_x=True, init='k-means++', max_iter=300,n_clusters=4, n_init=10, n_jobs=None, precompute_distances='auto',random_state=None, tol=0.0001, verbose=0)
y_pred = m_kmeans.predict(X)
draw(m_kmeans,X,y_pred,4)

K-Means 聚类算法升级

  1. K-Means++ 算法:K-Means++ 算法是 K-Means 算法的改进版,它通过改进初始质心的选择方式,提高了算法的聚类效果。K-Means++ 算法的初始质心选择方式是在数据集中随机选择一个点作为第一个质心,然后选择与前面已选质心距离最大的点作为下一个质心,直到选出 K 个质心。与 K-Means 算法相比,K-Means++ 算法的聚类效果更好,收敛速度更快。
  2. Mini-Batch K-Means 算法:Mini-Batch K-Means 算法是 K-Means 算法的一种变体,它采用了一种随机梯度下降的方式更新质心,从而加速了算法的收敛速度。Mini-Batch K-Means 算法将数据集划分为多个小批量,每个小批量包含一部分数据,然后在每个小批量上执行 K-Means 算法,更新质心。与 K-Means 算法相比,Mini-Batch K-Means 算法的计算速度更快,但聚类效果可能略有下降。
  3. K-Means++-C 算法:K-Means++-C 算法是一种基于 K-Means++ 算法的并行聚类算法,它可以加速大规模数据集的聚类过程。K-Means++-C 算法将数据集划分为多个子集,然后在每个子集上执行 K-Means++ 算法,得到每个子集的聚类结果。最后,将所有子集的聚类结果合并,得到最终的聚类结果。与 K-Means++ 算法相比,K-Means++-C 算法的计算速度更快,适用于大规模数据集的聚类。 这些升级版的 K-Means 算法可以根据不同的需求选择使用,以获得更好的聚类效果和更快的计算速度。

K-Means++ 算法对比K-Means 聚类算法示例

#导入必要的库
import numpy as np
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt#生成数据集
X, y = make_blobs(n_samples=300, centers=4, cluster_std=0.60, random_state=0)#定义 K-Means++ 聚类算法函数
def k_means_pp(X, K):centroids = []# 随机选择一个初始质心i = np.random.randint(0, len(X))centroids.append(X[i])# 选择剩余的质心for k in range(1, K):# 计算每个样本离最近质心的距离的平方和D2 = np.array([min([np.linalg.norm(x-c)**2 for c in centroids]) for x in X])# 按照概率分布选择下一个质心probs = D2 / D2.sum()cumprobs = probs.cumsum()r = np.random.rand()j = np.where(cumprobs >= r)[0][0]centroids.append(X[j])return centroids#定义 K-Means 聚类算法函数
def k_means(X, K, centroids):# 初始化聚类结果、距离矩阵和聚类中心clusters = np.zeros(len(X))D = np.zeros((len(X), K))for k in range(K):D[:, k] = np.linalg.norm(X - centroids[k], axis=1)# 迭代更新聚类结果、距离矩阵和聚类中心while True:# 更新聚类结果new_clusters = np.argmin(D, axis=1)if np.array_equal(new_clusters, clusters):breakclusters = new_clusters# 更新聚类中心centroids = [X[clusters == k].mean(axis=0) for k in range(K)]# 更新距离矩阵for k in range(K):D[:, k] = np.linalg.norm(X - centroids[k], axis=1)return clusters, centroids#调用函数进行聚类
K = 4
centroids = k_means_pp(X, K)
clusters, centroids = k_means(X, K, centroids)#可视化聚类结果
plt.scatter(X[:, 0], X[:, 1], c=clusters)
plt.scatter(np.array(centroids)[:, 0], np.array(centroids)[:, 1], marker='*', s=200, c='k')
plt.show()

基于密度的聚类算法

DBSCAN聚类算法

DBSCAN(Density-Based Spatial Clustering of Applications with Noise)聚类算法是一种基于密度的聚类算法,它可以自动识别任意形状的聚类簇,并能够有效地处理包含噪声的数据。DBSCAN 算法的基本思想是通过寻找数据点周围的相邻点,以及这些相邻点周围的相邻点,来判断数据点是否属于同一个簇中。DBSCAN 算法的核心有两个参数:半径 𝜖 和最小的样本个数 𝑀𝑖𝑛𝑃𝑡𝑠 。其中,半径 𝜖 定义了数据点之间的邻域范围,即距离某个数据点不超过 𝜖 的数据点都被认为是它的邻居;最小的样本个数 𝑀𝑖𝑛𝑃𝑡𝑠 定义了一个簇的最小密度,即在一个数据点的邻域范围内,如果包含的数据点个数不少于 𝑀𝑖𝑛𝑃𝑡𝑠,则认为该点是核心点,可以构成一个簇。DBSCAN 算法的具体实现步骤如下:

  1. 随机选择一个未访问过的数据点 p。
  2. 计算数据点 p 的邻域范围内所有数据点的距离,如果距离不超过半径 𝜖 ,则认为这些点是相互可达的,将它们加入同一个簇中。
  3. 对于簇中的每个数据点,递归地执行步骤 2,直到无法继续扩展该簇为止。
  4. 重复步骤 1 到步骤 3,直到所有数据点都被访问过为止。

示例:

import numpy as np
from sklearn.cluster import DBSCAN
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt# 生成随机数据
X, y = make_blobs(n_samples=1000, centers=3, cluster_std=0.5, random_state=0)# 使用DBSCAN算法进行聚类
dbscan = DBSCAN(eps=0.5, min_samples=5)
y_pred = dbscan.fit_predict(X)# 绘制聚类结果
plt.scatter(X[:, 0], X[:, 1], c=y_pred)
plt.title('DBSCAN Clustering')
plt.show()

Mean Shift聚类算法

Mean Shift 算法是一种基于密度的非参数聚类算法。它通过寻找密度函数的局部最大值来确定聚类簇的中心,进而将数据点分配到相应的聚类簇中。具体来说,Mean Shift 算法从任意一个数据点开始,通过迭代的方式不断移动该点,直到达到局部最大值为止。在移动过程中,Mean Shift 算法会不断地将数据点向密度函数值最大的方向移动,直到无法再移动为止,这样就能找到该点所在的聚类簇中心。然后,对于每个中心,可以找到与之相似的数据点并将它们分配到该簇中。最终,所有数据点都被分配到相应的聚类簇中。

import numpy as npdef euclidean_distance(x1, x2):return np.sqrt(np.sum((x1 - x2)**2))
#Mean Shift聚类算法
class MeanShift:def __init__(self, radius=4):self.radius = radiusdef fit(self, X):centroids = []for i in range(len(X)):point = X[i]while True:# Find all points within the given radiusneighbors = []for j in range(len(X)):if euclidean_distance(point, X[j]) <= self.radius:neighbors.append(X[j])# Calculate the mean of all points within the radiusnew_point = np.mean(neighbors, axis=0)# If the new point is within a certain distance of the last point, stopif euclidean_distance(point, new_point) < 0.00001:breakpoint = new_pointcentroids.append(point)self.centroids = np.unique(centroids, axis=0)def predict(self, X):labels = []for i in range(len(X)):distances = [euclidean_distance(X[i], c) for c in self.centroids]label = np.argmin(distances)labels.append(label)return labels

测试:

from sklearn.datasets import make_blobs
import matplotlib.pyplot as pltX, y = make_blobs(n_samples=200, centers=3, cluster_std=0.5, random_state=0)model = MeanShift()
model.fit(X)labels = model.predict(X)plt.scatter(X[:, 0], X[:, 1], c=labels)
plt.show()

层次聚类算法

凝聚层次聚类(Aglomerative Hierarchical Clustering,简称 AGNES)

从一个个单独的数据点开始,不断合并最近的两个聚类簇,直到所有数据点都被合并成一个聚类簇为止。凝聚层次聚类的核心是距离计算和聚类合并规则的选择。常用的距离计算方法有欧几里得距离、曼哈顿距离、余弦距离等。常用的聚类合并规则有最小距离法、最大距离法、重心法等。

分裂层次聚类(Divisive Hierarchical Clustering,简称 DIANA)

从所有数据点的整体开始,不断将数据点划分成两个或多个子集,直到每个子集都成为一个聚类簇为止。分裂层次聚类的核心是划分方法的选择,常用的划分方法有 K-Means、PAM 等。 层次聚类算法的优点在于可以自动确定聚类簇的数量和层次结构,但其缺点在于算法的时间复杂度较高,在大数据集上的计算时间可能非常长,并且容易受到噪声数据和异常值的影响。

基于图的聚类算法

谱聚类算法(Spectral Clustering)

将数据点看作图上的节点,通过计算节点之间的相似度矩阵和拉普拉斯矩阵来确定节点之间的相似性和距离,然后通过对拉普拉斯矩阵进行特征分解来得到聚类簇的划分。

import numpy as np
import scipy.spatial.distance as distclass SpectralClustering:def __init__(self, n_clusters=2, affinity='rbf', gamma=1.0):self.n_clusters = n_clustersself.affinity = affinityself.gamma = gammadef fit_predict(self, X):# 计算相似度矩阵if self.affinity == 'rbf':S = self._rbf_kernel(X, gamma=self.gamma)else:S = self._knn_kernel(X, k=self.gamma)# 计算拉普拉斯矩阵L = self._laplacian_matrix(S)# 计算特征值和特征向量eigvals, eigvecs = np.linalg.eig(L)# 取出前k个特征向量idx = eigvals.argsort()[:self.n_clusters]U = eigvecs[:, idx]# 对U进行归一化处理norm = np.linalg.norm(U, axis=1, keepdims=True)U_norm = U / norm# 对U_norm进行k-means聚类from sklearn.cluster import KMeanskmeans = KMeans(n_clusters=self.n_clusters)return kmeans.fit_predict(U_norm)def _rbf_kernel(self, X, gamma):dists = dist.squareform(dist.pdist(X, 'euclidean'))return np.exp(-gamma * dists ** 2)def _knn_kernel(self, X, k):dists = dist.squareform(dist.pdist(X, 'euclidean'))W = np.zeros_like(dists)for i in range(X.shape[0]):idx = np.argsort(dists[i])[:k+1]W[i, idx] = 1return Wdef _laplacian_matrix(self, S):# 计算度矩阵D = np.diag(np.sum(S, axis=1))# 计算拉普拉斯矩阵L = D - Sreturn L

社区发现算法(Community Detection)

将数据点看作社交网络上的节点,通过计算节点之间的社交关系和相似度来确定节点之间的相似性,然后利用社区发现算法将相似度高的节点划分到同一个社区中。

import networkx as nx
import community# 构建图
G = nx.karate_club_graph()# 使用Louvain算法进行社区发现
partition = community.modularity_max.greedy_modularity_communities(G)# 输出每个节点属于哪个社区
for i, com in enumerate(partition):print("Community %d: %s" % (i, com))

聚类算法使用领域

类算法是一种常用的无监督学习算法,可以将相似的数据点分组成簇,通常用于以下领域:

  1. 数据挖掘:聚类算法可以用于数据挖掘中的分析和分类,例如用户行为分析、产品定位、市场细分等。
  2. 图像处理:聚类算法可以用于图像分割、目标检测、图像压缩等应用,通过将图像像素聚类成不同的簇,实现对图像的分割和压缩。
  3. 自然语言处理:聚类算法可以用于文本聚类和主题模型,例如新闻分类、情感分析、文本推荐等。
  4. 生物信息学:聚类算法可以用于基因表达数据的聚类和分类,例如基因功能预测、新药研发等。
  5. 物联网:聚类算法可以用于传感器网络中的数据聚合和分类,例如智能交通、智能医疗等。 聚类算法在各个领域都有广泛的应用,可以帮助解决大规模数据的分类和分析问题,提高数据处理的效率和准确率。

总结

聚类算法是一种无监督学习算法,可以将相似的数据点分组成簇,是数据挖掘和机器学习领域中的重要技术之一。常用的聚类算法包括上文的K-Means、层次聚类、DBSCAN等。聚类算法的优点在于可以自动发现数据的内在结构和规律,可以用于数据挖掘、图像处理、自然语言处理、生物信息学、物联网等领域。在笔者看来,聚类算法的缺点在于需要大量计算资源和时间,容易受到噪声数据和异常值的影响,聚类结果也需要经过人工分析和解释,需要专业性,熟练性人才进入市场才能发挥这款无监督学习算法的强大作用。

原文链接:机器学习实战教程(一):聚类算法 - 知乎

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

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

相关文章

C++ 矩阵

目录 了解矩阵的数学原理&#xff08;大学线性代数&#xff09; 矩阵及转置矩阵 矩阵乘法 矩阵快速幂 相伴矩阵模板 [相伴矩阵,快速矩阵幂]CSES1722 Fibonacci Numbers 了解矩阵的数学原理&#xff08;大学线性代数&#xff09; 矩阵及转置矩阵 这里A就是一个矩阵&…

uniapp 桌面应用插件 Ba-Launcher

简介&#xff08;下载地址&#xff09; Ba-Launcher 可以让你的应用成为简单的桌面应用&#xff0c;如需扩展功能&#xff0c;请联系我。 截图展示 可关注博客&#xff0c;实时更新最新插件&#xff1a; uniapp 常用原生插件大全 使用方法 使用方法也很简单&#xff0c;在插…

PG数据库结构与oracle比较

1.数据库集簇逻辑结构 数据库集簇概念&#xff1a;一个大的数据库是由若干个小的数据库组成&#xff0c;实现数据的隔离存放&#xff0c;在概念上应该是与mysql一样的 在mysql中可以用show database列出数据库 PG中用\l 数据库对象存放在数据库中&#xff1a; PG中的所有数据…

计算机英文论文常见错误写作习惯3

目录 第一部分 Numbers and Equations ‘such as’ and ‘etc.’ 第二部分 第一部分 Numbers and Equations 两个非常常见的错误是关于阿拉伯数字和方程式的表示。中国作家通常写阿拉伯数字&#xff0c;而不是拼出单词。然而&#xff0c;使用阿拉伯数字本身并不是一个错误…

简约大气的全屏背景壁纸导航网源码(免费)

简约大气的全屏背景壁纸导航网模板 效果图部分代码领取源码下期更新预报 效果图 部分代码 <!DOCTYPE html> <html lang"zh-CN"> <!--版权归孤独 --> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible…

工厂模式和策略模式区别

工厂模式和策略模式都是面向对象设计模式&#xff0c;但它们的目的和应用场景有所不同。 工厂模式是一种创建型设计模式&#xff0c;旨在通过使用一个工厂类来创建对象&#xff0c;而不是直接使用new关键字来创建对象。这样做可以使系统更容易扩展和维护&#xff0c;因为新的对…

图论之最短路算法模板总结

来个大致的分类&#xff1a; 朴素的迪杰斯特拉&#xff1a; 实现&#xff1a; 我们让s表示当前已经确定的最短距离的点&#xff0c;我们找到一个不在s中的距离最近的点t&#xff0c;并用t来更新其他的点。 下面是AC代码&#xff1a; #include<bits/stdc.h> using nam…

C语言-整体内容简单的认识

目录 一、数据类型的介绍二、数据的变量和常量三、变量的作用域和生命周期四、字符串五、转义字符六、操作符六、常见的关键字6.1 关键字static 七、内存分配八、结构体九、指针 一、数据类型的介绍 sizeof是一个操作符&#xff0c;是计算机类型/变量所占内存空间的大小   sc…

中间件之异步通讯组件RabbitMQ入门

一、概述 微服务一旦拆分&#xff0c;必然涉及到服务之间的相互调用&#xff0c;目前我们服务之间调用采用的都是基于OpenFeign的调用。这种调用中&#xff0c;调用者发起请求后需要等待服务提供者执行业务返回结果后&#xff0c;才能继续执行后面的业务。也就是说调用者在调用…

Java IO流(二)

1. 缓冲流 1.1 字节缓冲流概述 当对文件或其他数据源进行频繁的读/写操作时&#xff0c;效率比较低&#xff0c;这时如果使用缓存流就能够更高效地读/写信息。 比如&#xff0c;可以使用缓冲输出流来一次性批量写出若干数据减少写出次数来提高写出效率。 如果用生活中的例子做…

使用qemu调试NVME driver

参考nvme驱动相关的博客&#xff0c;可以使用qemu buildroot进行nvme驱动的流程debug。 一、QEMU编译 首先需要编译qemu&#xff0c;可以参考QEMU编译。wget下载最新版本的QEMU&#xff0c;编译之前&#xff0c;最好检查下依赖包是否安装&#xff0c;避免安装过程出现各种错…

Qwen-Audio:推动通用音频理解的统一大规模音频-语言模型(开源)

随着人工智能技术的不断进步&#xff0c;音频语言模型&#xff08;Audio-Language Models&#xff09;在人机交互领域变得越来越重要。然而&#xff0c;由于缺乏能够处理多样化音频类型和任务的预训练模型&#xff0c;该领域的进展受到了限制。为了克服这一挑战&#xff0c;研究…

【WebGL】修改阴影体形状,实现相交分析

阴影体&#xff08;Shadow Volume&#xff09;技术是计算机图形学中实现阴影的重要方式&#xff0c;除了用于可视化阴影效果外&#xff0c;阴影体还能实现线、面等要素的贴地、贴对象显示。在用阴影体贴地、贴对象时&#xff0c;大多数情况下我们都会认为阴影体是一个带有高度的…

OpenCV的图像矩(64)

返回:OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 上一篇&#xff1a;OpenCV如何为等值线创建边界旋转框和椭圆(63) 下一篇 &#xff1a;OpenCV4.9的点多边形测试(65) Image Moments&#xff08;图像矩&#xff09;是 OpenCV 库中的一个功能&#xff0c;它可…

神经网络中常见的激活函数:理解与实践

神经网络中常见的激活函数&#xff1a;理解与实践 在神经网络中&#xff0c;激活函数是一个非常重要的组成部分&#xff0c;它为神经元引入了非线性特性&#xff0c;使得神经网络可以拟合各种复杂的函数关系。本文将介绍9种常见的激活函数&#xff0c;包括它们的概述、公式以及…

MATLAB 数据导入

MATLAB 数据导入&#xff08;ImportData&#xff09; 在MATLAB中导入数据意味着从外部文件加载数据。该importdata功能允许加载不同格式的各种数据文件。它具有以下五种形式 序号 功能说明 1 A importdata(filename) 从filename表示的文件中将数据加载到数组A中。 2 A i…

附录3-小程序常用事件

目录 1 点击事件 tap 2 文本框输入事件 input 3 状态改变事件 change 4 下拉刷新事件 onPullDownRefresh() 5 上拉触底事件 onReachBottom() 1 点击事件 tap 2 文本框输入事件 input 可以使用 e.detail.value 打印出当前文本框的值 我现在在文本框中依次输入12345&…

区块链 | IPFS 工作原理入门

&#x1f98a;原文&#xff1a;What is the InterPlanetary File System (IPFS), and how does it work? &#x1f98a;写在前面&#xff1a;本文属于搬运博客&#xff0c;自己留存学习。 1 去中心化互联网 尽管万维网是一个全球性的网络&#xff0c;但在数据存储方面&#…

帕金森患者应该怎么注意生活方式?

在面对帕金森病的挑战时&#xff0c;科学合理地改善日常生活方式&#xff0c;不仅能帮助患者更好地管理病情&#xff0c;还能提升生活质量。今天&#xff0c;让我们一起探索如何通过简单的日常调整&#xff0c;为患有帕金森病的朋友们带来积极的变化。 饮食调整&#xff1a;营养…

【Mac】Photoshop 2024 for mac最新安装教程

软件介绍 Photoshop 2024是Adobe公司推出的一款图像处理软件&#xff0c;它支持Windows和Mac OS系统。Adobe Photoshop是业界领先的图像编辑和处理软件之一&#xff0c;广泛用于设计、摄影、数字绘画等领域。 Photoshop 2024的功能包括&#xff1a; 1.图像编辑&#xff1a;提…