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()

#### 內容解密:

  1. PCA降維:透過PCA(n_components=3)將高維TF-IDF矩陣降至3維,方便進行3D視覺化。
  2. seaborn色彩調盤:利用sns.color_palette("Set1", n_colors=num_clusters)為不同的群組生成獨特的顏色,便於視覺區分。
  3. 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)

#### 內容解密:

  1. generate_wordclouds函式:根據分群標籤、TF-IDF矩陣及向量化器,生成每個群組的詞雲。
  2. TF-IDF匯總:對每個群組內的TF-IDF值進行匯總,以確定該群組中的關鍵字彙。
  3. WordCloud生成:利用WordCloud函式庫根據TF-IDF頻率生成詞雲,直觀展示每個群組的關鍵字彙。

透過上述實踐,我們不僅能夠有效地對文字資料進行分群與降維處理,還能透過多種視覺化技術深入理解分群結果,從而更好地應用無監督學習技術於實際場景中。