본문 바로가기
혼공학습단 머신러닝+딥러닝

[혼공머신] 1주차 -2 머신러닝 성능은 데이터 핸들링 실력에 좌우된다

by 알래스카코코넛 2024. 1. 6.
반응형

Ch.2 데이터 다루기... 

...전에 용어 정리 한번 하고 가겠습니다! 이 용어들은 이번 챕터 뿐만이 아니라, 머신러닝과 딥러닝 전반에 쓰이니 잊으면 상당히 곤란하니 스크린샷 찍던지 어디에 표 그대로 적어두던지 해주세요. 

지도학습 입력(데이터)과 타깃(정답)을 바탕으로 머신러닝을 실행
비지도학습 타깃(정답)이 없음 
강화학습 옳은 결정에는 보상을, 틀린 결정에는 패널티를 부여하여 학습 실행
특성(feature) 입력 데이터로 사용된 특성. 예) Ch.1에서 사용된 무게와 길이 데이터
타깃 데이터(target) 지도 학습에서 쓰이는 정답 데이터. 예) Ch.1에서 도미(1)인지 빙어(0)인지 
훈련 데이터(training data) 입력(특성) + 타깃 데이터 
샘플 데이터 하나. 예를 들어 데이터가 49개 있다 = 샘플의 수는 49개다 

 

저거 다 암기하셨으면 진짜 Ch.2 데이터 다루기


2-1. 훈련 세트와 데이터 세트 

Ch.1에서 작성했던 k-최근접이웃 공장 만드는 코드

from sklearn.neighbors import KNeighborsClassifier  #우리 k-최근접 이웃 사용함!!

kn = KNeighborsClassifier()   #k-최근접 이웃을 사용할 공장 생성 
kn.fit(fish_data, fish_target)   #공장 가동

kn.score(fish_data, fish_target) #성과 출력

1.0

 

여기서 kn.score(fish_data, fish_target)의 결과가 1.0이라는 뜻은 모든 데이터의 분류가 정확했다는 의미입니다. 즉, 모든 도미를 도미로, 빙어를 빙어로 분류했습니다. 그런데 코드를 보면, kn.fit()안의 데이터랑 kn.score()의 데이터가 fish_data, fish_target으로 같습니다. 이러면 훈련한 데이터를 그대로 평가하니까 사실상 당연히 성능이 1.0이 됩니다. 족보 문제를 주고 그대로 공부시켜서(fit) 족보 문제를 숫자 하나 안 바꾸고 출제하면 점수(score)가 100점이 나오는 건 자명하죠? 따라서 공부를 위한 데이터와 시험 문제는 반드시 달라야 정상적으로 출제되었다고 할 수 있습니다. 그대로 쓰면 학부생들이 돌 던져요 교수님들...흠흠

 

 그럼 족보도 줘야 하는데 시험 문제도 출제해야 해! 그런데 달리 문제 만들 시간은 없어! 이러면 어떻게 하는게 좋을까요? 공부할 자료와 출제할 자료를 나누어서 공부할 자료만 오픈하면 됩니다. 그리고 시험은 출제할 자료에서 내면 되죠. 머신러닝도 마찬가지로, 훈련에 사용할 데이터랑 테스트에 사용할 데이터를 나누면 성능 측정을 정확하게 할 수 있습니다. 이렇게 평가에 사용되는 데이터를 앞으로 테스트 세트, 훈련에 사용하는 데이터를 훈련 세트라고 합니다. 

훈련 세트 머신러닝 훈련(fit())에 사용되는 데이터 
테스트 세트  머신러닝 성능을 도출(score())하기 위해 사용하는 데이터 

 

그럼 데이터를 훈련 세트와 테스트 세트로 어떻게 나눌까요? 여기서 주의할 점은, 데이터를 훈련 세트: 도미/ 테스트 세트:빙어 처럼 나누면 큰일난다는 점입니다. 뭐가 문제인지 잘 모르겠다고요? 더 쉽게 설명하자면, 족보는 1단원 ~ 3단원 범위만큼 제공했는데 시험 문제를 4단원 ~ 6단원에서만 출제하면 이제 진짜로 학부생들이 돌을 들고 교수님의 연구실을 방문하겠죠. 이처럼 한쪽 샘플로 치우쳐서 데이터가 마련되는 것을 샘플링 편향이라고 부릅니다. 

 

그러니까 1단원에서 전체의 10%, 2단원에서 20%.... 6단원에서 15% 처럼 단원별로 골고루 출제해야 교수님의 목을 지킬 수 있습니다. 그러면 이제 또 의문이 생겼네요. 어떻게 적당히 데이터를 나누죠?

 

 시험 문제라면 대학원생 TA에게 맡기면 됩니다. 코딩에서는 대학원생이 없는데 어떻게 할까요? 머신러닝에서 '이걸 어떻게 구현하지?'의 정답은 크게 3가지입니다.

  1. 뛰어난 구글링과 코딩 실력으로 직접 구현한다
  2. ChatGPT에게 물어본다 <<new!
  3. sklearn에 있는지 찾아본다.

sklean은 머신러닝에서 전지전능한 존재라고 해도 과언이 아닙니다. 사실상 머신러닝과 데이터사이언스의 교수님이자 대학원생이자 TA니 모두 빨리 친해지도록 합시다. 

sklearn은 신이야!

 

자연스럽게 2-2. 데이터 전처리

sklearn의 train_test_split()함수는 훈련 세트와 테스트 세트를 골고루 잘 섞어서 분류까지 해줍니다. 물론 섞고 분로하는건 코딩을 통해서 해달라고 시켜야 해요.

from sklearn.model_selction import train_test_split

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

 

아니 선생님 코드에 t가 너무 많아요 train_input/ test_input/ train_target/ test_traget 차이가 뭔가요? 이걸 헷갈리면 머신러닝을 배우는 데 상당히 고달파질 수 있으니 아래 표로 잘 정리해둡시다. 오늘따라 표가 참 많네요. 이게 다 공짜 비행기표였으면 좋겠다...

train_input 훈련(train, 코드에서는 fit() 함수 안에 들어감)을 위해 입력하는 값. 빙어 vs 도미에서는 입력되는 weight와 length에 해당됨
test_input 성능이 어떤지 검사할 때 사용하는 특성값. score() 함수 안에 들어간다. 
train_target 훈련에 사용되는 타깃값. 빙어 vs 도미에서는 얘가 빙어인지(0), 도미인지(1) 나타낸다. 
test_target 성능 검사에 사용되는 타깃값

 

 슬슬 개념이 많이 등장해서 부담스럽기는 합니다. 그래서 머리도 식힐 겸 살짝 다른 얘기를 해보자면, 요즘 중학생들도 인공지능을 정식 교과목으로 배우고 있다는 점을 알고 계신가요? 컴퓨터교육과 전공생으로서 정보 교과의 변화를 열심히 보고 있는데, 요즘 정보 수업이 필수 과목으로 지정되고 내용이 점점 전문적으로 넘어가서 정보과 교사 TO도 늘어나고 있답니다. 만세~~~

https://www.gne.go.kr/upload_data/board_data/workroom/161467028247348.pdf 여기 보시면 고등학생 때 기계학습 모델을 구현한다네요... 후덜덜해라 저는 print("Hello, World!")를 대학교 들어오고 처음 배웠는데 열심히 안하면 고등학생들한테 명색이 전공자인데 질 듯

 

 밥줄의 위기감을 느끼고 다시 열심히 작성해보겠습니다. 

Ch.1에서 봤던 도미 & 빙어들을 다시 들고 와서, 산점도 그래프를 봅시다.친절한 주인장은 기억이 안 나시는 분들을 위해서 Ch.1 링크를 가져왔어요.

https://alasco-footprint.tistory.com/15

도미 & 빙어 산점도 그래프

Ch.1에서는 길이가 30cm, 무게가 600g인 생선을

kn.predict([[30, 600]])  #predict로 어느 소속인지

 

이 코드로 예측했습니다. 이번에는 길이가 25cm, 무게가 150cm인 다른 생선을 분류해봅시다. 역시나 kn.predict()를 사용하면 되겠네요.

kn.predict([[15, 150]])  #predict로 어느 소속인지

[0.]

 

앞서 우리는 1이 도미, 0이 빙어라고 했으니 머신러닝의 결과대로면 길이가 25cm, 무게가 150g인 생선은 빙어입니다. 그런데 이게 진짜일까요? 산점도로 생선의 위치를 찍어보겠습니다. 

주황색 세모가 정체를 알고자 하는 생선인데, 빙어 그룹보다 도미 그룹에 가까워 보임에도 불구하고 알고리즘은 빙어로 예측했네요. 왜 이런 현상이 발생했을까요? 코드를 통해, k-최근접 이웃의 그 '최근접 이웃'이 누구인지 알아봅시다. 

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

 초록색이 가까운 이웃 5개입니다. 이제 뭐가 잘못된지 알겠네요. 주황색 세모 생선이랑 가까운 5개의 이웃 중 4개가 빙어, 하나만 도미라서 이 생선을 빙어로 예측했습니다. 그런데 육안으로 보기에는 빙어 데이터보다 도미 데이터들에게 더 가까운데, 실제 거리는 아닌가봐요. 실제 거리를 코드를 통해 알아봅시다. 

print(distances)
 
 [[ 92.00086956 130.48375378 130.73859415 138.32150953 138.39320793]]
 

점과 점 사이의 실제 거리를 알아보니 뭔가 이상하네요. 가장 가까운 점과의 거리는 92인데, 두 번째로 가까운 점까지의 거리는 130? 이러면 그림의 배율이 확실히 잘 안맞다는 점을 알 수 있습니다.

배율이 130:92가 아닌 것 같은데 코드는 그렇다네요. 바꿔봅시다

 

지금 산점도의 문제는 length의 눈금은 5단위인데, weight의 단위는 200이라 y축이 조금만 커져도 거리가 크게 바뀐다는 점입니다. 따라서 축의 배율을 일정한 기준으로 맞춰주는 작업이 필요한데, 이를 데이터 전처리라고 부릅니다. 데이터 전처리에는 여러가지 방법이 사용되는데, 그 중 하나는 표준점수(z-score이라고도 합니다)를 사용합니다. 아마 고등학교 확률과 통계 시간에 졸지 않으셨다면 표준점수가 뭔지 어느 정도 알고 계실 거에요. 하지만 역시 친절한 주인장은 표준점수가 무엇인지 여러분께 코딩해드립니다.

 

 표준점수는 어떤 값이 평균에서 표준편차의 몇 배만큼 떨어져 있는지를 나타내는 값입니다. 이번 챕터에서는 일단 코드로 해보고, 사실 이후 챕터에서는 우리들의 만능친구 머신러닝의 희망! sklearn에서 제공하는 데이터 전처리 함수를 사용합니다.

mean = np.mean(train_input, axis=0)  #평균 mean
std = np.std(train_input, axis=0)  #표준편차 std

print(mean, std)
#결과: [ 27.29722222 454.09722222] [  9.98244253 323.29893931]

train_scaled = (train_input - mean) / std

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

print(kn.predict([new]))  #다시 생선 정체 알아내기

[1.]

이제 결과가 예쁘게 나왔습니다! 성공적으로 도미로 예측했고, 가장 가까운 이웃 5개도 잘 뽑아냈어요. 이런 식으로, 데이터를 냅다 넣으면 축의 배율이 이상하므로 적절한 데이터 전처리는 필수입니다. AI를 공부하려면 적절한 데이터사이언스 지식이 필요한 이유가 여기에 있네요. 반대로, 이게 데이터사이언스 전공인 제가 AI도 공부하는 이유입니다. 머신러닝과 데이터는 깊게 얽혀있는 관계거든요. 공부할게 배는 늘어쒀...


이제 마지막으로 1주차 기본미션 & 선택 미션입니다. 

 

먼저 어디보자 1주차 기본미션은 코랩 실습 화면 캡처네용

 

이걸 올리면 끝인가...? 생각보다 간단하게 끝났으니 다른 프로젝트 코랩에서 실습한것도 스크린샷 올립니당

전공 수업 프로젝트 실습했던 코드

 

 위에 코드는 저번 학기 전공 수업 기말 프로젝트로 웹 크롤링을 했던 코드 일부 캡쳐본입니다. 궁금하시면 여기 프로젝트 내용 있으니 한 번 읽어보세요 (겸사겸사 조회수도 좀 높이고...)

 

https://alasco-footprint.tistory.com/10

 

NLP 기반 야구경기 기록과 선수 네트워크 분석 - 소개ppt

2023년 2학기 자연어처리 수업 기말최종과제로 제출했던 프로젝트다. 계획을 발표하는 단계에서 제출한 ppt라 최종과제랑 조금 다른 부분도 있고, 2분 내외로 발표해야 했어서 거의 래퍼 빙의해서

alasco-footprint.tistory.com

https://alasco-footprint.tistory.com/11

 

NLP 기반 야구경기 기록과 선수 네트워크 분석 - 최종보고서

전 게시글에 소개했던 NLP 기반..어쩌구의 최종 보고서다. 분량 조건은 5페이지(목차, 제목, 참고문헌 제외)였는데 시험기간에 공부 빼고 다 재미있어서 보고서 쓰는 것도 재밌더라. 약간 분량 엄

alasco-footprint.tistory.com

 

다음은 선택 미션... 사진 올리고 싶었는데 지금 핸드폰 카메라가 좀 이상하네요 일일이 타이핑 하는 중 

 

1. 머신러닝 알고리즘의 한 종류로서 샘플의 입력과 타깃(정답)을 알고 있을 때 사용할 수 있는 학습 방법은?

머신러닝 알고리즘은 크게 지도 학습/ 비지도 학습/ 강화 학습으로 나누어지고  그 중 타깃(정답)이 있는 방법은 지도 학습입니다. 비지도 학습은 정답이 없고, 강화 학습은 행동에 따른 상벌으로 머신러닝을 진행합니다.

 

2. 훈련 세트와 테스트 세트가 잘못 만들어져 전체 데이터를 대표하지 못하는 현상은? 

샘플링이 한 쪽으로 치우친 현상으로, 샘플링 편향이라고 합니다.

 

3. 사이킷런은 입력 데이터(배열)가 어떻게 구성되어 있을 것으로 기대하나요?

행은 샘플, 열은 특성으로 구성합니다.. 

 

이상 1주차 끝!

반응형