cuML 機器學習技能
使用 NVIDIA RAPIDS cuML 進行 GPU 加速機器學習。cuML 提供與 scikit-learn 相容的 API,可在 NVIDIA GPU 上執行,為大型資料集帶來巨大加速。
使用時機
在以下情況使用此技能:
- 訓練分類模型(預測類別、偵測詐欺、分類文字)
- 訓練迴歸模型(預測數值、預測價格、估計數量)
- 資料分群(客戶分群、文件分組、尋找模式)
- 降維(視覺化高維資料、壓縮特徵)
- 大型資料集的預處理與特徵工程
- 任何資料行數達 10K 以上、GPU 加速有幫助的 ML 任務
初始化 (必要)
每個腳本都必須以此樣板開頭。它會測試實際的 GPU ML 操作。
import pandas as pd
import numpy as np
try:
import cudf
import cuml
# 快速測試:驗證 GPU ML 端到端可用
_test_data = cudf.DataFrame({'a': [1.0, 2.0, 3.0, 4.0], 'b': [5.0, 6.0, 7.0, 8.0]})
_km = cuml.cluster.KMeans(n_clusters=2, n_init=1, random_state=42)
_km.fit(_test_data)
assert len(_km.labels_) == 4
GPU = True
except Exception as e:
print(f"[GPU] cuml 不可用,回退至 scikit-learn:{e}")
GPU = False
def read_csv(path):
return cudf.read_csv(path) if GPU else pd.read_csv(path)
def to_pd(df):
"""將 cuML/cuDF 輸出轉換為 pandas。請使用此函數而非直接呼叫 .to_pandas()。"""
if not GPU:
return df
try:
return df.to_pandas()
except Exception as e:
print(f"[GPU] .to_pandas() 失敗,使用 Arrow 回退方案:{e}")
return df.to_arrow().to_pandas()
匯入模式
# GPU 模式
if GPU:
from cuml.cluster import KMeans, DBSCAN, HDBSCAN
from cuml.ensemble import RandomForestClassifier, RandomForestRegressor
from cuml.linear_model import LinearRegression, Ridge, Lasso, LogisticRegression
from cuml.neighbors import KNeighborsClassifier, KNeighborsRegressor
from cuml.svm import SVC, SVR
from cuml.decomposition import PCA, TruncatedSVD
from cuml.manifold import UMAP, TSNE
from cuml.preprocessing import StandardScaler, MinMaxScaler, LabelEncoder
from cuml.model_selection import train_test_split
from cuml.metrics import accuracy_score, r2_score, mean_squared_error
# CPU 回退
else:
from sklearn.cluster import KMeans, DBSCAN, HDBSCAN
from sklearn.ensemble import RandomForestClassifier, RandomForestRegressor
from sklearn.linear_model import LinearRegression, Ridge, Lasso, LogisticRegression
from sklearn.neighbors import KNeighborsClassifier, KNeighborsRegressor
from sklearn.svm import SVC, SVR
from sklearn.decomposition import PCA, TruncatedSVD
from sklearn.manifold import TSNE
from sklearn.preprocessing import StandardScaler, MinMaxScaler, LabelEncoder
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, r2_score, mean_squared_error
# UMAP 不在 sklearn 中 — 跳過或使用 pip install umap-learn
快速參考
訓練/測試分割(從這裡開始)
X = df[["feature1", "feature2", "feature3"]].astype("float32")
y = df["target"]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
分類
model = RandomForestClassifier(n_estimators=100, max_depth=10, random_state=42)
model.fit(X_train, y_train)
predictions = model.predict(X_test)
accuracy = float(accuracy_score(to_pd(y_test), to_pd(predictions)))
print(f"準確度:{accuracy:.4f}")
# 特徵重要性(僅限樹狀模型)
importances = to_pd(model.feature_importances_)
for name, imp in zip(feature_names, importances):
print(f" {name}:{imp:.4f}")
迴歸
model = Ridge(alpha=1.0)
model.fit(X_train, y_train)
predictions = model.predict(X_test)
r2 = float(r2_score(to_pd(y_test), to_pd(predictions)))
mse = float(mean_squared_error(to_pd(y_test), to_pd(predictions)))
print(f"R² 分數:{r2:.4f}")
print(f"MSE:{mse:.4f}")
# 係數
coeffs = to_pd(model.coef_)
print(f"截距:{float(model.intercept_):.4f}")
分群 (KMeans)
X = df[["feature1", "feature2"]].astype("float32")
model = KMeans(n_clusters=4, n_init=10, random_state=42)
model.fit(X)
labels = to_pd(model.labels_)
centroids = to_pd(model.cluster_centers_)
inertia = float(model.inertia_)
print(f"慣量:{inertia:.2f}")
print(f"群集大小:{labels.value_counts().sort_index().to_dict()}")
print(f"中心點:\n{centroids}")
降維 (PCA)
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X.astype("float32"))
pca = PCA(n_components=3)
X_reduced = pca.fit_transform(X_scaled)
variance_ratio = to_pd(pca.explained_variance_ratio_)
print(f"解釋變異數:{[f'{v:.4f}' for v in variance_ratio]}")
print(f"總解釋變異數:{float(sum(variance_ratio)):.4f}")
降維 (UMAP — 僅限 GPU)
if GPU:
reducer = UMAP(n_components=2, n_neighbors=15, min_dist=0.1, random_state=42)
embedding = to_pd(reducer.fit_transform(X_scaled))
print(f"UMAP 嵌入形狀:{embedding.shape}")
預處理
# 縮放數值特徵
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X.astype("float32"))
# 編碼類別欄位
le = LabelEncoder()
df["category_encoded"] = le.fit_transform(df["category"])
資料型別要求
- cuML 需要特徵為 float32 或 float64。務必轉型:
X.astype("float32") - 整數目標(分類標籤)可直接使用
- 類別欄位必須先編碼(LabelEncoder 或 OneHotEncoder)
- cuML 不支援稀疏矩陣 — 務必使用稠密資料
常見問題
| 問題 | 修正方法 |
|---|---|
TypeError: sparse input | 轉為稠密:X.toarray() 或避免使用稀疏格式 |
PCA solver='randomized' 失敗 | 使用 solver='full' 或不指定(cuML 會自動選擇) |
| CPU 模式下 UMAP 不可用 | 在 CPU 模式下跳過 UMAP 或使用 pip install umap-learn |
| Float64 比 float32 慢 | 轉為 float32:X.astype("float32") |
| 大型資料集記憶體不足 | 減少特徵或抽樣資料後再擬合 |
輸出指南
回報 ML 結果時:
- 包含資料集形狀(列數 × 特徵數)與目標分佈
- 顯示訓練/測試集分割大小
- 以格式化表格呈現主要指標(準確度、R²、MSE 等)
- 分類問題:若為多類別則顯示各類別指標
- 分群問題:顯示群集大小與中心點摘要
- 降維問題:顯示解釋變異數比例
- 按大小排序列出特徵重要性
- 註明任何資料品質問題(類別不平衡、缺失值、離群值)