摘要:聚類算法簡介聚類的目標是使同一類對象的相似度盡可能地大不同類對象之間的相似度盡可能地小。用戶地理位置信息的的聚類實現本實驗用實現,依賴等科學計算。
1. 聚類算法簡介
聚類的目標是使同一類對象的相似度盡可能地大;不同類對象之間的相似度盡可能地小。目前聚類的方法很多,根據基本思想的不同,大致可以將聚類算法分為五大類:層次聚類算法、分割聚類算法、基于約束的聚類算法、機器學習中的聚類算法和用于高維度的聚類算法。
以下實現主要選取了基于劃分的Kmeans算法和基于密度的DBSCAN算法來處理
一種典型的劃分聚類算法,它用一個聚類的中心來代表一個簇,即在迭代過程中選擇的聚點不一定是聚類中的一個點。其目的是使各個簇(共k個)中的數據點與所在簇質心的誤差平方和SSE(Sum of Squared Error)達到最小,這也是評價K-means算法最后聚類效果的評價標準。
算法的詳細原理可自行Google或Wiki。
一種典型的基于密度的聚類算法,該算法采用空間索引技術來搜索對象的鄰域,引入了“核心對象”和“密度可達”等概念,從核心對象出發,把所有密度可達的對象組成一個簇。簡單的說就是根據一個根據對象的密度不斷擴展的過程的算法。一個對象O的密度可以用靠近O的對象數來判斷。
在DBSCAN算法中將數據點分為一下三類: 核心點:在半徑Eps內含有超過MinPts數目的點 邊界點:在半徑Eps內點的數量小于MinPts,但是落在核心點的鄰域內 噪音點:既不是核心點也不是邊界點的點 這里有兩個量,一個是半徑Eps,另一個是指定的數目MinPts。2. 用戶地理位置信息的的聚類實現
本實驗用python實現,依賴numpy, pandas, sklearn, scipy等科學計算library。
數據來自收集得到的用戶的地理位置信息,即經緯度數據的序列集。
xy = numpy.array([[116.455788, 39.920767], [116.456065, 39.920965], [116.452312, 39.92304], [116.421385, 39.989539], [116.455685, 39.92069], [116.455876, 39.920845], [116.455973, 39.920902], [116.455645, 39.920657], [116.456022, 39.920934], [116.455685, 39.920691], [116.456023, 39.920671], [116.45596, 39.920864], [116.455522, 39.920856], [116.455276, 39.920407], [116.455799, 39.920867], [116.455349, 39.920425], [116.45511, 39.920377], [116.455318, 39.920442], [116.455298, 39.920474], [116.455839, 39.920636], [116.455979, 39.921168], [116.454281, 39.920006], [116.45598, 39.920612], [116.45388, 39.919584], [116.455474, 39.920737], [116.456009, 39.920641], [116.455439, 39.920574], [116.455759, 39.920841], [116.455838, 39.920644], [116.455983, 39.920847], [116.459803, 39.922041], [116.456029, 39.92088], [116.455539, 39.920603], [116.455989, 39.920851], [116.455719, 39.920789], [116.45601, 39.92082], [116.456229, 39.920564], [116.455906, 39.920771], [116.456248, 39.920868], [116.455805, 39.920544], [116.455896, 39.920758], [116.43692, 39.926767], [116.454672, 39.92024], [116.454813, 39.917848], [116.381415, 40.00875], [116.422925, 39.980757], [116.422849, 39.9808], [116.38107, 40.009217], [116.456078, 39.920747], [116.455242, 39.919515], [116.455615, 39.920533], [116.422092, 39.991104], [116.454847, 39.917724], [116.456686, 39.924316], [116.45575, 39.920642], [116.456713, 39.924413], [116.455846, 39.920828], [116.422108, 39.991098], [116.422075, 39.991139], [118.775572, 31.97337], [118.776968, 31.97392], [118.778187, 31.973121], [118.775695, 31.973254], [118.775302, 31.973807], [118.776303, 31.973692], [118.777541, 31.973439], [118.776196, 31.973489], [116.448944, 39.926799], [116.45487, 39.917804], [116.455762, 39.920645], [116.456146, 39.920441], [116.455857, 39.920043], [116.455458, 39.920826], [116.455533, 39.920791], [116.455426, 39.920896], [116.45566, 39.920811], [116.455696, 39.920621], [116.453667, 39.9259], [116.466606, 39.886322], [116.455917, 39.92062]])2.1 基于Kmeans的聚類實現
假設用戶的地理位置信息通常是工作地點和家,因此選取k值為2,代碼如下
res, idx = kmeans2(numpy.array(zip(xy[:, 0], xy[:, 1], z)), 2, iter=20, minit="points")
實現輸出結果
但是實際上用戶并未在河北出現過,用戶經常出現的地方除了北京的工作地方和家,還曾經在南京出差一段時間。所以將K值設定為3,再次運行
res, idx = kmeans2(numpy.array(zip(xy[:, 0], xy[:, 1], z)), 3, iter=20, minit="points")
輸出結果
這樣就將南京的地理位置區分出來了。工作地方和出差地方已經非常貼合了,但是家的地方離實際距離還是差了不少距離。
其實已經可以看出來,由于用戶的出現地點不可預知,因此很難確定K值。并且Kmeans聚合得到的結果取得是聚合簇的質心位置,并不是用戶的實際地理位置,而且我選取的是相似度量是歐式距離,而不是經緯度計算的球面距離。因此得到的結果并不理想。
DBSCAN算法的重點是選取的聚合半徑參數和聚合所需指定的MinPts數目。
在此使用球面距離來衡量地理位置的距離,來作為聚合的半徑參數。
如下實驗,選取2公里作為密度聚合的半徑參數,MinPts個數為5.
def haversine(lonlat1, lonlat2): lat1, lon1 = lonlat1 lat2, lon2 = lonlat2 lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2]) dlon = lon2 - lon1 dlat = lat2 - lat1 a = sin(dlat / 2) ** 2 + cos(lat1) * cos(lat2) * sin(dlon / 2) ** 2 c = 2 * asin(sqrt(a)) r = 6371 # Radius of earth in kilometers. Use 3956 for miles return c * r def clustering_by_dbscan(): ...... distance_matrix = squareform(pdist(X, (lambda u, v: haversine(u, v)))) db = DBSCAN(eps=2, min_samples=5, metric="precomputed") y_db = db.fit_predict(distance_matrix) X["cluster"] = y_db ...... plt.scatter(X["lat"], X["lng"], c=X["cluster"]) plt.show()
輸出如下
結果顯示該用戶的地理位置信息聚合簇為4塊,在結果中分別用0.0,1.0,2.0,-1.0來標記。可以看出DBSCAN算法可以根據用戶的活動半徑,也就是設定的最小半徑參數2公里,將用戶的活動地理位置數據集合分為了4簇,而且每一簇在空間上都是任意形狀的,分類聚合的效果是不錯的,但是得到的結果是一個個的簇,也就是一個個的地理點的集合,并不是一個“中心”。并且存在的噪聲點無法區分。
3.基于DBSCAN和Kmeans的混合算法實現從上面的實驗結果,Kmeans算法的關鍵的是 K值的選取,而我無法確定用戶地理信息聚類的簇的個數,如果實際上的地理位置的分布過于分散,按照固定K值聚合,得到的質心的位置可能和實際位置相差甚遠。而DBSCAN的算法,聚類結果不錯,因為是按照設定的人的活動半徑的密度可達來聚合的,但其結果是將數據集合分類,并不求出中心點。
因此我設計了一種基于DBSCAN和Kmeans的混合算法:先利用DBSCAN算法的密度可達特性將用戶的地理位置數據集按照活動半徑聚合成若干個簇,并且將每一簇的數據集作為新的輸入,再利用Kmeans算法的迭代聚合求出質心的位置,設定K值為1。
代碼如下
def clustering_by_dbscan_and_kmeans2(): X = pd.DataFrame( {"lat": [39.920767, 39.920965, 39.92304, 39.989539, 39.92069, 39.920845, 39.920902, 39.920657, 39.920934, 39.920691, 39.920671, 39.920864, 39.920856, 39.920407, 39.920867, 39.920425, 39.920377, 39.920442, 39.920474, 39.920636, 39.921168, 39.920006, 39.920612, 39.919584, 39.920737, 39.920641, 39.920574, 39.920841, 39.920644, 39.920847, 39.922041, 39.92088, 39.920603, 39.920851, 39.920789, 39.92082, 39.920564, 39.920771, 39.920868, 39.920544, 39.920758, 39.926767, 39.92024, 39.917848, 40.00875, 39.980757, 39.9808, 40.009217, 39.920747, 39.919515, 39.920533, 39.991104, 39.917724, 39.924316, 39.920642, 39.924413, 39.920828, 39.991098, 39.991139, 31.97337, 31.97392, 31.973121, 31.973254, 31.973807, 31.973692, 31.973439, 31.973489, 39.926799, 39.917804, 39.920645, 39.920441, 39.920043, 39.920826, 39.920791, 39.920896, 39.920811, 39.920621, 39.9259, 39.886322, 39.92062], "lng": [116.455788, 116.456065, 116.452312, 116.421385, 116.455685, 116.455876, 116.455973, 116.455645, 116.456022, 116.455685, 116.456023, 116.45596, 116.455522, 116.455276, 116.455799, 116.455349, 116.45511, 116.455318, 116.455298, 116.455839, 116.455979, 116.454281, 116.45598, 116.45388, 116.455474, 116.456009, 116.455439, 116.455759, 116.455838, 116.455983, 116.459803, 116.456029, 116.455539, 116.455989, 116.455719, 116.45601, 116.456229, 116.455906, 116.456248, 116.455805, 116.455896, 116.43692, 116.454672, 116.454813, 116.381415, 116.422925, 116.422849, 116.38107, 116.456078, 116.455242, 116.455615, 116.422092, 116.454847, 116.456686, 116.45575, 116.456713, 116.455846, 116.422108, 116.422075, 118.775572, 118.776968, 118.778187, 118.775695, 118.775302, 118.776303, 118.777541, 118.776196, 116.448944, 116.45487, 116.455762, 116.456146, 116.455857, 116.455458, 116.455533, 116.455426, 116.45566, 116.455696, 116.453667, 116.466606, 116.455917] }) distance_matrix = squareform(pdist(X, (lambda u, v: haversine(u, v)))) db = DBSCAN(eps=2, min_samples=5, metric="precomputed") y_db = db.fit_predict(distance_matrix) X["cluster"] = y_db results = {} for i in X.values: if i[2] not in results.keys(): results[i[2]] = [[i[1], i[0]]] else: if results[i[2]]: results[i[2]].append([i[1], i[0]]) else: results[i[2]] = [[i[1], i[0]]] print "DBSCAN output: ", len(results), results.keys() print "KMeans calc center as below: " for k in results.keys(): xy = numpy.array(results[k]) z = numpy.sin(xy[:, 1] - 0.2 * xy[:, 1]) z = whiten(z) res, idx = kmeans2(numpy.array(zip(xy[:, 0], xy[:, 1], z)), 1, iter=20, minit="points") address_text = my_get_address_text_by_location(res[0][1], res[0][0]) print res, address_text
輸出如下
其中”家“,”公司“,”出差“的位置信息已經非常貼合用戶的實際信息了。
但是仍然存在的噪聲點的信息。這個暫時還沒找到解決方案,下一步的思路是帶入用戶地理位置信息收集時候得到的附屬信息如時間來輔助分析,希望可以有更好的結果。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/44321.html
摘要:貢獻者飛龍版本最近總是有人問我,把這些資料看完一遍要用多長時間,如果你一本書一本書看的話,的確要用很長時間。為了方便大家,我就把每本書的章節拆開,再按照知識點合并,手動整理了這個知識樹。 Special Sponsors showImg(https://segmentfault.com/img/remote/1460000018907426?w=1760&h=200); 貢獻者:飛龍版...
摘要:摘要前文數據挖掘與機器學習技術入門實戰與大家分享了分類算法,在本文中將為大家介紹聚類算法和關聯分析問題。比如,聚類算法可以實現公司客戶價值自動劃分,網頁自動歸類等。 摘要:前文數據挖掘與機器學習技術入門實戰與大家分享了分類算法,在本文中將為大家介紹聚類算法和關聯分析問題。分類算法與聚類到底有何區別?聚類方法應在怎樣的場景下使用?如何使用關聯分析算法解決個性化推薦問題?本文就為大家揭曉答...
閱讀 2785·2021-10-14 09:42
閱讀 3608·2021-10-11 10:59
閱讀 2941·2019-08-30 11:25
閱讀 3074·2019-08-29 16:25
閱讀 3224·2019-08-26 17:40
閱讀 1225·2019-08-26 13:30
閱讀 1143·2019-08-26 11:46
閱讀 1329·2019-08-23 15:22