機(jī)器學(xué)習(xí)入門系列(2)--如何構(gòu)建一個完整的機(jī)器學(xué)習(xí)項目古胆,第八篇榆俺!
該系列的前七篇文章:
- 機(jī)器學(xué)習(xí)入門系列(2)--如何構(gòu)建一個完整的機(jī)器學(xué)習(xí)項目(一)
- 機(jī)器學(xué)習(xí)數(shù)據(jù)集的獲取和測試集的構(gòu)建方法
- 特征工程之?dāng)?shù)據(jù)預(yù)處理(上)
- 特征工程之?dāng)?shù)據(jù)預(yù)處理(下)
- 特征工程之特征縮放&特征編碼
- 特征工程(完)
- 常用機(jī)器學(xué)習(xí)算法匯總比較(上)
上一篇文章介紹了線性回歸棉磨、邏輯回歸呢蛤、決策樹和隨機(jī)森林四種算法雁社,本文會繼續(xù)介紹四種算法--SVM置济、樸素貝葉斯所坯、KNN 以及 kmean 算法谆扎,其中最后一種是無監(jiān)督學(xué)習(xí)的聚類算法,前面三種也是非常常見的算法芹助,特別是 SVM堂湖,在 2012 年 AlexNet 網(wǎng)絡(luò)的成功之前,一直都是圖像分類中非常常用的分類算法状土。
因為公眾號不支持外鏈无蜂,所以可以點擊文末“閱讀原文”查看外部鏈接。
5. 支持向量機(jī)(SVM)
簡述
定義:SVM 是一種二類分類模型蒙谓,其基本模型定義為特征空間上的間隔最大的線性分類器斥季,即支持向量機(jī)的學(xué)習(xí)策略便是間隔最大化,最終可轉(zhuǎn)化為一個凸二次規(guī)劃問題的求解累驮。
或者簡單的可以理解為就是在高維空間中尋找一個合理的超平面將數(shù)據(jù)點分隔開來酣倾,其中涉及到非線性數(shù)據(jù)到高維的映射以達(dá)到數(shù)據(jù)線性可分的目的。
訓(xùn)練數(shù)據(jù)線性可分時谤专,通過硬間隔最大化躁锡,學(xué)習(xí)一個線性分類器,即線性可分支持向量機(jī)置侍,又稱為硬間隔支持向量機(jī)映之;訓(xùn)練數(shù)據(jù)近似線性可分時,通過軟間隔最大化蜡坊,也學(xué)習(xí)一個線性分類器杠输,即線性支持向量機(jī),也稱為軟間隔支持向量機(jī)秕衙;訓(xùn)練數(shù)據(jù)線性不可分時抬伺,通過使用核技巧和軟間隔最大化,學(xué)習(xí)非線性支持向量機(jī)灾梦。
原始的 SVM 是一個二類分類器峡钓,但后續(xù)針對多類分類問題,也進(jìn)行了拓展若河,有以下幾種改進(jìn)來實現(xiàn)多類分類問題:
1.直接法
直接在目標(biāo)函數(shù)上進(jìn)行修改能岩,將多個分類面的參數(shù)求解合并到一個最優(yōu)化問題中,通過求解該優(yōu)化就可以實現(xiàn)多分類萧福。
但是計算復(fù)雜度很高拉鹃,實現(xiàn)起來較為困難。一般很少使用這種方法
2.間接法,間接法又分為以下幾種:
- 一對多:每次訓(xùn)練的時候設(shè)置其中某個類為一類膏燕,其余所有類為另一個類钥屈。
比如有 A,B,C,D 四個類,第一次 A 是一個類坝辫,B,C,D 是一個類篷就,訓(xùn)練一個分類器,第二次 B 是一個類近忙,然后 A,C,D 是一個類竭业,訓(xùn)練一個分類器,依次類推及舍。因此未辆,如果總共有 n 個類,最終將訓(xùn)練 n 個分類器锯玛。
測試的時候咐柜,將測試樣本都分別送入所有分類器中,取得到最大值的類別作為其分類結(jié)果攘残。這是因為到分類面距離越大炕桨,分類越可信。
這種方法的優(yōu)點是每個優(yōu)化問題的規(guī)模比較小肯腕,而且分類速度很快献宫,因為分類器數(shù)目和類別數(shù)目相同;但是实撒,有時會出現(xiàn)這樣兩種情況:對一個測試樣本姊途,每個分類器都得到它屬于分類器所在類別;或者都不屬于任意一個分類器的類別知态。前者稱為分類重疊現(xiàn)象捷兰,后者叫不可分類現(xiàn)象。前者可以任意選擇一個結(jié)果或者就按照其到每個超平面的距離來分负敏,哪個遠(yuǎn)選哪個類別贡茅;而后者只能分給新的第 n+1 個類別了。最大的缺點還是由于將 n-1 個類別作為一個類別其做,其數(shù)目會數(shù)倍于只有 1 個類的類別顶考,這樣會人為造成數(shù)據(jù)集偏斜的問題。
- 一對一:任意兩個類都訓(xùn)練一個分類器妖泄,預(yù)測的時候通過投票選擇最終結(jié)果驹沿。
這個方法同樣會有分類重疊的現(xiàn)象,但不會有不可分類現(xiàn)象蹈胡,因為不可能所有類別的票數(shù)都是 0渊季。這種方法會比較高效朋蔫,每次訓(xùn)練使用的樣本其實就只有兩類數(shù)據(jù),而且預(yù)測會比較穩(wěn)定却汉,但是缺點是預(yù)測時間會很久驯妄。
優(yōu)缺點
優(yōu)點
- 使用核函數(shù)可以向高維空間進(jìn)行映射
- 使用核函數(shù)可以解決非線性的分類
- 分類思想很簡單,就是將樣本與決策面的間隔最大化
- 分類效果較好
缺點
- 對大規(guī)模數(shù)據(jù)訓(xùn)練比較困難
- 無法直接支持多分類合砂,但是可以使用間接的方法來做
- 噪聲也會影響SVM的性能青扔,因為SVM主要是由少量的支持向量決定的。
代碼實現(xiàn)
線性 SVM 的代碼實現(xiàn):
from sklearn import datasets
import numpy as np
from sklearn.cross_validation import train_test_split
iris = datasets.load_iris() # 由于Iris是很有名的數(shù)據(jù)集既穆,scikit-learn已經(jīng)原生自帶了。
X = iris.data[:, [2, 3]]
y = iris.target # 標(biāo)簽已經(jīng)轉(zhuǎn)換成0雀鹃,1幻工,2了
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0) # 為了看模型在沒有見過數(shù)據(jù)集上的表現(xiàn),隨機(jī)拿出數(shù)據(jù)集中30%的部分做測試
# 為了追求機(jī)器學(xué)習(xí)和最優(yōu)化算法的最佳性能黎茎,我們將特征縮放
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
sc.fit(X_train) # 估算每個特征的平均值和標(biāo)準(zhǔn)差
sc.mean_ # 查看特征的平均值囊颅,由于Iris我們只用了兩個特征,所以結(jié)果是array([ 3.82857143, 1.22666667])
sc.scale_ # 查看特征的標(biāo)準(zhǔn)差傅瞻,這個結(jié)果是array([ 1.79595918, 0.77769705])
X_train_std = sc.transform(X_train)
# 注意:這里我們要用同樣的參數(shù)來標(biāo)準(zhǔn)化測試集踢代,使得測試集和訓(xùn)練集之間有可比性
X_test_std = sc.transform(X_test)
X_combined_std = np.vstack((X_train_std, X_test_std))
y_combined = np.hstack((y_train, y_test))
# 導(dǎo)入SVC
from sklearn.svm import SVC
svm = SVC(kernel='linear', C=1.0, random_state=0) # 用線性核,你也可以通過kernel參數(shù)指定其它的核嗅骄。
svm.fit(X_train_std, y_train)
# 打印決策邊界胳挎,這個函數(shù)是我自己寫的,如果你想要的話溺森,我發(fā)給你
plot_decision_regions(X_combined_std, y_combined, classifier=svm, test_idx=range(105,150))
plt.xlabel('petal length [standardized]')
plt.ylabel('petal width [standardized]')
plt.legend(loc='upper left')
plt.show()
接下來是使用非線性 SVM 的代碼:
svm = SVC(kernel='rbf', random_state=0, gamma=x, C=1.0) # 令gamma參數(shù)中的x分別等于0.2和100.0
svm.fit(X_train_std, y_train) # 這兩個參數(shù)和上面代碼中的訓(xùn)練集一樣
plot_decision_regions(X_combined_std, y_combined, classifier=svm, test_idx=range(105,150))
plt.xlabel('petal length [standardized]')
plt.ylabel('petal width [standardized]')
plt.legend(loc='upper left')
plt.show()
6. 樸素貝葉斯
簡述
樸素貝葉斯是基于貝葉斯定理與特征條件獨立假設(shè)的分類方法慕爬。
貝葉斯定理是基于條件概率來計算的,條件概率是在已知事件 B 發(fā)生的前提下屏积,求解事件 A 發(fā)生的概率医窿,即
所以貝葉斯定理如下所示:
樸素貝葉斯分類器可表示為:
這里 P(y_k) 是先驗概率,而 P(y_k|x) 則是后驗概率炊林,樸素貝葉斯的目標(biāo)就是最大化后驗概率姥卢,這等價于期望風(fēng)險最小化。
樸素貝葉斯根據(jù)特征是否離散渣聚,分為三種模型独榴,如下所示:
- 貝葉斯估計/多項式模型:當(dāng)特征是離散的時候,使用該模型奕枝;
- 高斯模型:特征是連續(xù)的時候采用該模型括眠;
- 伯努利模型:特征是離散的,且取值只能是 0 和 1倍权。
優(yōu)缺點
優(yōu)點
- 對小規(guī)模的數(shù)據(jù)表現(xiàn)很好掷豺,適合多分類任務(wù)捞烟,適合增量式訓(xùn)練。
缺點
- 對輸入數(shù)據(jù)的表達(dá)形式很敏感(離散当船、連續(xù)题画,值極大極小之類的)。
對比邏輯回歸和樸素貝葉斯
相同點
- 兩者都是對特征的線性表達(dá)德频;
- 兩者建模的都是條件概率苍息,對最終求得的分類結(jié)果有很好的解釋性。
與邏輯回歸的不同
-
樸素貝葉斯是一個生成模型壹置,在計算 P(y|x) 之前竞思,先要從訓(xùn)練數(shù)據(jù)中計算 P(x|y) 和 P(y) 的概率,從而利用貝葉斯公式計算 P(y|x)钞护。
邏輯回歸是一個判別模型盖喷,它通過在訓(xùn)練數(shù)據(jù)集上最大化判別函數(shù) P(y|x) 學(xué)習(xí)得到,不需要知道 P(x|y) 和 P(y) 难咕。
-
樸素貝葉斯是建立在條件獨立假設(shè)基礎(chǔ)之上的课梳,設(shè)特征 X 含有n個特征屬性(X1,X2余佃,...Xn)暮刃,那么在給定Y的情況下,X1爆土,X2椭懊,...Xn是條件獨立的。
邏輯回歸的限制則要寬松很多步势,如果數(shù)據(jù)滿足條件獨立假設(shè)灾搏,能夠取得非常好的效果;當(dāng)數(shù)據(jù)不滿足條件獨立假設(shè)時立润,邏輯回歸仍然能夠通過調(diào)整參數(shù)讓模型最大化的符合數(shù)據(jù)的分布狂窑,從而訓(xùn)練得到在現(xiàn)有數(shù)據(jù)集下的一個最優(yōu)模型。
-
當(dāng)數(shù)據(jù)集比較小的時候桑腮,應(yīng)該選用Naive Bayes泉哈,為了能夠取得很好的效果,數(shù)據(jù)的需求量為 O(log n)
當(dāng)數(shù)據(jù)集比較大的時候破讨,應(yīng)該選用Logistic Regression丛晦,為了能夠取得很好的效果,數(shù)據(jù)的需求量為 O( n)
代碼實現(xiàn)
下面是使用sklearn
的代碼例子提陶,分別實現(xiàn)上述三種模型,例子來自 樸素貝葉斯的三個常用模型:高斯烫沙、多項式、伯努利隙笆。
首先是高斯模型的實現(xiàn):
>>> from sklearn import datasets
>>> iris = datasets.load_iris()
>>> iris.feature_names # 四個特征的名字
['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']
>>> iris.data
array([[ 5.1, 3.5, 1.4, 0.2],
[ 4.9, 3. , 1.4, 0.2],
[ 4.7, 3.2, 1.3, 0.2],
[ 4.6, 3.1, 1.5, 0.2],
[ 5. , 3.6, 1.4, 0.2],
[ 5.4, 3.9, 1.7, 0.4],
[ 4.6, 3.4, 1.4, 0.3],
[ 5. , 3.4, 1.5, 0.2],
......
[ 6.5, 3. , 5.2, 2. ],
[ 6.2, 3.4, 5.4, 2.3],
[ 5.9, 3. , 5.1, 1.8]]) #類型是numpy.array
>>> iris.data.size
600 #共600/4=150個樣本
>>> iris.target_names
array(['setosa', 'versicolor', 'virginica'],
dtype='|S10')
>>> iris.target
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,....., 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ......, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])
>>> iris.target.size
150
>>> from sklearn.naive_bayes import GaussianNB
>>> clf = GaussianNB()
>>> clf.fit(iris.data, iris.target)
>>> clf.predict(iris.data[0])
array([0]) # 預(yù)測正確
>>> clf.predict(iris.data[149])
array([2]) # 預(yù)測正確
>>> data = numpy.array([6,4,6,2])
>>> clf.predict(data)
array([2]) # 預(yù)測結(jié)果很合理
接著锌蓄,多項式模型如下:
>>> import numpy as np
>>> X = np.random.randint(5, size=(6, 100))
>>> y = np.array([1, 2, 3, 4, 5, 6])
>>> from sklearn.naive_bayes import MultinomialNB
>>> clf = MultinomialNB()
>>> clf.fit(X, y)
MultinomialNB(alpha=1.0, class_prior=None, fit_prior=True)
>>> print(clf.predict(X[2]))
[3]
值得注意的是升筏,多項式模型在訓(xùn)練一個數(shù)據(jù)集結(jié)束后可以繼續(xù)訓(xùn)練其他數(shù)據(jù)集而無需將兩個數(shù)據(jù)集放在一起進(jìn)行訓(xùn)練。在 sklearn 中瘸爽,MultinomialNB() 類的partial_fit() 方法可以進(jìn)行這種訓(xùn)練您访。這種方式特別適合于訓(xùn)練集大到內(nèi)存無法一次性放入的情況。
在第一次調(diào)用 partial_fit()
時需要給出所有的分類標(biāo)號剪决。
>>> import numpy
>>> from sklearn.naive_bayes import MultinomialNB
>>> clf = MultinomialNB()
>>> clf.partial_fit(numpy.array([1,1]), numpy.array(['aa']), ['aa','bb'])
GaussianNB()
>>> clf.partial_fit(numpy.array([6,1]), numpy.array(['bb']))
GaussianNB()
>>> clf.predict(numpy.array([9,1]))
array(['bb'],
dtype='|S2')
伯努利模型如下:
>>> import numpy as np
>>> X = np.random.randint(2, size=(6, 100))
>>> Y = np.array([1, 2, 3, 4, 4, 5])
>>> from sklearn.naive_bayes import BernoulliNB
>>> clf = BernoulliNB()
>>> clf.fit(X, Y)
BernoulliNB(alpha=1.0, binarize=0.0, class_prior=None, fit_prior=True)
>>> print(clf.predict(X[2]))
[3]
7. KNN 算法
簡述
k 近鄰(KNN)是一種基本分類與回歸方法灵汪。
其思路如下:給一個訓(xùn)練數(shù)據(jù)集和一個新的實例,在訓(xùn)練數(shù)據(jù)集中找出與這個新實例最近的 k 個訓(xùn)練實例柑潦,然后統(tǒng)計最近的 k 個訓(xùn)練實例中所屬類別計數(shù)最多的那個類享言,就是新實例的類。其流程如下所示:
- 計算訓(xùn)練樣本和測試樣本中每個樣本點的距離(常見的距離度量有歐式距離渗鬼,馬氏距離等)览露;
- 對上面所有的距離值進(jìn)行排序;
- 選前 k 個最小距離的樣本乍钻;
- 根據(jù)這 k 個樣本的標(biāo)簽進(jìn)行投票肛循,得到最后的分類類別铭腕;
KNN 的特殊情況是 k=1 的情況银择,稱為最近鄰算法。對輸入的實例點(特征向量)x累舷,最近鄰法將訓(xùn)練數(shù)據(jù)集中與 x 最近鄰點的類作為其類別浩考。
三要素
- k 值的選擇
- 距離的度量(常見的距離度量有歐式距離,馬氏距離)
- 分類決策規(guī)則(多數(shù)表決規(guī)則)
k 值的選擇
- k 值越小表明模型越復(fù)雜被盈,更加容易過擬合析孽,其偏差小,而方差大
- 但是 k 值越大只怎,模型越簡單袜瞬,如果 k=N 的時候就表明無論什么點都是訓(xùn)練集中類別最多的那個類,這種情況身堡,則是偏差大邓尤,方差小。
所以一般 k 會取一個較小的值贴谎,然后用過交叉驗證來確定
這里所謂的交叉驗證就是將樣本劃分一部分出來為預(yù)測樣本汞扎,比如 95% 訓(xùn)練,5% 預(yù)測擅这,然后 k 分別取1澈魄,2,3仲翎,4痹扇,5 之類的铛漓,進(jìn)行預(yù)測,計算最后的分類誤差帘营,選擇誤差最小的 k
距離的度量
KNN 算法使用的距離一般是歐式距離票渠,也可以是更一般的 Lp 距離或者馬氏距離,其中 Lp 距離定義如下:
KNN的回歸
在找到最近的 k 個實例之后芬迄,可以計算這 k 個實例的平均值作為預(yù)測值问顷。或者還可以給這 k 個實例添加一個權(quán)重再求平均值禀梳,這個權(quán)重與度量距離成反比(越近權(quán)重越大)杜窄。
優(yōu)缺點
優(yōu)點
- 思想簡單,理論成熟算途,既可以用來做分類也可以用來做回歸塞耕;
- 可用于非線性分類;
- 訓(xùn)練時間復(fù)雜度為 O(n)嘴瓤;
- 準(zhǔn)確度高扫外,對數(shù)據(jù)沒有假設(shè),對異常值不敏感廓脆;
缺點
- 計算量大筛谚;
- 樣本不平衡問題(即有些類別的樣本數(shù)量很多,而其它樣本的數(shù)量很少)停忿;
- 需要大量的內(nèi)存驾讲;
代碼實現(xiàn)
使用sklearn
的簡單代碼例子:
#Import Library
from sklearn.neighbors import KNeighborsClassifier
#Assumed you have, X (predictor) and Y (target) for training data set and x_test(predictor) of test_dataset
# Create KNeighbors classifier object model
KNeighborsClassifier(n_neighbors=6) # default value for n_neighbors is 5
# Train the model using the training sets and check score
model.fit(X, y)
#Predict Output
predicted= model.predict(x_test)
最后,在用KNN前你需要考慮到:
- KNN的計算成本很高
- 所有特征應(yīng)該標(biāo)準(zhǔn)化數(shù)量級席赂,否則數(shù)量級大的特征在計算距離上會有偏移吮铭。
- 在進(jìn)行KNN前預(yù)處理數(shù)據(jù),例如去除異常值颅停,噪音等谓晌。
8. Kmeans 算法
簡述
K-均值(Kmeans)是最普及的聚類算法,算法接受一個未標(biāo)記的數(shù)據(jù)集癞揉,然后將數(shù)據(jù)集聚類成不同的組纸肉。
K-均值是一個迭代算法,假設(shè)我們想要將數(shù)據(jù)聚類成 n 個組烧董,其方法為:
- 首先選擇 K 個隨機(jī)的點毁靶,稱其為聚類中心
- 對于數(shù)據(jù)集中的每一個數(shù)據(jù),按照距離 K 個中心點的距離逊移,將其與距離最近的中心點關(guān)聯(lián)起來预吆,與同一個中心點關(guān)聯(lián)的所有點聚成一個類
- 計算每一個組的平均值,將該組所關(guān)聯(lián)的中心點移動到平均值的位置
- 重復(fù)步驟 2-3胳泉,直到中心點不再變化
這個過程中分兩個主要步驟拐叉,第一個就是第二步岩遗,將訓(xùn)練集中的樣本點根據(jù)其與聚類中心的距離,分配到距離最近的聚類中心處凤瘦,接著第二個就是第三步宿礁,更新類中心,做法是計算每個類的所有樣本的平均值蔬芥,然后將這個平均值作為新的類中心值梆靖,接著繼續(xù)這兩個步驟,直到達(dá)到終止條件笔诵,一般是指達(dá)到設(shè)定好的迭代次數(shù)返吻。
當(dāng)然在這個過程中可能遇到有聚類中心是沒有分配數(shù)據(jù)點給它的,通常的一個做法是刪除這種聚類中心乎婿,或者是重新選擇聚類中心测僵,保證聚類中心數(shù)還是初始設(shè)定的 K 個。
隨機(jī)初始化
在運行 K-均值算法之前谢翎,首先需要隨機(jī)初始化所有的聚類中心點捍靠,做法如下:
- 首先應(yīng)該選擇 K<m ,即聚類中心點的個數(shù)要小于所有訓(xùn)練集實例的數(shù)量
- 隨機(jī)選擇 K 個訓(xùn)練實例,然后令 K 個聚類中心分別和這 K 個訓(xùn)練實例相等
K-均值的一個問題在于森逮,它有可能會停留在一個局部最小值處榨婆,而這取決于初始化的情況。
為了解決這個問題吊宋,通常需要多次運行 K-均值算法纲辽,每一次都重新進(jìn)行隨機(jī)初始化颜武,最后再比較多次運行 K-均值的結(jié)果璃搜,選擇代價函數(shù)最小的結(jié)果。這種方法在** K 較辛凵稀(2-10)**的時候還是可行的这吻,但是如果 K 較大,這種做法可能不會有明顯地改善篙议。
優(yōu)缺點
優(yōu)點
- k-means 算法是解決聚類問題的一種經(jīng)典算法唾糯,算法簡單、快速鬼贱。
- 對處理大數(shù)據(jù)集移怯,該算法是相對可伸縮的和高效率的,因為它的復(fù)雜度大約是 O(nkt)这难,其中 n 是所有對象的數(shù)目舟误,k 是簇的數(shù)目, t 是迭代的次數(shù)。通常 k<<n姻乓。這個算法通常局部收斂嵌溢。
- 算法嘗試找出使平方誤差函數(shù)值最小的k個劃分眯牧。當(dāng)簇是密集的、球狀或團(tuán)狀的赖草,且簇與簇之間區(qū)別明顯時学少,聚類效果較好。
缺點
- k-平均方法只有在簇的平均值被定義的情況下才能使用秧骑,且對有些分類屬性的數(shù)據(jù)不適合版确。
- 要求用戶必須事先給出要生成的簇的數(shù)目 k。
- 對初值敏感乎折,對于不同的初始值阀坏,可能會導(dǎo)致不同的聚類結(jié)果。
- 不適合于發(fā)現(xiàn)非凸面形狀的簇笆檀,或者大小差別很大的簇忌堂。
- 對于"噪聲"和孤立點數(shù)據(jù)敏感,少量的該類數(shù)據(jù)能夠?qū)ζ骄诞a(chǎn)生極大影響酗洒。
代碼實現(xiàn)
代碼參考自K-Means Clustering士修。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@Time : 2016/10/21 16:35
@Author : cai
實現(xiàn) K-Means 聚類算法
"""
import numpy as np
import matplotlib.pyplot as plt
from scipy.io import loadmat
import os
# 尋址最近的中心點
def find_closest_centroids(X, centroids):
m = X.shape[0]
k = centroids.shape[0]
idx = np.zeros(m)
for i in range(m):
min_dist = 1000000
for j in range(k):
# 計算每個訓(xùn)練樣本和中心點的距離
dist = np.sum((X[i, :] - centroids[j, :]) ** 2)
if dist < min_dist:
# 記錄當(dāng)前最短距離和其中心的索引值
min_dist = dist
idx[i] = j
return idx
# 計算聚類中心
def compute_centroids(X, idx, k):
m, n = X.shape
centroids = np.zeros((k, n))
for i in range(k):
indices = np.where(idx == i)
# 計算下一個聚類中心,這里簡單的將該類中心的所有數(shù)值求平均值作為新的類中心
centroids[i, :] = (np.sum(X[indices, :], axis=1) / len(indices[0])).ravel()
return centroids
# 初始化聚類中心
def init_centroids(X, k):
m, n = X.shape
centroids = np.zeros((k, n))
# 隨機(jī)初始化 k 個 [0,m]的整數(shù)
idx = np.random.randint(0, m, k)
for i in range(k):
centroids[i, :] = X[idx[i], :]
return centroids
# 實現(xiàn) kmeans 算法
def run_k_means(X, initial_centroids, max_iters):
m, n = X.shape
# 聚類中心的數(shù)目
k = initial_centroids.shape[0]
idx = np.zeros(m)
centroids = initial_centroids
for i in range(max_iters):
idx = find_closest_centroids(X, centroids)
centroids = compute_centroids(X, idx, k)
return idx, centroids
dataPath = os.path.join('data', 'ex7data2.mat')
data = loadmat(dataPath)
X = data['X']
initial_centroids = init_centroids(X, 3)
# print(initial_centroids)
# idx = find_closest_centroids(X, initial_centroids)
# print(idx)
# print(compute_centroids(X, idx, 3))
idx, centroids = run_k_means(X, initial_centroids, 10)
# 可視化聚類結(jié)果
cluster1 = X[np.where(idx == 0)[0], :]
cluster2 = X[np.where(idx == 1)[0], :]
cluster3 = X[np.where(idx == 2)[0], :]
fig, ax = plt.subplots(figsize=(12, 8))
ax.scatter(cluster1[:, 0], cluster1[:, 1], s=30, color='r', label='Cluster 1')
ax.scatter(cluster2[:, 0], cluster2[:, 1], s=30, color='g', label='Cluster 2')
ax.scatter(cluster3[:, 0], cluster3[:, 1], s=30, color='b', label='Cluster 3')
ax.legend()
plt.show()
# 載入一張測試圖片樱衷,進(jìn)行測試
imageDataPath = os.path.join('data', 'bird_small.mat')
image = loadmat(imageDataPath)
# print(image)
A = image['A']
print(A.shape)
# 對圖片進(jìn)行歸一化
A = A / 255.
# 重新調(diào)整數(shù)組的尺寸
X = np.reshape(A, (A.shape[0] * A.shape[1], A.shape[2]))
# 隨機(jī)初始化聚類中心
initial_centroids = init_centroids(X, 16)
# 運行聚類算法
idx, centroids = run_k_means(X, initial_centroids, 10)
# 得到最后一次的最近中心點
idx = find_closest_centroids(X, centroids)
# map each pixel to the centroid value
X_recovered = centroids[idx.astype(int), :]
# reshape to the original dimensions
X_recovered = np.reshape(X_recovered, (A.shape[0], A.shape[1], A.shape[2]))
# plt.imshow(X_recovered)
# plt.show()
完整代碼例子和數(shù)據(jù)可以查看Kmeans練習(xí)代碼棋嘲。
小結(jié)
這四種算法就簡單介紹這么多內(nèi)容,下一篇會介紹最后幾種常見的算法矩桂,包括目前非常常用的深度學(xué)習(xí)網(wǎng)絡(luò)--卷積神經(jīng)網(wǎng)絡(luò)沸移。
如果對本文有任何建議或者想法,都可以在后臺留言給我侄榴,謝謝雹锣!
參考
- 《統(tǒng)計學(xué)習(xí)方法》
- SVM詳解(包含它的參數(shù)C為什么影響著分類器行為)-scikit-learn擬合線性和非線性的SVM
- 機(jī)器學(xué)習(xí)常見算法個人總結(jié)(面試用)
- SVM-支持向量機(jī)算法概述
- 機(jī)器學(xué)習(xí)算法與Python實踐之(二)支持向量機(jī)(SVM)初級
- 機(jī)器學(xué)習(xí)算法與Python實踐之(三)支持向量機(jī)(SVM)進(jìn)階
- 機(jī)器學(xué)習(xí)算法與Python實踐之(四)支持向量機(jī)(SVM)實現(xiàn)
- 【模式識別】SVM核函數(shù)
- SVM的核函數(shù)如何選取?--知乎
- 樸素貝葉斯理論推導(dǎo)與三種常見模型
- 樸素貝葉斯的三個常用模型:高斯、多項式癞蚕、伯努利
- 機(jī)器學(xué)習(xí)&數(shù)據(jù)挖掘筆記_16(常見面試之機(jī)器學(xué)習(xí)算法思想簡單梳理)
- K-Means Clustering
- 斯坦福大學(xué)公開課 :機(jī)器學(xué)習(xí)課程
歡迎關(guān)注我的微信公眾號--算法猿的成長蕊爵,或者掃描下方的二維碼,大家一起交流桦山,學(xué)習(xí)和進(jìn)步攒射!
往期精彩推薦
機(jī)器學(xué)習(xí)系列
- 機(jī)器學(xué)習(xí)入門系列(1)--機(jī)器學(xué)習(xí)概覽
- 機(jī)器學(xué)習(xí)入門系列(2)--如何構(gòu)建一個完整的機(jī)器學(xué)習(xí)項目(一)
- 機(jī)器學(xué)習(xí)數(shù)據(jù)集的獲取和測試集的構(gòu)建方法
- 特征工程之?dāng)?shù)據(jù)預(yù)處理(上)
- 特征工程之?dāng)?shù)據(jù)預(yù)處理(下)
- 特征工程之特征縮放&特征編碼
- 特征工程(完)
- 常用機(jī)器學(xué)習(xí)算法匯總比較(上)