Data Analysis/Machine Learning
Python_ML_Supervised_KNN
mansoorrr
2024. 2. 28. 22:54
KNN(K-최근접이웃)
- KNN은 유사한 특징을 가진 데이터는 유사한 범주에 속하는 경향이 있다는 가정으로 데이터를 분류
- 새로운 데이터가 등장하면 가장 가까운 k개(학습데이터)의 데이터를 찾음
- 찾은 데이터를 통해 새로운 데이터를 레이블링
- 비모수적인 방식을 사용하기 때문에 결정경계가 불규칙한 분류 상황에서 종종 예측성능이 좋음
[KNN 분류]
- 새로운 데이터를 레이블링 하기 위해 주로 유클리디안 거리를 주로 사용
- 경계가 뚜렷하지 않은 특징은 noise로 간주(노이즈를 고려한 파라미터 k를 설정해야함)
예시 1) kaggle 간질환자 데이터
- 데이터정의
- 전처리
liver.info()
#결측치확인
liver.isnull().sum() / liver.shape[0]
#결측치 제거: 수가 적으므로
liver.dropna(axis=0, inplace=True)
liver.isnull().sum()
#gender 수치화
liver["Gender"] = np.where(liver["Gender"]=="Female", 0, 1)
liver["Gender"].value_counts()
- 데이터 분리
#데이터분리
X = liver.drop(["Dataset"], axis=1)
y = liver["Dataset"]
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(X, y, test_size=.3, random_state=1)
print(x_train.shape, y_train.shape) #(405, 10) (405,)
print(x_test.shape, y_test.shape) #(174, 10) (174,)
- 모델 학습 및 예측
#분류기 생성
from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier(n_neighbors=15, weights="uniform")
knn.fit(x_train, y_train)
pred = knn.predict(x_test)
from sklearn.metrics import confusion_matrix, classification_report
cm = confusion_matrix(y_test, pred)
'''
array([[107, 22],
[ 31, 14]])
'''
cr = classification_report(y_test, pred)
'''
precision recall f1-score support
1 0.78 0.83 0.80 129
2 0.39 0.31 0.35 45
accuracy 0.70 174
macro avg 0.58 0.57 0.57 174
weighted avg 0.68 0.70 0.68 174
'''
[KNN 회귀]
- 가까운 이웃 데이터들을 고려하지만 개별값을 예측
- 새로운 데이터가 들어오면 k개의 이웃데이터를 이용해 회귀선을 도출
- 선형회귀와 달리 하나의 회귀선을 도출하지 않음
- 주어진 입력을 바탕으로 가장 잘 예측된 평균 값들의 집합을 나타냄(회귀계수는 도출되지 않음)
예시1) 가데이터로 weights 에 따른 예측선 확인
- 가데이터 생성
#샘플데이터 생성
X = np.sort(5 * np.random.rand(400, 1), axis=0)
y = np.sin(X).ravel()
T = np.linspace(0, 5, 500)[:, np.newaxis]
#노이즈추가
y[::1] += 1 * (0.5 - np.random.rand(400))
- 데이터분리
x_train, x_test, y_train, y_test = train_test_split(X, y, test_size=.3, random_state=1)
- 모델학습 및 예측
- weights별로 차이 있음
#모델정의
from sklearn.neighbors import KNeighborsRegressor
knn_uni = KNeighborsRegressor(n_neighbors=20, weights="uniform")
knn_dis = KNeighborsRegressor(n_neighbors=20, weights="distance")
knn_uni.fit(x_train, y_train)
knn_dis.fit(x_train, y_train)
uni_pred = knn_uni.predict(x_test)
dis_pred = knn_dis.predict(x_test)
preds = [uni_pred, dis_pred]
weights = ["uniform", "distance"]
evals = ["mae", "mse", "rmse"]
results = pd.DataFrame(index=weights, columns=evals)
for pred, weight in zip(preds, weights):
mae = mean_absolute_error(y_test, pred)
mse = mean_squared_error(y_test, pred)
rmse = mean_squared_error(y_test, pred, squared=False)
results.loc[weight, "mae"] = mae
results.loc[weight, "mse"] = mse
results.loc[weight, "rmse"] = rmse
results
- 시각화
#시각화
for i, weight in enumerate(weights):
knnReg = KNeighborsRegressor(n_neighbors=20, weights=weight)
new_pred = knnReg.fit(X, y).predict(T)
plt.subplot(2, 1, i+1)
plt.scatter(X, y, color="orange", label="org")
plt.plot(T, new_pred, color="navy", label="predict")
plt.axis("tight")
plt.legend()
plt.title(f"KNeighborsRegressor (k=5, weights='{weight}')")
plt.tight_layout()
plt.show();