GMM聚类模型(高斯混合聚类)

it2022-05-09  54

1.查看数据

查看数据类型 import pandas as pd data = pd.read_csv ('Fremont.csv', index_col='Date', parse_dates=True) data.head() data.tail()

绘图 data.plot();

数据重采样,按天进行计算 data.resample('D').sum().head()

数据重采样,按周进行计算,看看这两年多的变化趋势 data.resample('w').sum().plot();

数据表现出很强的季节性,并且有一些局部特征,可能是受温度、日期、降水等因素的影响。

data.resample('D').sum().rolling(365).sum().plot();

取time为索引,各类在一天的时间段的流量的均值,并绘图 print(data.index.time) print(data.groupby(data.index.time).mean())

import matplotlib.pyplot as plt data.groupby(data.index.time).mean().plot(); plt.xticks(rotation=45)

取得总流量,以time为索引,date为列,添加透视表并绘图 data.columns =['West', 'East'] data ['Total'] =data['West']+data['East'] pivoted = data.pivot_table('Total', index=data.index.time, columns=data.index.date) pivoted.iloc[:5,:5]

pivoted.plot(legend=False, alpha =0.01); plt.xticks(rotation=45)

2.PCA降维

PCA(Principal Component Analysis)是一种常用的数据分析方法。PCA通过线性变换将原始数据变换为一组各维度线性无关的表示,可用于提取数据的主要特征分量,常用于高维数据的降维。

查看透视表的形状 pivoted.shape

补充缺失值,并倒置数据 X = pivoted.fillna(0).T.values 降维 from sklearn.decomposition import PCA X2 = PCA(2).fit_transform(X) X2.shape

画出降维后值的分布情况 plt.scatter(X2[:,0],X2[:,1])

3.GMM聚类模型(高斯混合聚类)

k-means聚类模型非常简单并且易于理解,但是他的简单性也为实际应用带来了挑战。特别是实际应用中,k-means的非概率性和它仅根据到簇中心点的距离来指派将导致性能低下。高斯混合模型可以看作是k-means的一个扩展,但它也是一种非常强大的聚类评估工具。

k-means算法的缺陷:在实际聚类的过程中,两个簇往往会存在重合部分。k-means算法对于重合部分的点被分配到哪个簇缺乏一个评估方案,k-means模型本身也没有度量簇的分配概率或不确定性的方法。 理解k-means模型的一个方法是,它在每个簇的中心放置了一个圆圈(在更高维空间是一个超空间),圆圈半径根据最远的点和簇中心点的距离算出。这个半径作为训练集分配的硬切断,即在这个圆圈之外的任何点都不是该簇的成员。而且,k-means要求这些簇的模型必须是圆形:k-means算法没有内置方法来实现椭圆形的簇。这就使得某些情况下k-means模型拟合出来的簇(圆形)与实际数据分布(可能是椭圆)差别很大,导致多个圆形的簇混在一起,相互重叠。 总的来说,k-means存在两个缺点——类的形状缺少灵活性、缺少簇分配的概率——使得它对许多数据集(特别是低维数据集)的拟合效果不尽如人意。

混合高斯模型(Gaussian Mixture Model,简称GMM)是用高斯概率密度函数(正态分布曲线)精确地量化事物,将一个事物分解为若干的基于高斯概率密度函数(正态分布曲线)形成的模型。通俗点讲,无论观测数据集如何分布以及呈现何种规律,都可以通过多个单一高斯模型的混合进行拟合。

一个高斯混合模型试图找到多维高斯模型概率分布的混合体,从而找到任意数据最好的模型。在最简单的场景中,GMM可以用与k-means相同的方式寻找类。 如下图是一个观测数据集,数据集明显分为两个聚集核心,我们通过两个单一的高斯模型混合成一个复杂模型来拟合数据。这就是一个混合高斯模型。

from sklearn.mixture import GaussianMixture gmm =GaussianMixture(2) gmm.fit(X) labels = gmm.predict_proba(X) labels

labels = gmm.predict(X) pivoted['labels'] = labels labels

聚类绘图 plt.scatter(X2[:,0],X2[:,1], c=labels, cmap='rainbow') #plt.colorbar()

把每一类每天各小时的平均流量数据绘图 fig, ax = plt.subplots(1, 2, figsize =(14, 6)) pivoted.T[labels == 0].T.plot(legend =False, alpha =0.1, ax=ax[0]) pivoted.T[labels == 1].T.plot(legend =False, alpha =0.1, ax=ax[1]) ax[0].set_title ('Purple Cluster') ax[1].set_title ('Red Cluster')

4.数据分析

西雅图市民的工作习惯 下面,我们进一步深入研究这些数据,看看能不能发现关于西雅图骑行上班族工作习惯的更多信息。容易想到,第一类很有可能是工作日,而第二类可能是休息日。重新画图,标记出每一个样本点是星期几就能检验这一猜想。 dayofweek = pd.to_datetime(data.index).dayofweek plt.scatter(pivoted[:, 0], pivoted[:, 1], c=dayofweek,cmap=plt.cm.get_cmap('jet', 7)) cb = plt.colorbar(ticks=range(7)) cb.set_ticklabels(['Mon', 'Tues', 'Wed', 'Thurs', 'Fri', 'Sat', 'Sun']) plt.clim(-0.5, 6.5);

显然,关于工作日和周末的猜测基本正确,但是有一点例外,少数工作日服从周末的车流量模式。另外还有一个有趣的现象,在这张图上周五虽然属于工作日这一类,但是更靠近周末这一类。

让我们仔细看看这些“站错队”的工作日特殊在哪里。先将每一天的类别和星期几列出来。

results = pd.DataFrame({'cluster': labels, 'is_weekend': (dayofweek > 4), 'weekday': data.index.map(lambda x: x.strftime('%a'))}, index=pivoted.index) results.head()

查一下有多少周末被归入第一类,即工作日模式。 weekend_workdays = results.query('cluster == 0 and is_weekend') len(weekend_workdays) 0

没有!显然,西雅图骑行上班族作为一个整体在这几年的周末都没有去上班。

类似地,看看有多少工作日被归入第二类,即休息日模式。 midweek_holidays = results.query('cluster == 1 and not is_weekend') len(midweek_holidays) 23

过去几年中有23个工作日,西雅图骑行上班族没去上班。为了标记这些日子,先用Pandas读取美国的法定节假日。

from pandas.tseries.holiday import USFederalHolidayCalendar cal = USFederalHolidayCalendar() holidays = cal.holidays('2012', '2016', return_name=True) holidays.head()

完整起见,将这些节假日之前和之后一天也标记出来。

holidays_all = pd.concat([holidays, "Day Before " + holidays.shift(-1, 'D'), "Day After " + holidays.shift(1, 'D')]) holidays_all = holidays_all.sort_index() holidays_all.head()

注意,这些假期是调休后的日期(observed holiday),比如2012年的元旦标注在1月2日。

现在,将西雅图骑行上班族没去上班的所有非周末的日子列出来。 holidays_all.name = 'name' # required for join joined = midweek_holidays.join(holidays_all) set(joined['name'])

同时也能得到,在下面这些法定节假日,西雅图骑行上班族还是去上班了。

set(holidays) - set(joined.name)

5.总结

我们使用基本的可视化方法和非监督机器学习技术对Fremont桥的自行车流量数据进行了研究,得到一些关于经过该桥骑车上下班人群的工作习惯的结论。概括起来,主要有以下几点:

西雅图的骑行上班族整体上在元旦、阵亡将士纪念日、独立日、美国劳动节,以及感恩节和圣诞节前后这些节日不去上班。但在一些小的节日,他们一般会去单位,如哥伦布日、马丁·路德·金日、总统日,以及美国退伍军人节等。西雅图骑行上班族整体上从来不在周末去上班。

参考:https://blog.csdn.net/weixin_43746433/article/details/96890459

6.聚类对比

make_blobs,多类单标签数据集,为每个类分配一个或多个正太分布的点集 from sklearn.datasets.samples_generator import make_blobs X, y_true = make_blobs(n_samples=800, centers=4, random_state=11)# plt.scatter(X[:, 0], X[:, 1]);

KMeans聚类 from sklearn.cluster import KMeans kmeans = KMeans(n_clusters=4) kmeans.fit(X) y_kmeans = kmeans.predict(X) plt.scatter(X[:, 0], X[:, 1], c=y_kmeans, s=50, cmap='viridis') centers = kmeans.cluster_centers_

GMM聚类 from sklearn.mixture import GaussianMixture gmm = GaussianMixture(n_components=4).fit(X) labels = gmm.predict(X) plt.scatter(X[:, 0], X[:, 1], c=labels, s=40, cmap='viridis');

GMM更详细的内容: https://blog.csdn.net/jasonzhoujx/article/details/81947663


最新回复(0)