首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >聚类边界条件

聚类边界条件
EN

Data Science用户
提问于 2015-11-11 14:27:51
回答 3查看 2.5K关注 0票数 4

我有一些数据,我想用k均值进行聚类。

其中一个特点是一天中的时间。

问题是,23小时被认为远离'0‘小时。

如何映射数据,以便边界是循环的?

EN

回答 3

Data Science用户

回答已采纳

发布于 2015-11-19 02:21:26

,因为你接受了另一个答案,它说这是不能做到的,所以我正在编辑它,包括一个它正在完成的例子。希望这能帮上忙!

原始答案:

将小时转换为两个变量是最符合逻辑的方法,这些变量在接收器中来回摆动。想象一下24小时钟的时针结束时的位置。x位置随y位置来回摆动。对于24小时的时钟,您可以通过x=sin(2pi*hour/24)y=cos(2pi*hour/24)来完成这一任务.

你需要这两个变量,否则就失去了经过时间的适当运动。这是由于sin或cos的导数在时间上的变化,当(x,y)位置在单位圆周时平稳地变化。

在欧氏空间中,这种方法对于聚类和保持午夜后15分钟到午夜前5分钟之间的距离非常有效。所有的模块建议都没有做到这一点,它们所完成的循环表示非常笨拙。

最后,考虑是否值得添加第三个特性来跟踪线性时间,从第一个记录开始,或者Unix时间戳或类似的东西开始,可以用小时(或分钟或秒)来构造线性时间。然后,这三个特征为时间的循环和线性发展提供了代理,例如,你可以提取循环现象,比如人们运动中的睡眠周期,以及人口和时间的线性增长。

希望这能有所帮助!

如果完成的话,

示例:

代码语言:javascript
复制
# Enable inline plotting
%matplotlib inline

#Import everything I need...

import numpy as np
import matplotlib as mp

import matplotlib.pyplot as plt
import pandas as pd

# Grab some random times from here: https://www.random.org/clock-times/
# put them into a csv.
from pandas import DataFrame, read_csv
df = read_csv('/Users/angus/Machine_Learning/ipython_notebooks/times.csv',delimiter=':')
df['hourfloat']=df.hour+df.minute/60.0
df['x']=np.sin(2.*np.pi*df.hourfloat/24.)
df['y']=np.cos(2.*np.pi*df.hourfloat/24.)

df
代码语言:javascript
复制
def kmeansshow(k,X):

    from sklearn import cluster
    from matplotlib import pyplot
    import numpy as np

    kmeans = cluster.KMeans(n_clusters=k)
    kmeans.fit(X)

    labels = kmeans.labels_
    centroids = kmeans.cluster_centers_
    #print centroids

    for i in range(k):
        # select only data observations with cluster label == i
        ds = X[np.where(labels==i)]
        # plot the data observations
        pyplot.plot(ds[:,0],ds[:,1],'o')
        # plot the centroids
        lines = pyplot.plot(centroids[i,0],centroids[i,1],'kx')
        # make the centroid x's bigger
        pyplot.setp(lines,ms=15.0)
        pyplot.setp(lines,mew=2.0)
    pyplot.show()
    return centroids

现在让我们尝试一下:

代码语言:javascript
复制
kmeansshow(6,df[['x', 'y']].values)

你几乎看不到午夜后的一些时间包含在午夜前的绿色星系团中。现在,让我们减少集群的数量,并显示午夜前后可以在单个集群中更详细地连接:

代码语言:javascript
复制
kmeansshow(3,df[['x', 'y']].values)

查看蓝色集群如何包含午夜前后在同一集群中聚集在一起的时间.

QED!

票数 7
EN

Data Science用户

发布于 2015-11-18 12:14:08

K-意思是使用平均值.

K-均值是为最小二乘设计的.它仅适用于欧氏距离的变式(=平方偏差之和)。

Counterexample:

假设你有两个小时0和23。

如果它们被分配到同一个集群,k-均值将计算平均值。

这两个数值的平均值为11.5。不是23.5。

滥用k-意味着循环“距离”可能不再收敛,并将返回无意义的结果。

但是,有更多的情况下,集群中心的概念是不可行的循环数据。例如,假设每一小时都有一个活动,中心是什么?算术平均值为12,但如果将循环空间考虑在内,在循环空间中,每小时都是一个同样好的选择。因此,循环空间中的“中心”概念是脆弱的。

交替聚类算法

您可以尝试使用适当的相似性度量,例如PAM或DBSCAN。

投影技术

正如其他答案所指出的,您可以通过sin/cos( time /24*2pi)将时间投影到单位圆。通过计算质心的角度,你可以把它映射回一个时间点。但是,一旦您需要额外的属性,就很难对数据进行有意义的规范化(以组合属性),并且您可以得到未定义的时间(例如,如果集群中有两个点,一个是6点,一个是18点)。我没有讨论这个问题,因为我想指出,修改距离函数对于k-方法来说不是一个好主意。

票数 1
EN

Data Science用户

发布于 2015-11-11 15:06:18

模运算一般情况下你会做end - start mod 24

代码语言:javascript
复制
julia> mod(-23,24)
1

我似乎还记得一些编程语言以不同的方式对待负数的模式,所以首先检查一下您的实现。

票数 0
EN
页面原文内容由Data Science提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://datascience.stackexchange.com/questions/8799

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档