匠心精神 - 良心品质腾讯认可的专业机构-IT人的高薪实战学院

咨询电话:4000806560

用Python实现机器学习中的聚类算法

用Python实现机器学习中的聚类算法

聚类算法是一种无监督学习的机器学习算法,它旨在将数据集中的数据分成不同的群组或者簇。聚类算法可以应用于数据挖掘、图像处理、自然语言处理等领域。本文将会介绍常用的聚类算法和如何用Python实现它们。

1. K-Means聚类算法

K-Means是一种常用的聚类算法,它的核心思想是将数据点分配到K个簇中,使得同一簇内的数据点相似度高,不同簇之间的数据点相似度低。K-Means算法可以分为以下几个步骤:

1)初始化K个中心点。

2)将数据点分配到距离最近的中心点所在的簇。

3)重新计算每个簇的中心点。

4)重复2)和3)直到簇不再发生变化或达到最大迭代次数。

下面是用Python实现K-Means算法的样例代码:

```
import numpy as np
import matplotlib.pyplot as plt

class KMeans:
    def __init__(self, k=2, max_iter=100):
        self.k = k
        self.max_iter = max_iter
        
    def dist(self, x, y):
        return np.sqrt(np.sum((x-y)**2))
    
    def fit(self, X):
        self.centers = X[np.random.choice(X.shape[0], self.k, replace=False)]
        
        for iter in range(self.max_iter):
            clusters = [[] for _ in range(self.k)]
            for i in range(X.shape[0]):
                distances = [self.dist(X[i], center) for center in self.centers]
                cluster = np.argmin(distances)
                clusters[cluster].append(i)
            new_centers = []
            for i in range(self.k):
                new_centers.append(np.mean(X[clusters[i]], axis=0))
            if np.allclose(self.centers, new_centers):
                break
            else:
                self.centers = new_centers
                
    def predict(self, X):
        y_pred = []
        for i in range(X.shape[0]):
            distances = [self.dist(X[i], center) for center in self.centers]
            cluster = np.argmin(distances)
            y_pred.append(cluster)
        return np.array(y_pred)
```

2. DBSCAN聚类算法

DBSCAN是一种基于密度的聚类算法,它的核心思想是基于数据点周围的密度来确定簇的数量和形状。DBSCAN算法可以分为以下几个步骤:

1)选择一个未被访问的核心点。

2)寻找与该核心点距离小于阈值的所有点,并将它们加入同一簇中。

3)对于簇中的每个点,如果它也是一个核心点,那么将它的邻居加入簇中,并继续迭代。

4)重复1)到3)直到所有点都被访问。

下面是用Python实现DBSCAN算法的样例代码:

```
import numpy as np
import matplotlib.pyplot as plt

class DBSCAN:
    def __init__(self, eps=0.5, min_samples=5):
        self.eps = eps
        self.min_samples = min_samples
        
    def region_query(self, X, i):
        return np.where(np.linalg.norm(X-X[i], axis=1) < self.eps)[0]
    
    def fit(self, X):
        self.labels = np.zeros(X.shape[0])
        C = 0
        
        for i in range(X.shape[0]):
            if self.labels[i] != 0:
                continue
            neighbors = self.region_query(X, i)
            if len(neighbors) < self.min_samples:
                self.labels[i] = -1
            else:
                C += 1
                self.labels[i] = C
                while len(neighbors) > 0:
                    j = neighbors[0]
                    neighbors = np.delete(neighbors, 0)
                    if self.labels[j] == -1:
                        self.labels[j] = C
                    elif self.labels[j] == 0:
                        self.labels[j] = C
                        new_neighbors = self.region_query(X, j)
                        if len(new_neighbors) >= self.min_samples:
                            neighbors = np.concatenate((neighbors, new_neighbors))
                            
    def predict(self, X):
        return self.labels
```

3. 层次聚类算法

层次聚类算法是一种基于类似树状结构的层次结构的聚类算法,它可以自动决定簇的数量。层次聚类算法可以分为以下几个步骤:

1)将每个数据点视为一个簇。

2)计算所有簇之间的相似度。

3)将相似度最高的两个簇合并成一个新的簇。

4)重复2)和3)直到所有数据点都被合并为一个簇或达到最大簇的数量。

下面是用Python实现层次聚类算法的样例代码:

```
import numpy as np
import matplotlib.pyplot as plt
from scipy.spatial.distance import pdist, squareform

class Hierarchical:
    def __init__(self, linkage='single', max_clusters=None):
        self.linkage = linkage
        self.max_clusters = max_clusters
        
    def fit(self, X):
        dists = pdist(X)
        link = squareform(dists)
        clusters = [i for i in range(X.shape[0])]
        while len(clusters) > 1:
            i, j = np.unravel_index(np.argmin(link), link.shape)
            if len(clusters) == self.max_clusters:
                break
            if self.linkage == 'single':
                new_link = np.min(link[(clusters == i)[:, None], clusters == j], axis=0)
            elif self.linkage == 'complete':
                new_link = np.max(link[(clusters == i)[:, None], clusters == j], axis=0)
            else:
                new_link = np.mean(link[(clusters == i)[:, None], clusters == j], axis=0)
            link = np.delete(link, [i, j], axis=0)
            link = np.delete(link, [i, j], axis=1)
            new_row = np.hstack((new_link, link[:, [i, j]]))
            new_col = np.vstack((new_link, link[[i, j], :]))
            link = np.vstack((new_row, new_col))
            clusters = np.delete(clusters, [i, j])
            clusters = np.append(clusters, [max(clusters)+1])
        self.labels = np.zeros(X.shape[0])
        for i, c in enumerate(np.unique(clusters)):
            self.labels[clusters == c] = i
            
    def predict(self, X):
        return self.labels
```

总结

本文介绍了K-Means、DBSCAN和层次聚类三种常用的聚类算法以及如何用Python实现它们。聚类算法在机器学习中的应用越来越广泛,它可以发现数据中的隐藏结构并支持更深入的数据分析。在使用聚类算法时,还需要注意选择合适的距离度量和相似度度量方法,以及对数据进行适当的归一化和缩放。