머신러닝(파이썬) - KMC 알고리즘 코드리뷰

LSH·2023년 6월 30일
0

교육 정보

  • 교육 명: 경기미래기술학교 AI 교육
  • 교육 기간: 2023.05.08 ~ 2023.10.31
  • 오늘의 커리큘럼:
    파이썬 기반의 머신러닝 이해와 실습 (06/14~07/07)
  • 강사: 양정은 강사님
  • 강의 계획:
    1. 개발환경세팅 - IDE, 가상환경
    2. 인공지능을 위한 Python
    3. KNN 구현을 위한 NumPy
    4. K Nearest Neighbors Classification 구현
    5. K Means Clustering Mini-project
    6. Scikit-learn을 이용한 SVM의 학습
    7. Decision Tree의 개념
    8. ID3 Algorithm
    9. Impurity Metrics - Information Gain Ratio, Gini Index
    10. Decision Tree 구현
    11. 확률 기초
    12. Bayes 정리 예시
    13. Naive Bayes Classifier
    14. Gaussian Naive Bayes Classifier

K Means Clustering

코드 리뷰

함수 설정

  • 내 코드
    : 하나의 파일 위쪽에 함수를 작성하고 아래에서 실행함
  • 강사님 코드
    : 함수 파일과 실행 파일을 각각 만들어서 실행 파일에서 함수 파일의 함수를 import해서 실행함

✏️ 개선점: layering? 기능별로 파일을 구분해서 가독성 올리고 유지보수 용이하게 하기


함수 기능 분리

  • 내 코드
def create_dataset(n_class, n_data, n_feature, mock_loc_scl=[[1, 1], [1, -1], [-1, 1], [-1, -1]]):
    dataset = []
    for idx in range(n_class):
        temp_data = np.random.normal(loc=mock_loc_scl[idx], scale=0.3, size=(n_data, n_feature))
        dataset.append(temp_data)
    dataset = np.vstack(dataset)
    ax[0].scatter(dataset[:, 0], dataset[:, 1], c='grey', alpha=0.2)
    return dataset

: 함수 내에 구한 데이터를 시각화 하는것까지 같이 넣음

  • 강사님 코드
#-------utils-------
def get_dataset():
    n_cluster_samples = 100
    means = [[1, 1], [-1, 1], [-1, -1], [1, -1]]
    stds = [0.5, 0.4, 0.3, 0.2]
    n_clusters = len(means)
    data = []
    for cluster_idx in range(n_clusters):
        cluster_data = np.random.normal(loc=means[cluster_idx],
                                        scale=stds[cluster_idx],
                                        size=(n_cluster_samples, 2))
        data.append(cluster_data)
    data = np.vstack(data)
    return data
#-------step7_1-------
dataset = get_dataset()
centroids = get_initial_centroids(dataset, K)
fig, axes = plt .subplots(2, 3, figsize=(10, 6))
axes[0, 0].scatter(dataset[:, 0], dataset[:, 1], alpha=0.7)
axes[0, 0].scatter(centroids[:, 0], centroids[:, 1], color='r', s=50)

: 시각화는 함수 밖으로 꺼냄

✏️ 개선점: 함수 이름이 의미하는 것만 동작하도록 하는게 좋을것 같음


가독성 - 코드 한줄로 쓰기

  • 내 코드
temp_data = np.random.normal(loc=mock_loc_scl[idx], scale=0.3, size=(n_data, n_feature))

: 긴 코드를 한줄로 씀

  • 강사님 코드
cluster_data = np.random.normal(loc=means[cluster_idx],
                                 scale=stds[cluster_idx],
                                 size=(n_cluster_samples, 2))

: 코드를 속성별로 알아보기 쉽게 줄바꿈

✏️ 개선점: 가독성 개선, 코드가 길어질수록 중요할 듯


함수에서 전역 변수 사용

  • 내 코드
def get_initial_centroid(dataset):
    centroid_index = np.random.permutation(np.argwhere(dataset[:, 0]))[:n_class].reshape(4,)
    centroid_init = dataset[centroid_index]
    ...

: 함수 내에서 전역 변수 사용 (n_class)

  • 강사님 코드
def get_initial_centroids(dataset, K):
    n_data = dataset.shape[0]
    random_idx = np.arange(n_data)
    np.random.shuffle(random_idx)
    centroid_idx = random_idx[:K]
    ...

: 사용한 변수를 인자로 받음 (K)

✏️ 개선점: 사용할 변수를 인자로 받는 편이 함수 이해에 더 용이할 것 같음


조건문의 조건 설정

  • 내 코드
ax = axs.flatten()

try:
    while True:
        updated_centroid = clustering_data_and_update_centroid(data_set, centroid)
        ax_order += 1
        ...
        

: ax_order를 만들어서 반복문 안에서 증가시키면서 plot을 그림

  • 강사님 코드
for ax in axes.flat[1:]:  #axes.flatten()[1:]
    clusters = clustering(dataset, centroids, K)
    centroids = update_centroids(clusters)
    for cluster_idx in range(K):
        cluster = clusters[cluster_idx]
        ax.scatter(cluster[:, 0], cluster[:, 1], alpha=0.3)
        ax.scatter(centroids[:, 0], centroids[:, 1], color='r')

: ax을 반복문의 조건으로 사용

✏️ 개선점: ax_order를 따로 사용할게 아니면 굳이 선언할 필요 없이 반복문을 ax 조건으로 돌리면 될듯.. try-except 문도 사용할 필요 없어짐.

  • while 문의 조건으로 ax를 사용하고 centroid 고정시 break하는 방법 시도해보기

→ 코드 작성 후 한번 더 효율적인 방법을 생각해보는 연습을 해야 할 것 같음

profile
:D

0개의 댓글