❤️ 배운 것
2023-10-11 KNN Full Code
decision boundary를 위한 dataset 만들기 (using np.meshgrid)
def get_decision_boundary(x1_lim, x2_lim, X, y, K):
x1 = np.linspace(x1_lim[0], x1_lim[1], 100)
x2 = np.linspace(x2_lim[0], x2_lim[1], 100)
X1, X2 = np.meshgrid(x1, x2)
grid = np.column_stack((X1.flatten(), X2.flatten()))
pred_knn = list()
for g in grid:
_, _, y_hat = code8_classify(X, y, K, X_te=g)
pred_knn.append(y_hat)
pred_knn = np.array(pred_knn)
return grid, pred_knn
KNN 시각화 + decision boundary
def code9_knn_visualization(X, y, K, X_te):
class_colors = ['#FF5733', '#FFA500', '#008000', '#FF69B4']
knn_X, knn_y, y_hat = code8_classify(X, y, K, X_te)
fig, ax = plt.subplots(figsize=(7, 7))
# all data
ax.scatter(x=X[:, 0], y=X[:, 1], c=[class_colors[label] for label in y], alpha=0.5)
# to predict
ax.scatter(x=X_te[0], y=X_te[1], marker="*", s=300, color="dodgerblue")
ax.text(x=X_te[0]+1, y=X_te[1], s=f"class {y_hat}", color="hotpink", size=15)
# k nearest data
for i in range(len(knn_X)):
ax.plot([X_te[0], knn_X[i, 0]], [X_te[1], knn_X[i, 1]], color="dodgerblue")
# decision boundary
x1_lim, x2_lim = ax.get_xlim(), ax.get_ylim()
grid, pred_knn = get_decision_boundary(x1_lim, x2_lim, X, y, K)
target_cls = list(set(y))
for i in target_cls:
target_X = grid[pred_knn == i]
ax.scatter(target_X[:, 0], target_X[:, 1], alpha=0.04, color=class_colors[i])
Main Routine
def classify_knn(n_classes, n_data, K):
X, y, centroids = code6_knn_dataset(n_classes, n_data)
X_te = X[0]
code9_knn_visualization(X, y, K, X_te)
- 코드 의존성 수정
- parameter 최적화
Full Code
def code6_knn_dataset(n_classes, n_data):
np.random.seed(8)
centroids = np.array([np.random.uniform(low=-10, high=10, size=(2,)) for x in range(n_classes)])
target_cls = np.array([i for i in range(n_classes) for _ in range(n_data)])
data = None
for i, centroid in enumerate(centroids):
if i == 0:
data = get_data_from_centroid(centroid, n_data)
continue
curr_dataset = get_data_from_centroid(centroid, n_data)
data = np.vstack([data, curr_dataset])
return data, target_cls, centroids
def code7_euclidean_distances(X, X_te=None):
# KNN: 테스트 데이터와 dataset에 들어있는 샘플들 사이의 거리 구하기
if X_te is None:
X_te = X[0]
e_dists = np.sqrt(np.sum((X - X_te)**2, axis=1))
return X_te, e_dists
def code8_classify(X, y, K, X_te=None):
# test data가 어떤 클래스에 속하는지 구하기
K += 1
X_te, e_dists = code7_euclidean_distances(X, X_te)
ascending_idx = np.argsort(e_dists)
# get k values and predict
knn_X = X[ascending_idx][:K]
knn_y = y[ascending_idx][:K]
uniques, cnts = np.unique(knn_y, return_counts=True)
uniques = uniques.astype(dtype=np.int64)
most_frequent = np.argmax(cnts)
y_hat = uniques[most_frequent]
return knn_X, knn_y, y_hat
def get_decision_boundary(x1_lim, x2_lim, X, y, K):
x1 = np.linspace(x1_lim[0], x1_lim[1], 100)
x2 = np.linspace(x2_lim[0], x2_lim[1], 100)
X1, X2 = np.meshgrid(x1, x2)
grid = np.column_stack((X1.flatten(), X2.flatten()))
pred_knn = list()
for g in grid:
_, _, y_hat = code8_classify(X, y, K, X_te=g)
pred_knn.append(y_hat)
pred_knn = np.array(pred_knn)
return grid, pred_knn
def code9_knn_visualization(X, y, K, X_te):
class_colors = ['#FF5733', '#FFA500', '#008000', '#FF69B4']
knn_X, knn_y, y_hat = code8_classify(X, y, K, X_te)
fig, ax = plt.subplots(figsize=(7, 7))
# all data
ax.scatter(x=X[:, 0], y=X[:, 1], c=[class_colors[label] for label in y], alpha=0.5)
# to predict
ax.scatter(x=X_te[0], y=X_te[1], marker="*", s=300, color="dodgerblue")
ax.text(x=X_te[0]+1, y=X_te[1], s=f"class {y_hat}", color="hotpink", size=15)
# k nearest data
for i in range(len(knn_X)):
ax.plot([X_te[0], knn_X[i, 0]], [X_te[1], knn_X[i, 1]], color="dodgerblue")
# decision boundary
x1_lim, x2_lim = ax.get_xlim(), ax.get_ylim()
grid, pred_knn = get_decision_boundary(x1_lim, x2_lim, X, y, K)
target_cls = list(set(y))
for i in target_cls:
target_X = grid[pred_knn == i]
ax.scatter(target_X[:, 0], target_X[:, 1], alpha=0.04, color=class_colors[i])
def classify_knn(n_classes, n_data, K):
X, y, centroids = code6_knn_dataset(n_classes, n_data)
X_te = X[0]
code9_knn_visualization(X, y, K, X_te)
if __name__ == '__main__':
classify_knn(n_classes=4, n_data=100, K=5)
plt.show()
코드 기전
classify_knn(n_classes, n_data, K): 메인 루틴 KNN 데이터 생성하여 시각화
classify_knn(n_classes, n_data, K): 4개의 그룹으로 랜덤 데이터셋 생성
code7_euclidean_distances(X, X_te=None): 전체데이터셋 X와 X_te (테스트데이터)간의 euclidean distance 구하기
code8_classify(X, y, K, X_te=None): 테스트 데이터가 어떤 클래스에 해당하는지 분류
code9_knn_visualization(X, y, K, X_te):
1) 모든 데이터셋의 scatter plot 그리기(클래스 별로 색 구분)
2) 예측 데이터의 scatter plot을 별 모양으로 그리기
3) K개의 nearest data points들과 예측데이터(별)간 line plot으로 연결시키기
4) 10,000x10,000 크기의 meshgrid에 scatter plot하여 decision boundary 색 채우기
get_decision_boundary(x1_lim, x2_lim, X, y, K): decision boundary를 위한 데이터셋 구하기
💛 배운점/느낀점
- numpy boolean indexing을 이용하면 vector 연산을 활용하여 계산할 수 있어서 고차원 데이터에 비해 편리하게 데이터를 조작할 수 있다는 점을 느낌
- colormap 등 세부 조정하는 것에 익숙해질 필요가 있음..
- K-means clustering 구현 시작 예정
- CNN 합성곱 연산 자습중
'Education > 새싹 TIL' 카테고리의 다른 글
새싹 AI데이터엔지니어 핀테커스 6주차 (금) - Decision Tree with IGR (0) | 2023.10.14 |
---|---|
새싹 AI데이터엔지니어 핀테커스 6주차 (목) - Kmeans, Decision Tree 해부 (진짜열심히했음) (0) | 2023.10.12 |
새싹 AI데이터엔지니어 핀테커스 6주차 (화) - KNN (1) | 2023.10.10 |
새싹 AI데이터엔지니어 핀테커스 5주차 (금) - Boxplot, Numpy (1) | 2023.10.06 |
새싹 AI데이터엔지니어 핀테커스 5주차 (목) - matplotlib (3) (0) | 2023.10.05 |