반응형
# 바로 위에 개발한 머신러닝 모델은 길이가 25cm이고 무게가 150g이면 빙어모델로 예측한다고 함
fish_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, 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]
fish_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, 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]

import numpy as np
np.column_stack(([1, 2, 3], [4,5,6]))

fish_data = np.column_stack((fish_length, fish_weight))
print(fish_data[:5])

 

<출력>

[[ 25.4 242. ]
 [ 26.3 290. ]
 [ 26.5 340. ]
 [ 29.  363. ]
 [ 29.  430. ]]

 

 

# fish_target = [1] * 35 + [0] * 14 이 역할을 하던 놈
# np.ones(35) : 1이 35개인 배열, np.zeros(14) : 0이 14개인 배열
fish_target = np.concatenate((np.ones(35), np.zeros(14)))

# 앞에서는 훈련세트와 테스트 세트를 나눌때 
# 번거롭게 랜덤 돌린 뒤 잘라냈지만 
# 여기서는 train_test_spit()을 이용한다. 
# 이는 섞는것까지 알아서 해줌

from sklearn.model_selection import train_test_split

train_input, test_input, train_target, test_target 
 = train_test_split(fish_data, fish_target, random_state=42)
# 비율이 안맞아 샘플링 편향이 나타난다고 볼 수도 있음
# 이를 해결하려면 stratify를 사용하면된다.

print(test_target)

train_input, test_input, train_target, test_target 
 = train_test_split(fish_data, fish_target, stratify=fish_target, random_state=42)

print(test_target)

<출력>

[1. 0. 0. 0. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[0. 0. 1. 0. 1. 0. 1. 1. 1. 1. 1. 1. 1.]

 

from sklearn.neighbors import KNeighborsClassifier
kn = KNeighborsClassifier()
kn.fit(train_input, train_target)
kn.score(test_input, test_target)

# 바로 위에 개발한 머신러닝 모델은 길이가 25cm이고 무게가 150g이면 빙어모델로 예측한다고 함... 고쳐졌으려나?
print(kn.predict([[25, 150]]))

<출력>

[0.]
# 삐빅... 빙어 입니다!

 

# 도미? 놉! 어찌 된일 일까요?

import matplotlib.pyplot as plt
plt.scatter(train_input[:,0], train_input[:,1])
plt.scatter(25, 150, marker='^') # marker는 특정 값의 매개변수의 모양을 지정 ^ 는 삼각형 모양으로 표시시
plt.xlabel('length')
plt.ylabel('weight')
plt.show()

# 위 데이터 상에서는 도미 데이터에 가까운데 왜 빙어라고 평가 할까?

 

distances, indexes = kn.kneighbors([[25, 150]])

plt.scatter(train_input[:,0], train_input[:,1])
plt.scatter(25, 150, marker='^')
plt.scatter(train_input[indexes,0], train_input[indexes,1], marker='D')  # marder D는 마름모 모양
plt.xlabel('length')
plt.ylabel('weight')
plt.show()

 

# 그래프 y축 한칸의 크기가 너무 커서 그렇지 실제로는 
plt.scatter(train_input[:,0], train_input[:,1])
plt.scatter(25, 150, marker='^')
plt.scatter(train_input[indexes,0], train_input[indexes,1], marker='D') 
plt.xlim((0,1000))
plt.xlabel('length')
plt.ylabel('weight')
plt.show()
# 그래프와 같이 현재 데이터에서는  x값은 사실 생선을 판단하는데 큰 영향이 없다고 볼 수 있음
# (y축에 비해 너무 미미하여 영향력이 거의 없다고 받아들여짐
# 범위가 다르기 때문(스케일이 다르다) 
# 다른 단위로 이루어진 샘플간에 특성값을 일정한 기준으로 맞추는 것을 데이터 전처리 라고 한다.

 

# 교재에서는 널리 사용하는 전처리 방법 중 하나가 표준점수라고하고
# 값에서 평균을 뺴고 표준편차로 나누어주면된다고 한다.

# 통계학에서는 정규화 라고 하는데 크기에 상관없이 기준을 맞추는 작업으로 볼 수 있을 것같다

mean = np.mean(train_input, axis=0)
std = np.std(train_input, axis=0)

print(mean, std)

train_scaled = (train_input - mean) / std


# train_scaled 로 산점도를 다시 그려본다.

plt.scatter(train_scaled[:,0], train_scaled[:,1])
plt.scatter(25, 150, marker='^')
plt.xlabel('length')
plt.ylabel('weight')
plt.show()

 

# 새로 넣을 데이터도 표준화 해야한다.

new = ([25, 150] - mean) / std
plt.scatter(train_scaled[:,0], train_scaled[:,1])
plt.scatter(new[0], new[1], marker='^')
plt.xlabel('length')
plt.ylabel('weight')
plt.show()

kn.fit(train_scaled, train_target)
test_scaled = (test_input - mean) / std
kn.score(test_scaled, test_target)

print(kn.predict([new]))

<출력>

[1.]

 

 

distances, indexes = kn.kneighbors([new])

plt.scatter(train_scaled[:,0], train_scaled[:,1])
plt.scatter(new[0], new[1], marker='^')
plt.scatter(train_scaled[indexes,0], train_scaled[indexes,1], marker='D')  # marder D는 마름모 모양
plt.xlabel('length')
plt.ylabel('weight')
plt.show()

반응형
반응형

# 머신러닝 알고리즘

 1. 지도학습

  - 훈련 데이터 : {

          데이터 : 입력,

          정답 : 타깃

     }

 2. 비지도학습

  - (추후에 나옴)

 

훈련시킬때 데이터를 입력해서 맞추는 것은 답을 알려주고 문제를 맞추는 것과 같은 개념!

따라서 훈련시킬 데이터(훈련 세트)와 평가에 사용할 데이터(테스트 세트)를 구분하는 것이 바람직!

 

fish_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, 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]
fish_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, 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]

fish_data = [[l, w] for l, w in zip(fish_length, fish_weight)]
fish_target = [1]*35 + [0]*14

# 도미 35마리와 빙어 14마리로 전체 49개의 샘플이 있고, 길이와 무게 2개의 특성을 갖는다.
# 도미인 처음 35개 데이터를 훈련세트로, 나머지 14개(빙어)를 테스트 세트로 이용해보도록 하자

from sklearn.neighbors import KNeighborsClassifier
kn = KNeighborsClassifier()

# 슬라이싱 [0:35] -> 인덱스 0부터 35 전까지(35는 미포함) 데이터를 리턴
# 시작 인덱스가 0인 경우 생략 가능 [:35]
# 마찬가지로 뒤가 마지막 인덱스인 경우 생략 가능 [35:]

train_input = fish_data[:35] # 1~35 데이터 인덱스로는 0~34
train_target = fish_target[:35]

test_input = fish_data[35:] # 36~49 데이터 인덱스로는 35~48
test_target = fish_target[35:]

kn = kn.fit(train_input, train_target)
kn.score(test_input, test_target)

# 결과인 정확도가 0.0이 나온다....
# 너무 당연하다 도미 데이터만 훈련시켰기때문에 빙어데이터와 구분할 수 있는 방법이 학습되지 않았기 때문이다.

# 넘파이를 배울 타이밍 - 파이썬의 대표적인 배열 라이브러리
import numpy as np

input_arr = np.array(fish_data)
target_arr = np.array(fish_target)

print(input_arr)

print(input_arr.shape) #(샘플수, 특성 수) 출력

# index를 랜덤하게 돌려 편향성이 없으면서도 도미와 빙어가 골고루 들어갈 수 있도록 test set를 분리한다.
np.random.seed(42)
index = np.arange(49)
np.random.shuffle(index)

train_input = input_arr[index[:35]]
train_target = target_arr[index[:35]]

test_input = input_arr[index[35:]]
test_target = target_arr[index[35:]]

# 산점도를 그려 골고루 분리가 되었는지 확인해 본다.
import matplotlib.pyplot as plt
plt.scatter(train_input[:,0], train_input[:,1])
plt.scatter(test_input[:,0], test_input[:,1])
plt.xlabel('length')
plt.ylabel('weight')
plt.show()

# 새로 만든 데이터를 다시 학습시킨다
kn = kn.fit(train_input, train_target)
kn.score(test_input, test_target)
# 정확도는 1.0! 어디한번 테스트 세트를 돌려보자!


print('test_input')
print(kn.predict(test_input))

print('test data')
print(test_target)

위 소스에 대한 실행결과는 아래와 같음

[[  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]]
(49, 2)
test_input
[0 0 1 0 1 1 1 0 1 1 0 1 1 0]
test data
[0 0 1 0 1 1 1 0 1 1 0 1 1 0]
반응형
반응형

지난 포스팅에 이어 1단원을 마무리 한다.

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

# 두 종류의 물고기 길이와 무게라고 가정하고 종을 구분해내는 AI를 만들어 머신러닝한다.
# 제 3의 데이터가 주어졌을때 판단할 수 있는지 확인해보는 예제

# A종 길이와 크기 예제
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]

# B종 길이와 크기 예제
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

print('length')
print(length)

print('weight')
print(weight)

# [길이, 무게] 쌍으로 데이터를 변환한 2차원 리스트 생성성
fish_data = [[l,w] for l, w in zip(length, weight)]

print('fish_data')
print(fish_data)

# A종 35개와 B종 14개를 구분한 배열을 생성
# R 또는 다른 통계분석에서도 구분컬럼을 추가하는 방식과 동일한 개념으로 보인다.
fish_target = [1] * 35 + [0] * 14

print('fish_target')
print(fish_target)

# 사이킷런 패키지에서 k-최근접 이웃 알고리즘을 구현한 클래스를 임포트
# 통계학에서 qqplot 등에서 점이 몰려있거나 선형이거나.... 등등 일정한 규칙을 이루는 집단을 동일집단으로 보는 것과 유사한 알고리즘일 것으로 추정
# 이름부터가 해석하자면 이웃 분류
from sklearn.neighbors import KNeighborsClassifier

# 객체로 선언
kn = KNeighborsClassifier()

# 알고리즘 객체에 학습 - 요데이터는 요놈이야야
kn.fit(fish_data, fish_target)

print('kn.score')
print(kn.score(fish_data, fish_target))

#그렇다면 길이가 30, 무게가 600인 놈이 뭔지 예측해봐!(메소드 단어를 그대로 해석하는게 이해와 암기에 좋을것같아서!)

print('길이가 30, 무게가 600인 놈이 뭔지 예측해봐!')
kn.predict([[30, 600]])
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, 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]
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, 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]
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]]
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]
kn.score
1.0
길이가 30, 무게가 600인 놈이 뭔지 예측해봐!
Out[15]:
array([1])

그룹1 그러니까 A종으로 판단했다는 최종 결과를 얻었다.

반응형
반응형

필자는 통계학과 출신이라 R을 많이 공부했었고

 

전직장에서도 통계분석으로 업무를 하곤했는데

(회귀분석까지도 잘 안가고 t검정이나 가중평균 수준이 많긴했다...)

 

졸업후 python도 알려준다고 들어서 개발자가 되고난 뒤 아쉬웠다....

 

생각보다 인강과 책을 많이 사서 실제로 완주한 강의와 책이 많은데 프로젝트가 바쁘다는 핑계로 포스팅이나 깃허브 커밋을 잘 안했던 것 같다... 물론... 이번 프로젝트가 슬슬 끝나가서 적는 것이기도 하다

 

----------------------------------------(잡소리)----------------------------------------

 

아무튼, 사기는 작년 12월에 샀지만 이제야 펼쳐보는 머신러닝 기초 교재에서는 구글에서 제공하는 브라우저에서 python을 작성하는 사이트를 소개한다.

 

https://colab.research.google.com/?hl=ko 

 

Google Colaboratory

 

colab.research.google.com

아주 간편하게 새노트를 추가하는 것만으로 작성하고 바로 돌려볼 수 있다.

필자 처럼 처음 시작하는 사람들에겐 매우 편리한 사이트가 아닐 수 없다.

 

 

파이썬은 print 도 그렇고 전체적으로보면 언어가 R과 상당히 유사하다

사실 R에서는 변수를 선언할떄 a <- 1 이런식으로 한다.

자바를 처음배울때 학원에 같이 다니던 사람들이 a = 1을 받아들이지 못할때 R의 개념을 떠올리며 이해한 적이 있는데 파이썬은 이부분은 R과는 다른 것 같다.

교재에 나온 간단한 예제이다. 배열을 입력하는 방식도 R과 유사하고 plot을 그리는 것, 결과의 모양? 등도 R에서 배운 기초들과 유사하여 익히는데 그리 오래 걸리지 않을 것이라는 확신이 든다.

 

길이와 무게를 나타낸 것이라고 하는데 아마 점이 형성된 군집별로 개체의 종류가 다르게 분류될 수 있다라는 방식의 흐름이 이어질 것으로 예상되는데 과연 예상이 맞을지 책을 더 읽어 봐야겠다.

반응형

+ Recent posts