“UMAP:高效揭示數據深層結構的維度降低神器”

  • UMAP(Uniform Manifold Approximation and Projection)是一種強大的維度降低技術,它允許我們將高維度數據集映射到低維度空間,同時盡可能保留原始數據的結構。這種方法特別適用於大規模數據集和機器學習任務,因為它不僅效率高,而且能夠揭示數據的內在結構和模式。
  • UMAP的工作原理基於拓撲學的概念,它首先在高維空間中構建一個近似幾何結構,然後試圖在低維空間中以最佳方式再現這種結構。這樣,UMAP不僅能夠有效地降低數據的維度,而且還能在降維過程中保留數據點之間的相對距離和分布,使得降維後的數據依然能夠反映出原始數據集的關鍵特性和結構。
  • UMAP廣泛應用於各種領域,包括生物信息學、社會網絡分析、影像處理等,它對於數據可視化、特徵提取和機器學習模型的預處理具有重要意義。與其他維度降低方法相比,UMAP在保持局部結構的同時,還能夠揭示數據的全局分布,使其成為維度降低和數據探索領域的一個強有力的工具。
  • 步驟 1: 安裝必要的庫
    • 確保已安裝以下必要的Python庫:
      • numpy
      • matplotlib
      • sklearn
      • umap-learn
    • 如果尚未安裝,可以使用pip進行安裝,例如:
    • pip install numpy matplotlib scikit-learn umap-learn
  • 步驟 2: 生成模擬數據
    • 我們將使用scikit-learn的**make_blobs**函數來生成一組模擬的高維數據。
# 生成模擬數據 X:(300,10) y:(300) 類別為5類 X, y = make_blobs(n_samples=300, centers=5, n_features=10, random_state=42)
  • 步驟 3: 使用UMAP進行降維
    • 然後,我們將使用UMAP對這些數據進行降維,將數據從高維空間映射到二維空間,以便於可視化。
umap_model = UMAP(n_neighbors=5, min_dist=0.3, n_components=2, random_state=42) X_reduced = umap_model.fit_transform(X)
  • 步驟 4: 可視化降維後的數據
    • 最後,我們將使用matplotlib可視化降維後的結果。由於降成兩維,因此畫出所有數據的x,y 座標
# 可視化降維後的數據 
plt.figure(figsize=(8, 6))
plt.scatter(X_reduced[:, 0], X_reduced[:, 1], c=y, cmap='Spectral', s=5) plt.title('UMAP Dimensionality Reduction') plt.colorbar(label='Group ID') plt.show()

完整程式碼

import numpy as np
from sklearn.datasets import make_blobs
from umap import UMAP
import matplotlib.pyplot as plt

# 生成模擬數據
X, y = make_blobs(n_samples=300, centers=5, n_features=10, random_state=42)

# 使用UMAP進行降維
umap_model = UMAP(n_neighbors=5, min_dist=0.3, n_components=2, random_state=42)
X_reduced = umap_model.fit_transform(X)

# 可視化降維後的數據
plt.figure(figsize=(8, 6))
plt.scatter(X_reduced[:, 0], X_reduced[:, 1], c=y, cmap='Spectral', s=5)
plt.title('UMAP Dimensionality Reduction')
plt.colorbar(label='Group ID')
# plt.show()
plt.savefig("image/UMAP_example.png")

多組資料集完整程式碼

import numpy as np
from sklearn.datasets import make_blobs
from matplotlib import pyplot as plt
from umap import UMAP

class UMAPVisualizer:

    def __init__(self, n_components=2, n_neighbors=30, min_dist=0.1, random_state=None):

        self.n_components = n_components

        self.n_neighbors = n_neighbors
        
        self.min_dist = min_dist

        self.random_state = random_state

        self.data = []

        self.labels = []

        self.dataset_ids = []  # 保存每個點屬於的數據集ID

        self.dataset_props = {}  # 用字典保存每個數據集的顏色深淺設置



    def add_data(self, features, labels, dataset_id, dataset_color_intensity=1.0):

        self.data.append(features)

        self.labels.extend(labels)

        self.dataset_ids.extend([dataset_id] * len(labels))

        if dataset_id not in self.dataset_props:

            self.dataset_props[dataset_id] = {'color_intensity': dataset_color_intensity}



    def run_umap(self):

        all_data = np.concatenate(self.data, axis=0)

        self.umap_results = UMAP(init='random', densmap=True, n_components=self.n_components, random_state=self.random_state).fit_transform(all_data)



    def visualize(self, save_path=None):

        unique_labels = list(set(self.labels))

        # base_colors = plt.cm.tab10(np.linspace(0, 1, len(unique_labels)))
        base_colors = plt.cm.Set1(np.linspace(0, 1, len(unique_labels)))


        plt.figure(figsize=(10, 10))



        for i, label in enumerate(unique_labels):

            for dataset_id in self.dataset_props:

                indices = [idx for idx, (lbl, ds_id) in enumerate(zip(self.labels, self.dataset_ids)) if lbl == label and ds_id == dataset_id]

                intensity = self.dataset_props[dataset_id]['color_intensity']

                # 調整顏色的亮度,使之根據數據集的不同而有所變化

                adjusted_color = base_colors[i] * intensity

                plt.scatter(self.umap_results[indices, 0], self.umap_results[indices, 1],

                            color=[adjusted_color], label=f"Dataset {dataset_id}: {label}", alpha=0.8)



        plt.legend()

        plt.title('UMAP Visualization')
        if save_path:
            plt.savefig(save_path)


# 生成模擬數據

def main():
    features1, labels1 = make_blobs(n_samples=100, centers=2, n_features=2, random_state=42)

    features2, labels2 = make_blobs(n_samples=100, centers=2, n_features=2, random_state=43)



    visualizer = UMAPVisualizer(random_state=42)

    visualizer.add_data(features1, labels1, dataset_id="a", dataset_color_intensity=0.5)  # 淺色

    visualizer.add_data(features2, labels2, dataset_id="b", dataset_color_intensity=0.9)  # 深色

    visualizer.run_umap()

    visualizer.visualize(save_path="image/test_set_umap.jpg")

if __name__=="__main__":
    main()

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments