[TQC+][Python][PML3]人工智慧:機器學習-202.估算集群數量

文、意如

題目:
1.請使用DBSCAN 群聚演算法( Density-Based Spatial Clustering of Applications with Noise)撰寫程式,
讀取data_perf.txt檔中載入輸入資料,可得每個資料點的x,y值。

2.設定eps_grid = np.linspace(0.3, 1.2, num=10),請找出最佳的epsilon、最大的silhouette score及最佳集群數量。
(三)、 請依序回答下列問題:

1.請填入最佳的epsilon(計算至小數點第四位後無條件捨去)?

2.請填入最佳的epsilon對應之silhouette score最大值(四捨五入取至小數點後第四位)?

3.請填入最佳集群數量(Estimated number of clusters)(整數)?

4.讀取data_perf_add.txt(由原data_perf.txt加入下列五筆資料[1.65,1.91]、[2.77,4.98]、[5.82,2.56]、[7.24,5.24]、[-0.3,4.06])。
請填入Best epsilon 對應之silhouette score最大值(四捨五入取至小數點後第四位)?

MLD02.py
import numpy as np
# TODO

input_file = ('data_perf.txt')
# Load data 載入資料
# TODO




# Find the best epsilon 
eps_grid = np.linspace(            )
silhouette_scores = []
# TODO

    # Train DBSCAN clustering model 訓練DBSCAN分群模型
    # ################
    # min_samples = 5
    # ################
    

    # Extract labels 提取標籤


    # Extract performance metric 提取性能指標
 
    

    print("Epsilon:", eps, " --> silhouette score:", silhouette_score)

    # TODO
    
    

# Best params
print("Best epsilon ="           )

# Associated model and labels for best epsilon
model =   # TODO
labels =  # TODO

# Check for unassigned datapoints in the labels
# TODO


# Number of clusters in the data 
# TODO
print("Estimated number of clusters ="           )

# Extracts the core samples from the trained model
# TODO



參考解答:
import numpy as np
import pandas as pd
# Load data 載入資料
data = pd.read_csv('data_perf.txt', header=None)
#data = pd.read_csv('data_perf_add.txt', header=None)
X = data.copy()
# Find the best epsilon 
eps_grid = np.linspace(0.3, 1.2, num=10)
    # Train DBSCAN clustering model 訓練DBSCAN分群模型
    # ################
    # min_samples = 5
    # ################
from sklearn.cluster import DBSCAN
from sklearn.metrics import silhouette_score
best_silhouette_scores = float('-inf')
for eps in eps_grid:
    model = DBSCAN(eps=eps, min_samples=5).fit(X)
    scores = silhouette_score(X, model.labels_)
    if scores >= best_silhouette_scores:
        best_silhouette_scores = scores
        best_eps = eps
        best_model = model
        best_labels = model.labels_
    # print(f"Epsilon: {eps:.1f} --> silhouette score: {scores:.4f}")
print(f"Best epsilon= {best_eps}")
print(f"Best silhouette score= {best_silhouette_scores:.4f}")
if -1 in best_labels:
    count = len(set(best_labels))-1
else:
    count = len(set(best_labels))
print(f"Estimated number of clusters= {count}")
程式解析:
import numpy as np # 導入 NumPy 函式庫,主要用於數值運算,例如生成等間隔的數值陣列 (np.linspace)。
import pandas as pd # 導入 Pandas 函式庫,用於資料處理和分析,特別是讀取 CSV/TXT 檔案和操作 DataFrame。

# Load data 載入資料
data = pd.read_csv('data_perf.txt', header=None) # 讀取名為 'data_perf.txt' 的文本檔案。header=None 表示檔案沒有標頭行,所有行都被視為資料。將內容載入到 Pandas DataFrame 中,變數名為 data。
#data = pd.read_csv('data_perf_add.txt', header=None) # 這行是被註解掉的,表示另一種資料來源,目前未啟用。
X = data.copy() # 建立 data DataFrame 的一個副本 (copy),將其賦值給 X。在機器學習中,X 通常表示特徵數據。

# Find the best epsilon (找到最佳的 epsilon 值)
# epsilon (eps) 是 DBSCAN 演算法中的一個重要參數,它定義了數據點之間的最大距離,若在此距離內則被視為在同一個鄰域內。
eps_grid = np.linspace(0.3, 1.2, num=10) # 使用 numpy.linspace 在 0.3 和 1.2 之間生成 10 個等間隔的數值。這些數值將作為 DBSCAN 模型的 eps 參數的候選值。

# Train DBSCAN clustering model 訓練DBSCAN分群模型
# ################
# min_samples = 5 (這是一個註解,提示 min_samples 參數的設定值)
# min_samples 是 DBSCAN 演算法中的另一個重要參數,定義了一個核心點在其 eps 鄰域內所需的最少數據點數量(包括自身)。
# ################
from sklearn.cluster import DBSCAN # 從 scikit-learn 函式庫導入 DBSCAN (Density-Based Spatial Clustering of Applications with Noise) 分群演算法。
from sklearn.metrics import silhouette_score # 從 scikit-learn 函式庫導入 silhouette_score,這是一種用於評估分群結果好壞的指標(輪廓係數)。

best_silhouette_scores = float('-inf') # 初始化 best_silhouette_scores 為負無限大。這是一個追蹤最佳輪廓係數的變數。
for eps in eps_grid: # 迴圈遍歷 eps_grid 中定義的每一個 epsilon 候選值。
    model = DBSCAN(eps=eps, min_samples=5).fit(X) # 初始化一個 DBSCAN 模型,使用當前的 eps 值和固定的 min_samples=5,然後使用數據 X 訓練 (fit) 模型。
    # .fit(X) 會執行分群,並將每個數據點分配到一個群集標籤。
    
    # 檢查模型的 labels_ 是否有噪音點以外的群集。
    # 如果 model.labels_ 中只有 -1 (噪音點),silhouette_score 無法計算,會報錯。
    # 確保至少有兩個以上的非噪音群集。
    if len(set(model.labels_)) > 1: # 判斷分群結果中是否至少有兩個不同的標籤(不包括噪音點 -1)。
        scores = silhouette_score(X, model.labels_) # 如果有足夠的群集,計算當前分群結果的輪廓係數。X 是原始數據,model.labels_ 是分群標籤。
    else:
        scores = -1 # 如果沒有足夠的群集(例如所有點都被標記為噪音),則給予一個較低的得分,避免其被選為最佳。
    
    if scores >= best_silhouette_scores: # 比較當前的輪廓係數 scores 是否大於或等於目前記錄的最佳輪廓係數 best_silhouette_scores。
        best_silhouette_scores = scores # 如果當前分數更好,則更新 best_silhouette_scores。
        best_eps = eps # 更新最佳的 epsilon 值。
        best_model = model # 儲存當前訓練好的 DBSCAN 模型(如果它是最佳的)。
        best_labels = model.labels_ # 儲存當前模型的群集標籤(如果它是最佳的)。
    # print(f"Epsilon: {eps:.1f} --> silhouette score: {scores:.4f}") # 這行是被註解掉的,用於在測試時打印每個 epsilon 值的結果。

print(f"Best epsilon= {best_eps}") # 印出通過迭代找到的最佳 epsilon 值。
print(f"Best silhouette score= {best_silhouette_scores:.4f}") # 印出對應最佳 epsilon 值的最高輪廓係數,格式化為小數點後四位。

# 計算估計的群集數量
if -1 in best_labels: # 檢查最佳分群結果的標籤 (best_labels) 中是否包含 -1 (表示噪音點)。
    count = len(set(best_labels))-1 # 如果包含噪音點,則計算唯一標籤的數量減去 1(因為 -1 不算作一個真正的群集)。
else:
    count = len(set(best_labels)) # 如果不包含噪音點,則直接計算唯一標籤的數量。
print(f"Estimated number of clusters= {count}") # 印出估計的分群數量。

 

 

 

Yiru@Studio - 關於我 - 意如