k-mediods每次選取的中心點,必須是樣本點,而 k-means每次選取的中心點可以是樣本點之外的點,就好比中位數和平均值的區別;
k-medoids演算法步驟:
1.任意選取k個初始中心點medoids;
2.按照與medoids最近的原則,將剩餘點分配到當前最佳的medoids代表的類中;
3.在每一類中,計算每個樣本點與其他點的距離之和,選取距離之和最小的點作為新的medoids;
4.重複2-3的過程,直到所有的medoids點不再發生變化,或已達到設定的最大迭代次數;
k-medoids演算法選取簇中心點的準則函式是:當前簇中所有其他點到該中心點的距離之和最小,所以需要遍歷簇中所有點;
演算法總結
1)基於「代表物件」的聚類方法;
2)資料變數為數值型的聚類演算法;
3)異常點不會嚴重影響聚類結果;
4)時間複雜度高於k-means演算法。
#載入所需模組
import numpy as np
from numpy import
*import sys
from sklearn import metrics
from sklearn.preprocessing import standardscaler
import pandas as pd
import matplotlib.pyplot as plt
# 定義歐式距離的計算
deffunc_of_dis
(x, y)
:return np.sqrt(
sum(np.square(x - y)
))
#k-medoids演算法實現
defkmedoids
(df, k_num_center)
:"""
選定好距離公式開始進行訓練
:param df:樣本資料,pd.dataframe型別
:param k_num_center:類別數
"""print
('初始化'
,k_num_center,
'個中心點'
) data = df.values
#data = standardscaler().fit_transform(df) #資料標準化
indexs =
list
(range
(len
(data)))
random.shuffle(indexs)
# 隨機選擇質心
init_centroids_index = indexs[
:k_num_center]
centroids = data[init_centroids_index,:]
# 初始中心點
# 確定類別編號
levels =
list
(range
(k_num_center)
)print
('開始迭代'
)#sample_target = #樣本類別結果
if_stop =
false
while
(not if_stop)
: if_stop =
true
classify_points =
[[centroid]
for centroid in centroids]
#初始中心點轉換為列表
sample_target =
#樣本類別結果
# 遍歷資料
for sample in data:
# 計算距離,由距離該資料最近的核心,確定該點所屬類別
distances =
[func_of_dis(sample, centroid)
for centroid in centroids]
#計算所有樣本到初始中心點的距離
cur_level = np.argmin(distances)
#每個樣本到中心點的距離最小所對應的中心點的位置
# 統計,方便迭代完成後重新計算中間點
classify_points[cur_level]
#將樣本和最近的中心點歸為一類
# 重新劃分質心
distances_res =
#每個簇內各點到中心點的距離值之和列表,k個類別對應k個值
for i in
range
(k_num_center)
:# 幾類中分別尋找乙個最優點
distances =
[func_of_dis(point_1, centroids[i]
)for point_1 in classify_points[i]
]#計算之前被歸為一類的樣本中每個點和中心點的距離
now_distances =
sum(distances)
# 首先計算出現在中心點和其他所有點的距離總和
for point in classify_points[i]
: distances =
[func_of_dis(point_1, point)
for point_1 in classify_points[i]
]#計算簇中每個點和其他點的距離
new_distance =
sum(distances)
# 計算出該聚簇中各個點與其他所有點的總和,若是有小於當前中心點的距離總和的,中心點去掉
if new_distance < now_distances:
now_distances = new_distance
centroids[i]
= point # 換成該點
if_stop =
false
return
(sample_target,distances_res)
#確定k值
defk_value_sse
(k_value_list)
:#利用sse選擇k
sse =
# 存放每次結果的誤差平方和
sse_df = pd.dataframe(
)for i in k_value_list:
estimator = kmedoids(df,i)
# 構造聚類器
distances_res = estimator[1]
dist_sum =
sum(distances_res)
return
(k_value_list,sse)
不同的k值與sse值得對應關係,最終畫出一條曲線,這條曲線相當於人的手肘,而肘部對應的點就是最佳的k取值點,即曲線的拐點。
#確定最佳的k值後
best_model = kmedoids(data,k)
#模型評價,計算輪廓係數
labels = kmedoids(data,k)[0
]score = silhouette_score(data,labels,metric=
'euclidean'
)
聚類演算法 k medoids演算法
k means與k medoids之間的差異就是可以理解為對於資料樣本的平均值和中位數之間的差異 前者的取值範圍可以是連續空間中的任意值,而後者的取值卻只能是資料樣本範圍中的樣本。這個原因就是k means對於資料樣本的要求太高了,要求所有資料樣本處在乙個歐式空間中,對於有很多雜訊的資料就會造成極大...
聚類篇 (三)K Medoids聚類
k medoids演算法的基本思想為 對於給定聚類數目k,首先隨機選擇k個代表物件作為初始聚類中心,計算各剩餘物件與代表物件的距離並將其分配給最近的乙個簇,產生相應的聚類結果。然後開始迭代過程 對於每一次迭代,將隨機選擇的乙個非中心點替代原始中心點中的乙個,重新計算聚類結果。若聚類效果有所提高,保留...
聚類演算法 近鄰聚類演算法
time is always too short for those who need it,but for those who love,it lasts forever.dracula untold 近鄰聚類法同樣是一種基於距離閾值的聚類演算法。coding utf 8 近鄰聚類演算法的pyth...