Clustering
名義/循環變量的 SOM 聚類
只是想知道是否有人熟悉對標稱輸入進行聚類。我一直將 SOM 視為一種解決方案,但顯然它僅適用於數字特徵。分類特徵是否有任何擴展?具體來說,我想知道“星期幾”是一種可能的功能。當然可以將其轉換為數字特徵(即 Mon - Sun 對應於 1-7 號)但是那麼 Sun 和 Mon (1&7) 之間的歐幾里得距離將與 Mon 到 Tues 的距離 (1&2) 不同)。任何建議或想法將不勝感激。
背景:
轉換小時的最合乎邏輯的方法是轉換成兩個來回擺動不同步的變量。想像一下 24 小時制時針末端的位置。
x
位置前後擺動,與位置不同步y
。對於 24 小時制,您可以使用x=sin(2pi*hour/24)
,來完成此操作y=cos(2pi*hour/24)
。您需要這兩個變量,否則會丟失正確的時間運動。這是因為 sin 或 cos 的導數隨時間變化,而
(x,y)
位置在繞單位圓行進時平滑變化。最後,考慮是否值得添加第三個特徵來跟踪線性時間,它可以構造為從第一條記錄開始的小時(或分鐘或秒)或 Unix 時間戳或類似的東西。然後,這三個特徵為時間的循環和線性進程提供了代理,例如,您可以提取循環現象,如人們運動中的睡眠週期,以及人口與時間的線性增長。
如果完成的例子:
# 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
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
現在讓我們嘗試一下:
kmeansshow(6,df[['x', 'y']].values)
您幾乎看不到午夜之前的綠色集群中包含一些午夜之後的時間。現在讓我們減少集群的數量,並更詳細地展示午夜之前和之後可以連接到一個集群中:
kmeansshow(3,df[['x', 'y']].values)
看看藍色集群如何包含從午夜之前和之後聚集在同一個集群中的時間……
您可以針對時間、一周中的某天、一個月中的一周、一個月中的某天、季節或任何時間執行此操作。