关键词

python实现鸢尾花三种聚类算法(K-means,AGNES,DBScan)

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个簇,使得每个簇内的数据点相似度较高,而不同簇之间的相似度较低。具体实现步骤如下:

  1. 随机选择K个数据点作为初始质心。
  2. 将每个数据点分配到距离最近的质心所在的簇中。
  3. 计算每个簇的新质心。
  4. 重复步骤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算法是一种基于层次的聚类算法,它将数据点逐步合并成越来越大的簇,直到所有数据点都在同一个簇中。具体实现步骤如下:

  1. 将每个数据点视为一个簇。
  2. 计算每对簇之间的距离,并将距离最近的两个簇合并成一个新簇。
  3. 重复步骤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算法是一种基于密度的聚类算法,它将数据点分为核心点、边界点和噪声点三类。具体实现步骤如下:

  1. 对于每个数据点,计算它的邻域内的数据点数目。
  2. 如果一个数据点的邻域内的数据点数目大于等于指定阈值,则将其标记为核心点。
  3. 将所有核心点连接成簇,如果两个核心点的邻域有重叠,则将它们合并成一个簇。
  4. 将所有未被分配到簇中的数据点标记为噪声点。

以下是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)

这个示例将使用上述代码对数据集进行聚类,并输出聚类结果。

本文链接:http://task.lmcjl.com/news/14780.html

展开阅读全文