Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ruby-on-rails-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用R-K均值对时间序列进行聚类是否准确?_R_Time Series_Cluster Analysis_Distance Matrix_Dtw - Fatal编程技术网

用R-K均值对时间序列进行聚类是否准确?

用R-K均值对时间序列进行聚类是否准确?,r,time-series,cluster-analysis,distance-matrix,dtw,R,Time Series,Cluster Analysis,Distance Matrix,Dtw,我的数据集是由对105个国家(行)14年(列)相同指数的测量组成的。我想根据各国指数随时间变化的趋势对其进行分类 我正在尝试利用DTW距离矩阵(DTW包)进行分层聚类(hclust)和K medoid(pam) 我还尝试了K均值,使用DTW距离矩阵作为函数kmeans的第一个参数。该算法可行,但我不确定其准确性,因为K均值利用欧氏距离并计算质心作为均值 我也在考虑直接使用数据,但是我不能理解结果是如何准确的,因为算法将考虑不同变量的随时间变化的同一变量的不同测量,以便计算每次迭代和质心距离的重心

我的数据集是由对105个国家(行)14年(列)相同指数的测量组成的。我想根据各国指数随时间变化的趋势对其进行分类

我正在尝试利用DTW距离矩阵(
DTW
包)进行分层聚类(
hclust
)和K medoid(
pam

我还尝试了K均值,使用DTW距离矩阵作为函数
kmeans
的第一个参数。该算法可行,但我不确定其准确性,因为K均值利用欧氏距离并计算质心作为均值

我也在考虑直接使用数据,但是我不能理解结果是如何准确的,因为算法将考虑不同变量的随时间变化的同一变量的不同测量,以便计算每次迭代和质心距离的重心,以将观测值分配给簇。在我看来,这个过程不可能对时间序列进行聚类,也不可能对层次聚类和K-均值聚类进行聚类


在对时间序列进行聚类时,K均值算法是一个不错的选择,还是最好使用利用距离概念作为DTW的算法(但速度较慢)?是否存在一个R函数,允许使用带距离矩阵的K均值算法或特定包对时间序列数据进行聚类

KMeans将完全按照您的指示执行。不幸的是,试图将时间序列数据集提供给KMeans算法将导致无意义的结果。KMeans算法和大多数通用的聚类方法都是围绕欧几里德距离构建的,欧几里德距离似乎不是时间序列数据的良好度量。很简单,当簇不是圆形时,K-means通常不起作用,因为它使用某种距离函数,并且距离是从簇中心测量的。检查GMM算法作为替代方案。听起来你要和R一起做这个实验。如果是这样,请查看下面的示例代码

import numpy as np
import itertools

from scipy import linalg
import matplotlib.pyplot as plt
import matplotlib as mpl

from sklearn import mixture

print(__doc__)

# Number of samples per component
n_samples = 500

# Generate random sample, two components
np.random.seed(0)
C = np.array([[0., -0.1], [1.7, .4]])
X = np.r_[np.dot(np.random.randn(n_samples, 2), C),
          .7 * np.random.randn(n_samples, 2) + np.array([-6, 3])]

lowest_bic = np.infty
bic = []
n_components_range = range(1, 7)
cv_types = ['spherical', 'tied', 'diag', 'full']
for cv_type in cv_types:
    for n_components in n_components_range:
        # Fit a Gaussian mixture with EM
        gmm = mixture.GaussianMixture(n_components=n_components,
                                      covariance_type=cv_type)
        gmm.fit(X)
        bic.append(gmm.bic(X))
        if bic[-1] < lowest_bic:
            lowest_bic = bic[-1]
            best_gmm = gmm

bic = np.array(bic)
color_iter = itertools.cycle(['navy', 'turquoise', 'cornflowerblue',
                              'darkorange'])
clf = best_gmm
bars = []

# Plot the BIC scores
plt.figure(figsize=(8, 6))
spl = plt.subplot(2, 1, 1)
for i, (cv_type, color) in enumerate(zip(cv_types, color_iter)):
    xpos = np.array(n_components_range) + .2 * (i - 2)
    bars.append(plt.bar(xpos, bic[i * len(n_components_range):
                                  (i + 1) * len(n_components_range)],
                        width=.2, color=color))
plt.xticks(n_components_range)
plt.ylim([bic.min() * 1.01 - .01 * bic.max(), bic.max()])
plt.title('BIC score per model')
xpos = np.mod(bic.argmin(), len(n_components_range)) + .65 +\
    .2 * np.floor(bic.argmin() / len(n_components_range))
plt.text(xpos, bic.min() * 0.97 + .03 * bic.max(), '*', fontsize=14)
spl.set_xlabel('Number of components')
spl.legend([b[0] for b in bars], cv_types)

# Plot the winner
splot = plt.subplot(2, 1, 2)
Y_ = clf.predict(X)
for i, (mean, cov, color) in enumerate(zip(clf.means_, clf.covariances_,
                                           color_iter)):
    v, w = linalg.eigh(cov)
    if not np.any(Y_ == i):
        continue
    plt.scatter(X[Y_ == i, 0], X[Y_ == i, 1], .8, color=color)

    # Plot an ellipse to show the Gaussian component
    angle = np.arctan2(w[0][1], w[0][0])
    angle = 180. * angle / np.pi  # convert to degrees
    v = 2. * np.sqrt(2.) * np.sqrt(v)
    ell = mpl.patches.Ellipse(mean, v[0], v[1], 180. + angle, color=color)
    ell.set_clip_box(splot.bbox)
    ell.set_alpha(.5)
    splot.add_artist(ell)

plt.xticks(())
plt.yticks(())
plt.title('Selected GMM: full model, 2 components')
plt.subplots_adjust(hspace=.35, bottom=.02)
plt.show()
这是一个KMeans集群

这是一个GMM集群

你觉得哪一个更像是时间序列图

我在谷歌上搜索了一个很好的R代码示例,以演示GMM集群是如何工作的。不幸的是,我找不到任何像样的东西。就个人而言,我使用Python比使用R多得多。如果您对Python解决方案持开放态度,请查看下面的示例代码

import numpy as np
import itertools

from scipy import linalg
import matplotlib.pyplot as plt
import matplotlib as mpl

from sklearn import mixture

print(__doc__)

# Number of samples per component
n_samples = 500

# Generate random sample, two components
np.random.seed(0)
C = np.array([[0., -0.1], [1.7, .4]])
X = np.r_[np.dot(np.random.randn(n_samples, 2), C),
          .7 * np.random.randn(n_samples, 2) + np.array([-6, 3])]

lowest_bic = np.infty
bic = []
n_components_range = range(1, 7)
cv_types = ['spherical', 'tied', 'diag', 'full']
for cv_type in cv_types:
    for n_components in n_components_range:
        # Fit a Gaussian mixture with EM
        gmm = mixture.GaussianMixture(n_components=n_components,
                                      covariance_type=cv_type)
        gmm.fit(X)
        bic.append(gmm.bic(X))
        if bic[-1] < lowest_bic:
            lowest_bic = bic[-1]
            best_gmm = gmm

bic = np.array(bic)
color_iter = itertools.cycle(['navy', 'turquoise', 'cornflowerblue',
                              'darkorange'])
clf = best_gmm
bars = []

# Plot the BIC scores
plt.figure(figsize=(8, 6))
spl = plt.subplot(2, 1, 1)
for i, (cv_type, color) in enumerate(zip(cv_types, color_iter)):
    xpos = np.array(n_components_range) + .2 * (i - 2)
    bars.append(plt.bar(xpos, bic[i * len(n_components_range):
                                  (i + 1) * len(n_components_range)],
                        width=.2, color=color))
plt.xticks(n_components_range)
plt.ylim([bic.min() * 1.01 - .01 * bic.max(), bic.max()])
plt.title('BIC score per model')
xpos = np.mod(bic.argmin(), len(n_components_range)) + .65 +\
    .2 * np.floor(bic.argmin() / len(n_components_range))
plt.text(xpos, bic.min() * 0.97 + .03 * bic.max(), '*', fontsize=14)
spl.set_xlabel('Number of components')
spl.legend([b[0] for b in bars], cv_types)

# Plot the winner
splot = plt.subplot(2, 1, 2)
Y_ = clf.predict(X)
for i, (mean, cov, color) in enumerate(zip(clf.means_, clf.covariances_,
                                           color_iter)):
    v, w = linalg.eigh(cov)
    if not np.any(Y_ == i):
        continue
    plt.scatter(X[Y_ == i, 0], X[Y_ == i, 1], .8, color=color)

    # Plot an ellipse to show the Gaussian component
    angle = np.arctan2(w[0][1], w[0][0])
    angle = 180. * angle / np.pi  # convert to degrees
    v = 2. * np.sqrt(2.) * np.sqrt(v)
    ell = mpl.patches.Ellipse(mean, v[0], v[1], 180. + angle, color=color)
    ell.set_clip_box(splot.bbox)
    ell.set_alpha(.5)
    splot.add_artist(ell)

plt.xticks(())
plt.yticks(())
plt.title('Selected GMM: full model, 2 components')
plt.subplots_adjust(hspace=.35, bottom=.02)
plt.show()
将numpy导入为np
进口itertools
来自scipy进口公司
将matplotlib.pyplot作为plt导入
将matplotlib导入为mpl
从SKL学习进口混合物
打印(文档)
#每个组件的样本数
n_样本=500
#生成随机样本,两个分量
np.random.seed(0)
C=np.数组([[0.,-0.1],[1.7,.4]]
X=np.r_uu[np.dot(np.random.randn(n_样本,2),C),
.7*np.random.randn(n_样本,2)+np.array([-6,3])]
最低比克=np.infty
bic=[]
n_分量_范围=范围(1,7)
cv_类型=[‘球形’、‘平直’、‘对角’、‘完全’]
对于cv_类型中的cv_类型:
对于n_组件范围内的n_组件:
#用EM拟合高斯混合
gmm=混合物。高斯混合(n_组分=n_组分,
协方差类型=cv类型)
gmm.fit(X)
bic.append(gmm.bic(X))
如果bic[-1]<最低的\u bic:
最低比克=比克[-1]
最佳gmm=gmm
bic=np.数组(bic)
颜色=itertools.循环([‘海军蓝’、‘绿松石’、‘矢车菊蓝’,
“darkorange”])
clf=最佳值
条形图=[]
#绘制BIC分数
plt.图(figsize=(8,6))
spl=plt.子批次(2,1,1)
对于枚举(zip(cv_类型,颜色)中的i(cv_类型,颜色)):
xpos=np.array(n个分量范围)+.2*(i-2)
附加条(plt.bar(XPO,bic[i*len(n\u组件\u范围)):
(i+1)*len(n个分量范围)],
宽度=0.2,颜色=颜色)
plt.xticks(n\u组件\u范围)
plt.ylim([bic.min()*1.01-.01*bic.max(),bic.max()]))
产品名称(“每个型号的BIC分数”)
xpos=np.mod(bic.argmin(),len(n_components_range))+.65+\
.2*np.floor(bic.argmin()/len(n\u组件\u范围))
plt.text(xpos,bic.min()*0.97+.03*bic.max(),“*”,fontsize=14)
spl.set_xlabel('组件数量')
spl.图例([b[0]表示条形图中的b],cv_类型)
#策划赢家
splot=plt.子批次(2,1,2)
Y=clf.预测(X)
对于枚举(zip)中的i,(平均值,cov,颜色)(clf.means,clf.convariances,
颜色(iter):
v、 w=直线对数八(cov)
如果不是np.any(Y_u==i):
持续
plt.scatter(X[Y=i,0],X[Y=i,1],.8,color=color)
#绘制一个椭圆以显示高斯分量
角度=np.arctan2(w[0][1],w[0][0])
角度=180。*角度/np.pi#转换为度
v=2。*np.sqrt(2.)*np.sqrt(v)
ell=mpl.patches.Ellipse(平均值,v[0],v[1],180.+角度,颜色=颜色)
ell.set\u clip\u box(splot.bbox)
ell.set_α(.5)
splot.add_艺术家(ell)
plt.xticks(())
plt.yticks(())
产品名称(“选定的GMM:完整型号,2个部件”)
plt.子批次调整(hspace=.35,bottom=.02)
plt.show()

最后,从下面的图片中,您可以清楚地看到这是一个怎样的例子。要复制的代码如下:

require(quantmod)
SCHB  <- fortify(getSymbols('SCHB', auto.assign=FALSE))
set.seed(730) # for reproducibility
mixmdl <- mixtools::normalmixEM(Cl(SCHB), k = 5); plot_GMM(mixmdl, k = 5) # 5 clusters
plot_GMM(mixmdl, k = 5)
require(quantmod)

SCHB这似乎不是一个适合堆栈溢出的特定编程问题。如果您对各种统计方法的适当使用有一般性问题,那么您应该在上询问这些问题。你更有可能在那里得到更好的答案。在谷歌上询问是否存在函数更好。这里的问题应该包括一个简单的示例输入和所需的输出,以测试可能的解决方案。这是一个有趣而重要的问题,然而,无论是好是坏,答案只能通过尝试两种方法并观察哪些方法更有效来知道。关于使用哪个R包的问题将在stats.stackexchange.com或R-help邮件列表上引起更多关注。非常感谢