코딩헤딩

[ML(머신러닝)] 머신러닝 기초 1 <K최근접이웃모델> 본문

머신러닝 | 딥러닝

[ML(머신러닝)] 머신러닝 기초 1 <K최근접이웃모델>

멈머이 2023. 12. 20. 21:41
728x90

* 훈련 모델 처리 절차


  1. 데이터 전처리 
  2. 데이터 정규화
  3. 훈련 : 검증 : 테스트 데이터로 분류 (또는 훈련 : 테스트 데이터로 분류)
        - 6 : 2 : 2 또는 7 : 2 : 1, 데이터가 작은 경우에는 8 : 2 또는 7 : 3 정도로 분류
  4. 모델 생성
  5. 모델 훈련 [*fit(함수)] (훈련 데이터와 검증 데이터 사용, 또는 테스트 데이터)
  6. 모델 평가 (모델 선정, 검증데이터)
  7. 하이퍼파라미터 튜닝
  8. 5~6번 진행
  9. 최종테스트 [*predict, 예측] (테스트 데이터 사용)

 

* 생선구분하기 방어와 도미 데이터

데이터 처리
방어와 도미 데이터
 - 생선의 종류를 분류(구분)하기 위한 모델 생성을 위해 독립변수와 종속변수로 데이터를 가공해야 함
 - 독립변수(x) : 길이, 무게
 - 종속변수(y) : 생선종류(빙어 or 도미)

 

 - 도미 데이터

* 데이터 불러들이기

# - 도미길이(cm)
bream_length = [25.4, 26.3, 26.5, 29.0, 29.0, 29.7, 29.7, 30.0, 
                30.0, 30.7, 31.0, 31.0, 31.5, 32.0, 32.0, 32.0, 
                33.0, 33.0, 33.5, 33.5, 34.0, 34.0, 34.5, 35.0, 
                35.0, 35.0, 35.0, 36.0, 36.0, 37.0, 38.5, 38.5, 
                39.5, 41.0, 41.0]

# - 도미무게(g)
bream_weight = [242.0, 290.0, 340.0, 363.0, 430.0, 450.0, 500.0, 
                390.0, 450.0, 500.0, 475.0, 500.0, 500.0, 340.0, 
                600.0, 600.0, 700.0, 700.0, 610.0, 650.0, 575.0, 
                685.0, 620.0, 680.0, 700.0, 725.0, 720.0, 714.0, 
                850.0, 1000.0, 920.0, 955.0, 925.0, 975.0, 950.0]

 

* 데이터 갯수 확인

len(bream_length), len(bream_weight)

결과 : (35, 35)

 

* 데이터 분포 확인하기

산정도 그래프 그리기 : scatter()

보는 이유 : 가져온 데이터가 어떤 분포를 가지고 와서 분석하고 어떤 모델을 써야 할지 정하기 위해

plt.scatter(bream_length, bream_weight)
plt.xlabel("lenght")
plt.ylabel("weight")
plt.show()

 

<해석>
 - 길이가 길어질수록, 무게가 커지는 특징을 가지고 있음
 - 분포의 방향은 양(+)의 상관관계를 나타내고 있음
 - 양(+)의 상관관계를 우상향 분포라고 칭한다.
 - 우상향 분포를 선형 형태라고도 칭한다.
 - 모델을 분석하는 입장에서는 선형 형태를 나타낸다고 해석하며,           선형 형태에 대한 분석은 회귀분석을 사용한다.

 

 

 

 

 

 - 빙어데이터

* 데이터 불러들이기

# - 빙어 길이
smelt_lenght = [9.8, 10.5, 10.6, 11.0, 11.2, 11.3, 11.8, 11.8, 12.0, 12.2, 12.4, 13.0, 14.3, 15.0]

# - 빙어 무게
smelt_weight = [6.7, 7.5, 7.0, 9.7, 9.8, 8.7, 10.0, 9.9, 9.8, 12.2, 13.4, 12.2, 19.7, 19.9]

 

* 데이터 갯수 확인

len(smelt_lenght), len(smelt_weight)

결과 : (14, 14)

 

* 데이터 분포 확인하기

plt.scatter(smelt_lenght, smelt_weight)
plt.xlabel("lenght")
plt.ylabel("weight")
plt.show()

 

 

 

 

 

 

 

 

 

 

 

- 도미와 빙어 데이터 합치기

plt.scatter(bream_length, bream_weight, c="red", label="bream")
plt.scatter(smelt_lenght, smelt_weight, c="blue", label="smeelt")
plt.xlabel("lenght")
plt.ylabel("weight")
plt.legend()
plt.show()

 

* 도미와 빙어 비교
 - 도미와 빙어 모두 우상향 분포를 나타내고 있으며, 도미 데이터는 경사가 급한 반면, 방어 데이터는 경사가 완만하게 분포되어 있음,

 

선형형태 = 회귀분석  
   => 도미와 생선을 구분하기 위한 모델 사용
   => 구분 = 분류  
        ===> 분류 모델을 이용해서 진행을 한다.
                                                                           - 알고 있는 정보 : 길이, 무게, 생선이름

 

 * k최근접이웃 모델 사용
  - KNN : k최근접 이웃모델
  - 머신러닝에서 가장 간단한 모델
  - 비교용으로 주로 사용되는 모델 (실제 사용되기에는 성능이 약한 모델)

* KNN처리방식
 - 예측하고자 하는 값과 가장 가까운 이웃 개수의 비율(또는 평균)을 이용하여, 비율이 가장

    많은 쪽(다수결의 원칙을 따름)의 값으로 판단하는 방식


* 데이터 통합하기

# - 도미와 빙어 데이터를 하나의 길이와+ 무게 데이터로 통합하기
# - 길이(length)
length = bream_length + smelt_lenght

# - 무게 (weight)
weight = bream_weight + smelt_weight

len(length), len(weight)

결과 : (49, 49)

 


중요!!

* 머신러닝에서 사용하는 데이터 차원은 *2차원

 - 독립변수(길이와 무게)
    => 독립변수는 2차원 데이터 형태
 - 종속변수(생선이름)
    => 종속변수는 1차원 데이터 형태


* 독립변수(길이와 무게) 생성하기

# - 2차원으로 생성 : [[길이, 무게], [길이, 무게], ...]
fish_data = [ [l,w]for l,w in zip(length, weight)]
print(fish_data)
len(fish_data)

결과 :

[[25.4, 242.0], [26.3, 290.0], [26.5, 340.0], [29.0, 363.0], [29.0, 430.0], [29.7, 450.0], [29.7, 500.0], [30.0, 390.0], [30.0, 450.0], [30.7, 500.0], [31.0, 475.0], [31.0, 500.0], [31.5, 500.0], [32.0, 340.0], [32.0, 600.0], [32.0, 600.0], [33.0, 700.0], [33.0, 700.0], [33.5, 610.0], [33.5, 650.0], [34.0, 575.0], [34.0, 685.0], [34.5, 620.0], [35.0, 680.0], [35.0, 700.0], [35.0, 725.0], [35.0, 720.0], [36.0, 714.0], [36.0, 850.0], [37.0, 1000.0], [38.5, 920.0], [38.5, 955.0], [39.5, 925.0], [41.0, 975.0], [41.0, 950.0], [9.8, 6.7], [10.5, 7.5], [10.6, 7.0], [11.0, 9.7], [11.2, 9.8], [11.3, 8.7], [11.8, 10.0], [11.8, 9.9], [12.0, 9.8], [12.2, 12.2], [12.4, 13.4], [13.0, 12.2], [14.3, 19.7], [15.0, 19.9]]

49

 

* 종속변수(생선이름) 생성하기

# - 1차원으로 생성한다. : ["도미", "도미", ... , "빙어", "빙어"]
### 종속변수로 사용하는 데이터 형태 : 정수형을 주로사용
# - 범주 값의 갯수에 따라 : 0~n 값을 사용
# - 이진분류 : 0또는 1사용
# - 다중분류 : 0~n개 사용

### - 도미 : 방어 = 1 : 0
# - 이진분류에서 찾고자 하는 값을 1로 정의 하는것이 일반적 개녕.
# - 다만, 어떤 값을 사용하여도 무관.
fish_target = [1]*35 + [0]*14
print(fish_target)
len(fish_target)

결과 : 

[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
49


* 모델 생성하기

* 라이브러리 import

from sklearn.neighbors import KNeighborsClassifier
### 분류모델(클래스) 생성하기
kn = KNeighborsClassifier()

 

 

 

 

 

* 모델 훈련(학습) 시키기

# - KNN은 지도학습 모델 : 독립변수와 종속변수 모두 사용
kn.fit(fish_data, fish_target)

 

 

- fit() : 훈련(학습) 시키는 함수

 

 

* 모델 훈련(학습)이 잘 되었는지 확인하는 절차

# - score() 정확도 확인하는 함수
# - 첫번째 값 : 예측하고자 하는 값
# - 두번쨰 값 : 실제 정답
# - score()함수는 첫번째 값만 이용해서 훈련모델의 패턴에 적용하여 예측결과를 추출
# - 추출된 예측결과와 두번쨰값(실제 정답)과 비교하여 얼마나 잘맞추었는지 비교
kn.score(fish_data, fish_target)

결과 : 1.0

- score() 함수 : 첫 번째 값만 이용해서 훈련모델의 패턴에 적용하여 예측결과를 추출

 

* 예측 : 임의값으로 예측하기

# - 예측시에는 정답은 알려주지 않소, 문제민 넣어준다.
# - 즉, 문제는 독립변수에 속하며, 2차원데이터를 사용해야한다,
#     ****훈련에 사용된 독립변수 형태 그대로를 사용해야 한다. await
kn.predict([[30, 600]])

결과 : array([1])

 - 예측 : predict() 함수 시작

 

* 산정도 그리기

plt.scatter(bream_length, bream_weight, c="red", label="bream")
plt.scatter(smelt_lenght, smelt_weight, c="blue", label="smeelt")
plt.scatter(30, 600, marker="^", c="green", label="pred")
plt.xlabel("lenght")
plt.ylabel("weight")
plt.legend()
plt.show()

 


<해석>
 - 양의 예측 데이터가 분포한 위치를 통해서 시각적으로 확인 가능
 - 모델(클래스)이 사용하는 기본 이웃의 값은 5개를 기준으로 한다.

      (거리가 가장 가까운 5개)

 

 

 

 

728x90