KMeans 叢集分析與主成分分析(PCA)是無監督學習中常用的技術,適用於探索和分析未標記的資料。本文將示範如何使用 Python 程式碼執行 KMeans 叢集分析,並結合輪廓係數評估不同引陣列合(如 min_df 和叢集數量)對叢集品質的影響。文章也將示範如何使用 PCA 將高維資料降維至 3D 空間,並利用視覺化工具呈現叢集結果,以及如何使用詞雲圖直觀地展示每個叢集中的關鍵字彙,從而更深入地理解資料的結構和模式。
透過調整 min_df 引數,控制詞彙向量化的最低檔案頻率,進而影響特徵數量。結合不同叢集數量,觀察輪廓係數的變化趨勢,找出最佳的引陣列合。文章中提供的程式碼,可直接用於資料的前處理、向量化、KMeans 叢集分析、輪廓係數計算以及視覺化呈現。此外,也示範瞭如何使用 PCA 將高維資料降維,並使用 Seaborn 以及 Matplotlib 繪製 3D 散點圖,更直觀地呈現叢集結果。最後,利用 WordCloud 函式庫,根據每個叢集的詞彙權重生成詞雲圖,有效地突顯各叢集的主題和關鍵字彙。
無監督學習:叢集分析與主成分分析
叢集分析評估與視覺化
在進行叢集分析時,評估不同引陣列合對叢集品質的影響至關重要。本章節將介紹如何結合輪廓係數(Silhouette Score)評估KMeans叢集分析的效果,並視覺化不同引數下的叢集結果。
程式碼實作
import itertools
import pandas as pd
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
import matplotlib.pyplot as plt
# 定義 min_df 值與叢集數量範圍
min_df_values = [10, 20, 30]
num_clusters = [3, 4, 5, 6]
# 儲存輪廓係數結果
silhouette_scores = []
# 進行不同引陣列合的叢集分析與評估
for min_df, n_clusters in itertools.product(min_df_values, num_clusters):
# 資料前處理與向量化
tfidf_df = preprocess_and_vectorize_data(df, min_df)
# 執行 KMeans 叢集分析
kmeans = KMeans(n_clusters=n_clusters, random_state=42)
cluster_labels = kmeans.fit_predict(tfidf_df)
# 計算輪廓係數
silhouette_scores.append((min_df, n_clusters, silhouette_score(tfidf_df, cluster_labels)))
# 將輪廓係數結果轉換為 DataFrame 以便視覺化
silhouette_scores_df = pd.DataFrame(silhouette_scores, columns=['min_df', 'num_clusters', 'silhouette_score'])
# 繪製輪廓係數變化圖
plt.figure(figsize=(10, 6))
for min_df in min_df_values:
subset_df = silhouette_scores_df[silhouette_scores_df['min_df'] == min_df]
num_features = preprocess_and_vectorize_data(df, min_df).shape[1]
plt.plot(subset_df['num_clusters'], subset_df['silhouette_score'],
marker='o', label=f'min_df = {min_df}, 特徵數量 = {num_features}')
plt.xlabel('叢集數量')
plt.ylabel('輪廓係數')
plt.title('不同 min_df 值下輪廓係數與叢集數量的關係')
plt.legend()
plt.grid()
plt.show()
#### 輪廓係數變化圖解析:
此圖示顯示了在不同 `min_df` 值下,輪廓係數如何隨著叢集數量變化。透過觀察圖表,可以瞭解 `min_df` 與特徵數量如何共同影響叢集品質。
### 進一步分析:產品分佈視覺化
選擇特定的 `min_df` 值(例如20)並測試不同的叢集數量(例如[3, 4, 5, 6]),進一步分析每個叢集中的產品分佈情況。
#### 程式碼實作
```python
# 選定的引數
min_df_value = 20
num_clusters_values = [3, 4, 5, 6]
# 儲存結果
results = []
# 執行叢集分析並計算輪廓係數與產品分佈
for n_clusters in num_clusters_values:
tfidf_df = preprocess_and_vectorize_data(df, min_df_value)
kmeans = KMeans(n_clusters=n_clusters, random_state=42)
cluster_labels = kmeans.fit_predict(tfidf_df)
silhouette = silhouette_score(tfidf_df, cluster_labels)
cluster_counts = pd.Series(cluster_labels).value_counts().sort_index()
results.append((n_clusters, silhouette, cluster_counts))
# 將結果轉換為 DataFrame
results_df = pd.DataFrame(results, columns=['num_clusters', 'silhouette_score', 'cluster_counts'])
# 繪製輪廓係數與產品分佈圖
plt.figure(figsize=(15, 6))
# 輪廓係數變化圖
plt.subplot(1, 2, 1)
plt.plot(results_df['num_clusters'], results_df['silhouette_score'], marker='o')
plt.xlabel('叢集數量')
plt.ylabel('輪廓係數')
plt.title('輪廓係數 vs. 叢集數量')
plt.grid()
# 各叢集產品數量分佈圖
plt.subplot(1, 2, 2)
for i, row in results_df.iterrows():
plt.bar(row['cluster_counts'].index, row['cluster_counts'].values, alpha=0.5, label=f'叢集數量 = {row["num_clusters"]}')
plt.xlabel('叢集編號')
plt.ylabel('產品數量')
plt.title('不同叢集數量下的產品分佈')
plt.legend()
plt.grid()
plt.tight_layout()
plt.show()
#### 產品分佈圖解析:
此圖示展示了在不同叢集數量下,各叢集中的產品分佈情況,有助於理解不同叢集數量對產品分類別的影響。
### 重點技術解析
1. **輪廓係數(Silhouette Score)**:
- 用於評估叢集分析的效果,衡量樣本與其所在叢集的相似度。
- 取值範圍在[-1, 1]之間,越接近1表示樣本被正確分類別。
2. **引數調優**:
- `min_df`:控制特徵篩選的閾值,影響最終的特徵數量。
- `num_clusters`:決定KMeans演算法的叢集數量,直接影響叢集結果。
3. **視覺化**:
- 結合輪廓係數變化圖與產品分佈圖,能更全面地評估不同引數下的叢集效果。
#### 最終驗證與改進建議
#### 程式碼邏輯完整性驗證
1. 資料前處理流程 `preprocess_and_vectorize_data` 是否正確執行 TF-IDF 向量化?
2. KMeans 叢集分析的 `random_state` 是否固定以確保結果可復現?
3. 輪廓係數計算是否正確,並已儲存於 `silhouette_scores` 中?
#### 圖表解讀與改進方向
1. **輪廓係數變化趨勢**:
- 是否觀察到隨著叢集數量增加,輪廓係數呈現下降趨勢?這通常表示過多的叢集導致樣本區分過細。
- 不同 `min_df` 值下的特徵數量如何影響輪廓係數?較高的特徵數量是否導致更佳的叢集效果?
2. **產品分佈情況**:
- 各叢集中的產品數量是否相對均衡?還是某些叢集過於龐大或過小?
- 當叢集數量變化時,產品分佈的變化趨勢是否符合預期?
#### 可能的改進方向
1. **動態調整 `min_df` 與 `num_clusters`**:
- 結合網格搜尋(Grid Search)或貝葉斯最佳化(Bayesian Optimization)自動尋找最佳引陣列合。
2. **引入其他評估指標**:
- 除了輪廓係數外,可結合 Calinski-Harabasz 指數或 Davies-Bouldin 指數進行綜合評估。
3. **最佳化視覺化呈現**:
- 使用互動式視覺化工具(如 Plotly)以增強圖表的互動性和資訊展示豐富度。
4. **深入分析叢集特徵**:
- 對不同叢集中的產品進行特徵分析,例如使用詞雲或關鍵字提取技術,以瞭解各叢集的主題差異。
## 無監督學習:分群與PCA技術實踐
在前面的章節中,我們探討了無監督學習的基本概念及其在文字資料分析中的應用。本章節將深入實踐無監督學習中的分群(Clustering)與主成分分析(PCA)技術,透過具體的程式碼示例與視覺化結果,展示如何有效地對文字資料進行分群與降維處理。
### 分群結果解讀與視覺化
在進行分群分析時,解讀分群結果與視覺化是至關重要的步驟。良好的分群結果應具備以下特徵:
* **內聚力(Cohesion)**:確保每個群組內的資料點彼此相似。我們可以透過檢查每個群組中最具代表性的詞彙來評估內聚力。
* **分離度(Separation)**:各群組之間應保持良好的區隔,確保它們是獨特且具有意義的。
* **標籤(Labels)**:為每個群組賦予描述性的標籤,以便於理解與識別。
* **離群值(Outliers)**:識別那些不適合任何群組的資料點。
#### 視覺化技術
為了更好地理解分群結果,我們可以採用多種視覺化技術:
* **降維(Dimensionality Reduction)**:使用PCA等技術將高維的TF-IDF矩陣降維至2D或3D,以便於視覺化。
* **散點圖(Scatter Plots)**:利用散點圖展示資料點的分佈,其中每個點代表一個檔案,不同的顏色或形狀代表不同的群組。
* **詞雲(Word Clouds)**:對於文字資料,詞雲是一種直觀展示每個群組中最常見詞彙的方式。
* **熱力圖(Heat Maps)**:熱力圖可用於展示詞彙在不同群組中的頻率,有助於突出每個群組中的關鍵字彙。
### 實踐:3D視覺化分群結果
為了更直觀地展示分群結果,我們將使用PCA將TF-IDF矩陣降維至3D,並利用seaborn的色彩調盤為不同的群組賦予不同的顏色。
#### 程式碼實踐
```python
from sklearn.decomposition import PCA
import seaborn as sns
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
# 選定的min_df值與分群數量
min_df_value = 20
num_clusters = 5
# 資料預處理與分群
tfidf_matrix, tfidf_vectorizer = preprocess_and_vectorize_data(df['Description'], min_df_value)
kmeans = KMeans(n_clusters=num_clusters, random_state=42)
cluster_labels = kmeans.fit_predict(tfidf_matrix)
# 應用PCA降維至3個主成分
pca = PCA(n_components=3)
pca_result = pca.fit_transform(tfidf_matrix.toarray())
# 建立PCA結果的DataFrame
pca_df = pd.DataFrame(data=pca_result, columns=['PC1', 'PC2', 'PC3'])
pca_df['Cluster'] = cluster_labels
# 使用seaborn色彩調盤為群組賦色
color_palette = sns.color_palette("Set1", n_colors=num_clusters)
# 繪製3D散點圖
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection='3d')
for cluster_id in range(num_clusters):
cluster_points = pca_df[pca_df['Cluster'] == cluster_id]
ax.scatter(cluster_points['PC1'], cluster_points['PC2'], cluster_points['PC3'], color=color_palette[cluster_id], label=f'Cluster {cluster_id}')
ax.set_xlabel('PC1')
ax.set_ylabel('PC2')
ax.set_zlabel('PC3')
ax.set_title('產品分群3D視覺化')
ax.legend()
plt.show()
#### 內容解密:
- PCA降維:透過
PCA(n_components=3)將高維TF-IDF矩陣降至3維,方便進行3D視覺化。 seaborn色彩調盤:利用sns.color_palette("Set1", n_colors=num_clusters)為不同的群組生成獨特的顏色,便於視覺區分。- 3D散點圖繪製:使用
mpl_toolkits.mplot3d中的Axes3D建立3D坐標軸,並根據PCA結果與分群標籤繪製散點圖。
詞雲視覺化
為了進一步理解每個群組中的關鍵字彙,我們可以使用詞雲函式庫建立函式,輸出每個群組的詞雲圖。
詞雲實踐
from wordcloud import WordCloud
def generate_wordclouds(cluster_labels, tfidf_matrix, tfidf_vectorizer):
for cluster_id in np.unique(cluster_labels):
cluster_indices = np.where(cluster_labels == cluster_id)[0]
cluster_tfidf = tfidf_matrix[cluster_indices]
feature_names = tfidf_vectorizer.get_feature_names_out()
# 合併該群組內所有檔案的TF-IDF值
sum_tfidf = cluster_tfidf.sum(axis=0).A1
tfidf_dict = dict(zip(feature_names, sum_tfidf))
# 生成詞雲
wordcloud = WordCloud(width=800, height=400, background_color='white').generate_from_frequencies(tfidf_dict)
plt.figure(figsize=(10, 5))
plt.imshow(wordcloud, interpolation='bilinear')
plt.axis('off')
plt.title(f'Cluster {cluster_id} 詞雲')
plt.show()
# 呼叫函式生成詞雲
generate_wordclouds(cluster_labels, tfidf_matrix, tfidf_vectorizer)
#### 內容解密:
generate_wordclouds函式:根據分群標籤、TF-IDF矩陣及向量化器,生成每個群組的詞雲。- TF-IDF匯總:對每個群組內的TF-IDF值進行匯總,以確定該群組中的關鍵字彙。
WordCloud生成:利用WordCloud函式庫根據TF-IDF頻率生成詞雲,直觀展示每個群組的關鍵字彙。
透過上述實踐,我們不僅能夠有效地對文字資料進行分群與降維處理,還能透過多種視覺化技術深入理解分群結果,從而更好地應用無監督學習技術於實際場景中。