K-means
K-means
K-means算法優點:
1).是解決聚類問題的一種經典算法,原理簡單,實現容易。
2).當簇接近高斯分佈時,它的效果較好。
3).與密度聚類中的DSCAN相比,簇與簇之間劃分清晰。
4). 可作爲其他聚類方法的基礎算法,如譜聚類。
K-means算法缺點:
1).在簇的平均值可被定義的情況下才能使用,可能不適用於某些應用。
2).在K-means算法中K是事先給定的,這個K值的選定是非常難以估計的。很多時候,事先並不知道給定的數據集應該分成多少個類別才最合適。
3).在 K-means 算法中,首先需要根據初始聚類中心來確定一個初始劃分,然後對初始劃分進行優化。這個初始聚類中心的選擇對聚類結果有較大的影響,一旦初始值選擇的不好,可能無法得到有效的聚類結果。
4).該算法需要不斷地進行樣本分類調整,不斷地計算調整後的新的聚類中心,因此當數據量非常大時,算法的時間開銷是非常大的。
5).若簇中含有異常點,將導致均值偏離嚴重(即:對噪聲和孤立點數據敏感)。
6).不適用於發現非凸形狀的簇或者大小差別很大的簇。
7). 結果不一定是全局最優,只能保證局部最優
8). 算法時間複雜度比較高 O(nkt)。
K-means算法缺點的改進:
1).針對上述缺點2),通過類的自動合併和分裂,得到較爲合理的類型數目K,例如 ISODATA 算法。
2).針對上述缺點3),可選用二分K-均值聚類;或者多設置一些不同的初值,對比最後的運算結果,一直到結果趨於穩定結束。
3).針對上述缺點5),改成求點的中位數,這種聚類方式即K-Mediods聚類(K中值)。
k值如何確定
K-mediods(K中心點)算法
K-mediods算法是對K-means算法的一種改進算法。
K-mediods算法優點:
1).優點與K-means算法相同。
2).與K-means相比,K-mediods算法對於噪聲不那麼敏感,離羣點就不會造成劃分結果的偏差過大。
K-mediods算法缺點:
1).有K-means同樣的缺點。如:必須事先確定類簇數和中心點,簇數和中心點的選擇對結果影響很大;一般在獲得一個局部最優的解後就停止;對於除數值型以外的數據不適用;只適用於聚類結果爲凸形的數據集等。
2) K-mediods是對K-means的改進,但由於按照中心點選擇的方式進行計算,算法的時間複雜度也比K-means上升了O(n)。
K-mediods算法描述:
1). 首先隨機選取一組樣本作爲中心點集,每個中心點對應一個簇
2). 計算各樣本點到各個中心點的距離(如歐幾里德距離),將樣本點放入距離中心點最近的那個簇中
3). 計算各簇中,距離簇內各樣本點距離的絕度誤差最小的點,作爲新的中心點
4). 如果新的中心點集與原中心點集相同,算法終止;如果新的中心點集與原中心點集不完全相同,返回c)
K-mediods算法舉例:
a) 設有(A,B,C,D,E,F)一組樣本
b) 隨機選擇B、E爲中心點
c) 計算D和F到B的距離最近,A和C到E的距離最近,則B,D,F爲簇X1,A,C,E爲簇X2
d) 計算X1發現,D作爲中心點的絕對誤差最小,X2中依然是E作爲中心點絕對誤差最小
e) 重新以D、E作爲中心點,重複c)、d)步驟後,不再變換,則簇劃分確定。
層次聚類
密度聚類
DSCAN
DSCAN(Density-Based Spatial Clustering of Applications with Noise,具有噪聲的基於密度的聚類方法)是一種基於密度的空間聚類算法。它將簇定義爲密度相連的點的最大集合,能夠把具有足夠高密度的區域劃分爲簇,並在具有噪聲的空間數據庫中發現任意形狀的聚類。
優點:可以對任何形狀的數據進行聚類,而K-means系列主要針對高斯分佈的數據,類圓形的數據。
函數解釋:
sklearn.cluster.dbscan(X, eps=0.5, min_samples=5, metric=‘minkowski’, algorithm=‘auto’, leaf_size=30, p=2, sample_weight=None, random_state=None)
Parameters:
X:數組或稀疏矩陣,待聚類的特徵數組。
eps:float,可選,閾值,指兩個樣本之間的最大距,在距離內則視爲在同一個鄰域中。
min_samples:int,可選,將某個點視爲核心點的鄰域中的樣本數。
algorithm:{‘auto’,‘ball_tree’,‘kd_tree’,‘brute’},可選最近鄰模塊用來計算點距離和尋找最近鄰的算法。
leaf_size:int,可選(默認值=30)。作爲BallTree或cKDTree的參數,影響構造和查詢的速度,以及存儲樹所需的內存。
Returns:
labels:標籤
參數選擇:
- 半徑:半徑是最難指定的 ,大了圈住的點就多,簇的個數就少了;反之,簇的個數就多,這對我們最後的結果是有很大影響的。這個時候K距離可以幫助我們來設定半徑r,也就是要找到突變點,比如:首先選中一個點,計算它和其他點之間的距離,從小到大排序,,我們發現和之間的差異很大,於是認爲前面的距離是比較合適的,那麼就可以指定r半徑的大小爲0.13。這雖然是一個可取的方法,但確實很麻煩。
0.1 | 0.11 | 0.13 | 0.4 | 0.46 | 0.49 |
---|---|---|---|---|---|
代碼:
for i in range(2724):
item_third_ = item_third[i]
item_third_name_ = item_third_name[i]
dept_id_ = dept_id[i]
dept_name_ = dept_name[i]
# m
info_sql = "select m,dt from table where dept_id='"+ dept_id_ +"' and item_third='"+ item_third_ +"'"
info_df = spark.sql(info_sql)
info_df = info_df.sort(info_df.dt.asc())
info_list = info_df.collect()
m = [float(x['m']) for x in info_list]
dt = [x['dt'] for x in info_list]
dt_time = [datetime.datetime.strptime(x,"%Y-%m") for x in dt]
# average_sale_price
average_sale_price_sql = "select average_sale_price,dt from table where item_third='"+ item_third_ +"'"
average_sale_price_df = spark.sql(average_sale_price_sql)
average_sale_price_df = average_sale_price_df.sort(average_sale_price_df.dt.asc())
average_sale_price_list = average_sale_price_df.collect()
average_sale_price = [float(x['average_sale_price']) for x in average_sale_price_list]
dt_2 = [x['dt'] for x in average_sale_price_list]
dt_2_time = [datetime.datetime.strptime(x,"%Y-%m") for x in dt_2]
# draw image
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.rcParams['savefig.dpi'] = 100
plt.rcParams['figure.dpi'] = 100
fig = plt.figure()
fig.set_size_inches(18.5, 10.5)
plt.title('%s_%s_%s_%s_m' %(dept_id_, dept_name_, item_third_, item_third_name_))
ax1 = fig.add_subplot(211)
plt.plot(dt_time, m)
plt.grid()
plt.xlabel('dt')
plt.ylabel('m')
ax2 = fig.add_subplot(212)
plt.plot(dt_2_time, average_sale_price)
plt.grid()
plt.xlabel('dt_2')
plt.ylabel('average_sale_price')
plt.title('average_sale_price')
dept_name_backup = dept_name_.replace('/','')
item_third_name_backup = item_third_name_.replace('/','')
plt.savefig('./nox/average_sale_price_2year/%s_%s.png'%(dept_name_backup, item_third_name_backup), dpi=150)
國外有一個特別有意思的網站:https://www.naftaliharris.com/blog/visualizing-dbscan-clustering/
它可以把我們DBSCAN的迭代過程動態圖畫出來。
DBSCAN聚類的最終結果,如下:
沒有顏色標註的就是圈不到的樣本點,也就是離羣點,DBSCAN聚類算法在檢測離羣點的任務上也有較好的效果。如果是傳統的Kmeans聚類,我們也來看一下效果:
完美的體現出來DBSCAN算法基於密度聚類的優勢。
譜聚類
常用的評估方法:輪廓係數(Silhouette)
計算樣本i到同簇其它樣本到平均距離ai。ai越小,說明樣本i越應該被聚類到該簇,將ai稱爲樣本i到簇內不相似度。
計算樣本i到其它某簇Cj的所有樣本的平均距離bij,稱爲樣本i與簇Cj的不相似度。定義爲樣本i的簇間不相似度:bi=min(bi1,bi2,…,bik2)
si接近1,則說明樣本i聚類合理
si接近-1,則說明樣本i更應該分類到另外的簇
若si近似爲0,則說明樣本i在兩個簇的邊界上
所有樣本的的均值稱爲聚類結果的輪廓係數,是該聚類是否合理、有效的度量。
相似度度量及相互係數
參考:
https://blog.csdn.net/luanpeng825485697/article/details/79443512
https://blog.csdn.net/huacha__/article/details/81094891