在单个特征数据框中查找质心和点之间的距离 - KMeans
Find distance between centroid and points in a single feature dataframe - KMeans
我正在使用 KMeans 处理异常检测任务。
Pandas 我正在使用的数据框只有一个功能,类似于以下功能:
df = array([[12534.],
[12014.],
[12158.],
[11935.],
...,
[ 5120.],
[ 4828.],
[ 4443.]])
我能够按照以下说明拟合和预测值:
km = KMeans(n_clusters=2)
km.fit(df)
km.predict(df)
为了识别异常,我想计算质心与每个单点之间的距离,但是对于具有单个特征的数据框,我不确定这是正确的方法。
我找到了使用欧氏距离计算距离的例子。下面是一个例子:
def k_mean_distance(data, cx, cy, i_centroid, cluster_labels):
distances = [np.sqrt((x - cx) ** 2 + (y - cy) ** 2) for (x, y) in data[cluster_labels == i_centroid]]
return distances
centroids = self.km.cluster_centers_
distances = []
for i, (cx, cy) in enumerate(centroids):
mean_distance = k_mean_distance(day_df, cx, cy, i, clusters)
distances.append({'x': cx, 'y': cy, 'distance': mean_distance})
这段代码对我不起作用,因为在我的例子中,质心就像下面的一样,因为我只有一个特征数据框:
array([[11899.90692187],
[ 5406.54143126]])
在这种情况下,求质心和点之间距离的正确方法是什么?可能吗?
谢谢你,很抱歉提出这个小问题,我还在学习中
您可以使用scipy.spatial.distance.cdist
创建距离矩阵:
from scipy.spatial.distance import cdist
dm = cdist(df, centroids)
这应该为您提供一个二维数组,其中每一行代表原始数据集中的一个观察值,每一列代表一个质心。 y-th 列中的 x-th 行给出了 x-th 观测值与 y-th 簇质心之间的距离。 cdist
默认使用欧几里德距离,但您可以使用其他指标(对于只有一个特征的数据集来说并不重要)。
有scipy.spatial.distance_matrix
你可以利用:
# setup a set of 2d points
np.random.seed(2)
df = np.random.uniform(0,1,(100,2))
# make it a dataframe
df = pd.DataFrame(df)
# clustering with 3 clusters
from sklearn.cluster import KMeans
km = KMeans(n_clusters=3)
km.fit(df)
preds = km.predict(df)
# get centroids
centroids = km.cluster_centers_
# visualize
plt.scatter(df[0], df[1], c=preds)
plt.scatter(centroids[:,0], centroids[:,1], c=range(centroids.shape[0]), s=1000)
给予
现在距离矩阵:
from scipy.spatial import distance_matrix
dist_mat = pd.DataFrame(distance_matrix(df.values, centroids))
您可以通过
确认这是正确的
dist_mat.idxmin(axis=1) == preds
最后,到质心的平均距离:
dist_mat.groupby(preds).mean()
给出:
0 1 2
0 0.243367 0.525194 0.571674
1 0.525350 0.228947 0.575169
2 0.560297 0.573860 0.197556
其中列表示质心数,行表示簇中点的平均距离。
我正在使用 KMeans 处理异常检测任务。
Pandas 我正在使用的数据框只有一个功能,类似于以下功能:
df = array([[12534.],
[12014.],
[12158.],
[11935.],
...,
[ 5120.],
[ 4828.],
[ 4443.]])
我能够按照以下说明拟合和预测值:
km = KMeans(n_clusters=2)
km.fit(df)
km.predict(df)
为了识别异常,我想计算质心与每个单点之间的距离,但是对于具有单个特征的数据框,我不确定这是正确的方法。
我找到了使用欧氏距离计算距离的例子。下面是一个例子:
def k_mean_distance(data, cx, cy, i_centroid, cluster_labels):
distances = [np.sqrt((x - cx) ** 2 + (y - cy) ** 2) for (x, y) in data[cluster_labels == i_centroid]]
return distances
centroids = self.km.cluster_centers_
distances = []
for i, (cx, cy) in enumerate(centroids):
mean_distance = k_mean_distance(day_df, cx, cy, i, clusters)
distances.append({'x': cx, 'y': cy, 'distance': mean_distance})
这段代码对我不起作用,因为在我的例子中,质心就像下面的一样,因为我只有一个特征数据框:
array([[11899.90692187],
[ 5406.54143126]])
在这种情况下,求质心和点之间距离的正确方法是什么?可能吗?
谢谢你,很抱歉提出这个小问题,我还在学习中
您可以使用scipy.spatial.distance.cdist
创建距离矩阵:
from scipy.spatial.distance import cdist
dm = cdist(df, centroids)
这应该为您提供一个二维数组,其中每一行代表原始数据集中的一个观察值,每一列代表一个质心。 y-th 列中的 x-th 行给出了 x-th 观测值与 y-th 簇质心之间的距离。 cdist
默认使用欧几里德距离,但您可以使用其他指标(对于只有一个特征的数据集来说并不重要)。
有scipy.spatial.distance_matrix
你可以利用:
# setup a set of 2d points
np.random.seed(2)
df = np.random.uniform(0,1,(100,2))
# make it a dataframe
df = pd.DataFrame(df)
# clustering with 3 clusters
from sklearn.cluster import KMeans
km = KMeans(n_clusters=3)
km.fit(df)
preds = km.predict(df)
# get centroids
centroids = km.cluster_centers_
# visualize
plt.scatter(df[0], df[1], c=preds)
plt.scatter(centroids[:,0], centroids[:,1], c=range(centroids.shape[0]), s=1000)
给予
现在距离矩阵:
from scipy.spatial import distance_matrix
dist_mat = pd.DataFrame(distance_matrix(df.values, centroids))
您可以通过
确认这是正确的dist_mat.idxmin(axis=1) == preds
最后,到质心的平均距离:
dist_mat.groupby(preds).mean()
给出:
0 1 2
0 0.243367 0.525194 0.571674
1 0.525350 0.228947 0.575169
2 0.560297 0.573860 0.197556
其中列表示质心数,行表示簇中点的平均距离。