Open njs03332 opened 1 year ago
# 데이터셋 불러오기, 훈련 세트와 테스트 세트로 나누기
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
X_digits, y_digits = load_digits(return_X_y=True) X_train, X_test, y_train, y_test = train_test_split(X_digits, y_digits)
from sklearn.linear_model import LogisticRegression
log_reg = LogisticRegression() log_reg.fit(X_train, y_train) log_reg.score(X_test, y_test)
- k-평균을 전처리 단계로 사용하면 더 좋아지는지 확인
- 파이프라인을 만들어 먼저 훈련 세트를 50개의 클러스터로 모아 이미지를 50개 클러스터까지의 거리로 바꿈
- 그 후 로지스틱 회귀 모델을 적용
- 숫자가 10개이므로 클러스터 개수를 10개로 지정할 수 있지만, 숫자를 쓴 방식이 저마다 다르므로 50처럼 클러스터 개수를 더 크게 하는 것이 좋음
```python
from sklearn.pipeline import Pipeline
pipeline = Pipeline([
("kmenas", KMeans(n_clusters=50)),
("log_reg", LogisticRegression()),
])
pipeline.fit(X_train, y_train)
pipeline.score(X_test, y_test)
# 0.977777777777
from sklearn.model_selection import GridSearchCV
param_grid = dict(kmeans__n_clusters=range(2, 100))
grid_clf = GridSerachCV(pipeline, param_grid, cv=3, verbose=2)
grid_clf.fit(X_train, y_train)
grid_clf.best_params_
# {'kmeans__n_clusters': 99}
grid_clf.score(X_test, y_test)
# 0.9822222222222
n_labeled = 50
log_reg = LogisticRegression()
log_reg.fit(X_train[:n_labeled], y_train[:n_labeled])
log_reg.score(X_test, y_test) # 0.8333.. ; 전체 데이터셋을 사용했을 때 보다 낮은 정확도
- 성능 개선을 위해 훈련 세트를 50개의 클러스터로 모아, 각 클러스터의 센트로이드에 가장 가까운 이미지 즉, 대표이미지 찾기
```python
k = 50
kmeans - KMeans(n_clusters=k)
X_digits_dist = kmeans.fit_transform(X_train)
representative_digit_idx = np.argmin(X_digits_dist, axis=0)
X_representative_digits = X_train[representative_digit_idx]
y_representative_digits = np.array([4, 8, 0 ,,,])
log_reg = LogisticRegression()
log_reg.fit(X_representative_digits, y_representative_digits)
log_reg.score(X_test, y_test) # 0.922222...
- 전문가가 모든 샘플에 수동으로 레이블링 하는 것은 비용이 많이 들고 어려우므로, 무작위 샘플 대신 대표 샘플에 레이블을 할당하는 것이 좋음
#### step 2. 레이블 전파 label propagation
- 동일한 클러스터에 있는 모든 샘플에 레이블을 전파 후 성능 확인
```python
y_train_propagated = np.empty(len(X_train), dtype=np.int32)
for i in range(k):
y_train_propagated[kmeans.labels_ == i] = y_representative_digits[i]
log_reg = LogisticRegression()
log_reg.fit(X_train, y_train_propagated)
log_reg.score(X_test, y_test) # 0.933333 ;
percentile_closet=20
X_cluster_dist = X_digits_dist[np.arange(len(Xtrain)), kmeans.labels]
for i in range(k): incluster = (kmeans.labels == i) cluster_dist = X_cluster_dist[in_cluster] cutoff_distance = np.percentile(cluster_dist, percentile_closet) above_cutoff = (X_cluster_dist > cutoff_distnace) X_cluster_dist[in_cluster & above_cutoff] = -1
partially_propagated = (X_cluster_dist != -1) X_train_partially_propagated = X_trainppartially_propagated] y_train_partially_propagated = y_trainppartially_propagated]
log_reg = LogisticRegression() log_reg.fit(X_train_partially_propagated, y_train_partially_propagated) log_reg.score(X_test, y_test) # 0.94
- 레이블된 샘플 50개로 94% 정확도를 얻어냄
#### 능동 학습
- 모델과 훈련 세트를 지속적으로 향상하기 위해 능동 학습 active learning 을 몇 번 반복할 수 있음
- 이 방법은 전문가가 학습 알고리즘과 상호작용하여 알고리즘이 요청할 때 특정 샘플의 레이블을 제공
- 여러 전략 중 **불확실성 샘플링 uncertainty sampling**이 가장 널리 사용됨
- 수집한 레이블된 샘플에서 모델 훈련 후, 해당 모델로 레이블되지 않은 모든 샘플에 대한 예측 생성
- 가장 불확실하게 예측한 샘플 (추정 확률이 가장 낮은 샘플)을 전문가에게 보내 레이블을 붙임
- 레이블을 부여하는 노력만큼의 성능 향상이 되지 않을 때까지 반복
- 다른 전략은 추청 확률이 가장 낮은 샘플이 아닌 다른 샘플에 대해 레이블 부여 요청
- 가장 크게 바꾸는 샘플이나 모델의 검증 점수를 가장 크게 떨어뜨리는 샘플
- 여러개의 모델 (예를 들면 SVM, 랜덤 포레스트)이 동일한 예측을 내지 않는 샘플
이미지 분할은 이미지를 세그먼트 여러 개로 분할하는 작업
세그먼트 분할: 동일한 종류의 물체에 속한 모든 픽셀은 같은 세그먼트 ex) 보행자 세그먼트
예시로, 색상 분할 : 동일한 색상을 가진 픽셀을 같은 세그먼트에 할당 ex) 인공위성 사진에서 산림 면적이 얼마나 되는지 측정
from matplotlib.image import imread
image = imread(os.path.join(images_path, filename))
image.shape # (533, 800, 3) = (높이, 너비, 컬러 개수)
이 이미지를 RGB 색상, 3차원의 긴 리스트로 변환한 다음 k-평균을 사용해서 색상을 클러스터로 모음
X = image.reshape(-1, 3)
kmeans = KMeans(n_clusters=8, random_state=42).fit(X)
segmented_img = kmeans.cluster_centers_[kmeans.labels_]
segmented_img = segmented_img.reshape(image.shape)
예를 들어 초록색을 하나의 컬러 클러스터로 만들 수 있음
초록 클러스터의 평균 색이 밝은 초록일 때, 모든 초록색은 모두 밝은 초록색으로 바뀔 수 있음
마지막으로 원본 이미지와 동일한 크기로 다시 변경해줌
segmented_imgs = []
n_colors = (10, 8, 6, 4, 2)
for n_clusters in n_colors:
kmeans = KMeans(n_clusters=n_clusters, random_state=42).fit(X)
segmented_img = kmeans.cluster_centers_[kmeans.labels_]
segmented_imgs.append(segmented_img.reshape(image.shape))
클러스터 개수를 여러 개로 바꿔 테스트
8개보다 클러스터 개수를 작게하면 무당벌레의 화려한 빨간색이 독자적인 클러스터를 만들지 못하고 주위 색에 합쳐짐, 이는 무당벌레가 이미지 나머지 부분에 비해 훨씬 작기 때문에 화려한 색이더라도 하나의 클러스터로 만들지 못하기 때문