728x90
반응형

생선 데이터

# 생선 데이터

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]

 

column_stack()

  • 전달받은 리스트를 일렬로 세운 다음 차례대로 나란히 연결한다.
# column_stack() 함수 - 전달받은 리스트를 일렬로 세운 다음 차례대로 나란히 연결한다.
# 2개의 리스트를 나란히 붙이면 연결할 리스트는 파이썬 튜플(tuple)로 전달한다.

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

[그림1] column_statck()  예

 

 

튜플(tuple)

  • 리스트와 매우 비슷
  • 리스트처럼 원소에 순서가 있지만 한 번 만들어진 튜플은 수정할 수 없다.
  • 전달한 값이 변하지 않는다는 것을 믿을 수 있기 때문에 매개변수 값으로 많이 사용한다.

 

# 데이터 합치기

fish_data = np.column_stack((fish_length, fish_weight))

print(fish_data)

[그림2] column_stack() 예시 

 

concatenate()

# np.concatenate()함수 - 첫번째 차원을 따라 배열을 연결

fish_target = np.concatenate((np.ones(35), np.zeros(14)))
print(fish_target)

[그림3] 데이터 확인

 

사이킷런으로 데이터 나누기

# 사이킷런으로 훈련 세트와 테스트 세트 나누기

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) 
# 생선 데이터, 랜덤 시드 지정
# train_test_split 함수는 기본적으로 25%를 테스트 세트로 떼어낸다.
print(train_input.shape, test_input.shape)

[그림4] 사이킷런으로 데이터 나누기

 

# 도미와 빙어 데이터 확인
print(test_target)
  • 원래 두 생선의 비율은 2.5 : 1이지만 현재 3.3 : 1로 샘플링 편향이 나타난다.
  • train_test_split()함수는 이런 문제를 stratify 매개변수에 타깃 데이터를 전달하면 클래스 비유렝 맞게 데이터를 나눈다.
  • 훈련 데이터가 작거나 특정 클래스의 샘플 개수가 적을 때 특히 유용하다.

 

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

print(test_target)

 

[그림5] 데이터 확인

 

k-최근접 이웃 훈련

# k-최근접 이웃 훈련
# 훈련 데이터로 모델 훈련하고 테스트 데이터로 모델을 평가

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

[그림6] 정확도 

 

 

print(kn.predict([[25, 150]])) #  예측 실패

[그림7] 예측 실패

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

[그림8] 

  • KNeighborsClassifier 클래스는 주어진 샘플에서 가장 가까운 이웃을 찾아 주는 kneighbors() 메서드를 제공한다.
  • kneighbors() 메서드는 이웃까지의 거리와 이웃 샘플의 인덱스를 반환한다.

 

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')
plt.xlabel('length')
plt.ylabel('weight')

[그림9] 최근접 5개 

  • marker='D'는 산점도를 마름모로 그린다.
  • 가장 가까운 이웃에 도미가 하나고 나머지 4개는 전부 빙어
  • 시각적으로는 도미가 가장 가까워 보이므로 이웃 거리 출력해 확인해보기
print(distances)

[그림10] 이웃 거리 출력

  • x축과 y축의 비율이 달라 y축은 조금만 멀어져도 거리가 큰 값으로 계산된다.
  • 비율을 맞춰주기 위해 x축의 범위를 0~1,000으로 변경
# x축의 범위 0~1,000으로 변경하기

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)) # x축의 범위 변경
plt.xlabel('length')
plt.ylabel('weight')
plt.show()

[그림11] x축의 범위 변경

  • 스케일(scale)  - 두 특성 (길이와 무게)의 값이 놓인 범위가 다르다. 이를 두 특성의 스케일이 다르다고도 말한다.

데이터 전처리(data preprocessing)

  • 데이터를 표현하는 기준이 다르면 알고리즘이 올바르게 예측할 수 없다.
  • 때문에 특성값을 일정한 기준으로 맞춰야 한다.
  • 이를 데이터 전처리라고 한다.

분산

  • 데이터에서 평균을 뺀 값을 모두 제곱한 다음 평균을 내어 구한다.

 

표준편차

  • 분산의 제곱근으로 데이터가 분산된 정도를 나타낸다.

 

표준점수(standard score)

  • z점수라고도 한다.
  • 각 특성값이 0에서 표준편차의 몇 배만큼 떨어져 있는지를 나타낸다. 
  • 실제 특성값과 크기와 상관없이 동이한 조건으로 비교할 수 있다.

 

표준 점수 계산

# 표준점수 계산

mean = np.mean(train_input, axis = 0) # 평균을 계산
std = np.std(train_input, axis = 0) # 표준편차를 계산
# train_input은 (36, 2) 크기의 배열, 특성마다 값의 스케일이 다르므로 평균과 표준편차는 각 특성별로 계산해야 한다. 이를 위해 axis = 0
# axis = 0 - 각 행을 따라 각 열의 통계 값 계산, axis = 1 - 각 열을 따라 각 행의 통계 값 계산

print(mean, std)

# 표준점수
train_scaled = (train_input - mean) / std
print(train_scaled[:5])

[그림12] 표준 점수 계산

 

전처리 데이터로 모델 계산

# 전처리 데이터로 모델 훈련

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

[그림13] 전처리 데이터로 모델 계산

  • 훈련 세트는 표준점수 계산을 했지만 샘플 하나는 표준 점수 계산을 빼서 값의 범위가 달라졌다.
# 전처리 데이터로 모델 훈련 수정


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

[그림14] 전처리 데이터로 모델 수정

 

다시 모델 훈련

# 모델 훈련 다시

kn.fit(train_scaled, train_target)

test_scaled = (test_input - mean) / std

print(kn.score(test_scaled, test_target))
print(kn.predict([new])) # 예측 성공

[그림15] 다시 모델 훈련

 

kneighbors() 함수 이용

# kneighbors() 함수로 샘플 k-최근접 이웃 구하고 산점도 그리기

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')
plt.xlabel('legnth')
plt.ylabel('weight')
plt.show()

[그림16] kneighbors() 함수 이용

728x90
반응형
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기