Scikit-learn、GMM:来自 .means_ 属性的 return 问题
Scikit-learn, GMM: Issue with return from .means_ attribute
很明显.. means_
属性 returns 与我为每个集群计算的平均值不同的结果。 (或者我对这个return的理解有误!)
以下是我编写的代码,用于检查 GMM 如何适合我拥有的时间序列数据。
import numpy as np
import pandas as pd
import seaborn as sns
import time
import matplotlib as mpl
import matplotlib.pyplot as plt
from sklearn.mixture import BayesianGaussianMixture
from sklearn.mixture import GaussianMixture
toc = time.time()
input
包含(meters/samples 的数量)x(特征的数量)
read = pd.read_csv('input', sep='\t', index_col= 0, header =0, \
names =['meter', '6:30', '9:00', '15:30', '22:30', 'std_year', 'week_score', 'season_score'], \
encoding= 'utf-8')
read.drop('meter', 1, inplace=True)
read['std_year'] = read['std_year'].divide(4).round(2)
input = read.as_matrix(columns=['6:30', '9:00', '15:30', '22:30',])
将它放入 GMM 中,有 10 个簇。 (使用 BIC 图,5 是得分最低的最佳数字..但为 -7,000。这并非不可能,在与我的顾问讨论后但仍然很奇怪。)
gmm = GaussianMixture(n_components=10, covariance_type ='full', \
init_params = 'random', max_iter = 100, random_state=0)
gmm.fit(input)
print(gmm.means_.round(2))
cluster = gmm.predict(input)
我接下来要做的是手动计算 centroid/center - 如果使用这些术语表示平均向量是正确的 - 每个聚类,使用来自 return 的标签 .predict
.
具体来说,cluster包含一个从0到9的值,每个值表示集群。我将其转置并连接到(样本数)x(属性数)的输入矩阵作为数组。我想利用 pandas 库处理如此大数据的简便性,因此将其转换为数据框。
cluster = np.array(cluster).reshape(-1,1) #(3488, 1)
ret = np.concatenate((cluster, input), axis=1) #(3488, 5)
ret_pd = pd.DataFrame(ret, columns=['label','6:30', '9:00', '15:30', '22:30'])
ret_pd['label'] = ret_pd['label'].astype(int)
对于每个仪表的特征,其聚类被分类在列'label'下。因此,以下代码按每个标签聚类,然后我按列取平均值。
cluster_mean = []
for label in range(10):
#take mean by columns per each cluster
segment= ret_pd[ret_pd['label']== label]
print(segment)
turn = np.array(segment)[:, 1:]
print(turn.shape)
mean_ = np.mean(turn, axis =0).round(2) #series
print(mean_)
plt.plot(np.array(mean_), label='cluster %s' %label)
cluster_mean.append(list(mean_))
print(cluster_mean)
xvalue = ['6:30', '9:00', '15:30', '22:30']
plt.ylabel('Energy Use [kWh]')
plt.xlabel('time of day')
plt.xticks(range(4), xvalue)
plt.legend(loc = 'upper center', bbox_to_anchor = (0.5, 1.05),\
ncol =2, fancybox =True, shadow= True)
plt.savefig('cluster_gmm_100.png')
tic = time.time()
print('time ', tic-toc)
有趣的是,内部库中的 .means_
return 与我在此代码中计算的值不同。
Scikit-learn 的 .means_
:
[[ 0.46 1.42 1.12 1.35]
[ 0.49 0.78 1.19 1.49]
[ 0.49 0.82 1.01 1.63]
[ 0.6 0.77 0.99 1.55]
[ 0.78 0.75 0.92 1.42]
[ 0.58 0.68 1.03 1.57]
[ 0.4 0.96 1.25 1.47]
[ 0.69 0.83 0.98 1.43]
[ 0.55 0.96 1.03 1.5 ]
[ 0.58 1.01 1.01 1.47]]
我的结果:
[[0.45000000000000001, 1.6599999999999999, 1.1100000000000001, 1.29],
[0.46000000000000002, 0.73999999999999999, 1.26, 1.48],
[0.45000000000000001, 0.80000000000000004, 0.92000000000000004, 1.78],
[0.68000000000000005, 0.72999999999999998, 0.85999999999999999, 1.5900000000000001],
[0.91000000000000003, 0.68000000000000005, 0.84999999999999998, 1.3600000000000001],
[0.58999999999999997, 0.65000000000000002, 1.02, 1.5900000000000001],
[0.35999999999999999, 1.03, 1.28, 1.46],
[0.77000000000000002, 0.88, 0.94999999999999996, 1.3500000000000001],
[0.53000000000000003, 1.0700000000000001, 0.97999999999999998, 1.53],
[0.66000000000000003, 1.21, 0.95999999999999996, 1.3600000000000001]]
另一方面,我不确定为什么我 return 的结果没有正确四舍五入到 2 位小数。
虽然我不完全确定您的代码在做什么,但我相当确定问题出在哪里。
means_
返回的参数是构成模型的参数(高斯)分布的均值。当您通过取每个组件中聚集的所有数据的平均值来计算平均值时,这几乎总是会给出不同的结果(尽管结果相似)。为了更好地理解为什么这些可能不同,我建议阅读更多关于 scikit-learn
用于拟合 GMM 的 Expectation maximization algorithm。
很明显.. means_
属性 returns 与我为每个集群计算的平均值不同的结果。 (或者我对这个return的理解有误!)
以下是我编写的代码,用于检查 GMM 如何适合我拥有的时间序列数据。
import numpy as np
import pandas as pd
import seaborn as sns
import time
import matplotlib as mpl
import matplotlib.pyplot as plt
from sklearn.mixture import BayesianGaussianMixture
from sklearn.mixture import GaussianMixture
toc = time.time()
input
包含(meters/samples 的数量)x(特征的数量)
read = pd.read_csv('input', sep='\t', index_col= 0, header =0, \
names =['meter', '6:30', '9:00', '15:30', '22:30', 'std_year', 'week_score', 'season_score'], \
encoding= 'utf-8')
read.drop('meter', 1, inplace=True)
read['std_year'] = read['std_year'].divide(4).round(2)
input = read.as_matrix(columns=['6:30', '9:00', '15:30', '22:30',])
将它放入 GMM 中,有 10 个簇。 (使用 BIC 图,5 是得分最低的最佳数字..但为 -7,000。这并非不可能,在与我的顾问讨论后但仍然很奇怪。)
gmm = GaussianMixture(n_components=10, covariance_type ='full', \
init_params = 'random', max_iter = 100, random_state=0)
gmm.fit(input)
print(gmm.means_.round(2))
cluster = gmm.predict(input)
我接下来要做的是手动计算 centroid/center - 如果使用这些术语表示平均向量是正确的 - 每个聚类,使用来自 return 的标签 .predict
.
具体来说,cluster包含一个从0到9的值,每个值表示集群。我将其转置并连接到(样本数)x(属性数)的输入矩阵作为数组。我想利用 pandas 库处理如此大数据的简便性,因此将其转换为数据框。
cluster = np.array(cluster).reshape(-1,1) #(3488, 1)
ret = np.concatenate((cluster, input), axis=1) #(3488, 5)
ret_pd = pd.DataFrame(ret, columns=['label','6:30', '9:00', '15:30', '22:30'])
ret_pd['label'] = ret_pd['label'].astype(int)
对于每个仪表的特征,其聚类被分类在列'label'下。因此,以下代码按每个标签聚类,然后我按列取平均值。
cluster_mean = []
for label in range(10):
#take mean by columns per each cluster
segment= ret_pd[ret_pd['label']== label]
print(segment)
turn = np.array(segment)[:, 1:]
print(turn.shape)
mean_ = np.mean(turn, axis =0).round(2) #series
print(mean_)
plt.plot(np.array(mean_), label='cluster %s' %label)
cluster_mean.append(list(mean_))
print(cluster_mean)
xvalue = ['6:30', '9:00', '15:30', '22:30']
plt.ylabel('Energy Use [kWh]')
plt.xlabel('time of day')
plt.xticks(range(4), xvalue)
plt.legend(loc = 'upper center', bbox_to_anchor = (0.5, 1.05),\
ncol =2, fancybox =True, shadow= True)
plt.savefig('cluster_gmm_100.png')
tic = time.time()
print('time ', tic-toc)
有趣的是,内部库中的 .means_
return 与我在此代码中计算的值不同。
Scikit-learn 的 .means_
:
[[ 0.46 1.42 1.12 1.35]
[ 0.49 0.78 1.19 1.49]
[ 0.49 0.82 1.01 1.63]
[ 0.6 0.77 0.99 1.55]
[ 0.78 0.75 0.92 1.42]
[ 0.58 0.68 1.03 1.57]
[ 0.4 0.96 1.25 1.47]
[ 0.69 0.83 0.98 1.43]
[ 0.55 0.96 1.03 1.5 ]
[ 0.58 1.01 1.01 1.47]]
我的结果:
[[0.45000000000000001, 1.6599999999999999, 1.1100000000000001, 1.29],
[0.46000000000000002, 0.73999999999999999, 1.26, 1.48],
[0.45000000000000001, 0.80000000000000004, 0.92000000000000004, 1.78],
[0.68000000000000005, 0.72999999999999998, 0.85999999999999999, 1.5900000000000001],
[0.91000000000000003, 0.68000000000000005, 0.84999999999999998, 1.3600000000000001],
[0.58999999999999997, 0.65000000000000002, 1.02, 1.5900000000000001],
[0.35999999999999999, 1.03, 1.28, 1.46],
[0.77000000000000002, 0.88, 0.94999999999999996, 1.3500000000000001],
[0.53000000000000003, 1.0700000000000001, 0.97999999999999998, 1.53],
[0.66000000000000003, 1.21, 0.95999999999999996, 1.3600000000000001]]
另一方面,我不确定为什么我 return 的结果没有正确四舍五入到 2 位小数。
虽然我不完全确定您的代码在做什么,但我相当确定问题出在哪里。
means_
返回的参数是构成模型的参数(高斯)分布的均值。当您通过取每个组件中聚集的所有数据的平均值来计算平均值时,这几乎总是会给出不同的结果(尽管结果相似)。为了更好地理解为什么这些可能不同,我建议阅读更多关于 scikit-learn
用于拟合 GMM 的 Expectation maximization algorithm。