KNN ( K - Nearest Neighbor )

2021. 9. 11. 01:44ai/Machine Learning

728x90

# Keras에 대한 기본적인 설명을 했으니

# Ozone량 예측에 대한 linear regression을 TF 2.0으로 구현해 보아요!

 

# 우리가 사용하는 데이터에 결측치가 존재했어요!

# 초기에는 결측치를 모두 삭제해서 머신러닝을 진행했어요!

# 결측치를 삭제하는 대신 보간(Imputation)할꺼예요!

# 데이터량이 아주 많고 상대적으로 결측치가 적으면 삭제가 가장 좋아요!

# 우리예제는 데이터량이 적기때문에 삭제하면 곤란해요!

 

Imputation(결측치 보간)을 진행할때는 2가지 정도의 방법이 존재

 

# 대체값으로 평균화 기법을 이용해서 평균, 중앙값, 최빈값등을 이용

#           머신러닝기법을 이용(예측기법)해서 데이터를 보간시킬 수 있어요! 

 

# 일반적으로 독립변수에 NaN(결치값)이 있을경우 => 평균화기법을 이용

#           종속변수에 NaN(결치값)이 있을경우 => 예측기법

# => 태양광세기, 바람, 온도 여기에 결치값이 있는경우 -> 평균화기법

# => 오존량 여기에 결치값이 있는경우 -> 예측기법(머신러닝-KNN)

# 일단 머신러닝 알고리즘 KNN부터 알아보고 와요!

 

K - Nearest Neighbor( KNN )   : " K - 최근접 이웃 "

binary classification을 예로 들어

위 빨간점이 들어왔을때 빨간색일지 분홍색일지 

1. 빨간점을 주변확장하였을때 파란색이 들어온다 => 1NN : 빨간점이 파란점으로 예측

3. 3NN : 자신을 기준으로 넓혔을때 3개가 되면 멈춘다 => 어떤색이 더 많을지

 

그러면 regression (모델이 연속적인 값을 예측) - ex) 3NN인경우 3개의 평균의 값

 

- 상당히 간단한 machine learning algorithm

- KNN 에서 K는 숫자이며 일반적으로 홀수사용

- KNN 에서 NN은 주변 넓혔을때 숫자NN이되면 멈춤

- 학습과정이 없어요!! Instance - based Learning or Lazy Model Model - based Learning (regression)

- 모든 거리를 찾아내 가장 짧은 거리를 찾아내야한다 그래서 계산량이 많다   ==  약점 : 속도 ↓ (개선중이예요)

 

- 최상의 K값은 어떻게 결정하나요?

- 거리측정은 어떻게 하나요 ?

( 최단직선      → 유클리디안 distance

  직선(사선x)   → 맨하튼 distance

  분산, 공분산 → 마할라노비스 distance

  이외에도 많이 있다 ..  )

위 두가지 질문은 공식이 따로 없어 노동집약적 작업으로 찾아내야한다

 

많이 쓰이나요? 네이버에서도 실제로 현업에서 사용

K = 1 이 항상은 아니지만 머신러닝보다 오차율이 적을때도 많다

K = 1 이 성능이 많이 괜찮다라고 수학적으로 증명되었다

 


# KNN을 이용해서 간단하게 machine learning 작업을 진행해 보아요!

# 사용할 예제는 BMI 예제예요!!

 

# %reset

import numpy as np

import pandas as pd

from sklearn.linear_model import LogisticRegression

from sklearn.preprocessing import MinMaxScaler

from sklearn.model_selection import train_test_split

from sklearn.neighbors import KNeighborsClassifier

 

# raw data loading

df = pd.read_csv('/content/drive/MyDrive/융복합 프로젝트형 AI 서비스 개발(2021.06)/09월/10일(금요일)/bmi.csv',

                 skiprows=3)

# display(df)

 

# train validation 분리

train_x_data, valid_x_data, train_t_data, valid_t_data = \

train_test_split(df[['height''weight']],

                 df['label'],

                 test_size=0.3,

                 random_state=0,

                 stratify=df['label'])

 

# bmi 데이터는 결측치와 이상치는 없어요! 대신 Normalization은 해 줘야 해요!

scaler = MinMaxScaler()

scaler.fit(train_x_data)

train_x_data_norm = scaler.transform(train_x_data)

valid_x_data_norm = scaler.transform(valid_x_data)

 

# Tensorflow로 구현할때는 다중분류이기때문에 label(t)을 one-hot encoding으로 변환

# sklearn을 이용할때는 one-hot encoding 없이 사용해요!

 

# LogisticRegression을 이용해서 multinomial classification처리를 해 보아요!

model = LogisticRegression()

model.fit(train_x_data_norm, train_t_data)

print(model.score(valid_x_data_norm, valid_t_data))    # 0.9855

 

# KNN을 이용해 보아요!

knn_model = KNeighborsClassifier(n_neighbors=3)

knn_model.fit(train_x_data_norm, train_t_data)

print(knn_model.score(valid_x_data_norm, valid_t_data))  # 0.9986666666666667

 


# KNN에 대해서 알았으니..

# 이 KNN을 이용해서 Imputation을 해요!(종속변수에 대한 결측치 처리)

# 우리가 할 예제는 Ozone예제예요(regression)

 

# 1. 데이터를 로딩해요!

# 2. 독립변수에 대한 결측치를 찾아내서 각 column의 median값으로 대체

#    이상치 처리가 안되있어서 mean을 사용하기가 껄끄러워요!

# 3. 독립변수에 이상치를 검출해서 mean으로 처리할꺼예요!

# 4. 종속변수에 대한 이상치는 mean으로 처리할꺼예요! => 오존예제에서 종속변수에 대한 이상치는 없어요!

# 5. 정규화처리를 먼저 진행

# 6. 종속변수에 대한 결측치 처리를 KNN을 이용한 Imputation으로 처리해요!

# 이렇게 하면 데이터가 완성되요!

 

# 7. 이 데이터를 이용해서 TF 2.x Keras를 이용해서 구현해 보아요!

 


# %reset

import numpy as np

import pandas as pd

from scipy import stats   # zscore를 이용한 이상치 검출작업을 위해.

from sklearn.neighbors import KNeighborsRegressor  # Ozone량의 NaN값을 예측하기 위해서.

from sklearn.preprocessing import MinMaxScaler # Normalization 처리를 위해.

# from sklearn.model_selection import train_test_split # train, validation 데이터 분리를 위해.

# Keras로 구현하기 때문에 Keras의 train, validation분리 기능을 이용해서 학습할꺼예요!

import warnings

 

warnings.filterwarnings(action='ignore')   # warning 출력되지 않게 설정

 

# 1. Raw Data Loading

df = pd.read_csv('/content/drive/MyDrive/융복합 프로젝트형 AI 서비스 개발(2021.06)/09월/10일(금요일)/ozone.csv')

# display(df)

 

x_data = df[['Solar.R''Wind''Temp']]

t_data = df['Ozone']

 

# 2. 독립변수에 대한 결측치를 찾아내서 각 column의 median값으로 대체

#    이상치 처리가 안되있어서 mean을 사용하기가 껄끄러워요!

for col in x_data.columns:

    col_median = np.nanmedian(x_data[col])   # 각 column의 nan을 제외한 중위값을 알아내요!

    x_data[col].loc[x_data[col].isnull()] = col_median

 

# 3. 독립변수에 이상치를 검출해서 mean으로 처리할꺼예요!

zscore_threshold = 1.8

 

for col in x_data.columns:

    outlier = x_data[col][np.abs(stats.zscore(x_data[col])) > zscore_threshold]

    col_mean = np.mean(x_data.loc[~x_data[col].isin(outlier),col])

    # print(col_mean)

    x_data.loc[x_data[col].isin(outlier),col] = col_mean

 

# 4. 종속변수에 대한 이상치는 mean으로 처리할꺼예요! 

#    => 오존예제에서 종속변수에 대한 이상치는 없어요!    

 

# 5. 정규화처리를 먼저 진행

scaler_x = MinMaxScaler()

scaler_t = MinMaxScaler()

 

scaler_x.fit(x_data.values)

scaler_t.fit(t_data.values.reshape(-1,1))  # fit() 함수는 인자로 2차원데이터가 들어가야 해요!

 

x_data_norm = scaler_x.transform(x_data)

t_data_norm = scaler_t.transform(t_data.values.reshape(-1,1)).ravel()

 

# 6. 종속변수에 대한 결측치 처리를 KNN을 이용한 Imputation으로 처리해요!

 

# KNN을 학습해야 하니까.. train data와 label data에서 nan을 제외하고 가져와야 해요!

train_x_data_norm = x_data_norm[~np.isnan(t_data_norm)]

train_t_data_norm = t_data_norm[~np.isnan(t_data_norm)]

 

knn_regressor = KNeighborsRegressor(n_neighbors=2)

knn_regressor.fit(train_x_data_norm,train_t_data_norm)  # KNN 모델 완성

 

# KNN을 이용해서 prediction(종속변수가 Nan인것들에 대해!)

knn_predict = knn_regressor.predict(x_data_norm[np.isnan(t_data_norm)])

t_data_norm[np.isnan(t_data_norm)] = knn_predict

 

x_data_norm

t_data_norm

 


# 기존에도 Ozone data를 이용해서 python구현, sklearn구현, tensorflow 구현을 다 

# 했었어요! sklearn의 결과와 약간 다른 예측치를 보인걸로 기억해요!

 

from sklearn.linear_model import LinearRegression

from tensorflow.keras import Sequential

from tensorflow.keras.layers import Flatten, Dense

from tensorflow.keras.optimizers import SGD

 

test_data = [[3101580]]   # Solar.R, Wind, Temp

 

# sklearn 구현

model = LinearRegression()

model.fit(x_data_norm, t_data_norm)

result = model.predict(scaler_x.transform(test_data))

 

print(scaler_t.inverse_transform(result.reshape(-1,1)))   # [[38.75927452]]

 

# tensorflow 2.x 구현

keras_model = Sequential()

 

keras_model.add(Flatten(input_shape=(3,)))

keras_model.add(Dense(1, activation='linear'))

 

keras_model.compile(optimizer=SGD(learning_rate=1e-2),

                    loss='mse')

 

keras_model.fit(x_data_norm,

                t_data_norm,

                epochs=5000,

                verbose=0)

keras_result = keras_model.predict(scaler_x.transform(test_data))

 

print(scaler_t.inverse_transform(keras_result.reshape(-1,1)))   # [[38.87136]]

'ai > Machine Learning' 카테고리의 다른 글

ai 단어  (0) 2021.09.13
tensor flow 2.0 ver  (0) 2021.09.10
MNIST(Multinomial classification)/model평가  (0) 2021.09.10
Multinomial classification(다중분류)  (0) 2021.09.09
Regulerization(규제)  (0) 2021.09.08