Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

Seongho Jang

Ch.17 KNN 본문

Data Science Lv.2

Ch.17 KNN

seonghojang 2023. 1. 2. 23:37

1.  KNN (K-Nearest Neighbor)

    K의 가장 가까운 사례를 Train Data Set에서 찾아 해당하는 데이터의 y값을 기반으로 결과 제시

    분류와 회귀 문제를 모두 다를 수 있음

      - 분류 문제(Classifier)를 풀 떄는 class 다수결로 결과 class를 예측

      - 회귀 문제(Regressor)를 풀 떄는 가중평균값을 결과값으로 예측

    K값이 작을수록 overfitting, K값이 클수록 underfitting의 위험이 있음

 

 

2. KNeighbors

from sklearn.neighbors import KNeighborsClassifier
from sklearn.neighbors import KNeighborsRegressor
# 분류
model_c = KNeighborsClassifier(n_neighbors = 3)
model_c.fit(X = df.iloc[:, :4], y = df["is_setosa"])

# 회귀
model_r = KNeighborsRegressor(n_neighbors = 3)
model_r.fit(X = df.iloc[:, :3], y = df["Petal.Width"])

  구조는 동일하고, fit 뒤에 독립변수, 종속변수를 넣어준다. 분류는 독립변수가 범주형, 회귀는 수치형.

  분류형의 경우는 accuracy_score, precision 등으로 평가, 수치형은 MSE, RMSE 등으로 평가

 

문제 1

당뇨 발생 여부를 예측하기 위해 임신 횟수, 혈당, 혈압을 사용할 경우 그 정확도는 얼마인가?

import pandas as pd
from sklearn.neighbors import KNeighborsClassifier
from sklearn.neighbors import KNeighborsRegressor
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

df = pd.read_csv('diabetes.csv')
df_train, df_test = train_test_split(df, train_size = 0.7, test_size = 0.3, random_state = 123)

model = KNeighborsClassifier(n_neighbors = 5)
model.fit(X = df_train.loc[:, ["Pregnancies", "Glucose", "BloodPressure"]], y = df_train["Outcome"])
pred = model.predict(X = df_test.loc[:, ["Pregnancies", "Glucose", "BloodPressure"]])

accuracy_score(y_true = df_test["Outcome"], y_pred = pred)

pred 값은 array 형태였다는 걸 이제야 알았다. 어쨌든 맞춰서 기분이 좋은 문제~

 

문제 2

종속변수를 당뇨 발병 여부로 하고, 독립변수를 임신여부, 혈당, 혈압, 인슐린, 체질량지수로 하여 정확도를 확인했을 때 그 k값과 정확도가 올바르게 연결되지 않은 것은?

df = pd.read_csv('diabetes.csv')
df["is_preg"] = (df["Pregnancies"] > 0) + 0
df_train, df_test = train_test_split(df, train_size = 0.8, test_size = 0.2, random_state = 123)

X_cols = ["is_preg", "Glucose", "BloodPressure", "Insulin", "BMI"]
neighbors = [3, 5, 10, 20]
accs = []

for n_n in neighbors:
	model = KNeighborClassifier(n_neighbors = n_n)
	model.fit(X = df.loc[:, X_cols], y = df_train["Outcome"])
    pred = model.predict(X = df.loc[:, X_cols])
    acc_sub = accuracy_score(y_true = df_test["Outcome"], y_pred = pred)
    accs = accs + [acc_sub]
    
df_score = pd.DataFrame({"neighbors": neighbors, "accs" : accs})
df_score["accs"] = df_score["accs"].round(2)
df_score

물론 나는 그냥 일일이 neighbor 값을 바꿔가면서 풀었다.

보면 대강 따라갈 수는 있겠지만 실제로 이렇게 쓸 자신은 없다...

 

문제 3

종속변수를 체질량 지수로 하고, 독립변수를 임신여부, 혈당, 혈압, 인슐린으로 하여 예측값을 확인했을 때 그 k값과 RMSE가 올바르게 연결되지 않은 것은?

from sklearn.metrics import mean_squared_error
X_cols = ["is_preg", "Glucose", "BloodPressure", "Insulin"]
neighbors = [3, 5, 10, 20]
rmses = []

for n_n in neighbors:
    model = KNeighborsRegressor(n_neighbors = n_n).fit(X = df_train.loc[:,X_cols], y = df_train["BMI"])
    pred = model.predict(X = df_test.loc[:, X_cols])
    rmse_sub = mean_squared_error(y_pred = pred, y_true = df_test["BMI"]) ** 0.5
    rmses = rmse + [rmse_sub]

df_score = pd.DataFrame({"neighbors" : neighbors, "rmses" : rmses})
df_score["rmses"] = df_score["rmses"].round(3)
df_score

역시 2번과 동일한 방식. 근데 하나하나 대입했을 떄 답이 다르게 나왔는데... 나중에 다시 풀어봐야겠다.