'혼자 공부하는 머신러닝 + 딥러닝' 교재를 공부한 내용입니다.

 

해당 교재는 코랩으로 진행하지만, 필자는 파이참으로 진행하였습니다.


# 도미 데이터 준비하기
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]

도미의 길이와, 무게 각 리스트에 넣었습니다.

 

import matplotlib.pyplot as plt # matplotlib의 pylot 함수를 plt 로 줄여서 사용

plt.scatter(bream_length, bream_weight)
plt.xlabel('length')            # x축은 길이
plt.ylabel('weight')            # y축은 무게
plt.show()

산점도 그래프를 그릴 수 있는 패키지인 맷플롭립을 import한 후 산점도를 그리는 함수인 scatter을 사용하여 xlabel, ylabel 함수를 이용해 x축은 length, y축은 weight 이름을 표시하였고, show 함수를 이용해 그래프를 확인해봅니다.

 

도미는 길이가 길수록 무게가 많이 나가는 것을 확인 할 수 있습니다. 또한 산점도 그래프가 일직선에 가까운 형태로 나타는 경우를 선형적이라 말합니다.

# 빙어 데이터 준비하기
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)] # 리스트 내포를 이용한 fish_data 2차원 리스트 제작. 사이킷런을 사용하기 위해선 2차원 리스트로 구현해야 됨.

k-최근접 이웃 알고리즘을 사용하기 전에 도미와 빙어의 데이터를 하나의 데이터로 합쳤고, 머신러닝 패키지인 사이킷런을 사용하기 위해선 2차원 리스트를 만들어야 하기 때문에 zip 함수와, 리스트 내포 구문을 활용하여 2차원 리스트를 만듭니다.

 

출력 결과는 다음과 같습니다.

print(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 # 도미와 빙어를 구분해주는 target. 1일 경우 도미, 0일 경우 빙어를 나타냄.

 

from sklearn.neighbors import KNeighborsClassifier # 사이킷런 패키지에서 k-최근접 이웃 알고리즘을 구현한 클래스

kn = KNeighborsClassifier()

kn.fit(fish_data, fish_target) # fit() 메소드는 학습시키는 역할을 한다.

사이킷런 패키지에서 k-최근접 이웃 알고리즘을 구현한 클래스를 사용하기위해 KNeighborsClassifier를 import하고,

객체를 생성한 후 머신러닝을 훈련하는 fit 메소드를 이용하여 생선 데이터, 정답을 주어 훈련 시킵니다.

 

print(kn.score(fish_data, fish_target)) # 훈련이 얼마나 잘 됐는지를 평가하는 score() 메소드. 0부터 1까지 출력된다. 1이면 완벽하게 학습된것이고, 0.5면 절반.fish_target = [1] * 35 + [0] * 14 # 도미와 빙어를 구분해주는 target. 1일 경우 도미, 0일 경우 빙어를 나타냄.

1.0

훈련이 잘되었는지 평가하는 메소드인 score 로 확인해보면 정확도가 100%인 것을 확인할 수 있습니다.

 

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()

새로운 생선 데이터를 생성하여 삼각형으로 산점도 그래프를 그려 확인해봅니다.

 

새로운 데이터는 파란색 점인 도미 데이터에 가까운 것을 확인 할 수있습니다. 이러한 새로운 데이터를 우리가 훈련 시킨 머신러닝 모델에 입력하여 확인 해보겠습니다.

print(kn.predict([[30,600]]))     # predict() 메소드는 새로운 데이터의 정답을 예측한다.

[1]

# k-최근접 이웃 알고리즘은, 어떤 데이터에 대한 답을 구할 때 주위의 다른 데이터를 보고 다수를 차지하는 것을 정답으로 한다.
# 위 [30,600]의 데이터는 주위에 도미 데이터가 많으므로 이 데이터를 도미라고 판단하고 1을 출력함

새로운 데이터의 정답을 예측할 수 있는 predict 메소드로 입력하여 확인해보면 반환된 값이 1이라는 것을 알 수 있고, 우리가 훈련 시킨 머신러닝 모델(k-최근접 이웃 알고리즘)도 새로운 데이터가 도미라는 것을 확인할 수 있습니다.

 

# 보통 k-최근접 이웃 알고리즘은 주변에서 가장 가까운 5개의 데이터를 가지고 비교를 진행, 하지만 이 코드에선 5개로 비교하는 수를 49개. 모든 개수를 이용하여 비교한다는 의미이다.
kn49 = KNeighborsClassifier(n_neighbors=49)

k-최근접 이웃 알고리즘은 가장 가까운 5개의 데이터를 가지고 비교를 진행하지만, 49개의 데이터로 확인하는 모델을 다시 만들었습니다.

 

kn49.fit(fish_data, fish_target)
print(kn49.score(fish_data, fish_target))  # fish_data 의 데이터 49개 중 도미가 35개 로 다수를 차지하므로, 어떤 데이터를 넣어도 무조건 도미로 예측할 것이다.
0.7142857142857143
print(35/49)                        # 출력되는 수가 49개로 설정해놓고 데이터를 예측 할 수 있는 정확도이다.
0.7142857142857143

새로운 모델을 학습 시키고 정확도를 확인해 보면, 49개중 35개만 맞춘 정확도를 확인 할 수 있고, 도미만 맞추었다는 것을알 수 있습니다. 만약 모델을 학습시키는 데이터의 양이 많다면, kn49의 모델이 더욱 더 정확할 수 있지만, 해당 모델의 학습시키는 양은 작아 kn 모델이 더 정확한 것을 확인할 수 있습니다.

 


전체소스코드

# 도미 데이터 준비하기
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]

import matplotlib.pyplot as plt # matplotlib의 pylot 함수를 plt 로 줄여서 사용

plt.scatter(bream_length, bream_weight)
plt.xlabel('length')            # x축은 길이
plt.ylabel('weight')            # y축은 무게
plt.show()

# 빙어 데이터 준비하기
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)] # 리스트 내포를 이용한 fish_data 2차원 리스트 제작. 사이킷런을 사용하기 위해선 2차원 리스트로 구현해야 됨.

print(fish_data)

fish_target = [1] * 35 + [0] * 14 # 도미와 빙어를 구분해주는 target. 1일 경우 도미, 0일 경우 빙어를 나타냄.

from sklearn.neighbors import KNeighborsClassifier # 사이킷런 패키지에서 k-최근접 이웃 알고리즘을 구현한 클래스

kn = KNeighborsClassifier()

kn.fit(fish_data, fish_target) # fit() 메소드는 학습시키는 역할을 한다.

print(kn.score(fish_data, fish_target)) # 훈련이 얼마나 잘 됐는지를 평가하는 score() 메소드. 0부터 1까지 출력된다. 1이면 완벽하게 학습된것이고, 0.5면 절반.

# k-최근접 이웃 알고리즘

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()

print(kn.predict([[30,600]]))     # predict() 메소드는 새로운 데이터의 정답을 예측한다.
# k-최근접 이웃 알고리즘은, 어떤 데이터에 대한 답을 구할 때 주위의 다른 데이터를 보고 다수를 차지하는 것을 정답으로 한다.
# 위 [30,600]의 데이터는 주위에 도미 데이터가 많으므로 이 데이터를 도미라고 판단하고 1을 출력함

print(kn._fit_X)
print(kn._y)

# 보통 k-최근접 이웃 알고리즘은 주변에서 가장 가까운 5개의 데이터를 가지고 비교를 진행, 하지만 이 코드에선 5개로 비교하는 수를 49개. 모든 개수를 이용하여 비교한다는 의미이다.
kn49 = KNeighborsClassifier(n_neighbors=49)


kn49.fit(fish_data, fish_target)
print(kn49.score(fish_data, fish_target))  # fish_data 의 데이터 49개 중 도미가 35개 로 다수를 차지하므로, 어떤 데이터를 넣어도 무조건 도미로 예측할 것이다.
print(35/49)                        # 출력되는 수가 49개로 설정해놓고 데이터를 예측 할 수 있는 정확도이다.
1

+ Recent posts