cuML 머신러닝 스킬
NVIDIA RAPIDS cuML을 사용한 GPU 가속 머신러닝. cuML은 scikit-learn과 호환되는 API를 제공하며, NVIDIA GPU에서 실행되어 대규모 데이터셋에서 엄청난 속도 향상을 가능하게 합니다.
이 스킬을 사용해야 하는 경우
다음과 같은 경우에 이 스킬을 사용하세요:
- 분류 모델 훈련 (카테고리 예측, 사기 탐지, 텍스트 분류)
- 회귀 모델 훈련 (값 예측, 가격 예측, 수량 추정)
- 데이터 클러스터링 (고객 세분화, 문서 그룹화, 패턴 찾기)
- 차원 축소 (고차원 데이터 시각화, 특성 압축)
- 대규모 데이터셋의 전처리 및 특성 엔지니어링
- GPU 가속이 도움이 되는 10,000개 이상의 행이 있는 데이터셋의 모든 ML 작업
초기화 (필수)
모든 스크립트는 항상 이 보일러플레이트 코드로 시작하세요. 실제 GPU ML 연산을 테스트합니다.
import pandas as pd
import numpy as np
try:
import cudf
import cuml
# Smoke-test: GPU ML이 종단간(end-to-end)으로 작동하는지 확인
_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): {inertia:.2f}")
print(f"클러스터 크기: {labels.value_counts().sort_index().to_dict()}")
print(f"중심점:
{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은 희소 행렬(sparse matrix)을 지원하지 않습니다. 항상 밀집 데이터(dense data)를 사용하세요.
주의사항
| 문제 | 해결책 |
|---|---|
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") |
| 대규모 데이터셋 OOM (메모리 부족) | 특성 축소 또는 피팅 전 데이터 샘플링 |
출력 가이드라인
ML 결과를 보고할 때:
- 데이터셋 형태 (행 × 특성) 및 타겟 분포를 포함하세요.
- 학습/테스트 분할 크기를 보여주세요.
- 주요 지표를 포맷된 표로 보고하세요 (정확도, R², MSE 등).
- 분류의 경우: 다중 클래스라면 클래스별 지표를 표시하세요.
- 클러스터링의 경우: 클러스터 크기와 중심점 요약을 보여주세요.
- 차원 축소의 경우: 설명된 분산 비율을 표시하세요.
- 특성 중요도를 크기 순으로 나열하세요.
- 데이터 품질 문제 (클래스 불균형, 결측값, 이상치)를 기록하세요.