k-shape.py

**k-shape聚类论文:**Technical Perspective: k-Shape: Efficient and Accurate Clustering of Time Series
Zachary G. IvesPublished in SIGMOD Record 2016
DOI:10.1145/2949741.2949757
Database research frequently cuts across many layers of abstraction (from formal foundations to algorithms to languages to systems) and the software stack (from data storage and distribution to runtime systems and query optimizers). It does this in a way that is specialized to a particular class of data and workloads. Over the decades, we have seen this pattern applied to enterprise data, persistent objects, Web data, sensor data, data streams, and so on. Each time, the community has developed… CONTINUE READING

import numpy
import matplotlib.pyplot as plt

from tslearn.clustering import KShape
from tslearn.datasets import CachedDatasets
from tslearn.preprocessing import TimeSeriesScalerMeanVariance

seed = 0
numpy.random.seed(seed)
X_train, y_train, X_test, y_test = CachedDatasets().load_dataset(“Trace”)
X_train = X_train[y_train < 4] # Keep first 3 classes
numpy.random.shuffle(X_train)
X_train = TimeSeriesScalerMeanVariance().fit_transform(X_train[:50]) # Keep only 50 time series
sz = X_train.shape[1]

Euclidean k-means

ks = KShape(n_clusters=3, verbose=True, random_state=seed)
y_pred = ks.fit_predict(X_train)

plt.figure()
for yi in range(3):
plt.subplot(3, 1, 1 + yi)
for xx in X_train[y_pred == yi]:
plt.plot(xx.ravel(), “k-”, alpha=.2)
plt.plot(ks.cluster_centers_[yi].ravel(), “r-”)
plt.xlim(0, sz)
plt.ylim(-4, 4)
plt.title(“Cluster %d” % (yi + 1))

plt.tight_layout()
plt.show()

K-means++是一种改进的K-means聚类算法,它能够更好地初始化聚类中心,从而提高聚类效果。在yolov5的autoanchor.py中,可以将K-means替换为K-means++,具体步骤如下: 1. 初始化第一个聚类中心,随机选择一个样本点作为第一个聚类中心。 ```python centroids = [boxes[random.randrange(num_boxes)]] ``` 2. 对于其他的聚类中心,根据距离上一个聚类中心最远的样本点为下一个聚类中心。 ```python for _ in range(k - 1): distances = [min([1 - bbox_iou(c, box) for c in centroids]) for box in boxes] new_centroid_index = np.argmax(distances) centroids.append(boxes[new_centroid_index]) ``` 3. 在进行第2步时,需要使用bbox_iou函数计算距离,因此需要将bbox_iou函数添加到代码中。 ```python def bbox_iou(box1, box2): """ Calculate the Intersection of Union (IoU) of two bounding boxes. Args: box1: Tuple (x1, y1, x2, y2) representing the coordinates of the first bounding box. box2: Tuple (x1, y1, x2, y2) representing the coordinates of the second bounding box. Returns: The IoU of the two bounding boxes. """ # Calculate the coordinates of the intersection rectangle. x1 = max(box1[0], box2[0]) y1 = max(box1[1], box2[1]) x2 = min(box1[2], box2[2]) y2 = min(box1[3], box2[3]) # If the intersection is empty, return 0. if x2 <= x1 or y2 <= y1: return 0.0 # Calculate the areas of the bounding boxes and the intersection. box1_area = (box1[2] - box1[0]) * (box1[3] - box1[1]) box2_area = (box2[2] - box2[0]) * (box2[3] - box2[1]) intersection_area = (x2 - x1) * (y2 - y1) # Calculate the IoU and return it. iou = intersection_area / (box1_area + box2_area - intersection_area) return iou ``` 完整代码如下: ```python import random import numpy as np def bbox_iou(box1, box2): """ Calculate the Intersection of Union (IoU) of two bounding boxes. Args: box1: Tuple (x1, y1, x2, y2) representing the coordinates of the first bounding box. box2: Tuple (x1, y1, x2, y2) representing the coordinates of the second bounding box. Returns: The IoU of the two bounding boxes. """ # Calculate the coordinates of the intersection rectangle. x1 = max(box1[0], box2[0]) y1 = max(box1[1], box2[1]) x2 = min(box1[2], box2[2]) y2 = min(box1[3], box2[3]) # If the intersection is empty, return 0. if x2 <= x1 or y2 <= y1: return 0.0 # Calculate the areas of the bounding boxes and the intersection. box1_area = (box1[2] - box1[0]) * (box1[3] - box1[1]) box2_area = (box2[2] - box2[0]) * (box2[3] - box2[1]) intersection_area = (x2 - x1) * (y2 - y1) # Calculate the IoU and return it. iou = intersection_area / (box1_area + box2_area - intersection_area) return iou def kmeans_plus_plus(boxes, k, dist=np.median): """ Perform K-means++ clustering on a set of bounding boxes. Args: boxes: Numpy array of shape (num_boxes, 4) representing the bounding boxes. k: The number of clusters. dist: The distance function to use (default is median). Returns: A list of k centroids (each centroid is of shape (4,)). """ # Initialize the first centroid randomly. num_boxes = boxes.shape[0] centroids = [boxes[random.randrange(num_boxes)]] # Initialize the remaining centroids using K-means++. for _ in range(k - 1): distances = [min([1 - bbox_iou(c, box) for c in centroids]) for box in boxes] new_centroid_index = np.argmax(distances) centroids.append(boxes[new_centroid_index]) # Run K-means clustering on the centroids. centroids = np.asarray(centroids) while True: distances = 1 - np.asarray([[bbox_iou(c, box) for c in centroids] for box in boxes]) nearest_clusters = np.argmin(distances, axis=1) if (nearest_clusters == np.asarray([nearest_clusters]).T).all(): break for cluster in range(k): centroid_boxes = boxes[nearest_clusters == cluster] if len(centroid_boxes) == 0: continue centroids[cluster] = dist(centroid_boxes, axis=0) return centroids.tolist() ``` 在yolov5的autoanchor.py中,将以下代码: ```python def kmeans(boxes, k, dist=np.median): """ Perform K-means clustering on a set of bounding boxes. Args: boxes: Numpy array of shape (num_boxes, 4) representing the bounding boxes. k: The number of clusters. dist: The distance function to use (default is median). Returns: A list of k centroids (each centroid is of shape (4,)). """ num_boxes = boxes.shape[0] distances = np.empty((num_boxes, k)) last_nearest = np.zeros((num_boxes,)) np.random.seed() centroids = boxes[np.random.choice(num_boxes, k, replace=False)] while True: distances = 1 - bbox_iou(centroids, boxes) current_nearest = np.argmin(distances, axis=1) if (last_nearest == current_nearest).all(): break for cluster in range(k): centroids[cluster] = dist(boxes[current_nearest == cluster], axis=0) last_nearest = current_nearest return centroids.tolist() ``` 替换为以下代码即可: ```python def kmeans(boxes, k, dist=np.median): """ Perform K-means clustering on a set of bounding boxes. Args: boxes: Numpy array of shape (num_boxes, 4) representing the bounding boxes. k: The number of clusters. dist: The distance function to use (default is median). Returns: A list of k centroids (each centroid is of shape (4,)). """ return kmeans_plus_plus(boxes, k, dist) ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值