今天進入演算法的介紹,首先打頭陣介紹的是 KNN 與 K-means,兩者不太一樣。
KNN 是監督式學習演算法;K-means 是非監督式學習演算法
屬於監督式學習演算法,主要是找尋最鄰近的 K 個鄰居,透過多數決的概念決定屬於哪一類
K 會影響最後的結果
注意:通常會將數值進行正規化,讓計算出來的結果比較 robust
from sklearn import datasets
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import confusion_matrix, accuracy_score
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import train_test_split
import pandas as pd
iris_df = pd.DataFrame(iris.data, columns=iris.feature_names)
X = iris_df.drop(labels=['target_name', 'target'] ,axis=1)
y = iris_df['target'].values
X_train , X_test , y_train , y_test = train_test_split(X, y ,test_size=0.2 , random_state=55)
classifier = KNeighborsClassifier(n_neighbors=3)
classifier.fit(X_train, y_train)
y_pred = classifier.predict(X_test)
# 建立 KNN 的 K 串列
k_list = list(range(1, 50, 1))
# 實作 KNN 交叉驗證
cv_scores = []
for k in k_list:
knn = KNeighborsClassifier(n_neighbors=k)
scores = cross_val_score(knn, X_train, y_train, cv=10, scoring='accuracy')
cv_scores.append(scores.mean())
# 計算 MSE
MSE = [1 - x for x in cv_scores]
plt.figure()
plt.figure(figsize=(15,10))
plt.title('The optimal number of neighbors', fontsize=20, fontweight='bold')
plt.xlabel('Number of Neighbors K', fontsize=15)
plt.ylabel('Misclassification Error', fontsize=15)
sns.set_style("whitegrid")
plt.plot(k_list, MSE)
plt.show()
透過這張圖可以找到 K 大約在 15~17 有最好的成效!
屬於非監督式學習演算法,主要應用於分類,我們不會知道答案是什麼!
假設 K=2,然後我們隨機給兩個點,接著我們來計算每個樣本與各中心點的距離,並分配到不同區域
兩個點可以簡單用分割線來看最快
再度更新新的中心點,重新計算各中心點的距離,並更新區域
最後達到收斂(若再繼續分下去,中心點都會是一樣的)
注意: K-Means 不適合用於非數值型資料
from sklearn.cluster import KMeans
wcss = []
for i in range(1, 15):
kmeans = KMeans(n_clusters = i, init = 'k-means++', max_iter = 300, n_init = 10, random_state = 0)
kmeans.fit(x)
wcss.append(kmeans.inertia_)
plt.plot(range(1, 15), wcss)
plt.title('The elbow method')
plt.xlabel('Number of clusters')
plt.ylabel('WCSS')
plt.show()
# Kmeans 的預測
kmeans = KMeans(n_clusters = 3, init = 'k-means++', max_iter = 300, n_init = 10, random_state = 0)
y_kmeans = kmeans.fit_predict(x)
plt.scatter(x[:, 0], x[:, 1], c=y_kmeans, cmap='rainbow')
# 原始數據的分類
plt.scatter(iris_df['sepal length (cm)'], iris_df['sepal width (cm)'], c=iris_df.target, cmap='rainbow')
更詳細可以請參考連結