聲明:本文集的所有文章都只討論Python如何使用sklearn
進行機器學習直秆。且學習的部分截圖來自中國大學MOOC上的Python機器學習應用課程以及EduCoder拷获,侵權刪糊余。
2020.3.2
新的學期是真的開始了,就是需要早起有點腦殼疼。而機器學習這邊的算法補全也會陸陸續(xù)續(xù)進行,加油ヾ(?°?°?)??粪滤。
一、距離
在一個N維的空間中雀扶,每一個點在當前空間建立的坐標系中杖小,都有一個唯一標識的 坐標向量 ,例如在三維空間中就有一個點 P(x, y, z)愚墓。而兩個點之間的距離予权,就是在一定規(guī)則下,兩個坐標向量的計算浪册。以下將會講述
歐氏距離
和曼哈頓距離
扫腺。
-
歐氏距離:
歐氏距離是指空間中兩個坐標向量的 直線距離 ,所求的是兩個點的最短距離村象。公式如下:
-
曼哈頓距離:
曼哈頓距離就像是把兩個坐標向量當成兩間房子笆环,而它們之間隔著很多的十字路口(圖片中左右上下這些箭頭)攒至,計算方法是向量中 各維的差值的絕對值 的 和。
代碼示范 (點擊可以查看完整代碼)
import numpy as np
def distance(x, y, p=2):
'''
input:x(ndarray):第一個樣本的坐標
y(ndarray):第二個樣本的坐標
p(int):等于1時為曼哈頓距離躁劣,等于2時為歐氏距離
output:distance(float):x到y(tǒng)的距離
'''
if p == 1:
distances = np.abs(x - y)
dis = 0.0
for dist in distances:
dis += dist
distances = dis
else:
distances = np.power(x - y, 2)
dis = 0.0
for dist in distances:
dis += dist
distances = np.sqrt(dis)
return distances
二迫吐、質(zhì)心
質(zhì)心 是指在樣本空間中的所有樣本的均值點,可以想象為見縫插針的形式账忘。
它是所有樣本的均衡點志膀,也就是說,所有樣本離這一點的距離都是一樣的鳖擒。 K-means算法就是通過不同的質(zhì)心來給樣本聚類的溉浙,每個樣本都被歸類到離它最近的樣本。
代碼示范 (點擊可以查看完整代碼)
def cal_Cmass(data):
'''
input:data(ndarray):數(shù)據(jù)樣本
output:mass(ndarray):數(shù)據(jù)樣本質(zhì)心
'''
# ********* Begin *********#
Cmass = [0] * data.shape[1]
for d in data:
Cmass += d
Cmass /= data.shape[0]
# ********* End *********#
return Cmass
這里有一點需要特別說明: 被歸一化之后的數(shù)據(jù)蒋荚, 每一行為一個樣本戳稽,而列就是所有樣本點都具有的特征(屬性),也就是樣本們的維數(shù)圆裕。 比如說广鳍,有3列,就是有三個特征點吓妆,也就是說他們處于一個三維的空間赊时,質(zhì)心也應該是三維的。還有就是行拢, 質(zhì)心的每一維的值是樣本每維的均值祖秒,不需要等于某個樣本。
三舟奠、K-means算法思想
K-means算法旨在于使用迭代的方法竭缝,通過設定好的幾個質(zhì)心來對數(shù)據(jù)進行聚類。以下是K-means算法的大致步驟:
- 設定分類的數(shù)量與最大迭代數(shù)沼瘫,并隨機生成相應數(shù)量的質(zhì)心: 第一次的質(zhì)心是隨機的抬纸,因為K-means是非監(jiān)督學習,所以很依賴給出的分類數(shù)耿戚,分多了分少了都會出現(xiàn)沒那么好的結果湿故。而最大迭代數(shù)用于防止死循環(huán)。
- 計算樣本點與各質(zhì)心的距離膜蛔,分類坛猪,生成標簽:將所有樣本點依次跟每個質(zhì)心計算距離,將其歸類到離它最近的質(zhì)心的一類中皂股,生成一個 標簽數(shù)組 (一個一維數(shù)組墅茉,長度為數(shù)據(jù)源的行數(shù),因為源數(shù)據(jù)一行為一個樣本,所以這個標簽數(shù)組每一個元素就記錄著該樣本對應的類別)就斤。
- 更新每一類的質(zhì)心悍募,并再次分類和生成新標簽 : 分類計算,求出每一類樣本的均值战转,更新質(zhì)心搜立。之后每一類都再進行樣本跟每一個質(zhì)心的距離計算,生成新標簽槐秧。
- 如果達到最大迭代數(shù),或者所有質(zhì)心都基本不再變化忧设,聚類完畢 : 否則刁标,循環(huán)2、3兩步址晕,直到滿足這些條件膀懈,退出循環(huán),完成聚類谨垃。
代碼示范 (點擊可以查看完整代碼)
# 對整個數(shù)據(jù)集X進行Kmeans聚類启搂,返回其聚類的標簽
def predict(self, X):
# 從所有樣本中隨機選取self.k樣本作為初始的聚類中心
# 迭代,直到算法收斂(上一次的聚類中心和這一次的聚類中心幾乎重合)或者達到最大迭代次數(shù)
# 將所有進行歸類刘陶,歸類規(guī)則就是將該樣本歸類到與其最近的中心
# 計算新的聚類中心
# 如果聚類中心幾乎沒有變化胳赌,說明算法已經(jīng)收斂,退出迭代
self.init_random_centroids(X)
self.create_clusters(self.centroids_list, X)
for i in range(self.max_iterations):
new_centroid = self.update_centroids(self.clusters, X)
if 0.98 < np.sum((new_centroid / self.centroids_list)) < 1.02:
break
self.centroids_list = new_centroid
self.create_clusters(self.centroids_list, X)
return self.clusters
在這里說明一下匙隔,我設置只要兩次的所有質(zhì)心只差小于正負0.02疑苫,就可以結束循環(huán)了。
四纷责、Scikit-learn中的K-means
sklearn 中的 K-means 簡化了步驟捍掺,只需要先使用 fit() 函數(shù)來訓練,再使用 predict() 來預測生成標簽即可再膳。
代碼示范 (點擊可以查看完整代碼)
def kmeans_cluster(data):
'''
input:data(ndarray):樣本數(shù)據(jù)
output:result(ndarray):聚類結果
'''
km = KMeans(n_clusters=3, random_state=8)
km.fit(data)
result = km.predict(data)
return result