본문 바로가기

K-NN 알고리즘으로 MBTI 예측. 직접 실습해봤습니다!

728x90
반응형

 

k-NN 알고리즘을 통한 데이터 분석 및 모델 평가

  1. 거리 측정: 새로운 데이터 포인트와 모든 훈련 데이터 포인트 간의 거리를 계산합니다. 일반적으로 유클리드 거리(Euclidean Distance)를 사용하지만, 맨해튼 거리(Manhattan Distance) 등 다른 거리 측정 방법도 사용할 수 있습니다.
  2. 이웃 선택: 계산된 거리 값을 기준으로 가장 가까운 $k$개의 이웃을 선택합니다.
  3. 분류/회귀:
    • 분류: 선택된 k개의 이웃 중 가장 많은 클래스를 새로운 데이터 포인트의 클래스로 할당합니다. 즉, 다수결 투표(Majority Voting) 방식으로 클래스를 결정합니다.
    • 회귀: 선택된 k개의 이웃의 평균 값을 새로운 데이터 포인트의 예측 값으로 사용합니다.

 

실습으로 k-nn으로 mbti 유형 예측기를 만들어 VM으로 실습을 하였다.

완성
예측 결과 1
예측 결과 2

 

고객 데이터를 기반으로 K-NN(K-Nearest Neighbors) 알고리즘을 사용하여 새로운 고객과 가장 유사한 고객을 찾고, 그 고객의 구매 패턴을 기반으로 상품을 추천하는 로직이다.
 
아래는 코랩에서 돌리면 바로 돌아가는 실습로직에 주석달아서 해석해보았다.
import pandas as pd # Pandas 라이브러리를 pd라는 이름으로 임포트합니다. 데이터 분석에 유용한 도구들을 제공합니다.
from sklearn.model_selection import train_test_split # scikit-learn 라이브러리에서 train_test_split 함수를 임포트합니다. 데이터를 훈련 세트와 테스트 세트로 나누는 데 사용됩니다.
from sklearn.neighbors import KNeighborsClassifier # scikit-learn 라이브러리에서 KNeighborsClassifier 클래스를 임포트합니다. K-NN 알고리즘을 구현한 모델입니다.

# 데이터셋 로드
file_path = '/content/sales.csv' # CSV 파일의 경로를 지정합니다.
df = pd.read_csv(file_path) # Pandas를 사용하여 CSV 파일을 데이터프레임으로 읽어옵니다. 데이터프레임은 테이블 형태의 데이터를 다루는 데 유용합니다.

# 'PurchaseAmount (원)' 컬럼명을 'PurchaseAmount'로 변경
df.rename(columns={'PurchaseAmount (원)': 'PurchaseAmount'}, inplace=True) # 컬럼 이름 변경. inplace=True는 데이터프레임 자체를 변경한다는 의미입니다.

# 필요한 데이터 전처리
# 'Age', 'Gender', 'ClothingCategory', 'Brand', 'PurchaseAmount' 등의 열을 사용
X = df[['Age', 'Gender', 'ClothingCategory', 'Brand', 'PurchaseAmount']]  # 필요한 특성(Feature)만 선택하여 X에 저장합니다.  이 특성들을 기반으로 K-NN 모델이 학습합니다.
y = df['Email']  # 타겟 변수(Target Variable, Label)로 'Email'을 선택하여 y에 저장합니다. K-NN 모델은 X를 기반으로 y를 예측합니다.

# 범주형 데이터를 수치형으로 변환
X = pd.get_dummies(X) # One-Hot Encoding을 사용하여 범주형 데이터를 수치형 데이터로 변환합니다.  K-NN 알고리즘은 숫자 데이터만 처리할 수 있기 때문입니다. 예를 들어, 'Gender' 컬럼의 'Male', 'Female' 값은 각각 새로운 컬럼 'Gender_Male', 'Gender_Female'로 변환됩니다.

# 데이터셋을 학습과 테스트 세트로 분할
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 데이터를 훈련 세트(80%)와 테스트 세트(20%)로 나눕니다.  random_state는 랜덤 분할 시드를 설정하여 재현성을 확보합니다.

# K-NN 모델 학습
knn = KNeighborsClassifier(n_neighbors=3) # K-NN 분류기를 생성합니다. n_neighbors는 K 값으로, 여기서는 3으로 설정했습니다.  가장 가까운 3개의 이웃을 참고하여 분류합니다.
knn.fit(X_train, y_train) # 훈련 데이터(X_train, y_train)를 사용하여 K-NN 모델을 학습시킵니다.

# 새로운 고객 데이터로 예측
new_customer = pd.DataFrame({
    'Age': [30],
    'Gender': ['Female'],
    'ClothingCategory': ['Casual'],
    'Brand': ['Nike'],
    'PurchaseAmount': [150000]  # 구매 금액
}) # 새로운 고객의 정보를 담은 데이터프레임을 생성합니다.

# 새로운 고객 데이터에 대해 One-Hot Encoding 적용
new_customer = pd.get_dummies(new_customer) # 새로운 고객 데이터에 대해서도 One-Hot Encoding을 적용합니다.  훈련 데이터와 동일한 형태로 변환해야 합니다.
new_customer = new_customer.reindex(columns=X.columns, fill_value=0) # 훈련 데이터에 있는 컬럼과 동일하게 컬럼을 맞추고, 없는 컬럼은 0으로 채웁니다.  중요!

# 가장 유사한 고객의 Email 예측
predicted_customer = knn.predict(new_customer)[0] # 학습된 K-NN 모델을 사용하여 새로운 고객과 가장 유사한 고객의 Email을 예측합니다. predict() 메서드는 예측 결과를 배열 형태로 반환하므로, [0]을 사용하여 첫 번째 예측값을 추출합니다.

# 예측된 고객과 유사한 다른 고객들의 구매 패턴을 확인하고 추천 내용 생성
similar_customers = df[df['Email'] == predicted_customer] # 예측된 Email과 동일한 Email을 가진 고객들의 데이터를 필터링합니다.

# 입력된 new_customer의 금액에 최대한 유사한 상품 추천
if not similar_customers.empty: # 유사한 고객이 존재할 경우
    input_amount = new_customer['PurchaseAmount'].values[0] # 새로운 고객의 구매 금액을 가져옵니다.

    # 입력 금액과 가장 유사한 상품을 찾기 위해 오차를 계산
    df['AmountDifference'] = abs(df['PurchaseAmount'] - input_amount) # 각 상품의 구매 금액과 새로운 고객의 구매 금액 간의 차이(오차)를 계산하여 'AmountDifference' 컬럼에 저장합니다.

    # 오차가 작은 상품을 추천 (여기서는 상위 5개의 유사한 상품을 추천)
    recommended_products = df.nsmallest(5, 'AmountDifference') # 'AmountDifference' 컬럼을 기준으로 가장 작은 값 5개를 선택합니다.  즉, 새로운 고객의 구매 금액과 가장 유사한 금액의 상품 5개를 추천합니다.

    if not recommended_products.empty: # 추천할 상품이 존재할 경우
        print("추천 상품 목록:")
        print(recommended_products[['Brand', 'ClothingCategory', 'PurchaseAmount', 'PurchaseLocation']]) # 추천 상품의 'Brand', 'ClothingCategory', 'PurchaseAmount', 'PurchaseLocation' 정보를 출력합니다.
    else:
        print("추천할 상품이 없습니다.")
else:
    print("유사한 고객을 찾을 수 없어 추천할 내용이 없습니다.")

 

데이터 값만 바꿔서 사용하기 위한 팁

  1. CSV 파일 변경: file_path 변수에 새로운 CSV 파일 경로를 지정합니다.
  2. 컬럼 이름 확인: CSV 파일의 컬럼 이름을 확인하고, df.rename(), X = df[[...]], y = df['...'] 부분을 수정합니다.
  3. 범주형 데이터 확인: 범주형 데이터가 있다면, pd.get_dummies()를 사용하여 One-Hot Encoding을 적용해야 합니다.
  4. 새로운 고객 데이터 변경: new_customer 데이터프레임에 새로운 고객의 정보를 입력합니다.
  5. K 값 조정: KNeighborsClassifier(n_neighbors=3)에서 n_neighbors 값을 변경하여 K 값을 조정해봅니다. 일반적으로 K 값은 데이터셋 크기의 제곱근 정도로 설정합니다.
K-NN 알고리즘에서 가장 중요한 파라미터인 K (이웃의 개수)를 정할 때, 데이터셋의 크기를 고려하여 대략적인 범위를 정하는 경험적인 방법을 공부해보았다!

 

남은 수업도 화이팅!

반응형