Python实现鸢尾花三种聚类算法(K-means, AGNES, DBScan)
1. 简介
聚类是一种无监督学习算法,它将相似的数据点分组到同一个簇中。本文将介绍如何使用Python实现三种聚类算法:K-means、AGNES和DBScan,并使用鸢尾花数据集进行演示。
2. 数据集
我们将使用鸢尾花数据集来演示如何使用聚类算法。该数据集包含150个样本,每个样本有四个特征:花萼长度、花萼宽度、花瓣长度和花瓣宽度。以下是数据集的示例:
花萼长度 | 花萼宽度 | 花瓣长度 | 花瓣宽度 | 类别 |
---|---|---|---|---|
5.1 | 3.5 | 1.4 | 0.2 | 0 |
4.9 | 3.0 | 1.4 | 0.2 | 0 |
7.0 | 3.2 | 4.7 | 1.4 | 1 |
6.4 | 3.2 | 4.5 | 1.5 | 1 |
6.3 | 3.3 | 6.0 | 2.5 | 2 |
5.8 | 2.7 | 5.1 | 1.9 | 2 |
3. K-means算法
K-means算法是一种基于距离的聚类算法,它将数据点分为K个簇,使得每个簇内的数据点相似度较高,而不同簇之间的相似度较低。具体实现步骤如下:
- 随机选择K个数据点作为初始质心。
- 将每个数据点分配到距离最近的质心所在的簇中。
- 计算每个簇的新质心。
- 重复步骤2和3,直到质心不再改变或达到最大迭代次数。
以下是K-means算法的Python实现:
import numpy as np
class KMeans:
def __init__(self, k=3, max_iter=100):
self.k = k
self.max_iter = max_iter
def fit(self, X):
self.centroids = X[np.random.choice(len(X), self.k, replace=False)]
for i in range(self.max_iter):
clusters = [[] for _ in range(self.k)]
for x in X:
distances = [np.linalg.norm(x - c) for c in self.centroids]
cluster_idx = np.argmin(distances)
clusters[cluster_idx].append(x)
prev_centroids = self.centroids.copy()
for i, cluster in enumerate(clusters):
if len(cluster) > 0:
self.centroids[i] = np.mean(cluster, axis=0)
if np.allclose(prev_centroids, self.centroids):
break
def predict(self, X):
distances = np.array([np.linalg.norm(X - c, axis=1) for c in self.centroids])
return np.argmin(distances, axis=0)
这个代码实现了一个名为KMeans的类,它包含两个方法:
- fit(X):用于训练K-means聚类器,其中X是一个二维数组,表示每个样本的特征。
- predict(X):用于对新样本进行聚类,其中X是一个二维数组,表示每个样本的特征;一个一维数组,表示每个样本所属的簇。
4. AGNES算法
AGNES算法是一种基于层次的聚类算法,它将数据点逐步合并成越来越大的簇,直到所有数据点都在同一个簇中。具体实现步骤如下:
- 将每个数据点视为一个簇。
- 计算每对簇之间的距离,并将距离最近的两个簇合并成一个新簇。
- 重复步骤2,直到所有数据点都在同一个簇中。
以下是AGNES算法的Python实现:
import numpy as np
class AGNES:
def __init__(self, k=3):
self.k = k
def fit(self, X):
self.clusters = [[x] for x in X]
while len(self.clusters) > self.k:
distances = np.zeros((len(self.clusters), len(self.clusters)))
for i in range(len(self.clusters)):
for j in range(i+1, len(self.clusters)):
distances[i, j] = np.min([np.linalg.norm(x - y) for x in self.clusters[i] for y in self.clusters[j]])
i, j = np.unravel_index(np.argmin(distances), distances.shape)
self.clusters[i] += self.clusters[j]
self.clusters.pop(j)
def predict(self, X):
return [np.argmin([np.linalg.norm(x - c) for c in cluster]) for x in X for cluster in self.clusters]
这个代码实现了一个名为AGNES的类,它包含两个方法:
- fit(X):用于训练AGNES聚类器,其中X是一个二维数组,表示每个样本的特征。
- predict(X):用于对新样本进行聚类,其中X是一个二维数组,表示每个样本的特征;一个一维数组,表示每个样本所属的簇。
5. DBScan算法
DBScan算法是一种基于密度的聚类算法,它将数据点分为核心点、边界点和噪声点三类。具体实现步骤如下:
- 对于每个数据点,计算它的邻域内的数据点数目。
- 如果一个数据点的邻域内的数据点数目大于等于指定阈值,则将其标记为核心点。
- 将所有核心点连接成簇,如果两个核心点的邻域有重叠,则将它们合并成一个簇。
- 将所有未被分配到簇中的数据点标记为噪声点。
以下是DBScan算法的Python实现:
import numpy as np
class DBScan:
def __init__(self, eps=0.5, min_samples=5):
self.eps = eps
self.min_samples = min_samples
def fit(self, X):
self.labels_ = np.zeros(len(X), dtype=int)
cluster_idx = 0
for i, x in enumerate(X):
if self.labels_[i] != 0:
continue
neighbors = self.region_query(X, i)
if len(neighbors) < self.min_samples:
self.labels_[i] = -1
continue
cluster_idx += 1
self.labels_[i] = cluster_idx
for j in neighbors:
if self.labels_[j] == -1:
self.labels_[j] = cluster_idx
if self.labels_[j] != 0:
continue
self.labels_[j] = cluster_idx
new_neighbors = self.region_query(X, j)
if len(new_neighbors) >= self.min_samples:
neighbors += new_neighbors
def predict(self, X):
return self.labels_
def region_query(self, X, i):
return [j for j, x in enumerate(X) if np.linalg.norm(x - X[i]) <= self.eps]
这个代码实现了一个名为DBScan的类,它包含两个方法:
- fit(X):用于训练DBScan聚类器,其中X是一个二维数组,表示每个样本的特征。
- predict(X):用于对新样本进行聚类,其中X是一个二维数组,表示每个样本的特征;一个一维数组,表示每个样本所属的簇。
6. 示例
示例1
在示例1中,我们使用了鸢尾花数据集,使用KMeans类、AGNES类和DBScan类分别对数据集进行聚类,并输出聚类结果。
from sklearn.datasets import load_iris
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import silhouette_score
iris = load_iris()
X = iris.data
y = iris.target
scaler = StandardScaler()
X = scaler.fit_transform(X)
kmeans = KMeans(k=3)
kmeans.fit(X)
kmeans_labels = kmeans.predict(X)
print('K-means Silhouette Score:', silhouette_score(X, kmeans_labels))
agnes = AGNES(k=3)
agnes.fit(X)
agnes_labels = agnes.predict(X)
print('AGNES Silhouette Score:', silhouette_score(X, agnes_labels))
dbscan = DBScan(eps=0.5, min_samples=5)
dbscan.fit(X)
dbscan_labels = dbscan.predict(X)
print('DBScan Silhouette Score:', silhouette_score(X, dbscan_labels))
这个示例将使用上述代码对鸢尾花数据集进行聚类,并输出聚类结果和轮廓系数。
示例2
在示例2中,我们使用了一个包含6个样本的数据集,每个样本有两个征:长度和宽度。我们使用KMeans类、AGNES类和DBScan类分别对数据集进行聚类,并输出聚类结果。
X = np.array([
[1, 2],
[2, 3],
[3, 3],
[3, 4],
[4, 4],
[5, 5],
])
kmeans = KMeans(k=2)
kmeans.fit(X)
kmeans_labels = kmeans.predict(X)
print('K-means Labels:', kmeans_labels)
agnes = AGNES(k=2)
agnes.fit(X)
agnes_labels = agnes.predict(X)
print('AGNES Labels:', agnes_labels)
dbscan = DBScan(eps=1, min_samples=2)
dbscan.fit(X)
dbscan_labels = dbscan.predict(X)
print('DBScan Labels:', dbscan_labels)
这个示例将使用上述代码对数据集进行聚类,并输出聚类结果。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:python实现鸢尾花三种聚类算法(K-means,AGNES,DBScan) - Python技术站