You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ML-For-Beginners/translations/mo/5-Clustering/2-K-Means/README.md

261 lines
11 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "7cdd17338d9bbd7e2171c2cd462eb081",
"translation_date": "2025-09-06T09:11:48+00:00",
"source_file": "5-Clustering/2-K-Means/README.md",
"language_code": "mo"
}
-->
# K-Means 分群
## [課前測驗](https://ff-quizzes.netlify.app/en/ml/)
在本課程中,您將學習如何使用 Scikit-learn 和之前匯入的尼日利亞音樂數據集來建立分群。我們將介紹 K-Means 分群的基本概念。請記住,正如您在之前的課程中學到的,分群有許多不同的方法,使用哪種方法取決於您的數據。我們將嘗試 K-Means因為它是最常見的分群技術。讓我們開始吧
您將學到的術語:
- Silhouette 評分
- 肘部法則
- 慣性
- 方差
## 介紹
[K-Means 分群](https://wikipedia.org/wiki/K-means_clustering) 是一種源自信號處理領域的方法。它用於將數據分成 "k" 個分群,並通過一系列觀測來進行分割和劃分。每個觀測值的作用是將給定的數據點分配到距離最近的 "均值"(即分群的中心點)。
這些分群可以被視為 [Voronoi 圖](https://wikipedia.org/wiki/Voronoi_diagram),其中包括一個點(或 "種子")及其對應的區域。
![voronoi 圖](../../../../5-Clustering/2-K-Means/images/voronoi.png)
> 圖表由 [Jen Looper](https://twitter.com/jenlooper) 提供
K-Means 分群過程[分為三個步驟執行](https://scikit-learn.org/stable/modules/clustering.html#k-means)
1. 演算法通過從數據集中抽樣選擇 k 個中心點。接著進行迴圈:
1. 將每個樣本分配到最近的中心點。
2. 通過計算分配到之前中心點的所有樣本的平均值來創建新的中心點。
3. 計算新舊中心點之間的差異,並重複直到中心點穩定。
使用 K-Means 的一個缺點是需要確定 "k",即中心點的數量。幸運的是,"肘部法則" 可以幫助估算一個好的起始值。您將在稍後嘗試。
## 前置條件
您將在本課程的 [_notebook.ipynb_](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/2-K-Means/notebook.ipynb) 文件中工作,其中包括您在上一課中完成的數據匯入和初步清理。
## 練習 - 準備工作
首先再次查看歌曲數據。
1. 為每一列創建一個箱型圖,調用 `boxplot()`
```python
plt.figure(figsize=(20,20), dpi=200)
plt.subplot(4,3,1)
sns.boxplot(x = 'popularity', data = df)
plt.subplot(4,3,2)
sns.boxplot(x = 'acousticness', data = df)
plt.subplot(4,3,3)
sns.boxplot(x = 'energy', data = df)
plt.subplot(4,3,4)
sns.boxplot(x = 'instrumentalness', data = df)
plt.subplot(4,3,5)
sns.boxplot(x = 'liveness', data = df)
plt.subplot(4,3,6)
sns.boxplot(x = 'loudness', data = df)
plt.subplot(4,3,7)
sns.boxplot(x = 'speechiness', data = df)
plt.subplot(4,3,8)
sns.boxplot(x = 'tempo', data = df)
plt.subplot(4,3,9)
sns.boxplot(x = 'time_signature', data = df)
plt.subplot(4,3,10)
sns.boxplot(x = 'danceability', data = df)
plt.subplot(4,3,11)
sns.boxplot(x = 'length', data = df)
plt.subplot(4,3,12)
sns.boxplot(x = 'release_date', data = df)
```
這些數據有些雜亂:通過觀察每一列的箱型圖,您可以看到異常值。
![異常值](../../../../5-Clustering/2-K-Means/images/boxplots.png)
您可以逐一檢查數據集並移除這些異常值,但這樣會使數據變得非常稀少。
1. 現在,選擇您將用於分群練習的列。挑選範圍相似的列,並將 `artist_top_genre` 列編碼為數值數據:
```python
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
X = df.loc[:, ('artist_top_genre','popularity','danceability','acousticness','loudness','energy')]
y = df['artist_top_genre']
X['artist_top_genre'] = le.fit_transform(X['artist_top_genre'])
y = le.transform(y)
```
1. 接下來,您需要選擇目標分群的數量。您知道數據集中有 3 個歌曲類型,因此我們嘗試 3
```python
from sklearn.cluster import KMeans
nclusters = 3
seed = 0
km = KMeans(n_clusters=nclusters, random_state=seed)
km.fit(X)
# Predict the cluster for each data point
y_cluster_kmeans = km.predict(X)
y_cluster_kmeans
```
您會看到一個陣列列印出每行數據框的預測分群0、1 或 2
1. 使用此陣列計算 "Silhouette 評分"
```python
from sklearn import metrics
score = metrics.silhouette_score(X, y_cluster_kmeans)
score
```
## Silhouette 評分
尋找接近 1 的 Silhouette 評分。此評分範圍從 -1 到 1如果評分為 1則分群密集且與其他分群分離良好。接近 0 的值表示分群重疊,樣本非常接近鄰近分群的決策邊界。[(來源)](https://dzone.com/articles/kmeans-silhouette-score-explained-with-python-exam)
我們的評分是 **0.53**,介於中間。這表明我們的數據並不特別適合這種分群方式,但我們繼續進行。
### 練習 - 建立模型
1. 匯入 `KMeans` 並開始分群過程。
```python
from sklearn.cluster import KMeans
wcss = []
for i in range(1, 11):
kmeans = KMeans(n_clusters = i, init = 'k-means++', random_state = 42)
kmeans.fit(X)
wcss.append(kmeans.inertia_)
```
這裡有幾個部分需要解釋。
> 🎓 range這是分群過程的迭代次數
> 🎓 random_state"決定用於中心點初始化的隨機數生成。" [來源](https://scikit-learn.org/stable/modules/generated/sklearn.cluster.KMeans.html#sklearn.cluster.KMeans)
> 🎓 WCSS"分群內平方和" 測量分群內所有點到分群中心點的平均平方距離。 [來源](https://medium.com/@ODSC/unsupervised-learning-evaluating-clusters-bd47eed175ce)
> 🎓 慣性K-Means 演算法試圖選擇中心點以最小化 "慣性""慣性是衡量分群內部一致性的一種指標。" [來源](https://scikit-learn.org/stable/modules/clustering.html)。該值在每次迭代中附加到 wcss 變數。
> 🎓 k-means++:在 [Scikit-learn](https://scikit-learn.org/stable/modules/clustering.html#k-means) 中,您可以使用 "k-means++" 優化,該方法 "初始化中心點,使其(通常)彼此距離較遠,從而可能比隨機初始化產生更好的結果。
### 肘部法則
之前,您推測因為目標是 3 個歌曲類型,應選擇 3 個分群。但真的是這樣嗎?
1. 使用 "肘部法則" 來確認。
```python
plt.figure(figsize=(10,5))
sns.lineplot(x=range(1, 11), y=wcss, marker='o', color='red')
plt.title('Elbow')
plt.xlabel('Number of clusters')
plt.ylabel('WCSS')
plt.show()
```
使用您在前一步中建立的 `wcss` 變數,創建一個圖表,顯示肘部的 "彎曲" 處,這表明最佳分群數量。也許真的是 **3**
![肘部法則](../../../../5-Clustering/2-K-Means/images/elbow.png)
## 練習 - 顯示分群
1. 再次嘗試此過程,這次設置三個分群,並以散點圖顯示分群:
```python
from sklearn.cluster import KMeans
kmeans = KMeans(n_clusters = 3)
kmeans.fit(X)
labels = kmeans.predict(X)
plt.scatter(df['popularity'],df['danceability'],c = labels)
plt.xlabel('popularity')
plt.ylabel('danceability')
plt.show()
```
1. 檢查模型的準確性:
```python
labels = kmeans.labels_
correct_labels = sum(y == labels)
print("Result: %d out of %d samples were correctly labeled." % (correct_labels, y.size))
print('Accuracy score: {0:0.2f}'. format(correct_labels/float(y.size)))
```
此模型的準確性不太好,分群的形狀給了您一些提示原因。
![分群](../../../../5-Clustering/2-K-Means/images/clusters.png)
這些數據過於不平衡,相關性太低,列值之間的方差太大,導致分群效果不佳。事實上,形成的分群可能受到我們之前定義的三個類型分類的影響或偏斜。這是一個學習過程!
在 Scikit-learn 的文檔中,您可以看到像這樣的模型,分群劃分不清晰,存在 "方差" 問題:
![問題模型](../../../../5-Clustering/2-K-Means/images/problems.png)
> 圖表來自 Scikit-learn
## 方差
方差被定義為 "與平均值的平方差的平均值" [(來源)](https://www.mathsisfun.com/data/standard-deviation.html)。在此分群問題的背景下,它指的是數據集中數值偏離平均值的程度。
✅ 這是一個很好的時機來思考所有可能的方式來解決這個問題。進一步調整數據?使用不同的列?使用不同的演算法?提示:嘗試[縮放您的數據](https://www.mygreatlearning.com/blog/learning-data-science-with-k-means-clustering/)以進行標準化並測試其他列。
> 嘗試這個 "[方差計算器](https://www.calculatorsoup.com/calculators/statistics/variance-calculator.php)" 來更好地理解這個概念。
---
## 🚀挑戰
花一些時間在這個 notebook 上,調整參數。您能否通過進一步清理數據(例如移除異常值)來提高模型的準確性?您可以使用權重來給某些數據樣本更大的權重。還有什麼方法可以創建更好的分群?
提示嘗試縮放您的數據。notebook 中有註解的程式碼,添加了標準縮放,使數據列在範圍上更接近。您會發現,雖然 Silhouette 評分下降,但肘部圖中的 "彎曲" 更平滑。這是因為未縮放的數據允許方差較小的數據具有更大的權重。閱讀更多相關問題[此處](https://stats.stackexchange.com/questions/21222/are-mean-normalization-and-feature-scaling-needed-for-k-means-clustering/21226#21226)。
## [課後測驗](https://ff-quizzes.netlify.app/en/ml/)
## 回顧與自學
查看一個 K-Means 模擬器[例如這個](https://user.ceng.metu.edu.tr/~akifakkus/courses/ceng574/k-means/)。您可以使用此工具來視覺化樣本數據點並確定其中心點。您可以編輯數據的隨機性、分群數量和中心點數量。這是否幫助您更好地理解數據如何被分組?
此外,查看 [這份來自 Stanford 的 K-Means 手冊](https://stanford.edu/~cpiech/cs221/handouts/kmeans.html)。
## 作業
[嘗試不同的分群方法](assignment.md)
---
**免責聲明**
本文件使用 AI 翻譯服務 [Co-op Translator](https://github.com/Azure/co-op-translator) 進行翻譯。我們致力於提供準確的翻譯,但請注意,自動翻譯可能包含錯誤或不準確之處。應以原始語言的文件作為權威來源。對於關鍵資訊,建議尋求專業人工翻譯。我們對於因使用此翻譯而產生的任何誤解或錯誤解讀概不負責。