K-means算法详解及python代码实现
K-means算法
- 算法步驟
- 對數據的要求
- 算法的優缺點
- 算法需要注意的點
- 算法實現(python)(待更.......)
算法步驟
1、隨機選取K個點作為初始聚類中心
2、計算各個數據到個聚類中心的距離并歸類到最近的聚類中心
3、樣本全部劃分后重新計算K個類的聚類中心
4、重復2~3的步驟直至K個類的聚類中心不再變化(收斂)
對數據的要求
算法的優缺點
一、優點
一、缺點
算法需要注意的點
1. K-means初始點的選擇對結果有什么影響?
不合理的初始點的選取會導致長時間無法收斂且得到局部最優
2. K-means每個類別中心的初始點如何選擇?
1、隨機法
2、選擇各批次距離近可能遠的K個點
3、選擇層次聚類或者Canopy處理
3. K-means中k如何選擇?
1、比較類內間距,類間距離確定K(平均輪廓系數(大)或類內距離/類間距離(小))
2、按需選擇、觀察法或手肘法
輪廓系數(越大聚類效果越好): s(i)=b(i)?a(i)max(a(i),b(i))∈[?1,1]s(i)=\frac{b(i)-a(i)}{max(a(i),b(i))}\in[-1,1]s(i)=max(a(i),b(i))b(i)?a(i)?∈[?1,1]
其中b(i)b(i)b(i)是該簇中iii樣本到b簇中所有點的平均距離,遍歷所有其它簇,找到最近的這個平均距離,記作b(i)b(i)b(i),即為iii的鄰居類,用于量化簇之間的分離度
其中a(i)a(i)a(i)是樣本點iii與其同一簇內所有其它元素距離平均值,記作a(i)a(i)a(i),用于量化簇內凝聚度
手肘法:
隨著K值的增大,樣本會被劃分更加精細,每個簇的聚合程度會逐漸提高,那么誤差平方和SSE自然會逐漸變小。并且,當K小于真實聚類時,由于K的增大會大幅增加每個簇的聚合程度,故SSE下降幅度會很大,而當K到達真實聚類時,再增加K所得到的聚合程度回報會迅速變小,所以SSE的下降幅度會驟減,然后隨著K的增大也趨于平緩
4. K-means是否會一直陷入選擇質心的循環停不下來?
不會。有數學證明一定會收斂,利用SSE的概念(每個點到自身所屬質心距離平方和)是個凸函數,有局部最優解
5. 如何對K-means聚類效果進行評估?
輪廓系數、手肘法或結束收斂的閾值
6. 如何快速收斂數據越大的K-means?
1、第一次迭代的時候正常進行,選取K個初始點,然后計算所有節點到這些K的距離,再分到不同的組計算新的質心
2、后續迭代的時候,在第m次開始,每次不再計算每個點到所有K個質心的距離,僅僅計算上一次迭代中離這個節點最近的某幾個(2到3)個質心的距離,決定分組的歸屬。對于其它質心,因為距離實在太遠,所以歸屬到那些組的可能性會非常非常小,所以不再重復計算距離
3、用正常的迭代終止方法,結束迭代
注:
1、如何選擇m次?(過早后面那個歸屬到遠距離組的可能性會增加,過晚收斂速度不夠)
比較每個質心偏移量接近優化的閾值20%,結束收斂的閾值10%
2、最近的質心個數怎么選取?(過多收斂速度不明顯,過少可能出現分組錯誤)
排序距離選最近的20%那些質心點
算法實現(python)(待更…)
from sklearn.cluster import KMeansimport os os.chdir(r'E:/wyz/Desktop/data/') #讀取數據 data = pd.read_excel('lw.xlsx',sheet_name = 'Sheet2')#將類別數據轉化為數字,就是一種人工打標簽,具體的順序可通過le.classes_查看(也可以用one_hot) le = LabelEncoder() str_variable = list(data.dtypes[data.dtypes.values == object].index) for col in str_variable: data[col] = le.fit_transform(data[col].astype(str)) ####在單變量分析的基礎上填充缺失值 data['var1'] = data['var1'].fillna(0.42089) data['var2'] = data['var2'].fillna(125.854) #劃分數據集(3、7劃分) y = data_model['target'] x = data_model.drop('target', axis=1) x_train, x_test, y_train, y_test = train_test_split(x, y,random_state=0,train_size=0.7) #標準化數據(挑選做規則的變量最好不要標準化,建模時標準化) ss_x = StandardScaler() ss_y = StandardScaler() x_train = ss_x.fit_transform(x_train) x_test = ss_x.transform(x_test) #訓練 model = KMeans(n_clusters=3)#構造聚類器 model.fit(data)#聚類 predict = model.fit_predict(x_test )K-means參數詳解
| n_clusters | 默認值:8 | 生成的聚類數,即產生的質心(centroids)數 |
| max_iter | 默認值:300 | 執行一次k-means算法所進行的最大迭代數 |
| n_init | 默認值:10 | 用不同的質心初始化值運行算法的次數,最終解是在inertia意義下選出的最優結果 |
| init | 默認值:k-means++ | 1、‘k-means++’ 用一種特殊的方法選定初始質心從而能加速迭代過程的收斂(即上文中的k-means++介紹) 2、‘random’ 隨機從訓練數據中選取初始質心 3、如果傳遞的是一個ndarray,則應該形如 (n_clusters, n_features) 并給出初始質心。 |
| precompute_distances | 1、‘auto’:如果 樣本數乘以聚類數大于 12million 的話則不預計算距離。This corresponds to about 100MB overhead per job using double precision 2、True:總是預先計算距離。 3、False:永遠不預先計算距離 | |
| tol | 默認值:1e-4 | 與inertia結合來確定收斂條件 |
| n_jobs | 定計算所用的進程數。內部原理是同時進行n_init指定次數的計算 1、若值為 -1,則用所有的CPU進行運算。若值為1,則不進行并行運算,這樣的話方便調試 2、若值小于-1,則用到的CPU數為(n_cpus + 1 + n_jobs)。因此如果 n_jobs值為-2,則用到的CPU數為總CPU數減1 | |
| random_state | 用于初始化質心的生成器(generator)。如果值為一個整數,則確定一個seed。此參數默認值為numpy的隨機數生成器 | |
| copy_x | 默認值:True | 當我們precomputing distances時,將數據中心化會得到更準確的結果。如果把此參數值設為True,則原始數據不會被改變。如果是False,則會直接在原始數據上做修改并在函數返回值時將其還原。但是在計算過程中由于有對數據均值的加減運算,所以數據返回后,原始數據和計算前可能會有細小差別 |
總結
以上是生活随笔為你收集整理的K-means算法详解及python代码实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 电脑忽然卡了,键盘鼠标也失灵,问题所在,
- 下一篇: 算法建模流程详解及python代码实现