누군가가 사전에 규칙을 정해서, 프로그램을 작성해야한다.
fish_length = 31
if fish_length >= 30:
print("도미")
도미
규칙을 스스로 찾게한다. -> 전통적인 프로그래밍과의 차이
#도미 데이터
#각각의 데이터 = 샘플
#데이터의 특징 = 특성(feature) 이 예에서는 길이, 무게
#도미의 길이
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]
#도미의 무게
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]
#특성이 2개 있을때 2차원 그래프로 그려보기
#파이썬에서 과학계산용 그래프를 그리는 대표적인 패키지 맷플롯립matplib
import matplotlib.pyplot as plt
plt.scatter(bream_length, bream_weight) #도미의 특성 scatter plot 그리기,
plt.xlabel('length') #x축 이름 length
plt.ylabel('weight') #y축 이름 weight
plt.show()
# 산점도 그래프가 일직선에 가까운 모습으로 나타난다 = 선형적(linear)이다.
#빙어의 데이터
smelt_length = [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]
plt.scatter(bream_length, bream_weight)
plt.scatter(smelt_length, smelt_weight)
plt.xlabel('length')
plt.ylabel('weight')
plt.show()
#주황색 = 빙어, 파란색 = 도미
결과 : 빙어는 도미에 비해서 길이와 무게가 매우 작다. 빙어도 도미와 비슷하게 길이와 무게가 비례하지만 늘어나는 정도가 다르다. 빙어의 산점도도 선형적이지만, 무게가 길이에 영향을 덜 받는다.
length = bream_length + smelt_length
weight = bream_weight + smelt_weight
fish_data=[
[l,w]
for l,w in zip(length,weight)
]
#zip 함수를 이용하여 리스트 컴프리헨션
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]]
#정답과 오답의 데이터를 알려줌, 정답 : 1, 오답 : 0
fish_target = [1]*35 + [0]*14
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]
from sklearn.neighbors import KNeighborsClassifier
kn = KNeighborsClassifier() #K-NeighborsClassifier 객체생성
kn.fit(fish_data, fish_target) #kn객체의 fit method에 전달 -> 머신러닝 모델 훈련
kn.score(fish_data, fish_target) #얼마만큼 잘 학습이 되었는지 -> 정확도(accuracy)
1.0
어떤 데이터에 대한 답을 구할 때 주위의 다른 데이터를 보고 다수를 차지하는것을 정답으로 사용, (주위의 데이터로 현재 데이터를 판단)
kn.predict([[30,600]]) #새로운[[30,600]] 데이터를 주고 예측하기 -> 반환값 : 1 도미로 예측
array([1])
plt.scatter(bream_length, bream_weight)
plt.scatter(smelt_length, smelt_weight)
plt.scatter(30,600, marker='^')
plt.xlabel('length')
plt.ylabel('weight')
plt.show()
K-최근접 이웃 알고리즘의 장점 : 데이터를 그냥 가지고 있기만 하면됨, 새로운 데이터에 대해 예측할 때는 가장 가까운 직선거리에 어떤 데이터가 있는지 살피기만 하면 됨,
단점 : 데이터가 매우 많은 경우 사용하기 어려움, 데이터가 크기 때문에 메모리가 많이 필요하고, 직선거리를 계산하는데도 많은 시간이 필요
kn._fit_X #_fit_X 속성에 전달한 fish_data를 모두 가지고 있음
array([[ 25.4, 242. ], [ 26.3, 290. ], [ 26.5, 340. ], [ 29. , 363. ], [ 29. , 430. ], [ 29.7, 450. ], [ 29.7, 500. ], [ 30. , 390. ], [ 30. , 450. ], [ 30.7, 500. ], [ 31. , 475. ], [ 31. , 500. ], [ 31.5, 500. ], [ 32. , 340. ], [ 32. , 600. ], [ 32. , 600. ], [ 33. , 700. ], [ 33. , 700. ], [ 33.5, 610. ], [ 33.5, 650. ], [ 34. , 575. ], [ 34. , 685. ], [ 34.5, 620. ], [ 35. , 680. ], [ 35. , 700. ], [ 35. , 725. ], [ 35. , 720. ], [ 36. , 714. ], [ 36. , 850. ], [ 37. , 1000. ], [ 38.5, 920. ], [ 38.5, 955. ], [ 39.5, 925. ], [ 41. , 975. ], [ 41. , 950. ], [ 9.8, 6.7], [ 10.5, 7.5], [ 10.6, 7. ], [ 11. , 9.7], [ 11.2, 9.8], [ 11.3, 8.7], [ 11.8, 10. ], [ 11.8, 9.9], [ 12. , 9.8], [ 12.2, 12.2], [ 12.4, 13.4], [ 13. , 12.2], [ 14.3, 19.7], [ 15. , 19.9]])
kn._y #y속성에 fish_target을 가지고 있음
array([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])
K-최근접 이웃 알고리즘은 무언가 훈련되는게 없다. fit()메서드에 전달한 데이터를 모두 저장하고 있다가. 새로운 데이터가 등장하면 가장 각까운 데이터를 참고하여 도미인지 방어인지를 구분한다. 기본값으로 주변 5개의 데이터를 참조하지만. n_neighbors 매개변수로 바꿀 수 있다.
kn49 = KNeighborsClassifier(n_neighbors=49) #참고 데이터를 49개로 한 kn49 모델
#데이터에 도미가 절대 다수이므로 어떤 데이터를 넣어도 도미로 판단한다.
kn49.fit(fish_data, fish_target)
kn49.score(fish_data,fish_target)
0.7142857142857143
print(35/49) #정확히 도미의 개수와 같은 정확도가 나온다
0.7142857142857143
kn = KNeighborsClassifier()
kn.fit(fish_data,fish_target)
for n in range(5,50):
kn.n_neighbors = n
score = kn.score(fish_data,fish_target)
if score<1:
print(n,score)
break
18 0.9795918367346939