手动实现k-means聚类使用夹角余弦
时间: 2023-09-26 10:07:53 浏览: 43
以下是使用夹角余弦手动实现k-means聚类的Python代码:
```python
import numpy as np
class KMeans:
def __init__(self, k, cos_sim=False, max_iter=100):
self.k = k
self.max_iter = max_iter
self.cos_sim = cos_sim
def fit(self, X):
self.centroids = X[np.random.choice(X.shape[0], self.k, replace=False)]
for i in range(self.max_iter):
distances = self._get_distances(X)
labels = np.argmin(distances, axis=1)
new_centroids = np.array([X[labels == j].mean(axis=0) for j in range(self.k)])
if np.allclose(new_centroids, self.centroids):
break
self.centroids = new_centroids
self.labels_ = labels
self.inertia_ = np.sum(np.min(distances, axis=1))
def _get_distances(self, X):
if self.cos_sim:
X_norm = np.linalg.norm(X, axis=1)
centroids_norm = np.linalg.norm(self.centroids, axis=1)
dot_product = X @ self.centroids.T
distances = 1 - dot_product / (X_norm.reshape(-1, 1) * centroids_norm)
else:
distances = np.sqrt(((X - self.centroids[:, np.newaxis]) ** 2).sum(axis=2))
return distances
```
其中,`k`为聚类个数,`cos_sim`表示是否使用夹角余弦距离,`max_iter`表示最大迭代次数。`fit`方法进行聚类,`X`为数据集,返回`labels_`为每个样本的聚类标签,`inertia_`为聚类内的平方和距离。
`_get_distances`方法计算样本到聚类中心的距离,如果使用夹角余弦距离,则先进行归一化处理,然后计算点积,最后用1减去余弦相似度即可。否则使用欧式距离计算距离。