ML 세션 - Week2.데이터 다루기

» AI

훈련세트와 테스트세트

  • 훈련데이터: (데이터=입력)과 (정답=타깃)
  • 지도학습: 훈련데이터와 정답 필요
    • 알고리즘이 정답을 맞히는 것을 학습
  • 비지도학습: 정답 없음
    • 정답을 맞추는 게 아니라 데이터를 파악하거나 변형하는 데 사용
  • 훈련세트(train set): 훈련에 사용되는 데이터
    • 클수록 좋음
  • 테스트세트(test set): 평가에 사용되는 데이터
    • 데이터 중 일부를 떼어내어 테스트세트로 활용
train_input = fish_data[:35]
train_target = fish_target[:35]

test_input = fish_data[35:]
test_target = fish_target[35:]
#슬라이싱으로 데이터에서 훈련세트와 테스트세트 나누기
  • 샘플링 편향을 방지해야함
import numpy as np #배열 라이브러리
input_arr = np.array(fish_data)
target_arr = np.array(fish_target)
# array() 함수로 리스트 넘파이 배열로 변환

np.random.seed(42)
index = np.arange(49) #데이터랑 정답 같이 이동하도록
np.random.shuffle(index) #shuffle()로 무작위로 섞기
    
train_input = input_arr[index[:35]]
train_target = target_arr[index[:35]]

train_input = input_arr[index[:35]]
train_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()
    
  • alt text
    kn=kn.fit(train_input, train_target) #학습
    kn.score(test_input, test_target) #테스트
    

데이터 전처리

fish_data = np.column_stack((fish_length, fish_weight))
# column_stack() 함수로 리스트 일렬로 세우고 연결
fish_target = np.concatenate((np.ones(35), np.zeros(14))) # 타깃 데이터 만들기
  • alt text
    from sklearn.model_selection import train_test_split #훈련세트와 테스트세트 랜덤하게 섞은 후 비율 따라 나눠주는 기능
    train_input, test_input, train_target, test_target = train_test_split(
      fish_data, fish_target, stratify=fish_target, random_state=42)
    #stratify에 타깃 데이터 넘겨주면 클래스 비율에 맞게 나눠줌
    

수상한 도미 한 마리

  • 문제: 새로운 샘플이 산점도로 보면 도미데이터에 가깝지만 빙어데이터로 판단나옴
    import matplotlib.pyplot as plt
    plt.scatter(train_input[:,0], train_input[:,1])
    plt.scatter(25, 150, marker='^') #새로운 샘플 삼각형 표시
    plt.xlabel('length')
    plt.ylabel('weight')
    plt.show()
    
  • alt text
    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')
    plt.show()
    
  • alt text
  • 산점도 상에선 빙어가 멀어보이지만 최근접 이웃에 속하는 문제
  • print(distances)를 통해 보면 x축, y축의 범위(스케일)가 달라 알고리즘이 올바르게 예측하질 못함
  • alt text
  • 스케일을 맞추는 데이터 전처리 필요
    • 표준점수(z점수)
      • 각 특성값이 0에서 표준편차의 몇 배만큼 떨어져 있는지
      • 평균을 빼고 표준편차로 나누기
          mean = np.mean(train_input, axis=0) #np.mean(): 평균 계산
          std = np.std(train_input, axis=0) #np.std(): 표준편차 계산, axis=0: 평균과 표준편차는 각 특성별로 계산해야 하기 때문
          train_scaled = (train_input - mean) / std #넘파이 브로드캐스팅 적용
        
      • alt text
  • 구현
    new = ([25, 150] - mean) / std #샘플데이터도 변환
    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('length')
    plt.ylabel('weight')
    plt.show()
    
  • alt text
  • x축 y축의 범위가 바뀌었고 최근접 이웃도 달라짐