​『핸즈온 머신러닝』 맛보기

Page 1

아마존 인공지능 분야 부동의 1위 도서

사이킷런과 텐서플로를 활용한 머신러닝, 딥러닝 실무

H a n d s- O n M a ch in e Le a r n in g w i t h S cik i t- Le a r n a n d Te n s o r Fl ow

래머도 데이터로부터 학습하는 프로그램을 어렵지 않게 작성할 수 있다. 이 책은 그 지름길이다. 구체적인 예, 핵심 이론, 검증된 두 프레임워크(사이킷런, 텐서플로)를 이용해 지능형 시스템을 구축하는 개념과 방법을 확 실하게 알려준다. 또한, 각 장의 연습문제는 익힌 것을 실전에 응용하는 데 큰 도움이 될 것이다.

핸즈온 머신러닝

1부. 사이킷런을 활용한 머신러닝 실무

2부. 텐서플로를 활용한 딥러닝 실무

•한눈에 보는 머신러닝

•텐서플로 시작하기

•머신러닝 프로젝트 처음부터 끝까지

•인공 신경망 소개

•분류

•심층 신경망 훈련

•모델 훈련

•다중 머신과 장치를 위한 분산 텐서플로

•서포트 벡터 머신(SVM)

•합성곱 신경망(CNN)

•결정 트리

•순환 신경망(RNN)

•앙상블 학습과 랜덤 포레스트

•오토인코더(autoencoder)

•차원 축소

•강화 학습

Hands-On Machine Learning with Scikit-Learn & TensorFlow

최근의 눈부신 혁신들로 딥러닝은 머신러닝 분야 전체를 뒤흔들고 있다. 이제 이 기술을 거의 모르는 프로그

Hands-On Machine Learning with Scikit-Learn & TensorFlow 핸즈온 머신러닝

신경망으로 문제를 해결하는 이론과 실전을 멋지게 소개한 책이다. 효율적인 애플리케이션을 구축하 는 핵심을 잘 짚어냈고, 하루가 다르게 쏟아지는 새로운 관련 연구를 이해할 수 있는 기초를 확실히 닦아준다. 실용적인 머신러닝을 공부하려는 모든 이에게 이 책을 추천한다. 피트 워든, 텐서플로 모바일 리드

박해선 옮김

파이썬 라이브러리를 활용한 머신러닝

골빈해커의 3분 딥러닝, 텐서플로맛

오렐리앙 제롱 지음

관련 도서

처음 배우는 딥러닝 수학 머신러닝 / 딥러닝

93000

예제 소스 https://github.com/rickiepark/handson-ml

9 791162 240731

ISBN 979-11-6224-073-1

정가 33,000원

오렐리앙 제롱 지음 박해선 옮김


| 표지 설명 | 표지 그림은 중동 지역에서 서식하는 양서류인 극동 불도롱뇽 (학명:

Salamandra infraimmaculata )입니다. 피부가 검으며 등과 머리에 커 다란 노란 점이 있는 것이 특징입니다. 노란색은 포식자를 막기 위한 경계색입니 다. 다 자란 도롱뇽은 30cm가 넘기도 합니다. 불도롱뇽은 아열대 관목지와 강 또는 다른 민물 근처의 숲에 삽니다. 대부분 육 지에서 활동하지만 알은 물속에 낳습니다. 주로 곤충, 벌레나 작은 갑각류를 먹고 살고 때로는 다른 도롱뇽을 잡아먹습니다. 수컷은 23살까지 살고 암컷은 21살까지 살 수 있습니다. 아직 멸종 위기에 처하지는 않았지만 불도롱뇽의 개체 수는 감소하고 있습니다. 주요 원인은 (도롱뇽의 번식을 방해하는) 하천의 댐과 환경오염입니다. 또한 최근에는 모기고기(mosquitofish ) 같은 육식성 어류의 등장으로 위협받고 있습니다. 이 물고기는 모기 개체 수를 조절하는 역할을 하지만 어린 도롱뇽도 잡아먹습니다. 오라일리 표지의 동물들은 대부분 멸종위기종입니다. 이 동물들은 모두 우리에게 중요합니다. 이들을 돕고 싶다면

animals.oreilly.com을 방문해주세요. 표지 그림은 우드(Wood )의 『Illustrated Natural History』에서 가져왔습니다.

핸즈온 머신러닝 사이킷런과 텐서플로를 활용한 머신러닝, 딥러닝 실무 초판 1쇄 발행 2018년 4월 27일 지은이 오렐리앙 제롱 / 옮긴이 박해선 / 펴낸이 김태헌 펴낸곳 한빛미디어 (주) / 주소 서울시 서대문구 연희로2길 62 한빛미디어(주) IT출판부 전화 02 – 325 – 5544 / 팩스 02 – 336 – 7124 등록 1999년 6월 24일 제10 – 1779호 / ISBN 979 – 11 – 6224 – 073 – 1 93000 총괄 전태호 / 책임편집 김창수 / 기획 이복연 / 교정 김철수 디자인 표지 신종식 내지 김연정 조판 김철수 영업 김형진, 김진불, 조유미 / 마케팅 박상용, 송경석, 변지영 / 제작 박성우, 김정우 이 책에 대한 의견이나 오탈자 및 잘못된 내용에 대한 수정 정보는 한빛미디어(주)의 홈페이지나 아래 이메일로 알려주십시오. 잘못된 책은 구입하신 서점에서 교환해드립니다. 책값은 뒤표지에 표시되어 있습니다. 한빛미디어 홈페이지 www.hanbit.co.kr / 이메일 ask@hanbit.co.kr © 2018 Hanbit Media Inc.

Authorized Korean translation of the English edition of Hands - On Machine Learning with ScikitLearn and TensorFlow, ISBN 9781491962299 © 2017 Aurélien Géron This translation is published and sold by permission of O’Reilly Media, Inc., which owns or controls all rights to publish and sell the same. 이 책의 저작권은 오라일리와 한빛미디어 (주)에 있습니다. 저작권법에 의해 보호를 받는 저작물이므로 무단전재와 복제를 금합니다.

지금 하지 않으면 할 수 없는 일이 있습니다. 책으로 펴내고 싶은 아이디어나 원고를 메일 ( writer@hanbit.co.kr ) 로 보내주세요. 한빛미디어(주)는 여러분의 소중한 경험과 지식을 기다리고 있습니다.


Hands-On Machine Learning with Scikit-Learn & TensorFlow 핸즈온 머신러닝


지은이·옮긴이 소개

지은이

오렐리앙 제롱 Aurélien Géron

머신러닝 컨설턴트입니다. 2013년에서 2016년까지 구글에서 유튜브 동영상 분류 팀을 이 끌었습니다. 2002년에서 2012년까지 프랑스의 모바일 ISP 선두 주자인 Wifirst를 설립하고

CTO로 일했습니다. 2001년에는 Polyconseil을 설립하고 CTO로 일했습니다. 이 회사는 지 금 전기차 공유 서비스인 Autolib’을 운영하고 있습니다. 그전에는 재무( JP 모건과 소시에테 제네랄 Société Générale ), 방위(캐나다 DOD ), 의료(수혈) 등 다양한 분야에서 엔지니어로 일했습니다. C++, WiFi, 인터넷 구조에 대한 몇 권의 기술서 적을 썼으며 한 프랑스 공과대학교에서 컴퓨터 과학을 가르쳤습니다. 재미있는 몇 가지 사실: 세 아이에게 손가락으로 이진수 세는 법을 가르쳤습니다(1023까지). 소프트웨어 공학 분야에 들어오기 전에는 미생물학과 진화 유전학을 공부했습니다. 두 번째 점 프에서 낙하산이 펼쳐지지 않았습니다.

옮긴이

박해선 haesunrpark@gmail.com

기계공학을 전공했지만 졸업 후엔 대부분 코드를 읽고 쓰는 일을 했습니다. 텐서≈블로그 ( tensorflow.blog )와 홍대 머신러닝 스터디( meetup.com/Hongdae-Machine-LearningStudy/ )를 운영하면서 소프트웨어와 과학의 경계를 흥미롭게 탐험하고 있습니다.

『파이썬 라이브러리를 활용한 머신러닝』(한빛미디어, 2017 )과 『텐서플로 첫걸음』(한빛미디 어, 2016 )을 우리말로 옮겼습니다.

4


추천의 글

이 책이 한국에도 출간된다는 소식을 듣고 매우 매우 기대하고 있던 차에 마침 역자이신 박해 선 님과 인연이 닿아서 추천사까지 쓰게 된 점을 무한한 영광으로 생각합니다. 기하급수적으 로 다양하고 많은 데이터가 쌓이고 기술의 발전으로 데이터 저장 비용과 연산 비용이 지속해서 낮아지면서 자연스럽게 다시 주목받게 된 머신러닝 기술은 개발자라면 누구나 알아야 하는 교 양필수가 되고 있습니다. 특히 알파고 매치가 보여준 놀라운 결과는 한국 개발자들에게 엄청난 자극과 흥미를 유발하여 업계에 새로운 활력을 불어넣었음을 나날이 체감하고 있습니다. 그러한 가운데 이 책의 출간은 그동안 머신러닝을 공부해볼까 생각하던 분들뿐 아니라 이미 공 부한 분들에게도 아주 큰 도움이 되리라 확신합니다. 머신러닝을 공부하다 보면 여러 가지 새 로운 개념과 용어를 습득하고 그 개념/용어 사이의 관계를 이해하고 정리하는 일이 정말 어렵 습니다. 이 책은 머신러닝의 전반적인 이해를 도와주는 내용으로 시작해서 중요한 여러 개념과 이론을 쉽게 이해시켜 주고, 많이 쓰이는 딥러닝 알고리즘까지 아주 잘 설명했습니다. 또한 개 념과 이론 습득에 그치지 않고 직접 실습해볼 수 있는 방법까지 제공하여 독자의 이해를 더욱 효 과적으로 돕고 있습니다. 특히 머신러닝을 처음 접하는 경우 인터넷의 수많은 강좌와 자료에 압 도되기 쉬운데, 이렇게 일목요연하게 정리된 책 한 권이 주는 가치와 효용은 매우 클 것입니다. 부디 이 책을 통해 더욱 많은 분이 머신러닝이라는 이 중요한 기술을 잘 습득하여 더 나은 개발 자로 거듭나기를 진심으로 기원합니다! _권순선, Head of CJK/ANZ Developer Ecosystem, 구글

5


몇 년 전부터 머신러닝과 딥러닝이 학계는 물론 업계에서도 많은 화제가 되면서 각종 강의와 책 이 쏟아져 나왔습니다. 그런데 책 대부분은 비전공자를 위한 입문서이거나 특정 패키지(혹은 오 픈소스)를 설명하는 데 치중하여 실전에서 쓰기에는 부족했습니다. 그래서 우리 개발자들은 실 전에 쓸 수 있는 수준의, 저자의 경험이 녹아있는 책을 원해왔습니다. 작년에 이러한 갈증을 메워줄 이 책의 원서가 출간되었을 때 커뮤니티와 스터디 그룹에서 많은 관심을 보였고, 저 또한 많은 도움을 받았습니다. 거의 600쪽에 달하는 이 원서는 예제 코드만 많이 나열하거나 이론만을 길게 설명하기보다는, 여러 상황에서 해당 알고리즘을 써야 하는 이 유와 저자의 경험을 녹인 코드와 설명으로 실전에서 통하는 내용을 담았습니다. 또한 모든 코 드를 주피터 노트북에서 바로 실행해볼 수 있도록 깃허브에 공개했습니다. 이 코드는 굉장히 깔끔하고 이해하기 쉬우며 실전에 도움 되는 정말 Hands-On 자료입니다. 번역서의 번역 품질도 굉장히 높습니다. 저자의 의도가 그대로 전달되면서도 설명을 최대한 쉽 게 풀어냈습니다. 특히 독자가 이해하기 어려울 만한 부분을 풍부한 옮긴이의 주석이 세심히 메 워주며, 도움 될 만한 최신 정보까지 꼼꼼히 알려줍니다. 그래서인지 단순한 1:1 번역이 아니 라, 책을 완전히 이해한 다음 새롭게 한글책으로 다시 태어났다는 느낌을 받았습니다. 이 책은 빠르게 읽고 소비하는 일회성 책이 아닙니다. 항상 옆에 두고 시간을 더 투자하여 곱씹 어 이해하고 공개된 코드를 같이 실습한다면 다른 책에서 얻지 못하는 깊은 지식과 경험을 얻을 수 있습니다. 이 책이 여러분의 업무 전환이나 실무에 많은 도움이 되었으면 합니다. _이상훈, 삼성생명 DA Lab, 케라스 코리아, 스파크 사용자 모임 운영자

6


인공지능은 어느덧 우리 삶에 들어와 매우 중요한 위치를 차지하였고, 심지어 이제는 어색하지 도 않습니다. 알파고가 세상에 선보인 지 올해로 2년, 우리나라도 유수의 스타트업과 대기업이

AI에 투자하고 있으며 1분 1초가 다르게 새로운 AI 기술에 관한 뉴스가 쏟아지고 있습니다. AI 열풍과 더불어 관련 서적이 수없이 출간됐습니다. 하지만 이 책처럼 이론과 활용이 유기적 으로 연결되는 책은 거의 없습니다. 이 책은 머신러닝 이론은 빠삭하게 공부한 것 같은데 어떻게 구현할지 막막한 순간, 텐서플로 코딩을 하다가 ‘이 코드가 왜 이렇게 흘러가는 거지?’ 하는 의문이 들 때 길을 밝혀줄, 마치 정 석처럼 책꽂이에 한 권씩은 꼭 꽂혀 있어야 하는 책이라고 생각합니다. 이제 막 머신러닝의 드 넓은 바다로 항해를 시작하신 여러분에게 이 책은 정말 견고한 나침반이 되어줄 것입니다. _이준우, MindsLab Brain팀

7


옮긴이의 말

한 가지 일에 오래 집중하다 보면 멈춰진 시간 속에 들어가 있는 듯한 기분이 듭니다. 유난히 추웠던 겨울이라 더 그랬던 것 같습니다. 재미있게 읽을 수 있는 책을 만들려고 노력했지만 아 쉬움이 많이 남습니다. 부족한 부분은 독자들이 채워주시리라 믿습니다. 에러타마다 친절한 답변을 많이 보내준 저자 오렐리앙에게 고맙다는 말을 전합니다. 귀중한 시 간을 내어 책을 읽고 추천의 글을 써주신 권순선 님, 이상훈 님, 이준우 님께 진심으로 감사의 말씀을 드립니다. 이따금 블로그나 이메일로 격려의 말을 전해주신 모든 분께도 감사드립니다. 좋은 책을 믿고 맡겨주신 한빛미디어 출판사와 꼼꼼하게 모든 일을 챙겨주신 이복연 님, 둔탁 한 글을 매끈하게 다듬어주신 김철수 님께 감사드립니다. 매번 염치없는 부탁을 흔쾌히 받아주 시고 작업 공간을 내어주신 니트머스 김용재 대표님께 감사드립니다. 언제나 명랑한 우리 가족 (주연이와 진우)의 배려가 없었다면 정말로 이 책을 끝내기 힘들었을 것입니다. 감사하고 사 랑합니다. 사이킷런과 텐서플로의 새로운 버전에 맞춘 코드와 정오표를 깃허브와 블로그에 꾸준히 반영 하겠습니다. 이 책에 관한 이야기라면 무엇이라도 환영입니다. 언제든지 이메일이나 블로그로 연락해주세요.

2018년 4월 박해선

8


이 책에 대하여

머신러닝 쓰나미 2006년 제프리 힌튼 Geoffrey Hinton 등은 최고 수준의 정확도(> 98%)로 손글씨 숫자를 인식할 수 있는 심층 신경망 훈련 기법에 관한 논문 1을 발표했습니다. 이 기법을 딥러닝 Deep Learning 이라고 불렀습니다. 그때까지는 심층 신경망을 훈련시키는 것이 불가능하다고 생각했고 2 대부분의 연 구자는 1990년대부터 심층 신경망을 연구하지 않았습니다. 이 논문은 과학계의 관심을 다시 불 러일으켰고 오래지 않아 많은 논문이 딥러닝이 가능하다는 사실뿐 아니라 (높은 컴퓨팅 성능과 많은 양의 데이터에 힘입어) 다른 머신러닝 기법과 비교할 수 없는 엄청난 성능을 낸다는 것을 보여주었습니다. 이런 열기는 다른 머신러닝 분야에도 곧바로 확산되었습니다.

10년이 지난 지금 머신러닝 Machine Learning 은 산업계를 정복했습니다. 오늘날 첨단 기술의 상품, 웹 검색 결과의 순위, 스마트폰 음성 인식, 비디오 추천, 바둑 세계챔피언과의 대결 등 마술 같 은 일들의 중심에 서 있습니다. 머지않아 여러분 차는 머신러닝이 운전할 것입니다.

나만의 머신러닝 프로젝트 따라서 머신러닝에 흥미를 갖고 이를 배우고 싶어 하는 것은 당연합니다! 지능을 갖춘 로봇을 직접 만들고 싶나요? 얼굴을 인식하게 하거나 걸어서 돌아다니게 만들고 싶나요? 여러분 회사가 엄청난 양의 데이터(사용자 로그, 금융 데이터, 생산 데이터, 센서 데이터, 상담 통계, 인사 기록 등)를 가지고 있고 무엇을 할지 알고 있다면 다음과 같은 숨겨진 보석을 캐낼 수 있을 것입니다. 고객을 나누고 각 그룹에 맞는 최선의 마케팅 전략 찾기

1 힌튼의 홈페이지에서 볼 수 있습니다. http://www.cs.toronto.edu/~hinton/ 옮긴이_ Hinton, G. E ., Osindero, S., Teh, Y.의 「A fast learning algorithm for deep belief nets」(2006, https://goo.gl/aoYtUK )를 말합니다. 2 얀 르쿤(Yann Lecun )의 심층 합성곱 신경망이 1990년대 이후에 이미지 인식 문제에서 잘 작동했음에도 불구하고 범용적인 도구는 아 니었습니다.

9


비슷한 고객의 구매 이력을 기반으로 상품 추천하기

부정 거래 감지하기

내년도 매출 예측하기

그 외(https ://www.kaggle.com/wiki/DataScienceUseCases )

이유가 무엇이든 머신러닝을 배우고 프로젝트에 도입하기로 결정했다면 아주 좋은 생각입니다!

목표와 방법 이 책은 여러분이 머신러닝에 관해 아는 것이 거의 없다고 가정합니다. 이 책의 목표는 데이터 로부터 학습할 수 있는 프로그램을 실제 구현하기 위해 필요한 개념과 직관, 도구를 설명하는 것입니다. (선형 회귀와 같이) 간단하고 아주 널리 사용되는 것부터 경연 대회에서 자주 우승을 차지하는 딥러닝 기법까지 많은 종류의 기술을 다룹니다. 머신러닝 알고리즘의 간단한 버전을 직접 구현하는 대신 실제 제품을 만드는 데 쓰는 파이썬 프레임워크를 사용할 것입니다. 사이킷런 Scikit-Learn (http ://scikit -learn.org/)은 매우 사용하기 쉽고 많은 머신러닝 알고리즘이 효율

적으로 구현되어 있으므로 머신러닝을 처음 배울 때 사용하기 아주 좋습니다. 텐서플로 TensorFlow (http ://tensorflow.org/)는 분산 수치 계산을 위해 데이터 플로 그래프 data flow graph

를 사용하는 탁월한 라이브러리입니다. 수천 대의 다중 GPU 서버에 계산을 분산하여 대규모 신경망을 효과 적으로 훈련하고 실행시킬 수 있습니다. 구글에서 만들었고 구글의 대규모 머신러닝 애플리케이션에서 사용 하고 있습니다. 2015년 11월에 오픈소스로 공개되었습니다.

이 책은 실제 활용할 수 있는 방법을 사용합니다. 구체적인 작동 예제와 약간의 이론을 통해 머 신러닝을 직관적으로 이해하도록 돕습니다. 이 책은 노트북 컴퓨터 없이 그냥 읽을 수 있지만 https://github.com/rickiepark/handson-ml/에 주피터 노트북으로 공개되어 있는 코드 예

제를 직접 실험해보는 것이 좋습니다.

10


필요한 기술 이 책은 여러분이 파이썬 프로그래밍 경험이 있고 특히 넘파이 NumPy (http://numpy.org/ ), 판 다스 Pandas (http://pandas.pydata.org/ ), 맷플롯립 Matplotlib (http://matplotlib.org/ ) 같은 파이썬의 주요 과학 라이브러리와 친숙하다고 가정합니다. 이론적 배경을 이해하려면 미적분, 선형대수, 확률, 통계 등 대학 수준의 수학 지식도 필요합 니다. 아직 파이썬을 모른다면 http://learnpython.org/가 시작하기 좋은 곳입니다. python.org 의 공식 튜토리얼(https://docs.python.org/3/tutorial/ )도 매우 훌륭합니다. 주피터 Jupyter 를 사용해본 적이 없다면 2장에서 설치와 기본적인 내용을 배울 수 있습니다. 주 피터는 여러분 도구상자에 있어야 할 아주 유용한 도구입니다. 파이썬의 과학 라이브러리와 친숙하지 않다면 주피터 노트북에 포함되어 있는 몇 가지 튜토리 얼을 참고하세요. 선형대수와 관련된 간단한 튜토리얼도 포함되어 있습니다.3

이 책의 구성 이 책은 두 부분으로 구성되어 있습니다. 1부 ‘머신러닝’에서는 다음 주제를 다룹니다. 머신러닝이 무엇인가요? 어떤 문제를 해결하려고 하나요? 머신러닝 시스템의 종류와 기본적인 개념은 무엇

인가요? 전형적인 머신러닝 프로젝트의 주요 단계

데이터를 사용해 모델 학습시키기

비용 함수 최적화하기

데이터 처리, 정제, 준비하기

3 옮긴이_ 깃허브에 맷플롯립( tools_matplotlib.ipynb ), 넘파이( tools_numpy.ipynb ), 판다스( tools_pandas.ipynb )에 대한 튜토리얼과 선형대수 튜토리얼(math_linear_algebra.ipynb )이 포함되어 있습니다.

11


특성 선택과 특성 공학

모델 선택과 교차 검증을 사용한 하이퍼파라미터 튜닝

머신러닝 주요 도전과제, 특히 과소적합과 과대적합(편향/분산 트레이드오프)

차원의 저주 문제를 해결하기 위해 훈련 데이터의 차원 감소시키기

가장 널리 사용되는 학습 알고리즘 : 선형 회귀, 다항 회귀, 로지스틱 회귀, k -최근접 이웃, 서포트 벡터 머신,

결정 트리, 앙상블 방법

2부 ‘신경망과 딥러닝’에서는 다음 주제를 다룹니다. 신경망이 무엇인가요? 어떤 작업에 잘 맞나요?

텐서플로를 사용하여 신경망 만들고 훈련시키기

가장 중요한 신경망 구조 : 피드포워드 신경망, 합성곱 신경망, 순환 신경망, LSTM 신경망, 오토인코더

심층 신경망을 훈련시키기 위한 기법

대규모 데이터셋을 위한 신경망의 규모 확장

강화 학습

1부에서는 대부분 사이킷런을 기반으로 하고 2부에서는 텐서플로를 사용합니다. CAUTION_ 깊은 곳으로 성급하게 뛰어들지 마세요. 딥러닝이 머신러닝에서 가장 흥미진진한 분야임에는 의

심의 여지가 없지만 먼저 기초적인 것을 마스터해야 합니다. 또한 대부분의 문제는 (1부에서 설명할) 랜덤 포레스트나 앙상블 방법 같은 좀 더 간단한 기법을 사용하여 해결할 수 있습니다. 딥러닝은 이미지 인식이나 음성 인식, 자연어 처리 같은 복잡한 문제에 가장 적합합니다. 충분한 데이터와 컴퓨팅 성능이 있어야 하고 인내도 필요합니다.

12


그 외 자료 머신러닝을 배울 수 있는 자료가 많이 있습니다. 앤드류 응 Andrew Ng 의 코세라 Coursera 머신러닝 강좌( https://www.coursera.org/learn/machine-learning/ ) 4 와 제프리 힌튼의 신경망과 딥러닝 강좌(https://www.coursera.org/course/neuralnets )가 아주 훌륭합니다. 이 강좌 들을 들으려면 상당한 시간을 투자해야 합니다(아마 몇 달 정도). 머신러닝에 관한 좋은 웹사이트도 많이 있습니다. 물론 사이킷런의 독보적인 사용자 가이드 ( http://scikit-learn.org/stable/user_guide.html )도 포함됩니다. 인터랙티브한 튜토 리얼을 제공하는 데이터퀘스트 Dataquest ( https://www.dataquest.io/ )와 쿠오라 Quora 에 나열 된( http://goo.gl/GwtU3A ) 머신러닝 블로그도 좋습니다. 더 많은 자료는 딥러닝 웹사이트 (http://deeplearning.net/ )에서 찾을 수 있습니다. 물론 머신러닝을 소개하는 다른 책들도 많이 있습니다.5 조엘 그루스 Joel Grus 의 『밑바닥부터 시작하는 데이터 과학』 (인사이트, 2016 ). 이 책은 머신러닝의 기초를 다

루고 몇 가지 주요 알고리즘을 파이썬을 이용하여 직접 구현합니다(이름 그대로 밑바닥부터). 스티븐 마슬랜드 Stephen Marsland 의 『알고리즘 중심의 머신러닝 가이드』 (제이펍, 2016 ). 이 책은 머신러닝을

잘 소개하고 있고 폭넓은 주제를 다루며 파이썬 코드 예제를 제공합니다(역시 밑바닥부터, 하지만 넘파이를 사용합니다). 세바스티안 라슈카 Sebastian Raschka 의 『파이썬 머신러닝』 (지앤선, 2017 ). 또 다른 좋은 머신러닝 입문서입니

다. 이 책은 파이썬 오픈소스 라이브러리(사이킷런과 씨아노 Theano )를 사용합니다.6

4 옮긴이_ 앤드류 응 교수는 최근 코세라에 다섯 개의 강좌로 이루어진 딥러닝 전문과정을 열었습니다(https://goo.gl/WnHK7a ). 영어 가 부담이 된다면 김성훈 님의 「모두의 머신러닝/딥러닝」 (https://goo.gl/7PEkVy ) 온라인 강좌를 추천합니다. 5 옮긴이_ 최근 인기가 높은 머신러닝 책은 사이킷런을 중심으로 방대한 알고리즘을 소개한 안드리아스 뮐러(Andreas Müller )와 세라 가이도(Sarah Guido )의 『파이썬 라이브러리를 활용한 머신러닝』 (한빛미디어, 2017 )과 케라스를 중심으로 딥러닝의 소개를 다룬 프 랑소와 숄레의 『Deep Learning with Python』 (Manning , 2018 )이 있습니다. 파이썬으로 신경망을 직접 구현해보는 『밑바닥부터 시 작하는 딥러닝』 (한빛미디어, 2017 )도 인기가 높습니다. 6 옮긴이_ 개정판에서는 씨아노 대신 텐서플로를 사용합니다

13


야세르 S. 아부-모스타파 Yaser S. Abu-Mostafa, 말릭 막돈 이스마일 Malik Magdon-Ismail, 쓰엔-티엔 린 Hsuan-Tien Lin 의

『Learning from Data』 (AMLBook ). 이 책은 머신러닝의 이론적인 면을 다루고 특히 편향/분산 트레이드 오프( 4장)를 자세히 설명합니다. 스튜어트 러셀 Stuart Russell, 피터 노빅 Peter Norvig 의 『인공지능 1, 2』(제이펍, 2016 ). 머신러닝을 포함하여 많은

주제를 다룬 좋은 (그리고 방대한) 책입니다. 머신러닝을 넓은 시각으로 바라보도록 도와줍니다.

마지막으로 Kaggle.com 같은 머신러닝 경연 대회 웹사이트에 참여하는 것이 학습하는 데 큰 도 움이 됩니다. 실전 문제로 기술을 연습할 수 있고 머신러닝 전문가들로부터 도움과 통찰을 얻을 수 있습니다.

예제 소스 이 책에 포함된 모든 예제 코드는 옮긴이의 깃허브에서 내려받을 수 있습니다. https://github.com/rickiepark/handson-ml

혹은 아래 주소에서도 예제 코드를 확인할 수 있습니다. 가끔 깃허브가 주피터 노트북을 제대 로 보여주지 못하는 경우에 활용하면 좋습니다. https://nbviewer.jupyter.org/github/rickiepark/handson-ml/tree/master/

14


감사의 글

구글 동료, 특히 필자에게 머신러닝에 관해 많은 것을 가르쳐준 유튜브 동영상 분류 팀에 감 사합니다. 그들이 없었다면 이 작업을 절대 시작하지 못했을 것입니다. 필자의 머신러닝 멘 토 Clément Courbet, Julien Dubois, Mathias Kende, Daniel Kitachewsky, James

Pack, Alexander Pak, Anosh Raj, Vitor Sessak, Wiktor Tomczak, Ingrid von Glehn, Rich Washington, 그리고 유튜브 파리의 모든 분에게 특별히 감사드립니다. 바쁜 와중에도 시간을 내어 이 책을 자세히 리뷰해준 많은 분에게 매우 감사드립니다. 텐서플로 에 관한 저의 모든 질문에 대답을 해주었고 2부를 리뷰하고 매우 흥미로운 점들을 알려준 Pete

Warden에게 감사합니다. 물론 텐서플로 코어 팀의 일원이 된 것을 축하합니다. 꼭 그의 블로 그(https://petewarden.com/ )를 확인해보세요! 2부 전체를 통틀어 많은 리뷰를 해준 Lukas

Biewald에게 감사합니다. 가능한 모든 방법을 동원하여 전체 코드를 테스트하고(에러도 몇 개 찾았습니다) 많은 좋은 제안을 해주었습니다. 그의 열정은 본받을 만합니다. 그의 블로그 ( https://lukasbiewald.com/ )와 멋진 로봇( https://goo.gl/Eu5u28 )을 확인해보세요! 역 시 2부를 매우 자세하게 리뷰해준 Justin Francis에게 감사합니다. 특히 16장에 있는 에러를 찾아주고 훌륭한 통찰을 전해주었습니다. 텐서플로에 관한 그의 글(https://goo.gl/28ve8z ) 을 읽어보세요!

1부를 리뷰하고 아주 유용한 피드백을 해준 David Andrzejewski에게도 매우 감사합니다. 확실치 않은 장과 절을 지적하고 개선할 수 있도록 제한해주었습니다. 그의 웹사이트(http:// www.david-andrzejewski.com/ )를 확인해보세요! 2부를 리뷰하고 신경망을 훈련시키는 데

재미있는 실용적인 조언을 해준 Grégoire Mesnil에게 감사합니다. 1부를 리뷰하고 많은 유 용한 제안을 해준 Eddy Hung, Salim Sémaoune, Karim Matrah, Ingrid von Glehn,

Iain Smears, Vincent Guilbeau에게 감사합니다. 전직 수학 선생님이고 이제는 Anton Chekhov 작품의 훌륭한 번역가인 나의 장인 Michel Tessier에게 감사합니다. 이 책의 수학 식과 기호들을 매끄럽게 만드는 데 도움을 주고 선형대수에 관한 주피터 노트북을 리뷰해주었 습니다.

15


모든 장을 리뷰해주고, 모든 코드를 테스트하고, 장과 절마다 피드백을 주고, 처음부터 끝까지 저를 독려해준 나의 동생 Sylvain에게 당연히 엄청난 감사의 말을 전합니다. 사랑해 동생아! 오라일리의 환상적인 직원들에게 많은 감사를 드립니다. 특히 Nicole Tache는 아주 유용 한 피드백을 주고, 항상 응원하고, 독려하고 도움을 주었습니다. Marie Beaugureau, Ben

Lorica, Mike Loukides, Laurel Ruma에게도 감사합니다. 이 프로젝트를 믿어 주고 범위를 정하는 데 도움을 주었습니다. 문서 서식, 아스키독 asciidoc, 레이텍 LaTeX 에 관한 기술적인 모든 질문에 대답을 해준 Matt Hacker와 Atlas 팀 모두에게 감사드립니다. 그리고 최종 리뷰와 수 백 건의 오류를 교정해준 Rachel Monaghan, Nick Adams, 그리고 모든 제작 팀에 감사합 니다. 마지막이지만 정말 중요한 나의 사랑하는 아내 Emmanuelle 과 사랑스러운 세 아이

Alexandre, Rémi, Gabrielle에게 끝없는 감사를 보냅니다. 이 책을 열심히 작업할 수 있도 록 힘을 북돋아주었고 많은 질문을 해주었습니다(7살 아이에게 신경망을 가르칠 수 없다고 누 가 그러던가요? ). 그리고 쿠키와 커피를 가져다주기도 했습니다. 더 이상 무엇을 바랄까요?

16


CONTENTS

지은이·옮긴이 소개 �������������������������������������������������������������������������������������������������������� 4

추천의 글 ����������������������������������������������������������������������������������������������������������������������� 5

옮긴이의 말 �������������������������������������������������������������������������������������������������������������������� 8

이 책에 대하여 ���������������������������������������������������������������������������������������������������������������� 9 감사의 글 ��������������������������������������������������������������������������������������������������������������������� 15

Part

1

CHAPTER

머신러닝

1 한눈에 보는 머신러닝

1.1 머신러닝이란? ������������������������������������������������������������������������������������������������������������ 34 1.2 왜 머신러닝을 사용하는가? ������������������������������������������������������������������������������������������� 35 1.3 머신러닝 시스템의 종류 ������������������������������������������������������������������������������������������������ 38

1.3.1 지도 학습과 비지도 학습 ����������������������������������������������������������������������������������� 38

1.3.2 배치 학습과 온라인 학습 ����������������������������������������������������������������������������������� 46

1.3.3 사례 기반 학습과 모델 기반 학습 ������������������������������������������������������������������������ 49

1.4 머신러닝의 주요 도전 과제 �������������������������������������������������������������������������������������������� 55

1.4.1 충분하지 않은 양의 훈련 데이터 ������������������������������������������������������������������������� 55

1.4.2 대표성 없는 훈련 데이터 ����������������������������������������������������������������������������������� 56

1.4.3 낮은 품질의 데이터 ������������������������������������������������������������������������������������������ 58

1.4.4 관련 없는 특성 ������������������������������������������������������������������������������������������������ 58

1.4.5 훈련 데이터 과대적합 ��������������������������������������������������������������������������������������� 59

1.4.6 훈련 데이터 과소적합 ��������������������������������������������������������������������������������������� 61

1.4.7 한걸음 물러서서 ���������������������������������������������������������������������������������������������� 62

1.5 테스트와 검증 ������������������������������������������������������������������������������������������������������������ 62 1.6 연습문제 ������������������������������������������������������������������������������������������������������������������� 64

17


CONTENTS

CHAPTER

2 머신러닝 프로젝트 처음부터 끝까지

2.1 실제 데이터로 작업하기 ������������������������������������������������������������������������������������������������ 68 2.2 큰 그림 보기 �������������������������������������������������������������������������������������������������������������� 69

2.2.1 문제 정의 ������������������������������������������������������������������������������������������������������� 70

2.2.2 성능 측정 지표 선택 ����������������������������������������������������������������������������������������� 72

2.2.3 가정 검사 ������������������������������������������������������������������������������������������������������� 74

2.3 데이터 가져오기 ���������������������������������������������������������������������������������������������������������� 75

2.3.1 작업환경 만들기 ���������������������������������������������������������������������������������������������� 75

2.3.2 데이터 다운로드 ���������������������������������������������������������������������������������������������� 79

2.3.3 데이터 구조 훑어보기 ��������������������������������������������������������������������������������������� 80

2.3.4 테스트 세트 만들기 ������������������������������������������������������������������������������������������ 85

2.4 데이터 이해를 위한 탐색과 시각화 ���������������������������������������������������������������������������������� 90

2.4.1 지리적 데이터 시각화 ��������������������������������������������������������������������������������������� 91

2.4.2 상관관계 조사 ������������������������������������������������������������������������������������������������� 94

2.4.3 특성 조합으로 실험 ������������������������������������������������������������������������������������������ 97

2.5 머신러닝 알고리즘을 위한 데이터 준비 ���������������������������������������������������������������������������� 99

2.5.1 데이터 정제 ���������������������������������������������������������������������������������������������������� 99

2.5.2 텍스트와 범주형 특성 다루기 ��������������������������������������������������������������������������� 102

2.5.3 나만의 변환기 ����������������������������������������������������������������������������������������������� 105

2.5.4 특성 스케일링 ����������������������������������������������������������������������������������������������� 107

2.5.5 변환 파이프라인 �������������������������������������������������������������������������������������������� 108

2.6 모델 선택과 훈련 ������������������������������������������������������������������������������������������������������� 110

2.6.1 훈련 세트에서 훈련하고 평가하기 ��������������������������������������������������������������������� 111

2.6.2 교차 검증을 사용한 평가 ��������������������������������������������������������������������������������� 113

2.7 모델 세부 튜닝 ���������������������������������������������������������������������������������������������������������� 115

2.7.1 그리드 탐색 �������������������������������������������������������������������������������������������������� 116

2.7.2 랜덤 탐색 ����������������������������������������������������������������������������������������������������� 118

18


2.7.3 앙상블 방법 �������������������������������������������������������������������������������������������������� 119

2.7.4 최상의 모델과 오차 분석 ��������������������������������������������������������������������������������� 119

2.7.5 테스트 세트로 시스템 평가하기 ������������������������������������������������������������������������ 120

2.8 론칭, 모니터링, 그리고 시스템 유지 보수 ����������������������������������������������������������������������� 121 2.9 직접 해보세요! ��������������������������������������������������������������������������������������������������������� 122 2.10 연습문제 ����������������������������������������������������������������������������������������������������������������� 122

CHAPTER

3 분류

3.1 MNIST ������������������������������������������������������������������������������������������������������������������� 123 3.2 이진 분류기 훈련 ������������������������������������������������������������������������������������������������������� 126 3.3 성능 측정 ���������������������������������������������������������������������������������������������������������������� 127

3.3.1 교차 검증을 사용한 정확도 측정 ����������������������������������������������������������������������� 127

3.3.2 오차 행렬 ����������������������������������������������������������������������������������������������������� 129

3.3.3 정밀도와 재현율 �������������������������������������������������������������������������������������������� 132

3.3.4 정밀도/재현율 트레이드오프 ���������������������������������������������������������������������������� 133

3.3.5 ROC 곡선 ���������������������������������������������������������������������������������������������������� 137

3.4 다중 분류 ���������������������������������������������������������������������������������������������������������������� 141 3.5 에러 분석 ���������������������������������������������������������������������������������������������������������������� 144 3.6 다중 레이블 분류 ������������������������������������������������������������������������������������������������������� 148 3.7 다중 출력 분류 ���������������������������������������������������������������������������������������������������������� 150 3.8 연습문제 ����������������������������������������������������������������������������������������������������������������� 152

CHAPTER

4 모델 훈련

4.1 선형 회귀 ���������������������������������������������������������������������������������������������������������������� 156

4.1.1 정규방정식 ��������������������������������������������������������������������������������������������������� 158

19


CONTENTS

4.1.2 계산 복잡도 �������������������������������������������������������������������������������������������������� 160

4.2 경사 하강법 ������������������������������������������������������������������������������������������������������������� 161

4.2.1 배치 경사 하강법 ������������������������������������������������������������������������������������������� 165

4.2.2 확률적 경사 하강법 ���������������������������������������������������������������������������������������� 168

4.2.3 미니배치 경사 하강법 ������������������������������������������������������������������������������������� 171

4.3 다항 회귀 ���������������������������������������������������������������������������������������������������������������� 173 4.4 학습 곡선 ���������������������������������������������������������������������������������������������������������������� 175 4.5 규제가 있는 선형 모델 ������������������������������������������������������������������������������������������������ 179

4.5.1 릿지 회귀 ����������������������������������������������������������������������������������������������������� 180

4.5.2 라쏘 회귀 ����������������������������������������������������������������������������������������������������� 183

4.5.3 엘라스틱넷 ��������������������������������������������������������������������������������������������������� 185

4.5.4 조기 종료 ����������������������������������������������������������������������������������������������������� 186

4.6 로지스틱 회귀 ���������������������������������������������������������������������������������������������������������� 188

4.6.1 확률 추정 ����������������������������������������������������������������������������������������������������� 188

4.6.2 훈련과 비용 함수 ������������������������������������������������������������������������������������������� 189

4.6.3 결정 경계 ����������������������������������������������������������������������������������������������������� 191

4.6.4 소프트맥스 회귀 �������������������������������������������������������������������������������������������� 194

4.7 연습문제 ����������������������������������������������������������������������������������������������������������������� 198

CHAPTER

5 서포트 벡터 머신

5.1 선형 SVM 분류 �������������������������������������������������������������������������������������������������������� 201

5.1.1 소프트 마진 분류 ������������������������������������������������������������������������������������������� 202

5.2 비선형 SVM 분류 ����������������������������������������������������������������������������������������������������� 205

5.2.1 다항식 커널 �������������������������������������������������������������������������������������������������� 207

5.2.2 유사도 특성 추가 ������������������������������������������������������������������������������������������� 208

5.2.3 가우시안 RBF 커널 ��������������������������������������������������������������������������������������� 209

5.2.4 계산 복잡도 �������������������������������������������������������������������������������������������������� 211

20


5.3 SVM 회귀 ��������������������������������������������������������������������������������������������������������������� 212 5.4 SVM 이론 ��������������������������������������������������������������������������������������������������������������� 214

5.4.1 결정 함수와 예측 ������������������������������������������������������������������������������������������� 214

5.4.2 목적 함수 ����������������������������������������������������������������������������������������������������� 215

5.4.3 콰드라틱 프로그래밍 �������������������������������������������������������������������������������������� 217

5.4.4 쌍대 문제 ����������������������������������������������������������������������������������������������������� 218

5.4.5 커널 SVM ���������������������������������������������������������������������������������������������������� 219

5.4.6 온라인 SVM ������������������������������������������������������������������������������������������������� 222

5.5 연습문제 ����������������������������������������������������������������������������������������������������������������� 223

CHAPTER

6 결정 트리

6.1 결정 트리 학습과 시각화 ��������������������������������������������������������������������������������������������� 225 6.2 예측하기 ����������������������������������������������������������������������������������������������������������������� 227 6.3 클래스 확률 추정 ������������������������������������������������������������������������������������������������������� 229 6.4 CART 훈련 알고리즘 ������������������������������������������������������������������������������������������������ 230 6.5 계산 복잡도 ������������������������������������������������������������������������������������������������������������� 231 6.6 지니 불순도 또는 엔트로피? ���������������������������������������������������������������������������������������� 232 6.7 규제 매개변수 ���������������������������������������������������������������������������������������������������������� 233 6.8 회귀 ����������������������������������������������������������������������������������������������������������������������� 234 6.9 불안정성 ����������������������������������������������������������������������������������������������������������������� 236 6.10 연습문제 ����������������������������������������������������������������������������������������������������������������� 238

CHAPTER

7 앙상블 학습과 랜덤 포레스트

7.1 투표 기반 분류기 ������������������������������������������������������������������������������������������������������� 242 7.2 배깅과 페이스팅 �������������������������������������������������������������������������������������������������������� 245

21


CONTENTS

7.2.1 사이킷런의 배깅과 페이스팅 ���������������������������������������������������������������������������� 246

7.2.2 oob 평가 ����������������������������������������������������������������������������������������������������� 248

7.3 랜덤 패치와 랜덤 서브스페이스 ������������������������������������������������������������������������������������ 249 7.4 랜덤 포레스트 ���������������������������������������������������������������������������������������������������������� 250

7.4.1 엑스트라 트리 ����������������������������������������������������������������������������������������������� 251

7.4.2 특성 중요도 �������������������������������������������������������������������������������������������������� 252

7.5 부스팅 �������������������������������������������������������������������������������������������������������������������� 253

7.5.1 아다부스트 ��������������������������������������������������������������������������������������������������� 253

7.5.2 그래디언트 부스팅 ����������������������������������������������������������������������������������������� 258

7.6 스태킹 �������������������������������������������������������������������������������������������������������������������� 263 7.7 연습문제 ����������������������������������������������������������������������������������������������������������������� 266

CHAPTER

8 차원 축소

8.1 차원의 저주 ������������������������������������������������������������������������������������������������������������� 270 8.2 차원 축소를 위한 접근 방법 ����������������������������������������������������������������������������������������� 272

8.2.1 투영 ������������������������������������������������������������������������������������������������������������ 272

8.2.2 매니폴드 학습 ����������������������������������������������������������������������������������������������� 275

8.3 PCA ���������������������������������������������������������������������������������������������������������������������� 276

8.3.1 분산 보존 ����������������������������������������������������������������������������������������������������� 277

8.3.2 주성분 ��������������������������������������������������������������������������������������������������������� 277

8.3.3 d차원으로 투영하기 ��������������������������������������������������������������������������������������� 279

8.3.4 사이킷런 사용하기 ����������������������������������������������������������������������������������������� 280

8.3.5 설명된 분산의 비율 ���������������������������������������������������������������������������������������� 280

8.3.6 적절한 차원 수 선택하기 ��������������������������������������������������������������������������������� 281

8.3.7 압축을 위한 PCA ������������������������������������������������������������������������������������������ 282

8.3.8 점진적 PCA ������������������������������������������������������������������������������������������������� 283

8.3.9 랜덤 PCA ���������������������������������������������������������������������������������������������������� 284

22


8.4 커널 PCA ��������������������������������������������������������������������������������������������������������������� 285

8.4.1 커널 선택과 하이퍼파라미터 튜닝 ��������������������������������������������������������������������� 286

8.5 LLE ����������������������������������������������������������������������������������������������������������������������� 289 8.6 다른 차원 축소 기법 ��������������������������������������������������������������������������������������������������� 291 8.7 연습문제 ����������������������������������������������������������������������������������������������������������������� 292

Part

2

CHAPTER

신경망과 딥러닝

9 텐서플로 시작하기

9.1 설치 ����������������������������������������������������������������������������������������������������������������������� 298 9.2 첫 번째 계산 그래프를 만들어 세션에서 실행하기 ������������������������������������������������������������ 299 9.3 계산 그래프 관리 ������������������������������������������������������������������������������������������������������� 301 9.4 노드 값의 생애주기 ���������������������������������������������������������������������������������������������������� 302 9.5 텐서플로를 이용한 선형 회귀 ��������������������������������������������������������������������������������������� 303 9.6 경사 하강법 구현 ������������������������������������������������������������������������������������������������������� 305

9.6.1 직접 그래디언트 계산 ������������������������������������������������������������������������������������� 305

9.6.2 자동 미분 사용 ���������������������������������������������������������������������������������������������� 306

9.6.3 옵티마이저 사용 �������������������������������������������������������������������������������������������� 308

9.7 훈련 알고리즘에 데이터 주입 ��������������������������������������������������������������������������������������� 308 9.8 모델 저장과 복원 ������������������������������������������������������������������������������������������������������� 310 9.9 텐서보드로 그래프와 학습 곡선 시각화하기 �������������������������������������������������������������������� 312 9.10 이름 범위 ���������������������������������������������������������������������������������������������������������������� 316 9.11 모듈화 �������������������������������������������������������������������������������������������������������������������� 317 9.12 변수 공유 ���������������������������������������������������������������������������������������������������������������� 320 9.13 연습문제 ����������������������������������������������������������������������������������������������������������������� 324

23


CONTENTS

CHAPTER

10 인공 신경망 소개

10.1 생물학적 뉴런에서 인공 뉴런까지 ������������������������������������������������������������������������������� 328

10.1.1 생물학적 뉴런 ������������������������������������������������������������������������������������������� 329

10.1.2 뉴런을 사용한 논리 연산 ����������������������������������������������������������������������������� 331

10.1.3 퍼셉트론 �������������������������������������������������������������������������������������������������� 332

10.1.4 다층 퍼셉트론과 역전파 ������������������������������������������������������������������������������ 336

10.2 텐서플로의 고수준 API로 다층 퍼셉트론 훈련하기 ��������������������������������������������������������� 339 10.3 텐서플로의 저수준 API로 심층 신경망 훈련하기 ����������������������������������������������������������� 341

10.3.1 구성 단계 ������������������������������������������������������������������������������������������������� 341

10.3.2 실행 단계 ������������������������������������������������������������������������������������������������� 346

10.3.3 신경망 사용하기 ���������������������������������������������������������������������������������������� 347

10.4 신경망 하이퍼파라미터 튜닝하기 �������������������������������������������������������������������������������� 348

10.4.1 은닉층의 수 ���������������������������������������������������������������������������������������������� 348

10.4.2 은닉층의 뉴런 수 ��������������������������������������������������������������������������������������� 350

10.4.3 활성화 함수 ���������������������������������������������������������������������������������������������� 350

10.5 연습문제 ��������������������������������������������������������������������������������������������������������������� 351

CHAPTER

11 심층 신경망 훈련

11.1 그래디언트 소실과 폭주 문제 ������������������������������������������������������������������������������������� 354

11.1.1 세이비어 초기화와 He 초기화 ���������������������������������������������������������������������� 355

11.1.2 수렴하지 않는 활성화 함수 �������������������������������������������������������������������������� 357

11.1.3 배치 정규화 ���������������������������������������������������������������������������������������������� 360

11.1.4 그래디언트 클리핑 ������������������������������������������������������������������������������������� 366

11.2 미리 훈련된 층 재사용하기 ���������������������������������������������������������������������������������������� 366

24

11.2.1 텐서플로 모델 재사용하기 ��������������������������������������������������������������������������� 367


11.2.2 다른 프레임워크의 모델 재사용하기 �������������������������������������������������������������� 370

11.2.3 신경망의 하위층을 학습에서 제외하기 ����������������������������������������������������������� 371

11.2.4 동결된 층 캐싱하기 ������������������������������������������������������������������������������������ 372

11.2.5 상위층을 변경, 삭제, 대체하기 ��������������������������������������������������������������������� 373

11.2.6 모델 저장소 ���������������������������������������������������������������������������������������������� 374

11.2.7 비지도 사전훈련 ���������������������������������������������������������������������������������������� 374

11.2.8 보조 작업으로 사전훈련 ������������������������������������������������������������������������������ 375

11.3 고속 옵티마이저 ������������������������������������������������������������������������������������������������������ 376

11.3.1 모멘텀 최적화 ������������������������������������������������������������������������������������������� 377

11.3.2 네스테로프 가속 경사 ��������������������������������������������������������������������������������� 378

11.3.3 AdaGrad ������������������������������������������������������������������������������������������������ 380

11.3.4 RMSProp ����������������������������������������������������������������������������������������������� 382

11.3.5 Adam 최적화 ������������������������������������������������������������������������������������������� 383

11.3.6 학습률 스케줄링 ���������������������������������������������������������������������������������������� 385

11.4 과대적합을 피하기 위한 규제 방법 ������������������������������������������������������������������������������ 387

11.4.1 조기 종료 ������������������������������������������������������������������������������������������������� 388

11.4.2 1과 2 규제 ��������������������������������������������������������������������������������������������� 388

11.4.3 드롭아웃 �������������������������������������������������������������������������������������������������� 390

11.4.4 맥스-노름 규제 ����������������������������������������������������������������������������������������� 393

11.4.5 데이터 증식 ���������������������������������������������������������������������������������������������� 395

11.5 실용적 가이드라인 ��������������������������������������������������������������������������������������������������� 397 11.6 연습문제 ��������������������������������������������������������������������������������������������������������������� 398

CHAPTER

12 다중 머신과 장치를 위한 분산 텐서플로

12.1 단일 머신의 다중 장치 ���������������������������������������������������������������������������������������������� 402

12.1.1 설치 �������������������������������������������������������������������������������������������������������� 402

25


CONTENTS

12.1.2 GPU RAM 관리 ��������������������������������������������������������������������������������������� 405

12.1.3 장치에 연산 배치하기 ��������������������������������������������������������������������������������� 408

12.1.4 병렬 실행 ������������������������������������������������������������������������������������������������� 411

12.1.5 제어 의존성 ���������������������������������������������������������������������������������������������� 413

12.2 다중 머신의 다중 장치 ���������������������������������������������������������������������������������������������� 414

12.2.1 세션 열기 ������������������������������������������������������������������������������������������������� 416

12.2.2 마스터와 워커 서비스 ��������������������������������������������������������������������������������� 417

12.2.3 여러 태스크에 연산 할당하기 ����������������������������������������������������������������������� 418

12.2.4 여러 대의 파라미터 서버에 변수를 나누어 분산하기 ����������������������������������������� 418

12.2.5 리소스 컨테이너를 사용해 여러 세션에서 상태 공유하기 ����������������������������������� 420

12.2.6 텐서플로 큐를 사용한 비동기 통신 ���������������������������������������������������������������� 422

12.2.7 그래프에서 직접 데이터 로드하기 ����������������������������������������������������������������� 429

12.3 텐서플로 클러스터에서 신경망 병렬화하기 ������������������������������������������������������������������� 437

12.3.1 장치마다 하나의 신경망 ������������������������������������������������������������������������������ 438

12.3.2 그래프 내 복제와 그래프 간 복제 ������������������������������������������������������������������ 439

12.3.3 모델 병렬화 ���������������������������������������������������������������������������������������������� 442

12.3.4 데이터 병렬화 ������������������������������������������������������������������������������������������� 444

12.4 연습문제 ��������������������������������������������������������������������������������������������������������������� 449

CHAPTER

13 합성곱 신경망

13.1 시각 피질의 구조 ����������������������������������������������������������������������������������������������������� 452 13.2 합성곱층 ��������������������������������������������������������������������������������������������������������������� 454

13.2.1 필터 �������������������������������������������������������������������������������������������������������� 456

13.2.2 여러 개의 특성 맵 쌓기 ������������������������������������������������������������������������������� 457

13.2.3 텐서플로 구현 ������������������������������������������������������������������������������������������� 459

13.2.4 메모리 요구사항 ���������������������������������������������������������������������������������������� 462

26


13.3 풀링층 ������������������������������������������������������������������������������������������������������������������ 463 13.4 CNN 구조 ������������������������������������������������������������������������������������������������������������� 465

13.4.1 LeNet-5 ������������������������������������������������������������������������������������������������� 467

13.4.2 AlexNet �������������������������������������������������������������������������������������������������� 468

13.4.3 GoogLeNet �������������������������������������������������������������������������������������������� 470

13.4.4 ResNet �������������������������������������������������������������������������������������������������� 473

13.5 연습문제 ��������������������������������������������������������������������������������������������������������������� 478

CHAPTER

14 순환 신경망

14.1 순환 뉴런 ��������������������������������������������������������������������������������������������������������������� 482

14.1.1 메모리 셀 ������������������������������������������������������������������������������������������������� 484

14.1.2 입력과 출력 시퀀스 ������������������������������������������������������������������������������������ 485

14.2 텐서플로로 기본 RNN 구성하기 �������������������������������������������������������������������������������� 486

14.2.1 정적으로 타임 스텝 펼치기 �������������������������������������������������������������������������� 488

14.2.2 동적으로 타임 스텝 펼치기 �������������������������������������������������������������������������� 491

14.2.3 가변 길이 입력 시퀀스 다루기 ���������������������������������������������������������������������� 491

14.2.4 가변 길이 출력 시퀀스 다루기 ���������������������������������������������������������������������� 493

14.3 RNN 훈련하기 ������������������������������������������������������������������������������������������������������� 493

14.3.1 시퀀스 분류기 훈련하기 ������������������������������������������������������������������������������ 494

14.3.2 시계열 예측을 위해 훈련하기 ����������������������������������������������������������������������� 497

14.3.3 RNN의 창조성 ����������������������������������������������������������������������������������������� 503

14.4 심층 RNN ������������������������������������������������������������������������������������������������������������� 504

14.4.1 여러 GPU에 심층 RNN 분산하기 ���������������������������������������������������������������� 505

14.4.2 드롭아웃 적용하기 ������������������������������������������������������������������������������������� 506

14.4.3 많은 타임 스텝에서 훈련의 어려움 ���������������������������������������������������������������� 508

14.5 LSTM 셀 �������������������������������������������������������������������������������������������������������������� 509

27


CONTENTS

14.5.1 핍홀 연결 ������������������������������������������������������������������������������������������������� 512

14.6 GRU 셀 ���������������������������������������������������������������������������������������������������������������� 512 14.7 자연어 처리 ������������������������������������������������������������������������������������������������������������ 514

14.7.1 워드 임베딩 ���������������������������������������������������������������������������������������������� 514

14.7.2 기계 번역을 위한 인코더-디코더 네트워크 ����������������������������������������������������� 516

14.8 연습문제 ��������������������������������������������������������������������������������������������������������������� 519

CHAPTER

15 오토인코더

15.1 효율적인 데이터 표현 ����������������������������������������������������������������������������������������������� 522 15.2 과소완전 선형 오토인코더로 PCA 수행하기 ����������������������������������������������������������������� 524 15.3 적층 오토인코더 ������������������������������������������������������������������������������������������������������ 526

15.3.1 텐서플로 구현 ������������������������������������������������������������������������������������������� 527

15.3.2 가중치 묶기 ���������������������������������������������������������������������������������������������� 528

15.3.3 한 번에 한 층씩 훈련하기 ���������������������������������������������������������������������������� 529

15.3.4 재구성 시각화 ������������������������������������������������������������������������������������������� 532

15.3.5 특성 시각화 ���������������������������������������������������������������������������������������������� 533

15.4 적층 오토인코더를 사용한 비지도 사전훈련 ������������������������������������������������������������������ 535 15.5 잡음제거 오토인코더 ������������������������������������������������������������������������������������������������ 536

15.5.1 텐서플로 구현 ������������������������������������������������������������������������������������������� 537

15.6 희소 오토인코더 ������������������������������������������������������������������������������������������������������ 539

15.6.1 텐서플로 구현 ������������������������������������������������������������������������������������������� 540

15.7 변이형 오토인코더 ��������������������������������������������������������������������������������������������������� 542

15.7.1 숫자 이미지 생성 ��������������������������������������������������������������������������������������� 545

15.8 다른 오토인코더들 ��������������������������������������������������������������������������������������������������� 546 15.9 연습문제 ��������������������������������������������������������������������������������������������������������������� 547

28


CHAPTER

16 강화 학습

16.1 보상을 최적화하기 위한 학습 ������������������������������������������������������������������������������������� 552 16.2 정책 탐색 ��������������������������������������������������������������������������������������������������������������� 554 16.3 OpenAI 짐 ������������������������������������������������������������������������������������������������������������ 556 16.4 신경망 정책 ������������������������������������������������������������������������������������������������������������ 560 16.5 행동 평가: 신용 할당 문제 ���������������������������������������������������������������������������������������� 563 16.6 정책 그래디언트 ������������������������������������������������������������������������������������������������������ 564 16.7 마르코프 결정 과정 �������������������������������������������������������������������������������������������������� 570 16.8 시간차 학습과 Q -러닝 ��������������������������������������������������������������������������������������������� 575

16.8.1 탐험 정책 ������������������������������������������������������������������������������������������������� 578

16.8.2 근사 Q -러닝과 딥 Q -러닝 �������������������������������������������������������������������������� 578

16.9 DQN 알고리즘으로 미스 팩맨 플레이 학습하기 ������������������������������������������������������������ 580 16.10 연습문제 ��������������������������������������������������������������������������������������������������������������� 589 감사합니다! ����������������������������������������������������������������������������������������������������������������������������������������������

Part

3

591

부록

부록 A 연습문제 정답 �������������������������������������������������������������������������������������������������������������������������������

595

부록 B

머신러닝 프로젝트 체크리스트 ���������������������������������������������������������������������������������������������������������

625

부록 C

SVM 쌍대 문제 �����������������������������������������������������������������������������������������������������������������������������

633

부록 D

자동 미분 �������������������������������������������������������������������������������������������������������������������������������������

637

부록 E

유명한 다른 인공 신경망 구조 �����������������������������������������������������������������������������������������������������������

645

찾아보기 ���������������������������������������������������������������������������������������������������������������������������������������������������

655

29



Part

I

머신러닝


Part I

머신러닝

1장

한눈에 보는 머신러닝

2장

머신러닝 프로젝트 처음부터 끝까지

3장

분류

4장

모델 훈련

5장

서포트 벡터 머신

6장

결정 트리

7장

앙상블 학습과 랜덤 포레스트

8장

차원 축소


CHAPTER

1

한눈에 보는 머신러닝

대부분 사람들은 ‘머신러닝 Machine Learning ’이란 말을 들으면 로봇을 떠올립니다. 누구에게 묻는 지에 따라 믿음직한 집사 로봇이나 살인 병기 터미네이터를 생각할 것입니다. 하지만 머신러 닝은 초현실 판타지가 아니고 이미 우리 주위에 있습니다. 사실 광학 문자 판독기 Optical Character Recognition

(OCR ) 같은 특별한 몇 가지 애플리케이션이 수십 년 동안 사용되어 왔습니다. 수억

명의 생활을 편리하게 만들어 주류가 된 첫 번째 머신러닝 애플리케이션은 1990년대에 시작되 었습니다. 바로 스팸 필터 spam filter 입니다. 스스로 생각하는 스카이넷 Skynet 1 정도는 아니지만 기 술적으로 머신러닝이라 할 수 있습니다(실제로 잘 학습되어 있어서 여러분은 더 이상 이메일에 스팸이라고 표시할 일이 거의 없습니다). 이후 추천과 음성 검색으로 발전했으며, 매일 사용하 는 많은 제품과 기능을 소리 없이 향상시킨 수백 개의 머신러닝 애플리케이션이 나왔습니다. 머신러닝은 어디서 시작하고 어디서 끝나는 걸까요? 기계가 배운다는 것이 정확히 무엇을 의 미하는 걸까요? 내가 위키백과 문서를 내려받으면 내 컴퓨터가 실제로 무언가를 배울 수 있을 까요? 컴퓨터가 갑자기 똑똑해질 수 있을까요? 머신러닝이 무엇인지, 왜 머신러닝이 필요한지 살펴보면서 이 장을 시작하겠습니다. 머신러닝의 세상을 탐험하기 전에 전체 머신러닝의 그림을 조망하고 주요 영역과 가장 중요한 랜드마크인 지도 학습과 비지도 학습, 온라인 학습과 배치 학습, 사례 기반 학습과 모델 기반 학습을 알아보겠습니다. 또한 전형적인 머신러닝 프로젝트의 작업 흐름을 살펴보고 만날 수 있 는 주요 문제점과 머신러닝 시스템을 평가하고 세밀하게 튜닝하는 방법을 다루겠습니다. 1 옮긴이_ 스카이넷은 영화 <터미네이터> 시리즈에 나오는 인공지능 슈퍼컴퓨터입니다.

1장 한눈에 보는 머신러닝

33


이 장에서는 모든 데이터 과학자가 꼭 알아야 할 여러 가지 기초 개념과 용어를 소개합니다. 거 시적인 소개를 담고 있고 코드가 많지 않은 유일한 장입니다. 간단한 내용이지만 이 책의 나머 지를 읽기 전에 반드시 모든 내용을 완벽하게 이해해야 합니다. 커피 한잔하면서 같이 시작해 보죠! TIP

이미 머신러닝의 기초를 모두 알고 있다면 2장으로 건너뛰어도 됩니다. 확실하지 않다면 2장으로 건너뛰기 전에 이 장 끝에 있는 연습문제를 풀어보세요.

1.1 머신러닝이란? 머신러닝은 데이터로부터 학습하도록 컴퓨터를 프로그래밍하는 과학(또는 예술)입니다. 조금 더 일반적인 정의는 다음과 같습니다. [머신러닝은] 명시적인 프로그래밍 없이 컴퓨터가 학습하는 능력을 갖추게 하는 연구 분야다. _아서 사무엘 Arthur Samuel , 1959

조금 더 공학적인 정의는 다음과 같습니다. 어떤 작업 T에 대한 컴퓨터 프로그램의 성능을 P로 측정했을 때 경험 E로 인해 성능이 향상됐다 면, 이 컴퓨터 프로그램은 작업 T와 성능 측정 P에 대해 경험 E로 학습한 것이다. _톰 미첼 Tom Mitchell , 1997

예를 들어 스팸 필터는 (사용자가 스팸이라고 지정한) 스팸 메일과 일반 메일의 샘플을 이용해 스팸 메일 구분법을 배울 수 있는 머신러닝 프로그램입니다. 시스템이 학습하는 데 사용하는 샘 플을 훈련 세트 training set 라고 하고 각 훈련 데이터를 훈련 사례 training instance (혹은 샘플)2라고 합 니다. 이 경우 작업 T는 새로운 메일이 스팸인지 구분하는 것이고, 경험 E는 훈련 데이터 training data

이며, 성능 측정 P는 직접 정의해야 합니다. 예를 들면 정확히 분류된 메일의 비율을 P로 사

용할 수 있습니다. 이 성능 측정을 정확도 accuracy 라고 부르며 분류 작업에 자주 사용됩니다.

2 옮긴이_ 원서에서는 ‘instance’가 여러 의미로 사용됩니다. 번역서에서는 ‘instance - based’의 경우 사례 기반으로, ‘example’을 의 미할 때는 ‘샘플’로, 파이썬 객체를 나타낼 때는 ‘인스턴스’라고 번역했습니다.

34

1부 머신러닝


위키백과 문서를 모두 내려받으면 여러분 컴퓨터는 아주 많은 데이터를 갖게 됩니다. 그렇다고 해서 어떤 작업이 갑자기 좋아지는 것은 아닙니다. 그러므로 이는 머신러닝이 아닙니다.

1.2 왜 머신러닝을 사용하는가? 전통적인 프로그래밍 기법을 사용해 어떻게 스팸 필터를 만들 수 있을지 생각해봅시다. 1 먼저 스팸에 어떤 단어들이 주로 나타나는지 살펴봅니다. 그러면 ‘4U ’, ‘신용카드’, ‘무료’, ‘굉장한’ 같은 단어나 구절이 제목에 많이 나타나는 경향이 있다는 것을 알 수 있습니다. 어쩌면 보낸이의 이름이나 메일 주소, 본문 등에서 다른 패턴을 감지할 수도 있습니다. 2 발견한 각 패턴을 감지하는 알고리즘을 작성하여 프로그램이 이런 패턴을 발견했을 때 그 메일을 스팸으로 분 류하게 합니다. 3 프로그램을 테스트하고 충분한 성능이 나올 때까지 1단계와 2단계를 반복합니다.

전통적인 접근 방법에서는 문제가 단순하지 않아 규칙이 점점 길고 복잡해지므로 유지 보수하 기 매우 힘들어집니다(그림 1-1 ). 그림 1-1 전통적인 접근 방법

론칭!

문제 연구

규칙 작성

평가

오차 분석

반면 머신러닝 기법에 기반을 둔 스팸 필터는 일반 메일에 비해 스팸에 자주 나타나는 패턴을 감 지하여 어떤 단어와 구절이 스팸 메일을 판단하는 데 좋은 기준인지 자동으로 학습합니다(그림

1-2 ). 그러므로 프로그램이 훨씬 짧아지고 유지 보수하기 쉬우며 대부분 정확도가 더 높습니다.

1장 한눈에 보는 머신러닝

35


그림 1-2 머신러닝 접근 방법

론칭! 데이터

문제 연구

머신러닝 알고리즘 훈련

솔루션 평가

오차 분석

더군다나 스팸 메일 발송자가 ‘4U ’를 포함한 모든 메일이 차단된다는 것을 안다면 ‘4U ’ 대신 ‘For U ’를 쓰기 시작할지도 모릅니다. 전통적인 프로그래밍 방식의 스팸 필터는 ‘For U ’ 메일 을 구분하기 위해 수정이 필요합니다. 스팸 메일 발송자가 스팸 필터에 대항해 계속 단어를 바 꾸면 영원히 새로운 규칙을 추가해야 합니다. 하지만 머신러닝 기반의 스팸 필터는 사용자가 스팸으로 지정한 메일에 유독 ‘For U ’가 자주 나타나는 것을 자동으로 인식하고 별도의 작업을 하지 않아도 자동으로 이 단어를 스팸으로 분 류합니다(그림 1-3 ). 그림 1-3 자동으로 변화에 적응함 데이터 업데이트

데이터

자동화

머신러닝 알고리즘 훈련

36

1부 머신러닝

론칭!

솔루션 평가


머신러닝이 유용한 또 다른 분야는 전통적인 방식으로는 너무 복잡하거나 알려진 알고리즘이 없는 문제입니다. 음성 인식 speech recognition 을 예로 들 수 있습니다. ‘one’과 ‘two’ 두 단어를 구 분하는 프로그램을 작성한다고 합시다. 단어 ‘two’는 높은 피치 pitch 의 사운드(‘ T ’ )로 시작하므 로 높은 피치의 사운드 강도를 측정하는 알고리즘을 하드코딩해서 ‘one’과 ‘two’를 구분할 수 도 있습니다. 당연히 이 방법은 소음이 있는 환경에서 수백만 명이 말하는 여러 언어로 된 수천 개의 단어를 구분하는 것으로 확장하기 어렵습니다. 각 단어를 녹음한 샘플을 사용해 스스로 학습하는 알고리즘을 작성하는 것이 현재 가장 좋은 솔루션입니다. 우리는 머신러닝을 통해 배울 수도 있습니다(그림 1-4 ). 즉, 머신러닝 알고리즘이 학습한 것 을 조사할 수 있습니다(어떤 알고리즘은 이렇게 하기 어렵습니다). 예를 들어 스팸 필터가 충 분한 스팸 메일로 훈련되었다면 스팸을 예측하는 데 가장 좋은 단어와 단어의 조합이 무엇인지 확인할 수 있습니다. 가끔 예상치 못한 연관 관계나 새로운 추세가 발견되기도 해서 해당 문제 를 더 잘 이해하도록 도와줍니다. 머신러닝 기술을 적용해서 대용량의 데이터를 분석하면 겉으로는 보이지 않던 패턴을 발견할 수 있습니다. 이를 데이터 마이닝 data mining 이라고 합니다. 그림 1-4 머신러닝을 통해 배웁니다.

문제 연구

머신러닝 알고리즘 훈련 솔루션

많은 양의 데이터

필요하다면 반복

솔루션 분석

문제에 대한 이해 증가

1장 한눈에 보는 머신러닝

37


요약하면 머신러닝은 다음 분야에 뛰어납니다. 기존 솔루션으로는 많은 수동 조정과 규칙이 필요한 문제 : 하나의 머신러닝 모델이 코드를 간단하고 더 잘 수

행되도록 할 수 있습니다. 전통적인 방식으로는 전혀 해결 방법이 없는 복잡한 문제 : 가장 뛰어난 머신러닝 기법으로 해결 방법을 찾을

수 있습니다. 유동적인 환경 : 머신러닝 시스템은 새로운 데이터에 적응할 수 있습니다.

복잡한 문제와 대량의 데이터에서 통찰 얻기

1.3 머신러닝 시스템의 종류 머신러닝 시스템의 종류는 굉장히 많으므로 다음을 기준으로 넓은 범주에서 분류하면 도움이 됩니다. 사람의 감독 하에 훈련하는 것인지 그렇지 않은 것인지(지도, 비지도, 준지도, 강화 학습)

실시간으로 점진적인 학습을 하는지 아닌지(온라인 학습과 배치 학습)

단순하게 알고 있는 데이터 포인트와 새 데이터 포인트를 비교하는 것인지 아니면 훈련 데이터셋에서 과학자

들처럼 패턴을 발견하여 예측 모델을 만드는지(사례 기반 학습과 모델 기반 학습)

이 범주들은 서로 배타적이지 않으며 원하는 대로 연결할 수 있습니다. 예를 들어 최첨단 스팸 필터가 심층 신경망 모델을 사용해 스팸과 스팸이 아닌 메일로부터 실시간으로 학습할 지도 모 릅니다. 그렇다면 이 시스템은 온라인이고 모델 기반이며 지도 학습 시스템입니다. 이 범주들을 조금 더 자세히 들여다보겠습니다.

1.3.1 지도 학습과 비지도 학습 머신러닝 시스템을 ‘학습하는 동안의 감독 형태나 정보량’에 따라 분류할 수 있습니다. 지도 학 습, 비지도 학습, 준지도 학습, 강화 학습 등 네 가지 주요 범주가 있습니다.

38

1부 머신러닝


지도 학습 지도 학습 supervised learning 에는 알고리즘에 주입하는 훈련 데이터에 레이블 label 3이라는 원하는 답이 포함됩니다(그림 1-5 ). 그림 1-5 지도 학습에서 레이블된 훈련 세트(예를 들면 스팸 분류) 훈련 세트

레이블 샘플

새로운 샘플

분류 classification 가 전형적인 지도 학습 작업이며, 스팸 필터가 좋은 예입니다. 스팸 필터는 많은 메일 샘플과 소속 정보(스팸인지 아닌지)로 훈련되어야 하며 어떻게 새 메일을 분류할지 학습 해야 합니다. 또 다른 전형적인 작업은 예측 변수 predictor variable 라 부르는 특성 feature (주행거리, 연식, 브랜 드 등)을 사용해 중고차 가격 같은 타깃 수치를 예측하는 것입니다. 이런 종류의 작업을 회귀 regression 4

라고 부릅니다(그림 1-6 ). 시스템을 훈련시키려면 예측 변수와 레이블(중고차 가격)

이 포함된 중고차 데이터가 많이 필요합니다.5 NOTE_ 머신러닝에서 속성 ( attribute )은 데이터 타입(예를 들면 주행거리)을 말합니다. 특성은 문맥에 따라

여러 의미를 갖지만 일반적으로 속성과 값이 합쳐진 것을 의미합니다(예를 들면 주행거리= 15,000 ). 하지만 많은 사람이 속성과 특성을 구분하지 않고 사용합니다.5

3 옮긴이_ 머신러닝에서 레이블의 범주를 클래스(class )라고 부릅니다. 이 책에서는 프로그램 언어의 클래스와 같은 용어를 사용하므로 혼동하지 않도록 주의하세요. 4 재미있는 사실: 이 이상한 이름은 프란시스 골턴(Francis Galton )이 키가 큰 사람의 아이가 부모보다 작은 경향이 있다는 사실을 연구 하면서 소개한 통계학 용어입니다. 부모보다 아이가 더 작기 때문에 이를 평균으로 회귀한다고 불렀습니다. 그 후 프란시스가 두 변수 사 이의 상관관계를 분석하기 위해 사용한 방법에 이 이름을 붙였습니다. 5 옮긴이_ 이러한 이유로 원서에서는 데이터의 열(column )을 표현할 때 특성과 속성을 혼용하고 있습니다. 번역서에서는 데이터의 열 또 는 변수를 의미할 때는 ‘특성’으로, 파이썬 클래스나 인스턴스의 변수를 의미하는 ‘property’와 ‘attribute’는 ‘속성’으로 번역했습니다.

1장 한눈에 보는 머신러닝

39


그림 1-6 회귀 값

값?

새로운 샘플

특성 1

일부 회귀 알고리즘은 분류에 사용할 수도 있고 또 반대의 경우도 있습니다. 예를 들어 분류 에 널리 쓰이는 로지스틱 회귀는 클래스에 속할 확률을 출력합니다(예를 들면 스팸일 가능성

20%). 다음은 가장 중요한 지도 학습 알고리즘들입니다(이 책에서 모두 다룹니다). k -최근접 이웃 k-Nearest Neighbors

선형 회귀 Linear Regression

로지스틱 회귀 Logistic Regression

서포트 벡터 머신 Support Vector Machines (SVM )

결정 트리 Decision Tree 와 랜덤 포레스트 Random Forests

신경망 Neural networks 6

비지도 학습 비지도 학습 unsupervised learning 에는 말 그대로 훈련 데이터에 레이블이 없습니다(그림 1-7 ). 시 스템이 아무런 도움 없이 학습해야 합니다. 6 오토인코더나 제한된 볼츠만 머신(restricted Boltzmann machine ) 같이 일부 신경망 구조는 비지도 학습일 수 있습니다. 신경망은 또한 심층 신뢰 신경망(deep belief networks )이나 비지도 사전훈련(unsupervised pretraining )처럼 준지도 학습일 수도 있습니 다. 옮긴이_ 비지도 사전훈련은 11장을, 제한된 볼츠만 머신과 심층 신뢰 신경망은 부록 E를 참조하세요. 오토인코더는 15장에서 자세히 설명합니다.

40

1부 머신러닝


그림 1-7 비지도 학습에서 레이블 없는 훈련 세트 훈련 세트

다음은 가장 중요한 비지도 학습 알고리즘7입니다(8장에서 차원 축소에 대해 다룹니다). 군집 clustering

- k -평균 k-Means - 계층 군집 분석 Hierarchical Cluster Analysis (HCA ) - 기댓값 최대화 Expectation Maximization 시각화 visualization 와 차원 축소 dimensionality reduction

- 주성분 분석 Principal Component Analysis (PCA ) - 커널 kernel PCA - 지역적 선형 임베딩 Locally-Linear Embedding (LLE ) - t -SNE t-distributed Stochastic Neighbor Embedding 연관 규칙 학습 Association rule learning

- 어프라이어리 Apriori - 이클렛 Eclat

예를 들어 블로그 방문자에 대한 데이터가 많이 있다고 합시다. 비슷한 방문자들을 그룹으로 묶 기 위해 군집 알고리즘을 적용하려 합니다(그림 1-8 ). 하지만 방문자가 어떤 그룹에 속하는지 알고리즘에 알려줄 수 있는 데이터 포인트가 없습니다. 그래서 알고리즘이 스스로 방문자 사이 의 연결고리를 찾습니다. 예를 들어 40%의 방문자가 만화책을 좋아하며 저녁때 블로그 글을 읽 는 남성이고, 20%는 주말에 방문하는 공상 과학을 좋아하는 젊은 사람임을 알게 될지도 모릅 7 옮긴이_ k -평균, 계층 군집 등 여러 가지 비지도 학습 알고리즘은 『파이썬 라이브러리를 활용한 머신러닝』(한빛미디어, 2017 )을 참고하 세요.

1장 한눈에 보는 머신러닝

41


니다. 계층 군집 hierarchical clustering 알고리즘을 사용하면 각 그룹을 더 작은 그룹으로 세분화할 수 있습니다.8 그러면 각 그룹에 맞춰 블로그에 글을 쓰는 데 도움이 될 것입니다. 그림 1-8 군집 특성 2

특성 1

시각화 visualization 알고리즘도 비지도 학습 알고리즘의 좋은 예입니다. 레이블이 없는 대규모의 고차원 데이터를 넣으면 도식화가 가능한 2D나 3D 표현을 만들어줍니다(그림 1-9 ). 이런 알 고리즘은 가능한 한 구조를 그대로 유지하려 하므로(예를 들어 입력 공간에서 떨어져 있던 클 러스터 cluster 는 시각화된 그래프에서 겹쳐지지 않게 유지됩니다) 데이터가 어떻게 조직되어 있 는지 이해할 수 있고 예상하지 못한 패턴을 발견할 수도 있습니다. 비슷한 작업으로는 너무 많은 정보를 잃지 않으면서 데이터를 간소화하려는 차원 축소 dimensionality reduction

가 있습니다. 이렇게 하는 한 가지 방법은 상관관계가 있는 여러 특성을 하나

로 합치는 것입니다. 예를 들어 차의 주행거리는 연식과 매우 연관되어 있으므로 차원 축소 알 고리즘으로 두 특성을 차의 마모 정도를 나타내는 하나의 특성으로 합칠 수 있습니다. 이를 특 성 추출 feature extraction 이라고 합니다. TIP

(지도 학습 알고리즘 같은) 머신러닝 알고리즘에 데이터를 주입하기 전에 차원 축소 알고리즘을 사용하여 훈

련 데이터의 차원을 줄이는 것이 유용할 때가 많습니다. 실행 속도가 훨씬 빨라지고 디스크와 메모리를 차지하는 공 간도 줄고 경우에 따라 성능이 좋아지기도 합니다.

8 옮긴이_ 여기에서 설명하는 계층 군집은 하향식(top - down )인 분할 군집(divisive clustering )을 말합니다. 사이킷런(Scikit - Learn ) 에서는 상향식(bottom - up ) 계층 군집인 병합 군집(agglomerative clustering , https://goo.gl/9xKpxQ ) 알고리즘을 제공하고 있습니다.

42

1부 머신러닝


그림 1-9 의미 있는 군집을 강조한 t-SNE 시각화의 예 9 개구리

고양이 새 개 트럭

고양이 승용차 트럭

승용차

개구리 배 비행기

사슴

말 새 개 사슴

비행기

또 하나의 중요한 비지도 학습은 이상치 탐지 anomaly detection 입니다. 예를 들어 부정 거래를 막 기 위해 이상한 신용카드 거래를 감지하고, 제조 결함을 잡아내고, 학습 알고리즘에 주입하기 전에 데이터셋에서 이상한 값을 자동으로 제거하는 것 등입니다. 시스템은 정상 샘플로 훈련되 고, 새로운 샘플이 정상 데이터인지 혹은 이상치인지 판단합니다(그림 1-10 ). 널리 사용되는 또 다른 비지도 학습은 대량의 데이터에서 특성 간의 흥미로운 관계를 찾는 연 관 규칙 학습 association rule learning 입니다.10 예를 들어 여러분이 슈퍼마켓을 운영한다고 가정합시 다. 판매 기록에 연관 규칙을 적용하면 바비큐 소스와 감자를 구매한 사람이 스테이크도 구매 하는 경향이 있다는 것을 찾을지도 모릅니다.

9 동물이 운송 수단과 잘 구분되어 있고 말이 사슴과 가깝지만 새와 떨어져 있는 것 등을 확인할 수 있습니다. 이 그림은 소셔(Socher ), 간 주(Ganjoo ), 매닝(Manning ), 앤드류 응(Andrew Ng )의 「T- SNE visualization of the semantic word space」(2013 )입니다. 옮긴이_ 이 그림은 「Zero - Shot Learning Through Cross- Modal Transfer」 (https://arxiv.org/abs/1301.3666 )에서 발 췌했습니다. 10 옮긴이_ 연관 규칙은 규칙 기반(rule - based ) 학습의 한 종류로, 사이킷런에서는 제공하지 않습니다.

1장 한눈에 보는 머신러닝

43


그림 1-10 이상치 탐지 특성 2

새로운 샘플 이상치 정상

훈련 샘플 특성 1

준지도 학습 어떤 알고리즘은 레이블이 일부만 있는 데이터도 다룰 수 있습니다. 보통은 레이블이 없는 데이 터가 많고 레이블이 있는 데이터는 아주 조금입니다. 이를 준지도 학습 semisupervised learning 이라고 합니다(그림 1-11 ). 구글 포토 호스팅 서비스가 좋은 예입니다. 이 서비스에 가족사진을 모두 올리면 사람 A는 사 진 1, 5, 11에 있고, 사람 B는 사진 2, 5, 7에 있다고 자동으로 인식합니다. 이는 비지도 학습 (군집)입니다. 이제 시스템에 필요한 것은 이 사람들이 누구인가 하는 정보입니다. 사람마다 레이블이 하나씩만 주어지면 11 사진에 있는 모든 사람의 이름을 알 수 있고, 편리하게 사진을 찾을 수 있습니다. 대부분의 준지도 학습 알고리즘은 지도 학습과 비지도 학습의 조합으로 이루어져 있습니다. 예를 들어 심층 신뢰 신경망 deep belief network (DBN )은 여러 겹으로 쌓은 제한된 볼츠만 머신 restricted Boltzmann machine

(RBM )이라 불리는 비지도 학습에 기초합니다. RBM이 비지도 학습 방

식으로 순차적으로 훈련된 다음 전체 시스템이 지도 학습 방식으로 세밀하게 조정됩니다.

11 이는 시스템이 완벽했을 때입니다. 실제로는 사람마다 여러 개의 군집이 만들어지고 때로는 비슷한 외모의 두 사람이 섞이기도 합니다. 그래서 사람마다 레이블링을 여러 번 하고 어떤 군집은 수동으로 정리해야 합니다.

44

1부 머신러닝


그림 1-11 준지도 학습 특성 2

클래스?

특성 1

강화 학습 강화 학습 Reinforcement Learning 은 매우 다른 종류의 알고리즘입니다. 여기서는 학습하는 시스템을 에이전트라고 부르며 환경 environment 을 관찰해서 행동 action 을 실행하고 그 결과로 보상 reward (또 는 [그림 1-12]처럼 부정적인 보상에 해당하는 벌점 penalty )을 받습니다. 시간이 지나면서 가장 큰 보상을 얻기 위해 정책 policy 이라고 부르는 최상의 전략을 스스로 학습합니다. 정책은 주어진 상황에서 에이전트가 어떤 행동을 선택해야 할지 정의합니다. 그림 1-12 강화 학습 에이전트

환경

관찰 정책에 따라 행동을 선택

앗 뜨거워!

행동 실행!

-50점

보상이나 벌점을 받음

안 좋군! 다음엔 피해야지

정책 수정 (학습 단계) 최적의 정책을 찾을 때까지 반복

1장 한눈에 보는 머신러닝

45


예를 들어 보행 로봇을 만들기 위해 강화학습 알고리즘을 많이 사용합니다. 딥마인드 DeepMind 의 알파고 AlphaGo 프로그램도 강화 학습의 좋은 예입니다. 2017년 5월 바둑 세계챔피언인 커제 선 수를 이겨서 신문의 헤드라인을 장식했습니다. 알파고는 수백만 개의 게임을 분석해서 승리에 대한 전략을 학습했으며 자기 자신과 많은 게임을 했습니다. 알파고가 세계챔피언과 게임할 때 는 학습 기능을 끄고 그동안 학습했던 전략을 적용한 것입니다.12

1.3.2 배치 학습과 온라인 학습 머신러닝 시스템을 분류하는 데 사용하는 다른 기준은 입력 데이터의 스트림 stream 으로부터 점 진적으로 학습할 수 있는지 여부입니다.

배치 학습 배치 학습 batch learning 에서는 시스템이 점진적으로 학습할 수 없습니다. 가용한 데이터를 모두 사 용해 훈련시켜야 합니다. 일반적으로 이 방식은 시간과 자원을 많이 소모하므로 보통 오프라인 에서 수행됩니다. 먼저 시스템을 훈련시키고 그런 다음 제품 시스템에 적용하면 더 이상의 학습 없이 실행됩니다. 즉, 학습한 것을 단지 적용만 합니다. 이를 오프라인 학습 offline learning 이라고 합니다. 배치 학습 시스템이 (새로운 종류의 스팸 같은) 새로운 데이터에 대해 학습하려면 (새로운 데 이터뿐만 아니라 이전 데이터도 포함한) 전체 데이터를 사용하여 시스템의 새로운 버전을 처음 부터 다시 훈련해야 합니다. 그런 다음 이전 시스템을 중지시키고 새 시스템으로 교체합니다. 다행히 ([그림 1-3]에 보았듯이) 머신러닝 시스템을 훈련, 평가, 론칭하는 전체 과정이 쉽게 자동화될 수 있어서 배치 학습 시스템도 변화에 적응할 수 있습니다. 데이터를 업데이트하고 시스템의 새 버전을 필요한 만큼 자주 훈련시키면 됩니다. 이런 방식이 간단하고 잘 작동하지만 전체 데이터셋을 사용해 훈련하는 데 몇 시간이 소요될 수 있습니다. 보통 24시간마다 또는 매주 시스템을 훈련시킵니다. 시스템이 빠르게 변하는 데 이터에 적응해야 한다면(예를 들면 주식가격) 더 능동적인 방법이 필요합니다.

12 옮긴이_ 딥마인드는 2017년 10월에 기보 없이 스스로 학습하여 기존 알파고를 능가하는 알파고 제로(AlphaGo Zero )를 공개했습 니다. https://goo.gl/MeFZmM

46

1부 머신러닝


또한 전체 데이터셋을 사용해 훈련한다면 많은 컴퓨팅 자원이 필요합니다(CPU, 메모리 공간, 디스크 공간, 디스크 IO, 네트워크 IO 등). 대량의 데이터를 가지고 있는데 매일 처음부터 새 로 훈련시키도록 시스템을 자동화한다면 큰 비용이 발생할 것입니다. 데이터 양이 아주 많으면 배치 학습 알고리즘을 사용하는 게 불가능할 수도 있습니다. 마지막으로, 자원이 제한된 시스템(예를 들면 스마트폰 또는 화성 탐사 로버 rover )이 스스로 학 습해야 할 때 많은 양의 훈련 데이터를 나르고 학습을 위해 매일 몇 시간씩 많은 자원을 사용하 면 심각한 문제를 일으킵니다. 이런 경우에는 점진적으로 학습할 수 있는 알고리즘을 사용하는 편이 낫습니다.

온라인 학습 온라인 학습 online learning 에서는 데이터를 순차적으로 한 개씩 또는 미니배치 mini-batch 라 부르는 작은 묶음 단위로 주입하여 시스템을 훈련시킵니다. 매 학습 단계가 빠르고 비용이 적게 들어 시스템은 데이터가 도착하는 대로 즉시 학습할 수 있습니다(그림 1-13 ). 그림 1-13 온라인 학습 실행 및 학습 새로운 데이터(실시간)

론칭! 데이터

머신러닝 알고리즘 훈련

솔루션 평가

온라인 학습은 연속적으로 데이터를 받고(예를 들면 주식가격) 빠른 변화에 스스로 적응해야 하는 시스템에 적합합니다. 컴퓨팅 자원이 제한된 경우에도 좋은 선택입니다. 온라인 학습 시스 템이 새로운 데이터 샘플을 학습하면 학습이 끝난 데이터는 더 이상 필요하지 않으므로 버리면 됩니다(이전 상태로 되돌릴 수 있도록 데이터를 재사용하기 위해 보관할 필요가 없다면). 이렇 게 되면 많은 공간을 절약할 수 있습니다.

1장 한눈에 보는 머신러닝

47


컴퓨터 한 대의 메인 메모리에 들어갈 수 없는 아주 큰 데이터셋을 학습하는 시스템에도 온라인 학습 알고리즘을 사용할 수 있습니다(이를 외부 메모리 out-of-core 학습이라고 합니다). 알고리 즘이 데이터 일부를 읽어 들이고 훈련 단계를 수행합니다. 전체 데이터가 모두 적용될 때까지 이 과정을 반복합니다(그림 1-14 ). CAUTION_ 이 경우 전체 프로세스는 보통 오프라인으로 실행됩니다(즉, 실시간 시스템에서 수행되는 것이

아닙니다). 그래서 온라인 학습이란 이름이 혼란을 줄 수 있습니다. 점진적 학습 incremental learning 이라고 생각하 세요.

그림 1-14 온라인 학습을 사용한 대량의 데이터 처리

많은 양의 데이터

문제 연구

부분으로 나누기

론칭!

온라인 머신러닝 알고리즘 훈련

솔루션 평가

오차 분석

온라인 학습 시스템에서 중요한 파라미터 하나는 변화하는 데이터에 얼마나 빠르게 적응할 것 인지 입니다. 이를 학습률 learning rate 이라고 합니다.13 학습률을 높게 하면 시스템이 데이터에 빠르게 적응하지만 예전 데이터를 금방 잊어버릴 것입니다(최근에 나타난 스팸의 종류만 걸러 낼 수 있는 스팸 필터를 원할 리는 없습니다). 반대로 학습률이 낮으면 시스템의 관성이 더 커 져서 더 느리게 학습됩니다. 하지만 새로운 데이터에 있는 잡음이나 대표성 없는 데이터 포인 트에 덜 민감해집니다. 온라인 학습에서 가장 큰 문제점은 시스템에 나쁜 데이터가 주입되었을 때 시스템 성능이 점진 적으로 감소한다는 점입니다. 운영 중인 시스템이라면 고객이 눈치챌지 모릅니다. 예를 들어 로 13 옮긴이_ 학습률은 대표적인 하이퍼파라미터입니다. 하이퍼파라미터에 대해서는 1.4.5절을 참조하세요.

48

1부 머신러닝


봇의 오작동 센서로부터, 혹은 검색 엔진을 속여 검색 결과 상위에 노출시키려는 누군가로부터 나쁜 데이터가 올 수 있습니다. 이런 위험을 줄이려면 시스템을 면밀히 모니터링하고 성능 감소 가 감지되면 즉각 학습을 중지시켜야 합니다(가능하면 이전 운영 상태로 되돌립니다). 입력 데 이터를 모니터링해서 비정상 데이터를 잡아낼 수도 있습니다(예를 들면 이상치 탐지 알고리즘 을 사용해서).

1.3.3 사례 기반 학습과 모델 기반 학습 머신러닝 시스템은 어떻게 일반화되는가에 따라 분류할 수도 있습니다. 대부분의 머신러닝 작 업은 예측을 만드는 것입니다. 이 말은 주어진 훈련 데이터로 학습하지만 훈련 데이터에서는 본 적 없는 새로운 데이터로 일반화되어야 한다는 뜻입니다. 훈련 데이터에서 높은 성능을 내는 것 이 좋지만 그게 전부는 아닙니다. 진짜 목표는 새로운 샘플에 잘 작동하는 모델입니다. 일반화를 위한 두 가지 접근법은 사례 기반 학습과 모델 기반 학습입니다.

사례 기반 학습 아마도 가장 간단한 형태의 학습은 단순히 기억하는 것입니다. 스팸 필터를 이러한 방식으로 만들면 사용자가 스팸이라고 지정한 메일과 동일한 모든 메일을 스팸으로 분류합니다. 최악의 방법은 아니지만 최선도 아닙니다. 스팸 메일과 동일한 메일을 스팸이라고 지정하는 대신 스팸 메일과 매우 유사한 메일을 구분하 도록 스팸 필터를 프로그램할 수 있습니다. 이렇게 하려면 두 메일 사이의 유사도 similarity 를 측 정해야 합니다. 두 메일 사이의 매우 간단한 유사도 측정 방법은 공통으로 포함한 단어의 수를 세는 것입니다. 스팸 메일과 공통으로 가지고 있는 단어가 많으면 스팸으로 분류합니다. 이를 사례 기반 학습 instance-based learning 이라고 합니다. 시스템이 사례를 기억함으로써 학습합니 다. 그리고 유사도 측정을 사용해 새로운 데이터에 일반화합니다(그림 1-15 ).

1장 한눈에 보는 머신러닝

49


그림 1-15 사례 기반 학습 특성 2

훈련 샘플 새로운 샘플

특성 1

모델 기반 학습 샘플로부터 일반화시키는 다른 방법은 이 샘플들의 모델을 만들어 예측에 사용하는 것입니다. 이를 모델 기반 학습 model-based learning 이라고 합니다(그림 1-16 ). 그림 1-16 모델 기반 학습 특성 2

모델

새로운 샘플

특성 1

예를 들어 돈이 사람을 행복하게 만드는지 알아본다고 가정합시다. OECD 웹사이트(https:// goo.gl/0Eht9W )에서 더 나은 삶의 지표 Better Life Index 데이터와 IMF 웹사이트( http://goo.gl/ j1MSKe )에서 1인당 GDP 통계를 내려받습니다. 두 데이터 테이블을 합치고 1인당 GDP로 정

렬합니다. [표 1-1]에 그 일부를 나타냈습니다.

50

1부 머신러닝


표 1-1 돈이 사람을 행복하게 만드는가? 국가

1인당 GDP(US달러)

삶의 만족도

헝가리

12,240

4.9

대한민국

27,195

5.8

프랑스

37,675

6.5

호주

50,962

7.3

미국

55,805

7.2

일부 국가를 무작위로 골라서 그래프를 그려봅시다(그림 1-17 ).

삶의 만족도

그림 1-17 어떤 경향이 보이나요?

호주

미국

프랑스 대한민국 헝가리

1인당 GDP

여기서 어떤 경향을 볼 수 있습니다! 데이터가 흩어져 있지만(즉, 어느 정도 무작위성이 있지 만) 삶의 만족도는 국가의 1인당 GDP가 증가할수록 거의 선형으로 같이 올라갑니다. 그러므로

1인당 GDP의 선형 함수로 삶의 만족도를 모델링해보겠습니다. 이 단계를 모델 선택 model selection 이라고 합니다. 1인당 GDP라는 특성 하나를 가진 삶의 만족도에 대한 선형 모델 linear model 입니 다(식 1-1 ). 식 1-1 간단한 선형 모델

삶의_만족도 = θ 0 + θ 1 × 1인당_GDP

이 모델은 두 개의 모델 파라미터 θ 0과 θ 1을 가집니다.14 이 모델 파라미터를 조정하여 [그림

1-18]처럼 어떤 선형 함수를 표현하는 모델을 얻을 수 있습니다. 14 관습적으로 그리스 문자 θ (세타)는 모델 파라미터를 표현할 때 자주 사용합니다. 옮긴이_ ω (오메가)와 β (베타)도 자주 사용합니다.

1장 한눈에 보는 머신러닝

51


삶의 만족도

그림 1-18 가능한 몇 개의 선형 모델

1인당 GDP

모델을 사용하기 전에 θ 0과 θ 1을 정의해야 합니다. 모델이 최상의 성능을 내도록 하는 값을 어떻 게 알 수 있을까요? 이 질문에 대답하려면 측정 지표를 정해야 합니다. 모델이 얼마나 좋은지 측 정하는 효용 함수 utility function (또는 적합도 함수 fitness function )를 정의하거나 얼마나 나쁜지 측정 하는 비용 함수 cost function 를 정의할 수 있습니다. 선형 회귀에서는 보통 선형 모델의 예측과 훈 련 데이터 사이의 거리를 재는 비용 함수를 사용합니다. 이 거리를 최소화하는 것이 목표입니다. 여기에서 선형 회귀 Linear Regression 알고리즘이 등장합니다. 알고리즘에 훈련 데이터를 공급하면 데이터에 가장 잘 맞는 선형 모델의 파라미터를 찾습니다. 이를 모델을 훈련 training 시킨다고 말 합니다. 이 경우에는 알고리즘이 최적의 파라미터로 θ 0 = 4.85와 θ 1 = 4.91 × 10-5을 찾았습니다. [그림 1-19]에서 볼 수 있듯이 모델이 훈련 데이터에 (선형 모델로서) 가능한 한 가깝게 맞춰졌 습니다.

삶의 만족도

그림 1-19 훈련 데이터에 최적인 선형 모델

1인당 GDP

52

1부 머신러닝


이제 이 모델을 사용해 예측을 할 수 있습니다. 예를 들어 OECD 데이터에 없는 키프로스 Cyprus 15 사람들이 얼마나 행복한지 알아보려면 이 모델을 사용해 예측할 수 있습니다. 키프로스의 1인당

GDP를 보면 22,587달러이므로 이를 모델에 적용해 4.85 + 22,587 × 4.91 × 10-5 = 5.96과 같 이 삶의 만족도를 계산합니다. [예제 1-1]의 파이썬 코드16는 데이터를 로드하고 준비한 다음 산점도 scatterplot 를 그려 시각화 하고 선형 모델을 훈련하여 예측하는 과정을 보여줍니다.17 예제 1-1 사이킷런을 이용한 선형 모델의 훈련과 실행

import import import import import

matplotlib matplotlib.pyplot as plt numpy as np pandas as pd sklearn

# 데이터 적재 oecd_bli = pd.read_csv("oecd_bli_2015.csv", thousands=',') gdp_per_capita = pd.read_csv("gdp_per_capita.csv",thousands=',',delimiter='\t', encoding='latin1', na_values="n/a") # 데이터 준비 country_stats = prepare_country_stats(oecd_bli, gdp_per_capita) X = np.c_[country_stats["GDP per capita"]] y = np.c_[country_stats["Life satisfaction"]] # 데이터 시각화 country_stats.plot(kind='scatter', x="GDP per capita", y='Life satisfaction') plt.show() # 선형 모델 선택 model = sklearn.linear_model.LinearRegression() # 모델 훈련 model.fit(X, y)

15 옮긴이_ 키프로스는 터키 아래쪽에 위치한 아름다운 지중해 섬나라입니다. 1974년에 일어난 내전 이후 터키계인 북부와 그리스계인 남부로 분단되어 있습니다. 16 이 코드는 GDP와 삶의 만족도 데이터를 하나의 판다스 데이터프레임으로 합치는 prepare_country_stats ( ) 함수가 미리 정의 되어 있다고 가정합니다. 옮긴이_ 1장의 주피터 노트북 안에 이 함수가 정의되어 있습니다. 17 전체 코드를 이해하지 못해도 괜찮습니다. 다음 장에서 사이킷런에 대해 소개합니다.

1장 한눈에 보는 머신러닝

53


# 키프로스에 대한 예측 X_new = [[22587]] # 키프로스 1인당 GDP print(model.predict(X_new)) # 결과 [[ 5.96242338]]

NOTE_ 사례 기반의 학습 알고리즘을 사용한다면 먼저 1인당 GDP가 키프로스와 가장 가까운 슬로베니아 Slovenia

(20,732달러)를 찾습니다. OECD 데이터에 있는 슬로베니아의 삶의 만족도가 5.7이므로 키프로스의

삶의 만족도를 5.7로 예측합니다. 조금 더 확대해서 그다음으로 가까운 두 나라를 더 고려하면 삶의 만족도가

5.1과 6.5인 포르투갈 Portugal 과 스페인 Spain 이 있습니다. 이 세 값을 평균하면 모델 기반의 예측과 매우 비슷한 5.77이 됩니다. 이 간단한 알고리즘을 k -최근접 이웃 k-Nearest Neighbors 회귀라고 합니다(여기서는 k = 3입니 다). 이전 코드에서 선형 회귀 모델을 k -최근접 이웃 회귀로 바꾸려면 아래 한 줄을 model = sklearn.linear_model.LinearRegression ( ) 다음과 같이 바꾸면 됩니다. model = sklearn.neighbors.KNeighborsRegressor (n_neighbors=3 )

모든 게 다 잘되면 모델은 좋은 예측을 내놓을 것입니다. 아니면 더 많은 특성(고용률, 건강, 대 기오염 등)을 사용하거나, 좋은 훈련 데이터를 더 많이 모으거나, 더 강력한 모델(예를 들면 다 항 회귀 모델)을 선택해야 할지 모릅니다. 지금까지의 작업을 요약해보겠습니다. 데이터를 분석합니다.

모델을 선택합니다.

훈련 데이터로 모델을 훈련시킵니다(즉, 학습 알고리즘이 비용 함수를 최소화하는 모델 파라미터를 찾습니

다). 마지막으로 새로운 데이터에 모델을 적용해 예측을 하고(이를 추론 inference 이라고 합니다), 이 모델이 잘 일반

화되길 기대합니다.

이것이 전형적인 머신러닝 프로젝트의 형태입니다. 2장에서 완전한 프로젝트를 진행하면서 직 접 경험해볼 것입니다. 지금까지 많은 부분을 다뤘습니다. 머신러닝이 무엇인지, 왜 유용한지, 머신러닝 시스템의 가장 일반적인 분류는 무엇인지, 그리고 전형적인 머신러닝 프로젝트의 작업 흐름이 어떤지 배웠습니 다. 다음 절에서는 학습 과정에서 발생할 수 있는 문제와 정확한 예측을 방해하는 것들에 대해 알아보겠습니다. 54

1부 머신러닝


1.4 머신러닝의 주요 도전 과제 간단하게 말해 우리의 주요 작업은 학습 알고리즘을 선택해서 어떤 데이터에 훈련시키는 것이므 로 문제가 될 수 있는 두 가지는 ‘나쁜 알고리즘’과 ‘나쁜 데이터’입니다. 이 절에서는 이 두 가지 에 대해 알아봅니다. 나쁜 데이터의 사례부터 알아보겠습니다.

1.4.1 충분하지 않은 양의 훈련 데이터 어린아이에게 사과에 대해 알려주려면 사과를 가리키면서 ‘사과’라고 말하기만 하면 됩니다(아 마도 이 과정을 여러 번 반복해야 합니다). 그러면 아이는 색깔과 모양이 달라도 모든 종류의 사 과를 구분할 수 있습니다. 정말 똑똑하지요. 머신러닝은 아직 이렇게까지는 못합니다. 대부분의 머신러닝 알고리즘이 잘 작동하려면 데이터 가 많아야 합니다. 아주 간단한 문제에서조차도 수천 개의 데이터가 필요하고 이미지나 음성 인 식 같은 복잡한 문제라면 수백만 개가 필요할지도 모릅니다(이미 만들어진 모델을 재사용할 수 없다면 말이죠).

믿을 수 없는 데이터의 효과 2001년에 발표한 유명한 논문(http://goo.gl/R5enIE )에서 마이크로소프트 연구자인 미셸 반 코 Michele Banko 와 에릭 브릴 Eric Brill 은 아주 간단한 모델을 포함하여 여러 다른 머신러닝 알고리즘 에 충분한 데이터가 주어지면 복잡한 자연어 중의성 해소 disambiguation18 문제를 거의 비슷하게 잘 처리한다는 것을 보였습니다([그림 1-20]에서 볼 수 있습니다). 이 논문의 저자들이 말한 것처럼 ‘이 결과가 제시하는 것은 시간과 돈을 알고리즘 개발에 쓰는 것 과 말뭉치 corpus 개발에 쓰는 것 사이의 트레이드오프에 대해 다시 생각해봐야 한다는 것입니다.’ 복잡한 문제에서 알고리즘보다 데이터가 더 중요하다는 이 생각은 2009년에 피터 노르빅 Peter Norvig

등이 쓴 「The Unreasonable Effectiveness of Data」(http://goo.gl/q6LaZ8, 2009 )

논문 때문에 더 유명해졌습니다. 하지만 기억할 점은 작거나 중간 규모의 데이터셋이 여전히 매 우 흔하고, 훈련 데이터를 추가로 모으는 것이 항상 쉽거나 저렴한 일은 아니므로, 아직은 알고 리즘을 무시하지 말아야 한다는 것입니다.

18 예를 들어 문맥에 따라 ‘to’, ‘two’, ‘too’ 중 어떤 것을 써야 할지 아는 것

1장 한눈에 보는 머신러닝

55


테스트 정확도

그림 1-20 알고리즘 대비 데이터의 중요성19

메모리 기반 윈나우 퍼셉트론 나이브 베이지

단어 수(백만)

1.4.2 대표성 없는 훈련 데이터 일반화가 잘되려면 우리가 일반화하기 원하는 새로운 사례를 훈련 데이터가 잘 대표하는 것이 중요합니다. 이는 사례 기반 학습이나 모델 기반 학습 모두 마찬가지입니다. 예를 들어 앞서 선형 모델을 훈련시키기 위해 사용한 나라의 집합에는 일부 나라가 빠져 있어 대표성이 완벽하지 못합니다. [그림 1-21]은 누락된 나라를 추가했을 때 데이터가 어떻게 나타 나는지 보여줍니다. 이 데이터에 선형 모델을 훈련시키면 실선으로 된 모델을 얻습니다. 반면 이전 모델은 점선으 로 나타나 있습니다. 그림에서 알 수 있듯이 누락된 나라를 추가하면 모델이 크게 변경될 뿐만 아니라 이런 간단한 선형 모델은 잘 작동하지 않는다는 걸 확실히 보여줍니다. 매우 부유한 나 19 이 그림은 반코와 브릴의 「Learning Curves for Confusion Set Disambiguation」(2001 )을 허락받아 옮긴 것입니다. 옮긴이_ 이 그림에서 윈나우(Winnow ) 알고리즘은 퍼셉트론(Perceptron )과 비슷한 선형 분류 알고리즘으로, 가중치 혹은 모델 파라미터를 변경할 때 덧셈이 아니라 곱셈, 즉 일정한 배수로 이루어집니다.

56

1부 머신러닝


라가 중간 정도의 나라보다 행복하지 않고(실제로도 더 행복해보이지 않습니다), 반대로 일부 가난한 나라가 부유한 나라보다 행복한 것 같습니다. 그림 1-21 대표성이 더 큰 훈련 샘플

칠레

체코

삶의 만족도

브라질 멕시코

노르웨이

스위스

룩셈부르크

1인당 GDP

대표성 없는 훈련 데이터를 사용했으므로 정확한 예측을 하지 못하는, 특히 매우 가난하거나 부 유한 나라에서 잘못 예측하는 모델을 훈련시켰습니다. 일반화하려는 사례들을 대표하는 훈련 세트를 사용하는 것이 매우 중요하지만, 이게 생각보다 어 려울 때가 많습니다. 샘플이 작으면 샘플링 잡음 sampling noise (즉, 우연에 의한 대표성 없는 데이 터)이 생기고, 매우 큰 샘플도 표본 추출 방법이 잘못되면 대표성을 띠지 못할 수 있습니다. 이 를 샘플링 편향 sampling bias 이라고 합니다.

유명한 샘플링 편향 사례 아마도 샘플링 편향에 대한 가장 유명한 사례는 랜던 Randon 과 루즈벨트 Roosevelt 가 경쟁했던 1936 년 미국 대통령 선거에서 Literary Digest 잡지사가 천만 명에게 우편물을 보내 수행한 대규모 여론조사일 것입니다. 240만 명의 응답을 받았고 랜던이 선거에서 57% 득표를 얻을 것이라고 높은 신뢰도로 예측했습니다. 하지만 루즈벨트가 62% 득표로 당선되었습니다. 문제는 Literary Digest의 샘플링 방법에 있었 습니다. 첫 째, 여론조사용 주소를 얻기 위해 전화번호부, 자사의 구독자 명부, 클럽 회원 명부 등을 사용했습니다. 이

런 명부는 모두 공화당(따라서 랜던)에 투표할 가능성이 높은 부유한 계층에 편중된 경향이 있습니다.

1장 한눈에 보는 머신러닝

57


둘 째, 우편물 수신자 중 25% 미만의 사람이 응답했습니다. 이는 정치에 관심 없는 사람, Literary Digest를

싫어하는 사람과 다른 중요한 그룹을 제외시킴으로써 역시 표본을 편향되게 만들었습니다. 특히 이러한 종류 의 샘플링 편향을 비응답 편향 nonresponse bias 이라고 합니다.

다른 예로 펑크 음악 비디오를 분류하는 시스템을 만든다고 가정합시다. 이를 위한 훈련 세트를 유투브에서 ‘펑크 음악’을 검색해 마련할 수 있습니다. 하지만 이는 유투브 검색 엔진이 결괏값으 로 유투브 내의 모든 펑크 음악을 대표하는 동영상을 반환한다고 가정하는 것입니다. 현실에서 는 검색 결과가 인기 음악가들로 편중될 가능성이 큽니다(브라질에 살고 있다면 ‘펑크 음악의 아 버지’ 제임스 브라운 James Brown 과 전혀 상관없는 ‘펑크 카리오카 funk carioca ’ 동영상을 결과로 보게 될 것입니다). 그렇다면 어떻게 대량의 훈련 세트를 구할 수 있을까요?20

1.4.3 낮은 품질의 데이터 훈련 데이터가 에러, 이상치 outlier , 잡음(예를 들면 성능이 낮은 측정 장치 때문에)으로 가득하 다면 머신러닝 시스템이 내재된 패턴을 찾기 어려워 잘 작동하지 않을 것입니다. 그렇기 때문에 훈련 데이터 정제에 시간을 투자할 만한 가치는 충분합니다. 사실 대부분의 데이터 과학자가 데 이터 정제에 많은 시간을 쓰고 있습니다. 예를 들어보겠습니다. 일부 샘플이 이상치라는 게 명확하면 간단히 그것들을 무시하거나 수동으로 잘못된 것을 고치는 것이 좋습

니다. 일부 샘플에 특성 몇 개가 빠져있다면(예를 들면 고객 중 5%가 나이를 기록하지 않음), 이 특성을 모두 무시

할지, 이 샘플을 무시할지, 빠진 값을 채울지(예를 들면 평균 나이로), 또는 이 특성을 넣은 모델과 제외한 모 델을 따로 훈련시킬 것인지 등을 정해야 합니다.

1.4.4 관련 없는 특성 속담에도 있듯이 엉터리가 들어가면 엉터리가 나옵니다 garbage in, garbage out. 훈련 데이터에 관련 없는 특성이 적고 관련 있는 특성이 충분해야 시스템이 학습할 수 있을 것입니다. 성공적인 머신 러닝 프로젝트의 핵심 요소는 훈련에 사용할 좋은 특성들을 찾는 것입니다. 이 과정을 특성 공학 feature engineering

이라 하며 다음 작업을 포함합니다.

20 옮긴이_ 음악 분류를 위한 데이터셋으로는 161개의 장르에 걸쳐 106,574개의 노래를 샘플링한 FMA 데이터셋이 대표적입니다. 이 데이터셋에 대한 자세한 내용은 FMA 깃허브(https://github.com/mdeff/fma )를 참고하세요.

58

1부 머신러닝


특성 선택 feature selection : 가지고 있는 특성 중에서 훈련에 가장 유용한 특성을 선택합니다.

특성 추출 feature extraction : 특성을 결합하여 더 유용한 특성을 만듭니다(앞서 본 것처럼 차원 축소 알고리즘을

사용할 수 있습니다). 새로운 데이터를 수집해 새 특성을 만듭니다.

지금까지 나쁜 데이터의 사례를 살펴보았고 이제 나쁜 알고리즘의 예를 몇 가지 살펴보겠습니다.

1.4.5 훈련 데이터 과대적합 해외여행 중 택시운전사가 내 물건을 훔쳤다고 가정합시다. 아마도 그 나라의 모든 택시운전사 를 도둑이라고 생각할 수도 있습니다. 사람은 종종 과도하게 일반화를 하지만 주의하지 않으면 기계도 똑같은 함정에 빠질 수 있습니다. 머신러닝에서는 이를 과대적합 overfitting 이라고 합니 다. 이는 모델이 훈련 데이터에 너무 잘 맞지만 일반성이 떨어진다는 뜻입니다. [그림 1-22]는 고차원의 다항 회귀 모델이 삶의 만족도 훈련 데이터에 크게 과대적합된 사례를 보여줍니다. 간단한 선형 모델보다 이 모델이 훈련 데이터에 더 잘 맞는다 하더라도 실제로 이 예측을 믿기는 힘듭니다.

삶의 만족도

그림 1-22 훈련 데이터에 과대적합

1인당 GDP

심층 신경망 같은 복잡한 모델은 데이터에서 미묘한 패턴을 감지할 수 있지만, 훈련 세트에 잡 음이 많거나 데이터셋이 너무 작으면 (샘플링 잡음이 발생하므로) 잡음이 섞인 패턴을 감지하 게 됩니다. 당연히 이런 패턴은 새로운 샘플에 일반화되지 못합니다. 예를 들어 삶의 만족도 모 델에 나라 이름 같은 관련 없는 특성을 많이 추가한다고 합시다. 이 경우 복잡한 모델이 이름에

1장 한눈에 보는 머신러닝

59


‘w’가 들어간 나라들의 삶의 만족도가 7보다 크다는 패턴을 감지할지 모릅니다. 뉴질랜드 New Zealand

(7.3 ), 노르웨이 Norway (7.4 ), 스웨덴 Sweden (7.2 ), 스위스 Switzerland (7.5 )가 여기에 속합

니다. 이 W-만족도 규칙을 르완다 Rwanda 나 짐바브웨 Zimbabwe 에 일반화하면 얼마나 신뢰할 수 있을까요? 확실히 이 패턴은 우연히 훈련 데이터에서 찾은 것이지만 이 패턴이 진짜인지 잡음 데이터로 인한 것인지 모델이 구분해낼 방법은 없습니다. CAUTION_ 과대적합은 훈련 데이터에 있는 잡음의 양에 비해 모델이 너무 복잡할 때 일어납니다. 해결 방법

은 다음과 같습니다. 파라미터 수가 적은 모델을 선택하거나(예를 들면 고차원 다항 모델보다 선형 모델), 훈련 데이터에

있는 특성 수를 줄이거나, 모델에 제약을 가하여 단순화시킵니다. 훈련 데이터를 더 많이 모읍니다.

훈련 데이터의 잡음을 줄입니다(예를 들면 오류 데이터 수정과 이상치 제거).

모델을 단순하게 하고 과대적합의 위험을 감소시키기 위해 모델에 제약을 가하는 것을 규제 regularization

라고 합니다. 예를 들어 앞서 만든 선형 모델은 두 개의 파라미터 θ 0 과 θ 1 을 가지고

있습니다. 이는 훈련 데이터에 모델을 맞추기 위한 두 개의 자유도 degree of freedom 를 학습 알고리 즘에 부여합니다. 모델은 직선의 절편(θ 0 )과 기울기(θ 1 )를 조절할 수 있습니다. 우리가 θ 1 = 0 이 되도록 강제하면 알고리즘에 한 개의 자유도만 남게 되고 데이터에 적절하게 맞춰지기 힘들 것입니다. 즉, 할 수 있는 것이 훈련 데이터에 가능한 한 가깝게 되도록 직선을 올리거나 내리는 것이 전부이므로 결국 평균 근처가 됩니다. 진짜 아주 간단한 모델이네요! 알고리즘이 θ 1 을 수 정하도록 허락하되 작은 값을 갖도록 유지시키면 학습 알고리즘이 자유도 1과 2 사이의 적절 한 어딘가에 위치할 것입니다. 이는 자유도 2인 모델보다는 단순하고 자유도 1인 모델보다는 복잡한 모델을 만듭니다. 데이터에 완벽히 맞추는 것과 일반화를 위해 단순한 모델을 유지하는 것 사이의 올바른 균형을 찾는 것이 좋습니다. [그림 1-23]에 세 가지 모델이 있습니다. 점선은 나라 몇 개가 빠진 채로 훈련한 원래 모델이고 파선은 모든 나라를 포함시켜 훈련한 두 번째 모델이며 실선은 첫 번째 모델과 같은 데이터에 규제를 적용해 만든 선형 모델입니다. 규제가 모델의 기울기를 더 작게 만들어 훈련 데이터에 는 덜 맞지만 새로운 샘플에는 더 잘 일반화됩니다.

60

1부 머신러닝


삶의 만족도

그림 1-23 규제로 과대적합될 위험 감소

모든 데이터로 만든 선형 모델 일부 데이터로 만든 선형 모델 일부 데이터로 만든 규제가 적용된 선형 모델

1인당 GDP

학습하는 동안 적용할 규제의 양은 하이퍼파라미터 hyperparameter 가 결정합니다. 하이퍼파라미터 는 (모델이 아니라) 학습 알고리즘의 파라미터입니다. 그래서 학습 알고리즘으로부터 영향을 받지 않으며, 훈련 전에 미리 지정되고, 훈련하는 동안에는 상수로 남아 있습니다. 규제 하이퍼 파라미터를 매우 큰 값으로 지정하면 (기울기가 0에 가까운) 거의 평편한 모델을 얻게 됩니다. 그러면 학습 알고리즘이 훈련 데이터에 과대적합될 가능성은 거의 없겠지만 좋은 모델을 찾지 못합니다. 머신러닝 시스템을 구축할 때 하이퍼파라미터 튜닝은 매우 중요한 과정입니다(다음 장에서 자세한 예를 보겠습니다).

1.4.6 훈련 데이터 과소적합 이미 짐작했겠지만 과소적합 underfitting 은 과대적합의 반대입니다. 이는 모델이 너무 단순해서 데이터의 내재된 구조를 학습하지 못할 때 일어납니다. 예를 들어 삶의 만족도에 대한 선형 모 델은 과소적합되기 쉽습니다. 현실은 이 모델보다 더 복잡하므로 훈련 샘플에서조차도 부정확 한 예측을 만들 것입니다. 이 문제를 해결하는 주요 기법은 다음과 같습니다. 파라미터가 더 많은 강력한 모델을 선택합니다.

학습 알고리즘에 더 좋은 특성을 제공합니다(특성 엔지니어링).

모델의 제약을 줄입니다(예를 들면 규제 하이퍼파라미터를 감소시킵니다).

1장 한눈에 보는 머신러닝

61


1.4.7 한걸음 물러서서 지금까지 여러분은 벌써 머신러닝에 관해 많은 것을 배웠습니다. 그러나 많은 개념을 한꺼번에 다루다 보니 정리가 제대로 되지 않았을 것입니다. 한걸음 물러서서 큰 그림을 보겠습니다. 머신러닝은 명시적인 규칙을 코딩하지 않고 기계가 데이터로부터 학습하여 어떤 작업을 더 잘하도록 만드는

것입니다. 여러 종류의 머신러닝 시스템이 있습니다. 지도 학습과 비지도 학습, 배치 학습과 온라인 학습, 사례 기반 학습

과 모델 기반 학습 등입니다. 머신러닝 프로젝트에서는 훈련 세트에 데이터를 모아 학습 알고리즘에 주입합니다. 학습 알고리즘이 모델 기

반이면 훈련 세트에 모델을 맞추기 위해 파라미터를 조정하고(즉, 훈련 세트에서 좋은 예측을 만들기 위해), 새로운 데이터에서도 좋은 예측을 만들 거라 기대합니다. 알고리즘이 사례 기반이면 샘플을 기억하는 것이 학 습이고 새로운 샘플에 일반화하기 위해 유사도 측정을 사용합니다. 훈련 세트가 너무 작거나, 대표성이 없는 데이터이거나, 잡음이 많고 관련 없는 특성으로 오염되어 있다면 시

스템이 잘 작동하지 않습니다(엉터리가 들어가면 엉터리가 나옵니다). 마지막으로, 모델이 너무 단순하거나 (과소적합된 경우) 너무 복잡하지 않아야 합니다(과대적합된 경우).

마지막으로 다루어야 할 중요한 주제가 하나 있습니다. 모델을 학습시켰다 해서 새로운 샘플에 일반화되길 그냥 바라기만 해서는 안 됩니다. 모델을 평가하고 필요하면 상세하게 튜닝해야 합 니다. 어떻게 하는지 살펴보겠습니다.

1.5 테스트와 검증 모델이 새로운 샘플에 얼마나 잘 일반화될지 아는 유일한 방법은 새로운 샘플에 실제로 적용해 보는 것입니다. 이를 위해 실제 서비스에 모델을 넣고 잘 동작하는지 모니터링하는 방법이 있습 니다. 이 방법이 괜찮긴 하지만 만약 모델이 아주 나쁘다면 고객이 불만을 토로할 테니 좋은 생 각이 아닙니다. 더 나은 방법은 훈련 데이터를 훈련 세트와 테스트 세트 두 개로 나누는 것입니다. 이름에서도 알 수 있듯이 훈련 세트를 사용해 모델을 훈련시키고 테스트 세트를 사용해 모델을 테스트합니 다. 새로운 샘플에 대한 오류 비율을 일반화 오차 generalization error (또는 외부 샘플 오차 out-of-sample error

)라고 하며, 테스트 세트에서 모델을 평가함으로써 이 오차에 대한 추정값 estimation 을 얻습

니다. 이 값은 이전에 본 적이 없는 새로운 샘플에 모델이 얼마나 잘 작동할지 알려줍니다.

62

1부 머신러닝


훈련 오차가 낮지만(즉, 훈련 세트에서 모델의 오차가 적음) 일반화 오차가 높다면 이는 모델 이 훈련 데이터에 과대적합되었다는 뜻입니다. TIP

보통 데이터의 80%를 훈련에 사용하고 20%는 테스트용으로 떼어놓습니다.21

모델 평가는 아주 간단합니다. 그냥 테스트 세트를 사용하면 됩니다. 두 모델(선형 모델과 다항 모델) 중 어떤 것을 선택할지 갈등하고 있다고 합시다. 어떻게 결정할 수 있을까요? 두 모델 모 두 훈련 세트로 훈련시키고 테스트 세트를 사용해 얼마나 잘 일반화되는지 비교해보면 됩니다. 이제 선형 모델이 더 잘 일반화되었다고 가정하고 과대적합을 피하기 위해 규제를 적용하려고 합니다. 이때 하이퍼파라미터 값을 어떻게 선택할까요? 100개의 하이퍼파라미터 값으로 100 개의 다른 모델을 훈련시키는 방법이 있습니다. 일반화 오차가 가장 낮은 모델(5%라고 합시 다)을 만드는 최적의 하이퍼파라미터를 찾았다고 가정합시다. 이제 이 모델을 실제 서비스에 투입합니다. 하지만 성능이 예상만큼 좋지 않고 오차를 15%나 만듭니다. 왜 그럴까요? 일반화 오차를 테스트 세트에서 여러 번 측정했으므로 모델과 하이퍼파라미터가 테스트 세트 에 최적화된 모델을 만들었기 때문입니다. 이는 모델이 새로운 데이터에 잘 작동하지 않을 수 있다는 뜻입니다. 이 문제에 대한 일반적인 해결 방법은 검증 세트 validation set 라 부르는 두 번째 홀드아웃 holdout 세 트를 만드는 것입니다. 훈련 세트를 사용해 다양한 하이퍼파라미터로 여러 모델을 훈련시키고 검증 세트에서 최상의 성능을 내는 모델과 하이퍼파라미터를 선택합니다. 만족스러운 모델을 찾으면 일반화 오차의 추정값을 얻기 위해 테스트 세트로 단 한 번의 최종 테스트를 합니다. 훈련 데이터에서 검증 세트로 너무 많은 양의 데이터를 뺏기지 않기 위해 일반적으로 교차 검 증 cross-validation 기법을 사용합니다. 훈련 세트를 여러 서브셋 subset 으로 나누고 각 모델을 이 서 브셋의 조합으로 훈련시키고 나머지 부분으로 검증합니다. 모델과 하이퍼파라미터가 선택되면 전체 훈련 데이터를 사용하여 선택한 하이퍼파라미터로 최종 모델을 훈련시키고 테스트 세트 에서 일반화 오차를 측정합니다.

21 옮긴이_ 사이킷런의 train_test_split 함수는 기본적으로 25%를 테스트 세트로 떼어놓습니다. 하지만 데이터셋이 크면 테스트 세트의 비율은 훨씬 줄어들 수 있습니다.

1장 한눈에 보는 머신러닝

63


공짜 점심 없음 이론 모델은 관측한 것을 간소화한 것입니다. 간소화의 의미는 새로운 샘플에 일반적이지 않을 것 같은 불필요한 세부사항을 제거하는 것입니다. 그러나 어떤 데이터를 버리고 어떤 데이터를 남길지 정 하기 위해 가정을 해야 합니다. 예를 들어 선형 모델은 데이터가 근본적으로 선형이고 샘플과 직 선 사이의 거리는 무시할 수 있는 잡음이라고 가정합니다.

1996년에 발표한 유명한 논문 22 에서 데이비드 월퍼트 David Wolperts 는 데이터에 관해 완벽하게 어 떤 가정도 하지 않으면 한 모델을 다른 모델보다 선호할 근거가 없음을 보였습니다. 이를 공짜 점 심 없음 No Free Lunch (NFL ) 이론이라 합니다. 어떤 데이터셋에서는 선형 모델이 가장 잘 들어맞지 만 다른 데이터셋에서는 신경망이 잘 들어맞습니다. 경험하기 전에 더 잘 맞을 거라고 보장할 수 있는 모델은 없습니다(이 이론의 이름이 유래된 이유입니다). 어떤 모델이 최선인지 확실히 아는 유일한 방법은 모든 모델을 평가해보는 것뿐입니다. 이것이 불가능하기 때문에 실전에서는 데이 터에 관해 타당한 가정을 하고 적절한 모델 몇 가지만 평가합니다. 예를 들어 간단한 작업에서는 규제의 수준이 다양한 선형 모델을 평가하고, 복잡한 문제라면 여러 가지 신경망을 평가합니다.

1.6 연습문제 이 장에서는 머신러닝에서 가장 중요한 개념을 다뤘습니다. 다음 장에서는 조금 더 깊게 들어 가고 더 많은 코드를 작성하겠습니다. 그전에 다음 질문에 대한 답을 찾아보세요.

1. 머신러닝을 어떻게 정의할 수 있나요? 2. 머신러닝이 도움을 줄 수 있는 문제 유형 네 가지를 말해보세요. 3. 레이블된 훈련 세트란 무엇인가요? 4. 가장 널리 사용되는 지도 학습 작업 두 가지는 무엇인가요? 5. 보편적인 비지도 학습 작업 네 가지는 무엇인가요? 6. 사전 정보가 없는 여러 지형에서 로봇을 걸어가게 하려면 어떤 종류의 머신러닝 알고리즘 을 사용할 수 있나요? 22 「The Lack of A Priori Distinctions Between Learning Algorithms」, D. Wolperts (1996 ), https://goo.gl/uJxSvo

64

1부 머신러닝


7. 고객을 여러 그룹으로 분할하려면 어떤 알고리즘을 사용해야 하나요? 8. 스팸 감지의 문제는 지도 학습과 비지도 학습 중 어떤 문제로 볼 수 있나요? 9. 온라인 학습 시스템이 무엇인가요? 10. 외부 메모리 학습이 무엇인가요? 11. 예측을 하기 위해 유사도 측정에 의존하는 학습 알고리즘은 무엇인가요? 12. 모델 파라미터와 학습 알고리즘의 하이퍼파라미터 사이에는 어떤 차이가 있나요? 13. 모델 기반 알고리즘이 찾는 것은 무엇인가요? 성공을 위해 이 알고리즘이 사용하는 가장 일반적인 전략은 무엇인가요? 예측은 어떻게 만드나요?

14. 머신러닝의 주요 도전 과제는 무엇인가요? 15. 모델이 훈련 데이터에서의 성능은 좋지만 새로운 샘플에서의 일반화 성능이 나쁘다면 어 떤 문제가 있는 건가요? 가능한 해결책 세 가지는 무엇인가요?

16. 테스트 세트가 무엇이고 왜 사용해야 하나요? 17. 검증 세트의 목적은 무엇인가요? 18. 테스트 세트를 사용해 하이퍼파라미터를 튜닝하면 어떤 문제가 생기나요? 19. 교차 검증이 무엇이고, 왜 하나의 검증 세트보다 선호하나요? 연습문제의 정답은 부록 A에 있습니다.

1장 한눈에 보는 머신러닝

65



CHAPTER

2

머신러닝 프로젝트 처음부터 끝까지

이 장에서는 여러분이 부동산 회사에 막 고용된 데이터 과학자라고 가정하고 예제 프로젝트의 처음부터 끝까지 진행해보겠습니다.1 진행할 주요 단계는 다음과 같습니다. 1 큰 그림을 봅니다. 2 데이터를 구합니다. 3 데이터로부터 통찰을 얻기 위해 탐색하고 시각화합니다. 4 머신러닝 알고리즘을 위해 데이터를 준비합니다. 5 모델을 선택하고 훈련시킵니다. 6 모델을 상세하게 조정합니다. 7 솔루션을 제시합니다. 8 시스템을 론칭하고 모니터링하고 유지 보수합니다.

1 이 예제 프로젝트는 완전히 가상으로 만든 것입니다. 머신러닝의 주요 단계를 설명하는 것이 목적이며 부동산 비즈니스에 대해 배우려는 것은 아닙니다.

2장 머신러닝 프로젝트 처음부터 끝까지

67


2.1 실제 데이터로 작업하기 머신러닝을 배울 때는 인공적으로 만들어진 데이터셋이 아닌 실제 데이터로 실험해보는 것이 가장 좋습니다. 다행히 여러 분야에 걸쳐 공개된 데이터셋이 아주 많습니다. 다음은 데이터를 구하기 좋은 곳입니다. 유명한 공개 데이터 저장소

- UC 얼바인 Irvine 머신러닝 저장소(http ://archive.ics.uci.edu/ml/) - 캐글 Kaggle 데이터셋(http ://www.kaggle.com/datasets ) - 아마존 AWS 데이터셋(http ://aws.amazon.com/ko/datasets ) 메타 포털(공개 데이터 저장소가 나열되어 있습니다)

- http ://dataportals.org/ - http ://opendatamonitor.eu/ - http ://quandl.com 인기 있는 공개 데이터 저장소가 나열되어 있는 다른 페이지

- 위키백과 머신러닝 데이터셋 목록(https ://goo.gl/SJHN2k ) - Quora.com 질문(http ://goo.gl/zDR78y ) - 데이터셋 서브레딧 subreddit (http ://www.reddit.com/r/datasets )

이 장에서는 StatLib 저장소2에 있는 캘리포니아 주택 가격 California Housing Prices 데이터셋을 사 용합니다(그림 2-1 ). 이 데이터셋은 1990년 캘리포니아 인구조사 데이터를 기반으로 합니다. 최근 데이터는 아니지만(그 당시의 가격이라면 여러분도 베이 에어리어 Bay Area 에 꽤 좋은 집을 살 수 있습니다) 학습용으로 아주 좋기 때문에 최근 데이터라고 생각하겠습니다. 교육 목적으 로 사용하기 위해 범주형 특성을 추가하고 몇 개 특성을 제외했습니다.

2 원본 데이터는 켈리 페이스(R. Kelley Pace )와 로널드 배리(Ronald Barry )의 「Sparse Spatial Autoregressions」, Statistics & Probability Letters 33, no. 3 ( 1997 ) : 291-297에 기술되어 있습니다. 옮긴이_ StatLib 저장소는 카네기 멜론( Carnegie

Mellon ) 대학교의 통계학과에서 운영하는 공개 데이터셋 저장소입니다(http://lib.stat.cmu.edu/datasets/ ). 여기에서는 원 본 데이터셋을 약간 수정한 버전을 사용합니다(https://goo.gl/QgRbUL ).

68

1부 머신러닝


그림 2-1 캘리포니아 주택 가격

위도

중간 주택 가격

인구

경도

2.2 큰 그림 보기 머신러닝 주택 회사에 오신 것을 환영합니다! 해야 할 일은 캘리포니아 인구조사 데이터를 사 용해 캘리포니아의 주택 가격 모델을 만드는 것입니다. 이 데이터는 캘리포니아의 블록 그룹 block group

마다 인구 population , 중간 소득 median income , 중간 주택 가격 median housing price 등을 담고

있습니다. 블록 그룹은 미국 인구조사국에서 샘플 데이터를 발표하는 데 사용하는 최소한의 지 리적 단위입니다(하나의 블록 그룹은 보통 600~3,000명의 인구를 나타냅니다). 여기서는 간 단하게 구역이라고 부르겠습니다. 이 데이터로 모델을 학습시켜서 다른 측정 데이터가 주어졌을 때 구역의 중간 주택 가격을 예 측해야 합니다.

2장 머신러닝 프로젝트 처음부터 끝까지

69


TIP

여러분은 잘 훈련된 데이터 과학자이므로 첫 번째로 할 일은 머신러닝 프로젝트 체크리스트를 준비하는 것입

니다. 부록 B에 준비한 것을 사용해도 됩니다. 대부분의 머신러닝 프로젝트에 잘 들어맞지만 필요에 따라 수정하는 것이 좋습니다. 이 장에서는 체크리스트에 있는 많은 항목을 다루겠지만 스스로 충분히 이해할 수 있는 항목이나 다 음 장에서 논의할 항목은 건너뛰겠습니다.

2.2.1 문제 정의 상사에게 첫 번째로 할 질문은 ‘비즈니스의 목적이 정확히 무엇인가요? ’입니다. 아마도 모델 만 들기가 최종 목적은 아닐 것입니다. 회사에서는 이 모델을 어떻게 사용해 이익을 얻으려고 할까 요? 이는 문제를 어떻게 구성할지, 어떤 알고리즘을 선택할지, 모델 평가에 어떤 성능 지표를 사 용할지, 모델 튜닝을 위해 얼마나 노력을 투여할지 결정하기 때문에 아주 중요한 질문입니다. 상사가 이 모델의 출력(구역의 중간 주택 가격에 대한 예측)이 여러 가지 다른 신호 signal 3와 함 께 다른 머신러닝 시스템(그림 2-2 )에 입력으로 사용된다고 이야기합니다. 뒤따르는 시스템이 해당 지역에 투자할 가치가 있는지 결정합니다. 이 결정이 수익에 직결되기 때문에 올바르게 예 측하는 것은 매우 중요합니다. 그림 2-2 부동산 투자를 위한 머신러닝 파이프라인 나의 컴포넌트

상위 컴포넌트

다른 신호들

구역 가격 결정

구역 데이터

투자 분석

구역 가격

투자

3 머신러닝 시스템에 주입하는 정보를 클로드 섀넌(Claude Shannon )의 정보 이론을 따라 종종 신호라고 부릅니다. 신호/잡음 비율이 높 은 것이 좋습니다. 옮긴이_ 섀넌은 미국의 수학자이자 전기공학자로 디지털 회로 이론을 창시하였고 정보 이론의 아버지로 불립니다.

70

1부 머신러닝


파이프라인 데이터 처리 컴포넌트

component

들이 연속되어 있는 것을 데이터 파이프라인 pipeline 이라고 합니다.

머신러닝 시스템은 데이터를 조작하고 변환할 일이 많아 파이프라인을 사용하는 일이 매우 흔합 니다. 보통 컴포넌트들은 비동기적으로 동작합니다. 각 컴포넌트는 많은 데이터를 추출해 처리하고 그 결과를 다른 데이터 저장소로 보냅니다. 그러면 일정 시간 후 파이프라인의 다음 컴포넌트가 그 데이터를 추출해 자신의 출력 결과를 만드는 식입니다. 각 컴포넌트는 완전히 독립적입니다. 즉, 컴포넌트 사이의 인터페이스는 데이터 저장소뿐입니다. 이는 (데이터 흐름도 덕분에) 시스템을 이해하기 쉽게 만들고, 각 팀은 각자의 컴포넌트에 집중할 수 있습니다. 한 컴포넌트가 다운되더 라도 하위 컴포넌트는 문제가 생긴 컴포넌트의 마지막 출력을 사용해 (적어도 한동안은) 평상시 와 같이 계속 동작할 수 있습니다. 그래서 시스템이 매우 견고해집니다. 한편 모니터링이 적절히 되지 않으면 고장 난 컴포넌트를 한동안 모를 수 있습니다. 데이터가 만 들어진지 오래 되면 전체 시스템의 성능이 떨어집니다.

다음으로 던질 질문은 ‘현재 솔루션은 어떻게 구성되어 있나요? ’입니다(만약 있다면). 이는 문 제 해결 방법에 대한 정보는 물론이고 참고 성능으로도 사용할 수 있습니다. 상사가 현재는 구 역 주택 가격을 전문가가 수동으로 추정한다고 알려주었습니다. 한 팀이 구역에 관한 최신 정 보를 모으고 있는데 중간 주택 가격을 얻을 수 없을 때는 복잡한 규칙을 사용하여 추정을 합니 다. 이는 비용과 시간이 많이 들고 추정 결과도 썩 좋지 않습니다. 실제 중간 주택 가격을 구해 보면 팀에서 추정한 것이 10% 이상 벗어났음을 알게 될 때가 많습니다. 이런 이유로 회사는 구 역의 데이터를 기반으로 중간 주택 가격을 예측하는 모델을 훈련시키는 쪽이 유용하다고 생각 합니다. 인구 조사 데이터에는 다른 데이터는 물론 수천 개 구역의 중간 주택 가격을 포함하므 로 이 작업에 매우 적합한 데이터셋으로 보입니다. 좋습니다. 이제 이런 정보들을 가지고 시스템을 설계할 준비가 되었습니다. 먼저 문제를 정의 해야 합니다. 이는 지도 학습, 비지도 학습, 강화 학습 중 무엇일까요? 분류나 회귀인가요 아니 면 다른 어떤 작업인가요? 배치 학습과 온라인 학습 중 어느 것을 사용해야 하나요? 이 책을 계 속 읽어 나가기 전에 잠시 멈추고 이 질문들의 답을 찾아보세요.

2장 머신러닝 프로젝트 처음부터 끝까지

71


답을 찾았나요? 같이 한번 보겠습니다. 레이블된 훈련 샘플이 있으니(각 샘플이 기대 출력값, 즉 구역의 중간 주택 가격을 가지고 있습니다) 이는 전형적인 지도 학습 작업입니다. 또한 값 을 예측해야 하므로 전형적인 회귀 문제입니다. 좀 더 구체적으로는 예측에 사용할 특성이 여 러 개(구역의 인구, 중간 소득 등)이므로 다변량 회귀 multivariate regression 문제입니다. 1장에서는

1인당 GDP 하나의 특성을 기반으로 삶의 만족도를 예측했으므로 단변량 회귀 univariate regression 문제였습니다. 마지막으로 이 시스템으로 들어오는 데이터에 연속적인 흐름이 없으므로 빠르 게 변하는 데이터에 적응하지 않아도 되고, 데이터가 메모리에 들어갈 만큼 충분히 작으므로 일반적인 배치 학습이 적절합니다. TIP

데이터가 매우 크면 (맵리듀스 MapReduce 4 기술을 사용하여) 배치 학습을 여러 서버로 분할하거나, 대신 온라 인 학습 기법을 사용할 수 있습니다.

2.2.2 성능 측정 지표 선택 다음 단계는 성능 측정 지표를 선택하는 것입니다. 회귀 문제의 전형적인 성능 지표는 평균 제 곱근 오차 Root Mean Square Error (RMSE )입니다. 오차가 커질수록 이 값은 더욱 커지므로 예측에 얼 마나 많은 오류가 있는지 가늠하게 해줍니다. [식 2-1]이 RMSE를 계산하는 공식입니다. 식 2-1 평균 제곱근 오차

RMSE ( X, h) =

1 m 2 ∑ (h(x (i ) ) − y (i ) ) m i =1

표기법 [식 2-1]에서 이 책 전체에 걸쳐 사용할 대표적인 머신러닝 분야의 표기법 몇 가지를 볼 수 있습 니다. m 은 RMSE를 측정할 데이터셋에 있는 샘플 수입니다.

예를 들어 2,000개 구역의 검증 세트에 대해 RMSE를 평가한다면 m = 2,000입니다.

4 옮긴이_ 맵리듀스가 구현된 대표적인 프레임워크는 아파치 하둡( Hadoop ) 프로젝트입니다( http://hadoop.apache.org/ ). 맵 리듀스를 사용하여 직접 회귀 분석을 구현할 수 있지만 일반적으로 하둡에서는 스파크(Spark )의 MLlib (https://spark.apache. org/mllib/ )을 사용하는 것이 편리하고 성능도 뛰어납니다.

72

1부 머신러닝


x (i ) 는 데이터셋에 있는 i번째 샘플(레이블은 제외한)의 전체 특성값의 벡터이고, y (i ) 는 해당 레이블(해당 샘

플의 기대 출력값)입니다. 예를 들어 데이터셋에 있는 첫 번째 구역이 경도 -118.29°, 위도 33.91°에 위치하고, 중간 소득이 $38,372 이며, 주민이 1,416명, 중간 주택 가격이 $156,400라면 x (1 ) 과 y (1 ) 은 다음과 같습니다(여기서 다른 특성은 고려하지 않았습니다).

x (1)

( (

− 118.29 33.91 = 1,416 38,372

y (1) = 156,400 X 는 데이터셋에 있는 모든 샘플의 모든 특성값(레이블은 제외)을 포함하는 행렬입니다. 샘플 하나가 하나의

행이어서 i번째 행은 x (i ) 의 전치 5 와 같고 (x ( i) ) 으로 표기합니다. T

((

예를 들어 첫 번째 구역이 앞의 예와 같다면 행렬 X는 다음과 같습니다.

(x (1) )T (x (2) )T

X=

(x (1999) )T (x (2000) )T

=

(

− 118.29 33.91 1,416 38,372    

(

h 는 시스템의 예측 함수며 가설 hypothesis 이라고도 합니다. 시스템이 하나의 샘플 특성 벡터 x (i ) 를 받으면 그

샘플에 대한 예측값 yˆ ( i ) = h(x ( i )) 를 출력합니다( ŷ 은 ‘y -햇’이라고 읽습니다). 예를 들어 시스템이 첫 번째 구역의 중간 주택 가격을 $158,400이라고 예측한다면 yˆ ( i ) = h(x ( i )) = 158,400입니다. 이 구역에 대한 예측 오차는 yˆ (1) = y (1) = 2,000 입니다.

R MSE (X, h )는 가설 h를 사용하여 일련의 샘플을 평가하는 비용 함수입니다.

스칼라 값이나 함수를 나타낼 때는 m 이나 y (i ) 또는 h와 같이 이탤릭체 소문자, 벡터를 나타낼 때 는 x (i ) 와 같이 굵은 소문자, 행렬을 나타낼 때는 X 와 같이 굵은 대문자를 사용하겠습니다.

RMSE가 일반적으로 회귀 문제에 선호되는 성능 측정 방법이지만 경우에 따라 다른 함수를 사 용할 수도 있습니다. 예를 들어 이상치로 보이는 구역이 많다고 가정합시다. 이런 경우에는 평 5 전치는 열 벡터를 행 벡터로(그리고 반대로도) 바꿉니다.

2장 머신러닝 프로젝트 처음부터 끝까지

73


균 절대 오차 Mean Absolute Error (평균 절대 편차 Mean Absolute Deviation 라고도 합니다)를 고려해볼 수 있습니다. [식 2-2]를 참조하세요. 식 2-2 평균 절대 오차

MAE ( X, h) =

1 m ∑ h(x(i ) ) − y (i ) m i =1

RMSE와 MAE 모두 예측값의 벡터와 타깃값의 벡터 사이의 거리를 재는 방법입니다. 거리 측 정에는 여러 가지 방법(또는 노름 norm )이 가능합니다. 제곱항을 합한 것의 제곱근(RMSE ) 계산은 유클리디안 노름 Euclidian norm 에 해당합니다. 우리와 친숙한 거리

개념입니다. 또는 2 노름이라고도 부르며 ⋅

2

(또는 그냥 ⋅ )로 표시합니다.

절댓값의 합을 계산하는 것은 1 노름에 해당하며 ⋅ 1 로 표기합니다. 이는 도시의 구획이 직각으로 나

뉘어 있을 때 이 도시의 두 지점 사이의 거리를 측정하는 것과 같아 맨해튼 노름 Manhattan norm 이라고도 합 니다.

(

k

k

일반적으로 원소가 n 개인 벡터 v의 k 노름은 v k = v0 + v1 +  + vn

⋅  정의합니다.  은 단 ) 으로

1 k k

0

0

순히 벡터에 있는 0이 아닌 원소의 수이고, ∞ 는 벡터에서 가장 큰 절댓값이 됩니다. 노름의 지수가 클수록 큰 값의 원소에 치우치며 작은 값은 무시됩니다. 그래서 RMSE가 MAE보다 조금 더

이상치에 민감합니다. 하지만 (종 모양 분포의 양 끝단처럼) 이상치가 매우 드물면 RMSE가 잘 맞아 일반적 으로 널리 사용됩니다.

2.2.3 가정 검사 마지막으로 (여러분과 동료들이) 지금까지 만든 가정을 나열하고 검사해보는 것이 좋습니다. 이 과정에서 심각한 문제를 일찍 발견할 수도 있습니다. 예를 들어 시스템이 출력한 구역의 가격 이 다음 머신러닝 시스템의 입력으로 들어가게 되는데 이 값이 있는 그대로 사용될 거라 가정했 습니다. 하지만 하위 시스템에서 이 값을 (‘저렴’, ‘보통’, ‘고가’ 같은) 카테고리로 바꾸고 가격 대신 카테고리를 사용하면 어떻게 될까요? 이럴 때는 정확한 가격을 구하는 것이 전혀 중요하 지 않습니다. 올바른 카테고리를 구하는 시스템이 필요합니다. 그렇다면 이제 이 문제는 회귀 가 아니라 분류 작업이 됩니다. 몇 달 동안 회귀 시스템을 구축하고 나서야 이런 사실을 깨닫게 되는 것을 아무도 원치 않을 것입니다.

74

1부 머신러닝


다행히도 하위 시스템을 담당하는 팀과 대화 후 그들이 카테고리가 아니라 실제 가격을 사용한 다는 것을 확인했습니다. 훌륭합니다! 모든 것이 준비되었고 출발선에 섰습니다. 이제 코딩을 시작할 수 있습니다!

2.3 데이터 가져오기 이제 직접 키보드를 두드릴 차례입니다. 노트북을 꺼내서 주피터 노트북에 있는 다음 코드 예제 를 따라 해보세요. 전체 주피터 노트북은 https://github.com/rickiepark/handson-ml 6 에 있습니다.

2.3.1 작업환경 만들기 먼저 파이썬이 설치되어 있어야 합니다. 여러분 컴퓨터에는 이미 설치되어 있을 것입니다. 그 렇지 않다면 http://www.python.org/에서 내려받을 수 있습니다.7 그다음엔 머신러닝 코드와 데이터셋을 저장할 작업 디렉터리를 만듭니다. 터미널을 열고 다음 명령을 실행합니다($ 프롬프트 다음이 명령입니다). $ export ML_PATH="$HOME/ml" $ mkdir -p $ML_PATH

# 원하는 경로로 바꿔도 됩니다.

필요한 파이썬 패키지가 많이 있습니다. 주피터, 넘파이, 판다스, 맷플롯립, 사이킷런입니다. 이미 이 패키지들을 설치했다면 2.3.2절 ‘데이터 다운로드’로 건너뛰어도 됩니다. 아직 이 패키 지들이 없다면 (의존성이 있는 다른 패키지도 포함해서) 설치할 수 있는 방법은 여러 가지입니 다. 시스템의 패키징 도구를 사용할 수 있고(예를 들면 우분투의 apt-get, macOS의 맥포츠 MacPorts

나 홈브류 Homebrew ), 아나콘다 같은 과학 파이썬 배포판을 설치하고 딸려오는 패키징 도

6 옮긴이_ 이 주소는 옮긴이의 저장소입니다. 저자의 저장소는 https://github.com/ageron/handson-ml입니다. 7 파이썬 3의 최신 버전을 추천합니다. 파이썬 2.7+도 아직 괜찮지만 더 이상 업데이트되지 않습니다. 옮긴이_ 파이썬 2.7+는 2020년까 지만 유지 관리됩니다.

2장 머신러닝 프로젝트 처음부터 끝까지

75


구 8를 사용하거나, 그냥 파이썬 바이너리 인스톨러에 (파이썬 2.7.9부터) 기본으로 포함된 자 체 패키징 도구인 pip를 사용할 수도 있습니다.9 시스템에 pip가 설치되어 있는지 다음 명령으 로 확인합니다. $ pip3 --version pip 9.0.1 from [...]/lib/python3.5/site-packages (python 3.5)

최신 버전의 pip가 설치되어 있는지 확인해야 합니다. 바이너리 패키지(휠 wheel 이라고도 합니 다) 설치를 지원하기 위해 최소한 1.4 버전보다 높아야 합니다. pip 패키지를 업그레이드하려 면 다음 명령을 실행합니다.10 $ pip3 install --upgrade pip Collecting pip [...] Successfully installed pip-9.0.1

독립적인 환경 만들기 독립된 개발 환경(다른 프로젝트의 라이브러리 버전과 충돌하는 것을 피하기 위해 권장하는 방 법입니다)을 선호한다면 다음 pip 명령으로 virtualenv를 설치하세요. $ pip3 install --user --upgrade virtualenv Collecting virtualenv [...] Successfully installed virtualenv

그런 다음 독립적인 파이썬 환경을 다음과 같이 만들 수 있습니다.

8 옮긴이_ 아나콘다는 운영체제별로 사전에 컴파일된 많은 과학 패키지를 제공하며, 시스템의 기본 파이썬을 변경하지 않고 사용자 권한으 로 다양한 버전의 파이썬을 설치할 수 있는 등 장점이 많아 대부분의 경우 권장하는 방법입니다. 아나콘다의 패키징 도구는 conda입니 다. 윈도우에서 아나콘다를 설치하는 과정은 옮긴이의 블로그를 참고하세요(https://goo.gl/QmSUwF ). 9 여기서는 리눅스나 macOS 시스템의 배시 셸(bash shell )에서 pip 명령을 사용한 설치 과정을 제시합니다. 윈도우에서는 아나콘다를 권장합니다. 10 이 명령을 실행하려면 시스템 어드민 권한이 필요할지 모릅니다. 이런 경우에는 앞에 sudo 명령을 붙여서 시도해보세요.

76

1부 머신러닝


$ cd $ML_PATH $ virtualenv env Using base prefix '[...]' New python executable in [...]/ml/env/bin/python3.5 Also creating executable in [...]/ml/env/bin/python Installing setuptools, pip, wheel...done.

이 환경을 활성화하려면 터미널을 열고 다음 명령을 입력합니다. $ cd $ML_PATH $ source env/bin/activate

환경이 활성화되면 pip 명령으로 설치하는 어떤 패키지든 독립된 이 환경에 설치되고 파이썬은 이 패키지만 사용하게 됩니다(시스템에 설치된 패키지를 사용하고 싶다면 virtualenv 환경을 만들 때 --system-site-packages 옵션을 사용해야 합니다). 더 자세한 정보는 virtualenv 문 서를 참고하세요.11

이제 다음 pip 명령으로 필요한 패키지와 의존성으로 연결된 다른 패키지를 모두 설치합니다. $ pip3 install --upgrade jupyter matplotlib numpy pandas scipy scikit-learn Collecting jupyter Downloading jupyter-1.0.0-py2.py3-none-any.whl Collecting matplotlib [...]

설치된 것을 확인하려면 다음과 같이 패키지를 모두 임포트해보세요. $ python3 -c "import jupyter, matplotlib, numpy, pandas, scipy, sklearn"

어떤 에러나 메시지도 출력되지 않아야 합니다. 이제 다음 명령으로 주피터를 실행합니다. $ jupyter notebook [I 15:24 NotebookApp] Serving notebooks from local directory: [...]/ml [I 15:24 NotebookApp] 0 active kernels 11 옮긴이_ virtualenv 문서는 https://virtualenv.pypa.io/ 주소에서 확인할 수 있습니다.

2장 머신러닝 프로젝트 처음부터 끝까지

77


[I 15:24 NotebookApp] The Jupyter Notebook is running at: http://localhost:8888/ [I 15:24 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).

주피터 서버가 터미널에서 실행되었고 포트 8888번에 대기 중입니다. 웹 브라우저를 사용해 http://localhost:8888/ 주소로 서버에 접근할 수 있습니다(보통 서버가 시작될 때 자동으로

브라우저를 띄워 연결해줍니다). 현재 작업공간 디렉터리가 보일 것입니다(virtualenv 설정을 그대로 따라했다면 env 디렉터리만 있습니다).

New 버튼을 클릭하고 적절한 파이썬 버전을 선택해 새로운 주피터 노트북 12을 만듭니다(그림 2-3 ). 이 과정에서 세 가지 작업이 일어납니다. 첫째, 작업공간 안에 Untitled.ipynb라는 이름의 새 로운 노트북 파일을 만듭니다. 둘째, 이 노트북을 실행하기 위한 주피터 파이썬 커널을 구동시킵 니다. 셋째, 새로운 브라우저 탭에서 이 노트북을 엽니다. 시작하기 전에 이 노트북의 Untitled 를 클릭해서 이름을 ‘Housing’으로 바꿉니다(이렇게 하면 자동으로 파일 이름이 Housing.

ipynb로 변경됩니다). 그림 2-3 주피터 작업공간

12 주피터는 여러 버전의 파이썬을 지원하며 R이나 옥타브(Octave ) 같은 다른 언어도 사용할 수 있습니다. 옮긴이_ 이 외에도 과학 계산 용 언어 줄리아(Julia )와 대화형 C++(https://goo.gl/b8aJyR ) 등 많은 언어를 지원합니다. 전체 주피터 커널 목록은 https:// goo.gl/tjKunR 주소를 확인하세요.

78

1부 머신러닝


노트북은 여러 셀 cell 을 포함합니다. 각 셀에는 실행 코드나 포맷된 텍스트를 넣을 수 있습니다. 처음엔 노트북에 ‘In [1]:’이라고 이름이 붙은 빈 코드 셀 하나만 있습니다. 셀에 print ("Hello world!")라고 입력하고 play 버튼이나 Shift-Enter 키를 눌러보세요. 이 명령은 현재 셀의 내

용을 파이썬 커널에 보내 실행하고 그 결과를 돌려받습니다. 결과가 셀의 아래에 표시되고 노 트북의 마지막 셀에 다다랐으므로 새로운 셀이 자동으로 생성됩니다. 주피터의 Help 메뉴에서

User Interface Tour를 사용해 기본 사용법을 익혀보세요. 그림 2-4 Hello world 주피터 노트북

2.3.2 데이터 다운로드 일반적으로 여러분이 다룰 데이터는 관계형 데이터베이스(또는 다른 데이터 저장소)에 들어 있고 여러 테이블, 문서, 파일로 나뉘어 있을 것입니다. 이런 데이터에 접근하려면 먼저 보안 자격과 접근 권한이 있어야 하고 13 그 데이터의 구조를 잘 알고 있어야 합니다. 하지만 이 프로 젝트는 간단합니다. 모든 데이터가 들어 있는 CSV comma-separated value 파일인 housing.csv를 압축한 housing.tgz 파일을 내려받기만 하면 됩니다. 웹 브라우저를 사용해 이 파일을 내려받고 tar xzf housing.tgz 명령을 실행해서 압축을 풀 어 CSV 파일을 얻을 수 있지만, 간단한 함수를 만들어 사용하면 더 편합니다. 특히 데이터가 정 기적으로 변경되면 최근 데이터가 필요할 때마다 스크립트를 실행하면 되니 유용합니다(또는 스케줄링하여 주기적으로 자동 실행할 수도 있습니다). 데이터를 내려받는 일을 자동화하면 여러 기기에 데이터셋을 설치해야 할 때도 편리합니다. 13 또한 개인 정보가 담긴 필드가 안전하지 않은 저장소로 복사되지 않는 등의 법적 제약도 검토해야 합니다.

2장 머신러닝 프로젝트 처음부터 끝까지

79


다음 코드가 데이터를 추출하는 함수입니다.14 import os import tarfile from six.moves import urllib DOWNLOAD_ROOT = "https://raw.githubusercontent.com/ageron/handson-ml/master/" HOUSING_PATH = "datasets/housing" HOUSING_URL = DOWNLOAD_ROOT + HOUSING_PATH + "/housing.tgz" def fetch_housing_data(housing_url=HOUSING_URL, housing_path=HOUSING_PATH): if not os.path.isdir(housing_path): os.makedirs(housing_path) tgz_path = os.path.join(housing_path, "housing.tgz") urllib.request.urlretrieve(housing_url, tgz_path) housing_tgz = tarfile.open(tgz_path) housing_tgz.extractall(path=housing_path) housing_tgz.close()

fetch_housing_data ( ) 를 호출하면 작업공간에 datasets /housing 디렉터리를 만들고

housing.tgz 파일을 내려받고 같은 디렉터리에 압축을 풀어 housing.csv 파일을 만듭니다. 이제 판다스를 사용하여 데이터를 읽어 들이겠습니다. 데이터를 읽어 들이는 간단한 함수도 하 나 만듭니다. import pandas as pd def load_housing_data(housing_path=HOUSING_PATH): csv_path = os.path.join(housing_path, "housing.csv") return pd.read_csv(csv_path)

이 함수는 모든 데이터를 담은 판다스의 데이터프레임 객체를 반환합니다.

2.3.3 데이터 구조 훑어보기 DataFrame의 head ( ) 메서드를 사용해 처음 다섯 행을 확인해보겠습니다(그림 2-5 ). 14 실제 프로젝트에서는 이 코드를 파이썬 파일에 저장하지만 여기서는 그냥 주피터 노트북에 작성합니다.

80

1부 머신러닝


그림 2-5 데이터셋의 처음 다섯 행

각 행은 하나의 구역을 나타냅니다. 특성은 longitude, latitude, housing_median_age, total_rooms, total_bedrooms, population, households, median_income, median_house_ value, ocean_proximity 등 10개입니다(그림에는 6개만 보입니다). info ( ) 메서드는 데이터에 대한 간략한 설명과 특히 전체 행 수, 각 특성의 데이터 타입과 널 null

이 아닌 값의 개수를 확인하는 데 유용합니다(그림 2-6 ). 그림 2-6 housing.info ( ) 결과

데이터셋에 20,640개의 샘플이 들어 있습니다. 머신러닝 프로젝트치고는 상당히 작은 편이지 만, 처음 시작하기에는 적당한 크기입니다. total_bedrooms 특성은 20,433개만 널 값이 아닙

2장 머신러닝 프로젝트 처음부터 끝까지

81


니다. 207개의 구역은 이 특성을 가지고 있지 않다는 것을 뜻합니다. 나중에 이 문제를 적절히 처리하겠습니다. ocean_proximity 필드만 빼고 모든 특성이 숫자형입니다. ocean_proximity 필드의 데이터

타입이 object이므로 어떤 파이썬 객체도 될 수 있지만, 데이터를 CSV 파일에서 읽어 들였기 때문에 텍스트 특성일 것입니다. 처음 다섯 행을 출력했을 때 ocean_proximity 열의 값이 반 복되는 것으로 보아서 15 이 특성은 아마도 범주형 categorical 일 것입니다. 어떤 카테고리가 있고 각 카테고리마다 얼마나 많은 구역이 있는지 value_counts ( ) 메서드로 확인합니다. housing["ocean_proximity"].value_counts() OCEAN 9136 INLAND 6551 NEAR OCEAN 2658 NEAR BAY 2290 ISLAND 5 Name: ocean_proximity, dtype: int64 >>> <1H

다른 필드도 살펴보겠습니다. describe ( ) 메서드는 숫자형 특성의 요약 정보를 보여줍니다(그 림 2-7 ). 그림 2-7 숫자형 특성의 요약 정보

15 옮긴이_ [그림 2-5]에는 모든 열이 나타나 있지 않고 깃허브 주피터 노트북에서 전체 열을 확인할 수 있습니다. 처음 다섯 행의 ocean_ proximity는 모두 ‘NEAR BAY’입니다.

82

1부 머신러닝


count, mean, min, max 행이 의미하는 바는 쉽게 알 수 있습니다. 널 값이 제외된 것을 볼 수

있습니다(예를 들어 total_bedrooms의 count는 20,640이 아니고 20,433입니다). std 행 은 값이 퍼져 있는 정도를 측정하는 표준편차를 나타냅니다.16 25%, 50%, 75% 행은 백분위수 percentile

를 나타냅니다. 백분위수는 전체 관측값에서 주어진 백분율이 속하는 하위 부분의 값을

나타냅니다. 예를 들어 25%의 구역은 housing_media_age가 18보다 작고, 50%는 29보다 작 고, 75%는 37보다 작습니다. 이를 25번째 백분위수(또는 제1사분위수), 중간값, 75번째 백분 위수(또는 제3사분위수)라고도 합니다. 데이터의 형태를 빠르게 검토하는 다른 방법은 각 숫자형 특성을 히스토그램으로 그려보는 것 입니다. 히스토그램은 주어진 값의 범위(수평축)에 속한 샘플 수(수직축)를 나타냅니다. 특성 마다 따로 히스토그램을 그릴 수도 있고 전체 데이터셋에 대해 hist ( ) 메서드를 호출하면 모 든 숫자형 특성에 대한 히스토그램을 출력합니다(그림 2-8 ). 예를 들어 median_house_value 가 약 $100,000인 구역은 800개가 조금 넘는 것을 볼 수 있습니다.17 %matplotlib inline # 주피터 노트북의 매직 명령 import matplotlib.pyplot as plt housing.hist(bins=50, figsize=(20,15)) plt.show()

NOTE_ hist ( ) 메서드는 맷플롯립을 사용하고 결국 화면에 그래프를 그리기 위해 사용자 컴퓨터의 그래픽

백엔드를 필요로 합니다. 그래서 그래프를 그리기 전에 맷플롯립이 사용할 백엔드를 지정해줘야 합니다. 주피 터의 매직 명령 %matplotlib inline을 사용하면 편리합니다. 이 명령은 맷플롯립이 주피터 자체의 백엔 드를 사용하도록 설정합니다. 그러면 그래프는 노트북 안에 그려지게 됩니다.17 주피터 노트북에서 그래프를 그릴 때 show ( ) 메서드를 호출하는 것은 선택사항입니다. 주피터는 셀이 실행될 때 자동으로 그래프를 그려 줍니다.

16 옮긴이_ 표준편차는 일반적으로 σ (시그마)로 표기하고, 평균에서부터 떨어진 거리를 제곱하여 평균한 분산의 제곱근입니다. 어떤 특성 이 정규분포(가우시안 분포)를 따르는 경우 약 68%의 값은 1σ 안에, 95%는 2σ 안에, 99.7%는 3σ 안에 있습니다. 17 옮긴이_ IPython kernel 4.4.0부터는 %matplotlib inline 매직 명령을 사용하지 않더라도 맷플롯립 1.5 이상에서는 자동으로 주피터 자체 백엔드로 설정됩니다.

2장 머신러닝 프로젝트 처음부터 끝까지

83


그림 2-8 모든 숫자형 특성에 대한 히스토그램

이 히스토그램에서 몇 가지 사항을 확인할 수 있습니다. 18 1 먼저 중간 소득 median income 특성이 US 달러로 표현되어 있지 않은 것 같습니다. 데이터를 취합한 팀에 확

인해보니 스케일을 조정하고, 상한이 15 (실제로는 15.0001 ), 하한이 0.5 (실제로는 0.4999 )가 되도록 만 들었다고 합니다. 머신러닝에서는 전처리된 데이터를 다루는 경우가 흔하고 이것이 문제가 되지는 않지만 데 이터가 어떻게 계산된 것인지 반드시 이해하고 있어야 합니다. 19 2 중간 주택 연도 housing median age 와 중간 주택 가격 median house value 역시 최댓값과 최솟값을 한정했습니다.

중간 주택 가격의 경우는 타깃 속성(레이블)으로 사용되기 때문에 심각한 문제가 될 수 있습니다. 가격이 한 곗값을 넘어가지 않도록 머신러닝 알고리즘이 학습될지도 모릅니다. 이것이 문제가 될지 안 될지는 클라이언 트 팀(이 시스템의 출력을 사용할 팀)과 함께 검토하는 것이 좋습니다. 만약 그 팀에서 $500,000를 넘어가 더라도 정확한 예측값이 필요하다고 한다면 우리가 선택할 수 있는 방법은 두 가지입니다. a 한곗값 밖의 구역에 대한 정확한 레이블을 구합니다.

18 옮긴이_ [그림 2-8]의 median_income 히스토그램을 보세요. 19 옮긴이_ 중간 주택 연도(housing_median_age )와 중간 주택 가격(median_housing_value ) 히스토그램은 오른쪽에서 그래프가 심하게 높아지면서 히스토그램이 끝나는 것으로 보아 마지막 값으로 한정되었음을 짐작할 수 있습니다.

84

1부 머신러닝


b 훈련 세트에서 이런 구역을 제거합니다($500,000가 넘는 값에 대한 예측은 평가 결과가 매우 나쁠 것이 므로 테스트 세트에서도 제거합니다). 3 특성들의 스케일이 서로 많이 다릅니다. 특성 스케일링에 대해서는 이 장의 뒷부분에서 살펴보겠습니다. 4 마지막으로 많은 히스토그램의 꼬리가 두껍습니다. 가운데에서 왼쪽보다 오른쪽으로 더 멀리 뻗어 있습니다. 이런 형태는 일부 머신러닝 알고리즘에서 패턴을 찾기 어렵게 만듭니다. 나중에 이런 특성들을 좀 더 종 모양 의 분포가 되도록 변형시키겠습니다.

이제 우리가 다룰 데이터를 많이 이해하게 되었습니다. CAUTION_ 데이터를 더 깊게 들여다보기 전에 테스트 세트를 따로 떼어놓아야 합니다. 그리고 테스트 세트

를 절대 들여다보면 안 됩니다.

2.3.4 테스트 세트 만들기 이 단계에서 데이터 일부를 자진해서 떼어놓으라는 것이 이상하게 들릴지 모르겠습니다. 지금 까지 데이터를 잠시 살펴봤을 뿐이고 어떤 알고리즘을 사용할지 정하기 전에 전체 데이터를 자 세히 파악해야 하지 않을까요? 사실 맞습니다. 하지만 우리 뇌는 매우 과대적합되기 쉬운 엄청 난 패턴 감지 시스템입니다. 만약 테스트 세트를 들여다본다면 테스트 세트에서 겉으로 드러난 어떤 패턴에 속아 특정 머신러닝 모델을 선택하게 될지도 모릅니다. 이 테스트 세트로 일반화 오차를 추정하면 매우 낙관적인 추정이 되며 시스템을 론칭했을 때 기대한 성능이 나오지 않을 것입니다. 이를 데이터 스누핑 data snooping 편향이라고 합니다. 테스트 세트를 생성하는 일은 이론적으로 매우 간단합니다. 그냥 무작위로 어떤 샘플을 선택해 서 데이터셋의 20% 정도를 떼어놓으면 됩니다. import numpy as np def split_train_test(data, test_ratio): shuffled_indices = np.random.permutation(len(data)) test_set_size = int(len(data) * test_ratio) test_indices = shuffled_indices[:test_set_size] train_indices = shuffled_indices[test_set_size:] return data.iloc[train_indices], data.iloc[test_indices]

2장 머신러닝 프로젝트 처음부터 끝까지

85


이 함수를 다음과 같이 사용할 수 있습니다. train_set, test_set = split_train_test(housing, 0.2) print(len(train_set), "train +", len(test_set), "test") 16512 train + 4128 test >>> >>>

좋네요. 이것도 괜찮지만 완벽하지는 않습니다. 프로그램을 다시 실행하면 다른 테스트 세트가 생성됩니다! 여러 번 계속하면 우리는(또는 우리 머신러닝 알고리즘이) 전체 데이터셋을 보는 셈이므로 이런 상황은 피해야 합니다. 한 가지 해결책은 처음 실행에서 테스트 세트를 저장하고 다음번 실행에서 이를 불러들이는 것 입니다. 또 다른 방법은 항상 같은 난수 인덱스가 생성되도록 np.random.permutation ( )을 호 출하기 전에 난수 발생기의 초깃값을 지정하는 것입니다(예를 들면 np.random.seed (42 )20 ). 하지만 이 두 해법 모두 다음번에 업데이트된 데이터셋을 사용하려면 문제가 됩니다. 일반적인 해결책은 샘플의 식별자를 사용하여 테스트 세트로 보낼지 말지 정하는 것입니다(샘플이 고유 하고 변경 불가능한 식별자를 가지고 있다고 가정합니다). 예를 들어 각 샘플마다 식별자의 해 시값을 계산하여 해시의 마지막 바이트의 값이 51 (256의 20% 정도)보다 작거나 같은 샘플만 테스트 세트로 보낼 수 있습니다. 이렇게 하면 여러 번 반복 실행되면서 데이터셋이 갱신되더 라도 테스트 세트가 동일하게 유지됩니다. 새로운 테스트 세트는 새 샘플의 20%를 갖게 되지만 이전에 훈련 세트에 있던 샘플은 포함시키지 않을 것입니다. 다음은 이를 구현한 코드입니다. from zlib import crc32 def test_set_check(identifier, test_ratio): return crc32(np.int64(identifier)) & 0xffffffff

<

test_ratio * 2**32

def split_train_test_by_id(data, test_ratio, id_column): ids = data[id_column] in_test_set = ids.apply(lambda id_: test_set_check(id_, test_ratio)) return data.loc[~in_test_set], data.loc[in_test_set]

20 사람들은 난수 초깃값으로 42를 자주 사용합니다. 이 숫자는 ‘삶, 우주, 그리고 모든 것에 대한 궁극적인 질문의 해답’인 것 외에는 특별 한 의미는 없습니다. 옮긴이_ 이 숫자는 더글러스 애덤스(Douglas Adams )의 소설 『은하수를 여행하는 히치하이커를 위한 안내서』에 서 슈퍼컴퓨터인 깊은 생각(Deep Thought )이 이 질문에 대해 750만 년 동안 계산하여 내놓은 답입니다.

86

1부 머신러닝


안타깝게도 주택 데이터셋에는 식별자 컬럼이 없습니다. 대신 행의 인덱스를 ID로 사용하면 간 단히 해결됩니다. housing_with_id = housing.reset_index() # ‘index’ 열이 추가된 데이터프레임이 반환됩니다. train_set, test_set = split_train_test_by_id(housing_with_id, 0.2, "index")

행의 인덱스를 고유 식별자로 사용할 때 새 데이터는 데이터셋의 끝에 추가되어야 하고 어떤 행도 삭제되지 않아야 합니다. 이것이 불가능할 땐 고유 식별자를 만드는 데 안전한 특성을 사 용해야 합니다. 예를 들어 구역의 위도와 경도는 몇백 년 후까지 안정적이라고 보장할 수 있으 므로 두 값을 연결하여 다음과 같이 ID를 만들 수 있습니다.21 housing_with_id["id"] = housing["longitude"] * 1000 + housing["latitude"] train_set, test_set = split_train_test_by_id(housing_with_id, 0.2, "id")

사이킷런은 데이터셋을 여러 서브셋으로 나누는 다양한 방법을 제공합니다. 가장 간단한 함수는 train_test_split으로, 앞서 우리가 만든 split_train_test와 아주 비슷하지만 두 가지 특

징이 더 있습니다. 첫째 앞서 설명한 난수 초깃값을 지정할 수 있는 random_state 매개변수가 있고, 둘째 행의 개수가 같은 여러 개의 데이터셋을 넘겨서 같은 인덱스를 기반으로 나눌 수 있 습니다(이는 예를 들어 데이터프레임이 레이블에 따라 여러 개로 나뉘어 있을 때 매우 유용합 니다).22 from sklearn.model_selection import train_test_split train_set, test_set = train_test_split(housing, test_size=0.2, random_state=42)

지금까지는 순수한 무작위 샘플링 방식을 보았습니다. 데이터셋이 충분히 크다면(특히 특성 수 에 비해) 일반적으로 괜찮지만, 그렇지 않다면 샘플링 편향이 생길 가능성이 큽니다. 설문조사 기관에서 1,000명에게 질문 몇 개를 하려 할 때 그냥 전화번호부에서 1,000명을 무작위로 뽑는

21 위치 정보는 사실 정밀도가 낮아 여러 구역의 ID가 동일해지므로 같은 테스트 세트 혹은 훈련 세트에 들어가게 됩니다. 이는 원치 않은 샘플링 편향을 만듭니다. 22 옮긴이_ train_test_split ( ) 함수는 파이썬 리스트, 넘파이 배열, 판다스 데이터프레임과 판다스 시리즈( Series ) 객체 등을 입 력으로 받을 수 있습니다.

2장 머신러닝 프로젝트 처음부터 끝까지

87


것이 아닙니다. 전체 인구를 대표할 수 있는 1,000명을 선택하기 위해 노력합니다. 미국 인구의

51.3%가 여성이고 48.7%가 남성이라면, 잘 구성된 설문조사는 샘플에서도 이 비율을 유지해 야 합니다. 즉, 여성은 513명, 남성은 487명이어야 합니다. 이를 계층적 샘플링 stratified sampling 이 라고 합니다. 전체 모수는 계층 strata 이라는 동질의 그룹으로 나뉘고, 테스트 세트가 전체 모수를 대표하도록 각 계층에서 올바른 수의 샘플을 추출합니다. 기본 무작위 샘플링을 사용하면 49% 보다 적거나 54%보다 많은 여성이 테스트 세트에 들어갈 확률이 약 12%입니다.23 어느 방법을 사용하든 설문조사 결과를 크게 편향시키게 됩니다. 전문가가 중간 소득이 중간 주택 가격을 예측하는 데 매우 중요하다고 이야기해주었다고 가정 합시다. 이 경우 테스트 세트가 전체 데이터셋에 있는 여러 소득 카테고리를 잘 대표해야 합니 다. 중간 소득이 연속적인 숫자형 특성이므로 소득에 대한 카테고리 특성을 만들어야 합니다. 중 간 소득의 히스토그램을 조금 더 자세히 살펴보겠습니다([그림 2-8] 참조). 중간 소득 대부분 은 $20,000~$50,000 사이에 모여 있지만 일부는 $60,000를 넘기도 합니다. 계층별로 데이 터셋에 충분한 샘플 수가 있어야 합니다. 그렇지 않으면 계층의 중요도를 추정하는 데 편향이 발생할 것입니다. 이 말은 너무 많은 계층으로 나누면 안 된다는 뜻이고 각 계층이 충분히 커야 합니다. 다음 코드는 중간 소득을 1.5로 나누고(소득의 카테고리 수를 제한하기 위해), ceil 함수를 사용하여 반올림해서 소득 카테고리 특성을 만들고(이산적인 카테고리를 만들기 위 해), 5보다 큰 카테고리는 5로 합칩니다. housing["income_cat"] = np.ceil(housing["median_income"] / 1.5) housing["income_cat"].where(housing["income_cat"] < 5, 5.0, inplace=True)

[그림 2-9]는 이 소득 카테고리의 히스토그램입니다.

23 옮긴이_ 샘플 수가 n 이고 모수에서의 비율이 p 일 때 n × p ≥ 10 이고 n × (1 − p ) ≥ 10 인 이항 분포는 평균이 np 고 표준편차 가 np (1 − p ) 인 정규분포로 근사할 수 있습니다. 따라서 전체 인구 중 51.3%인 여성이 샘플에서 차지할 비율의 분포는 평균이

1000 × 0.513 = 513이고 표준편차가 1000 × 0.513 × (1 − 0.513) = 15.8 입니다. 평균이 513이고 표준편차가 15.8인 정규분포에 서 490 이하와 540 이상인 부분의 면적은 약 11.65%입니다.

88

1부 머신러닝


그림 2-9 소득 카테고리의 히스토그램

이제 소득 카테고리를 기반으로 계층 샘플링을 할 준비가 되었습니다. 사이킷런의 Stratified ShuffleSplit를 사용할 수 있습니다.24

from sklearn.model_selection import StratifiedShuffleSplit split = StratifiedShuffleSplit(n_splits=1, test_size=0.2, random_state=42) for train_index, test_index in split.split(housing, housing["income_cat"]): strat_train_set = housing.loc[train_index] strat_test_set = housing.loc[test_index]

의도대로 되었는지 살펴보겠습니다. 전체 주택 데이터셋에서 소득 카테고리의 비율을 먼저 살 펴보겠습니다. housing["income_cat"].value_counts() / len(housing) 3.0 0.350581 2.0 0.318847 4.0 0.176308 5.0 0.114438 1.0 0.039826 Name: income_cat, dtype: float64

>>>

24 옮긴이_ StratifiedShuffleSplit는 StratifiedKFold의 계층 샘플링과 ShuffleSplit의 랜덤 샘플링을 합친 것으로 test_size와 train_size 매개변수의 합을 1 이하로 지정할 수도 있습니다.

2장 머신러닝 프로젝트 처음부터 끝까지

89


비슷한 코드로 테스트 세트에 있는 소득 카테고리의 비율을 측정합니다. [그림 2-10]은 전체 데 이터셋과 계층 샘플링으로 만든 테스트 세트에서 소득 카테고리 비율을 비교한 것입니다. 그림 에서 보듯이 계층 샘플링을 사용해 만든 테스트 세트가 전체 데이터셋에 있는 소득 카테고리의 비율과 거의 같습니다. 반면 일반 무작위 샘플링으로 만든 테스트 세트는 비율이 많이 달라졌습 니다. 그림 2-10 계층 샘플링과 순수한 무작위 샘플링의 샘플링 편향 비교 전체

무작위 샘플링

계층 샘플링

무작위 샘플링 오류율

계층 샘플링 오류율

이제 income_cat 특성을 삭제해서 데이터를 원래 상태로 되돌리겠습니다.25 for set_ in (strat_train_set, strat_test_set): set_.drop("income_cat", axis=1, inplace=True)

테스트 세트 생성에 대해 자세히 설명한 데는 그럴 만한 이유가 있습니다. 종종 등한시되기도 하지만 머신러닝 프로젝트에서 아주 중요한 부분이기 때문입니다. 게다가 이런 아이디어들은 나중에 교차 검증에 대해 이야기할 때 도움이 됩니다. 이제 데이터를 탐색하는 다음 단계로 넘 어갑시다.

2.4 데이터 이해를 위한 탐색과 시각화 지금까지는 다뤄야 할 데이터의 종류를 파악하기 위해 데이터를 간단히 살펴보았습니다. 이제 25 옮긴이_ 판다스 데이터프레임의 drop 메서드는 행 또는 열을 삭제합니다. axis 매개변수의 기본값이 0일 때는 행을 삭제하고 1일 때 는 열을 삭제합니다. 기본값이 False인 inplace 매개변수를 True로 설정하면 넘겨진 데이터프레임 자체를 수정하고 아무런 값도 반환하지 않습니다.

90

1부 머신러닝


조금 더 깊이 파악해보도록 하겠습니다. 먼저 테스트 세트를 떼어놓았는지 확인하고 훈련 세트에 대해서만 탐색을 하겠습니다. 또한 훈 련 세트가 매우 크면 조작을 간단하고 빠르게 하기 위해 탐색을 위한 세트를 별도로 샘플링할 수도 있습니다. 예제에서는 크기가 작으므로 훈련 세트 전체를 사용하겠습니다. 훈련 세트를 손상시키지 않기 위해 복사본을 만들어 사용합니다. housing = strat_train_set.copy()

2.4.1 지리적 데이터 시각화 지리 정보(위도와 경도)가 있으니 모든 구역을 산점도로 만들어 데이터를 시각화하는 것은 좋 은 생각입니다(그림 2-11 ). housing.plot(kind="scatter", x="longitude", y="latitude")

그림 2-11 데이터의 지리적인 산점도

이 그림은 캘리포니아 지역을 잘 나타내지만 어떤 특별한 패턴을 찾기는 힘듭니다. alpha 옵션 을 0.1로 주면 데이터 포인트가 밀집된 영역을 잘 보여줍니다(그림 2-12 ).

2장 머신러닝 프로젝트 처음부터 끝까지

91


housing.plot(kind="scatter", x="longitude", y="latitude", alpha=0.1)

그림 2-12 밀집된 지역이 잘 부각된 산점도

훨씬 나아졌네요. 확실히 베이 에어리어 Bay Area 와 로스앤젤레스 Los Angeles 근처, 샌디에이고 San Diego

같이 밀집된 지역이 눈에 잘 띄고, 센트럴 밸리 Central Valley 특히 새크라멘토 Sacramento 와 프

레즈노 Fresno 근처를 따라 밀집된 지역이 긴 띠를 이루고 있습니다.26 일반적으로 우리 뇌는 그림에서 패턴을 잘 인식해내지만 더 두드러진 패턴을 보려면 매개변수 를 다양하게 조절해봐야 합니다. 이제 주택 가격을 나타내보겠습니다(그림 2-13 ). 원의 반지름은 구역의 인구를 나타내고(매 개변수 s ), 색깔은 가격을 나타냅니다(매개변수 c ). 여기서는 미리 정의된 컬러 맵 color map 중 파란색(낮은 가격)에서 빨간색(높은 가격)까지 범위를 가지는 jet을 사용합니다(매개변수 cmap ).27

26 옮긴이_ 캘리포니아 해변을 따라서 경도 -122° 근처가 샌프란시스코가 있는 베이 에어리어 지역이고, 경도 -118° 근처가 로스앤젤레 스, 경도 -117° 근처가 샌디에이고 지역입니다. 센트럴 밸리는 샌프란시스코 위에서부터 로스앤젤레스 위쪽까지 캘리포니아 중앙부에 길게 뻗은 지역을 말합니다. 새크라멘토는 위도 38.5°, 경도 -121.5° 근처이며 프레즈노는 위도 36.7°, 경도 -119.8° 근처입니다. 이 지역 모두 산점도에서 밀도가 높은 것을 확인할 수 있습니다. 27 책에는 흑백으로 보일 텐데 베이 에어리어에서 샌디에이고까지 해안가 대부분이 붉게 나타납니다(아마 예상했겠지만). 새크라멘토 주변 에도 노란색이 나타납니다. 옮긴이_ 옮긴이의 깃허브에 있는 주피터 노트북을 보면 컬러 이미지를 확인할 수 있습니다.

92

1부 머신러닝


housing.plot(kind="scatter", x="longitude", y="latitude", alpha=0.4, s=housing["population"]/100, label="population", figsize=(10,7), c="median_house_value", cmap=plt.get_cmap("jet"), colorbar=True, sharex=False ) plt.legend()

그림 2-13 캘리포니아 주택 가격

위도

중간 주택 가격

인구

경도

아마 예상했겠지만 이 그림에서 주택 가격은 지역(예를 들면 바다와 인접한 곳)과 인구 밀도에 관련이 매우 크다는 사실을 알 수 있습니다. 이런 내용은 군집 알고리즘 clustering algorithm 을 사용 해 주요 군집을 찾고 군집의 중심까지의 거리를 재는 특성을 추가할 때 도움이 됩니다. 해안 근 접성 특성이 유용할 수도 있지만, 북부 캘리포니아 지역의 해안가는 주택 가격이 그리 높지 않아 간단한 규칙이 적용되기 어렵습니다.28

28 옮긴이_ 북부 캘리포니아는 대략 위도 35° 위쪽의 지역으로 베이 에어리어를 제외하고는 해안가의 주택 가격이 높지 않게 나타납니다.

2장 머신러닝 프로젝트 처음부터 끝까지

93


2.4.2 상관관계 조사 데이터셋이 너무 크지 않으므로 모든 특성 간의 표준 상관계수 standard correlation coefficient (피어슨 의 r 이라고도 부릅니다)를 corr ( ) 메서드를 이용해 쉽게 계산할 수 있습니다. corr_matrix = housing.corr()

중간 주택 가격과 다른 특성 사이의 상관관계 크기가 얼마나 되는지 살펴보겠습니다. corr_matrix["median_house_value"].sort_values(ascending=False) median_house_value 1.000000 median_income 0.687160 total_rooms 0.135097 housing_median_age 0.114110 households 0.064506 total_bedrooms 0.047689 population -0.026920 longitude -0.047432 latitude -0.142724 Name: median_house_value, dtype: float64 >>>

상관관계의 범위는 -1부터 1까지입니다. 1에 가까우면 강한 양의 상관관계를 가진다는 뜻입 니다. 예를 들어 중간 주택 가격(median_house_value )은 중간 소득(median_income )이 올라 갈 때 증가하는 경향이 있습니다. 계수가 -1에 가까우면 강한 음의 상관관계를 나타냅니다. 위 도 latitude 와 중간 주택 가격 사이에는 약한 음의 상관관계가 보입니다(즉, 북쪽으로 갈수록 주택 가격이 조금씩 내려가는 경향이 있습니다). 마지막으로 계수가 0에 가까우면 선형적인 상관관 계가 없다는 뜻입니다. [그림 2-14]는 가로축과 세로축 사이의 여러 가지 상관계수를 그래프로 보여줍니다.

94

1부 머신러닝


그림 2-14 여러 가지 데이터셋에 나타난 표준 상관계수(출처: 위키백과 - 퍼블릭 도메인 이미지)

CAUTION_ 상관계수는 선형적인 상관관계만 측정합니다( x 가 증가하면 y 는 증가하거나 감소합니다). 그래

서 비선형적인 관계는 잡을 수 없습니다(예들 들어 x 가 0에 가까워지면 y 가 증가합니다). [그림 2-14]의 마 지막 줄에 있는 그래프들은 두 축이 완전히 독립적이지 않음에도 상관계수가 0입니다. 즉, 비선형 관계의 예 입니다. 두 번째 줄은 상관계수가 1이거나 -1인 경우입니다. 상관계수는 기울기와 상관없습니다. 예를 들어 인치 inch 단위의 키는 피트 feet 나 나노미터 nanometer 단위의 키와 상관계수가 1입니다.

특성 사이의 상관관계를 확인하는 다른 방법은 숫자형 특성 사이에 산점도를 그려주는 판다 스의 scatter_matrix 함수를 사용하는 것입니다. 여기서는 숫자형 특성이 11개이므로 총

112 = 121개의 그래프가 되어 한 페이지에 모두 나타낼 수 없으므로, 중간 주택 가격과 상관관 계가 높아 보이는 특성 몇 개만 살펴보겠습니다(그림 2-15 ). from pandas.plotting import scatter_matrix attributes = ["median_house_value", "median_income", "total_rooms", "housing_median_age"] scatter_matrix(housing[attributes], figsize=(12, 8))

2장 머신러닝 프로젝트 처음부터 끝까지

95


그림 2-15 산점도 행렬

대각선 방향(왼쪽 위에서 오른쪽 아래로)은 각 변수 자신에 대한 것이라 그냥 직선이 되므로 유용하지 않습니다. 그래서 판다스는 이곳에 각 특성의 히스토그램을 그립니다(다른 옵션도 가능합니다. 자세한 내용은 판다스 문서를 참고하세요29 ). 중간 주택 가격(median_house_value )을 예측하는 데 가장 유용할 것 같은 특성은 중간 소득 (median_income )이므로 상관관계 산점도를 확대해보겠습니다(그림 2-16 ). housing.plot(kind="scatter", x="median_income", y="median_house_value", alpha=0.1)

29 옮긴이_ scatter_matrix 메서드의 diagonal 매개변수에 히스토그램을 나타내는 'hist'와 커널 밀도 추정(Kernel Density Estimation )을 나타내는 'kde'를 지정할 수 있습니다. 기본값은 'hist'입니다.

96

1부 머신러닝


중간 주택 가격

그림 2-16 중간 소득 대 중간 주택 가격

중간 소득

이 그래프는 몇 가지 사실을 보여줍니다. 첫째, 상관관계가 매우 강합니다. 위쪽으로 향하는 경 향을 볼 수 있으며 포인트들이 너무 널리 퍼져 있지 않습니다. 둘째, 앞서 본 가격 제한 값이 $500,000에서 수평선으로 잘 보입니다. 하지만 이 그래프에서 직선에 가까운 형태를 더 볼 수 있습니다. $450,000 근처에 수평선이 보이고 $350,000와 $280,000에도 있고 그 아래 조금 더 보입니다. 알고리즘이 데이터에서 이런 이상한 형태를 학습하지 않도록 해당 구역을 제거하 는 것이 좋습니다.

2.4.3 특성 조합으로 실험 앞 절에서 데이터를 탐색하고 통찰을 얻는 여러 방법에 대한 아이디어를 얻었기 바랍니다. 머 신러닝 알고리즘에 주입하기 전에 정제해야 할 조금 이상한 데이터를 확인했고, 특성 사이(특 히 타깃 속성과의 사이)에서 흥미로운 상관관계를 발견했습니다. 어떤 특성은 꼬리가 두꺼운 분포라서 데이터를 변형해야 할 것입니다(예를 들면 로그 스케일로). 물론 프로젝트마다 처한 상황은 다르겠지만 일반적인 아이디어는 비슷합니다. 머신러닝 알고리즘용 데이터를 실제로 준비하기 전에 마지막으로 해볼 수 있는 것은 여러 특성 의 조합을 시도해보는 것입니다. 예를 들어 특정 구역의 방 개수는 얼마나 많은 가구수가 있는 지 모른다면 그다지 유용하지 않습니다. 진짜 필요한 것은 가구당 방 개수입니다. 비슷하게 전

2장 머신러닝 프로젝트 처음부터 끝까지

97


체 침대 개수도 그 자체로는 유용하지 않습니다. 즉, 방 개수와 비교하는 게 낫습니다. 가구당 인원도 흥미로운 특성 조합일 것 같습니다. 이런 특성들을 만들어봅시다. housing["rooms_per_household"] = housing["total_rooms"]/housing["households"] housing["bedrooms_per_room"] = housing["total_bedrooms"]/housing["total_rooms"] housing["population_per_household"]=housing["population"]/housing["households"]

상관관계 행렬을 다시 확인해보겠습니다. corr_matrix = housing.corr() corr_matrix["median_house_value"].sort_values(ascending=False) median_house_value 1.000000 median_income 0.687160 rooms_per_household 0.146285 total_rooms 0.135097 housing_median_age 0.114110 households 0.064506 total_bedrooms 0.047689 population_per_household -0.021985 population -0.026920 longitude -0.047432 latitude -0.142724 bedrooms_per_room -0.259984 Name: median_house_value, dtype: float64 >>> >>>

나쁘지 않네요. 새로운 bedrooms_per_room 특성은 전체 방 개수나 침대 개수보다 중간 주택 가 격과의 상관관계가 훨씬 높습니다. 확실히 침대/방의 비율이 낮은 집은 더 비싼 경향이 있습니 다. 가구당 방 개수도 구역 내 전체 방 개수보다 더 유용합니다. 당연히 더 큰 집이 더 비쌉니다. 이 탐색 단계는 완벽하지 않습니다. 시작을 잘해서 빨리 통찰을 얻는 것이 처음 프로토타입을 잘 만드는 데 도움이 될 것입니다. 하지만 이는 반복적인 과정입니다. 프로토타입을 만들고 실 행한 후 그 결과를 분석해서 더 많은 통찰을 얻고 다시 이 탐색 단계로 돌아오게 됩니다.30

30 옮긴이_ 대부분의 소프트웨어 프로젝트가 그렇지만 특히 머신러닝 프로젝트는 빠른 프로토타이핑과 반복적인 프로세스가 권장됩니다.

98

1부 머신러닝


2.5 머신러닝 알고리즘을 위한 데이터 준비 이제 머신러닝 알고리즘을 위해 데이터를 준비할 차례입니다. 이 작업을 그냥 수동으로 하는 대신 함수를 만들어 자동화해야 하는 이유가 있습니다. 어떤 데이터셋에 대해서도 데이터 변환을 손쉽게 반복할 수 있습니다(예를 들어 다음번에 새로운 데이터셋을

사용할 때). 향후 프로젝트에 사용할 수 있는 변환 라이브러리를 점진적으로 구축하게 됩니다.

실제 시스템에서 알고리즘에 새 데이터를 주입하기 전에 변환시키는 데 이 함수를 사용할 수 있습니다.

여러 가지 데이터 변환을 쉽게 시도해볼 수 있고 어떤 조합이 가장 좋은지 확인하는 데 편리합니다.

하지만 먼저 원래 훈련 세트로 복원하고(strat_train_set을 다시 한번 복사합니다), 예측 변 수와 타깃 값에 같은 변형을 적용하지 않기 위해 예측 변수와 레이블을 분리하겠습니다(drop ( ) 은 데이터 복사본을 만들며 strat_train_set에는 영향을 주지 않습니다). housing = strat_train_set.drop("median_house_value", axis=1) housing_labels = strat_train_set["median_house_value"].copy()

2.5.1 데이터 정제 대부분의 머신러닝 알고리즘은 누락된 특성을 다루지 못하므로 이를 처리할 수 있는 함수를 몇 개 만들겠습니다. 앞서 total_bedrooms 특성에 값이 없는 경우를 보았는데 이를 고쳐보겠습니 다. 방법은 세 가지입니다. 해당 구역을 제거합니다.

전체 특성을 삭제합니다.

어떤 값으로 채웁니다(0, 평균, 중간값 등).

데이터프레임의 dropna ( ), drop ( ), fillna ( ) 메서드를 이용해 이런 작업을 간단하게 처리 할 수 있습니다. housing.dropna(subset=["total_bedrooms"]) # 옵션 1 housing.drop("total_bedrooms", axis=1) # 옵션 2 median = housing["total_bedrooms"].median() # 옵션 3 housing["total_bedrooms"].fillna(median, inplace=True)

2장 머신러닝 프로젝트 처음부터 끝까지

99


옵션 3을 선택하면 훈련 세트에서 중간값을 계산하고 누락된 값을 이 값으로 채워 넣어야 합니 다. 하지만 계산된 중간값을 저장하는 것 또한 잊지 말아야 합니다. 나중에 시스템을 평가할 때 테스트 세트에 있는 누락된 값을 바꾸기 위해 필요하고 시스템이 실제 운영될 때 새로운 데이 터에서 누락된 값을 바꿔야 하기 때문입니다.31 사이킷런의 Imputer는 누락된 값을 손쉽게 다루도록 해줍니다. 어떻게 사용하는지 살펴보죠. 먼저 누락된 값을 특성의 중간값으로 대체한다고 지정하여 Imputer의 객체를 생성합니다. from sklearn.preprocessing import Imputer imputer = Imputer(strategy="median")

중간값이 수치형 특성에서만 계산될 수 있기 때문에 텍스트 특성인 ocean_proximity를 제외 한 데이터 복사본을 생성합니다. housing_num = housing.drop("ocean_proximity", axis=1)

이제 imputer 객체의 fit ( ) 메서드를 사용해 훈련 데이터에 적용할 수 있습니다. imputer.fit(housing_num)

imputer는 각 특성의 중간값을 계산해서 그 결과를 객체의 statistics_ 속성에 저장합니다. total_bedrooms 특성에만 누락된 값이 있지만 나중에 시스템이 서비스될 때 새로운 데이터에

서 어떤 값이 누락될지 확신할 수 없으므로 모든 수치형 특성에 imputer를 적용하는 것이 바람 직합니다. imputer.statistics_ array([ -118.51 , 34.26 , 29. , 2119.5 , 433. , 1164. , 408. , 3.5409]) >>> housing_num.median().values array([ -118.51 , 34.26 , 29. , 2119.5 , 433. , 1164. , 408. , 3.5409]) >>>

31 옮긴이_ 훈련 세트에서 학습한 것이 소용없어지므로 테스트 세트의 중간값을 사용하면 안 됩니다.

100 1부 머신러닝


이제 학습된 imputer 객체를 사용해 훈련 세트에서 누락된 값을 학습한 중간값으로 바꿀 수 있 습니다. X = imputer.transform(housing_num)

이 결과는 변형된 특성들이 들어 있는 평범한 넘파이 배열입니다. 이를 다시 판다스 데이터프 레임으로 간단히 되돌릴 수 있습니다. housing_tr = pd.DataFrame(X, columns=housing_num.columns, index = list(housing.index.values))

사이킷런의 설계 철학 사이킷런의 API는 아주 잘 설계되어 있습니다. 주요 설계 원칙은 다음과 같습니다.32 일관성. 모든 객체가 일관되고 단순한 인터페이스를 공유합니다.

- 추정기 estimator. 데이터셋을 기반으로 일련의 모델 파라미터들을 추정하는 객체를 추정기라고 합니다(예 를 들어 imputer 객체는 추정기입니다). 추정 자체는 fit ( ) 메서드에 의해 수행되고 하나의 매개변수 로 하나의 데이터셋만 전달합니다(지도 학습 알고리즘에서는 매개변수가 두 개로, 두 번째 데이터셋은 레 이블을 담고 있습니다). 추정 과정에서 필요한 다른 매개변수들은 모두 하이퍼파라미터로 간주되고(예를 들면 imputer 객체의 strategy 매개변수), 인스턴스 변수 33 로 저장됩니다(보통 생성자의 매개변수 로 전달합니다 34 ). - 변환기 transformer. (imputer 같이) 데이터셋을 변환하는 추정기를 변환기라고 합니다. 여기서도 API는 매우 단순합니다. 변환은 데이터셋을 매개변수로 전달받은 transform ( ) 메서드가 수행합니다. 그리고 변환된 데이터셋을 반환합니다. 이런 변환은 일반적으로 imputer의 경우와 같이 학습된 모델 파라미터 에 의해 결정됩니다.35 모든 변환기는 fit ( ) 과 transform ( ) 을 연달아 호출하는 것과 동일한 fit_

transform ( ) 메서드도 가지고 있습니다(이따금 fit_transform ( )이 최적화되어 있어서 더 빠릅 니다). 32 설계 원칙에 대한 더 자세한 내용은 다음을 참고하세요. 「API design for machine learning software : experiences from the scikit- learn project」, L . Buitinck , G. Louppe , M. Blondel , F. Pedregosa , A . Müller, et al. (2013 ). http://goo.gl/

wL10sI 33 옮긴이_ 인스턴스 변수는 객체지향 프로그래밍에서 객체가 각각 독립적으로 가지고 있는 변수입니다. 34 옮긴이_ 파이썬 객체를 만들 때 전달하는 매개변수를 말합니다(예를 들면 Imputer (strategy="median") ). 이 매개변수는 파이 썬에서 새로운 객체가 생성될 때 자동으로 호출되는 특수 메서드인 __init__에 전달됩니다. 객체 생성 시 호출되는 또 다른 특수 메서 드인 __new__도 있지만 종종 __init__를 생성자라고 부릅니다. 35 옮긴이_ imputer가 실제로 계산한 것은 데이터셋에 있는 각 특성의 중간값입니다. 사이킷런에서는 변환기도 추정기와 인터페이스가 같기 때문에 학습한다고 표현합니다.

2장 머신러닝 프로젝트 처음부터 끝까지 101


- 예측기 predictor. 일부 추정기는 주어진 데이터셋에 대해 예측을 만들 수 있습니다. 예를 들어 앞 장에 나 온 LinearRegression 모델이 예측기입니다. 어떤 나라의 1인당 GDP가 주어질 때 삶의 만족도를 예측했습니다. 예측기의 predict ( ) 메서드는 새로운 데이터셋을 받아 이에 상응하는 예측값을 반환 합니다. 또한 테스트 세트(지도 학습 알고리즘이라면 레이블도 함께)를 사용해 예측의 품질을 측정하는

score ( ) 메서드를 가집니다.36 검 사 가능. 모든 추정기의 하이퍼파라미터는 공개 public 인스턴스 변수로 직접 접근할 수 있고(예를 들면

imputer.strategy ), 모든 추정기의 학습된 모델 파라미터도 접미사로 밑줄을 붙여서 공개 인스턴스 변 수로 제공됩니다(예를 들면 imputer.statistics_ ).37

클 래스 남용 방지. 데이터셋을 별도의 클래스가 아니라 넘파이 배열이나 사이파이 희소 sparse 행렬로 표현합

니다. 하이퍼파라미터는 보통의 파이썬 문자열이나 숫자입니다.

조 합성. 기존의 구성요소를 최대한 재사용합니다. 앞으로 보겠지만 예를 들어 여러 변환기를 연결한 다음 마

지막에 추정기 하나를 배치한 Pipeline 추정기를 쉽게 만들 수 있습니다.

합 리적인 기본값. 사이킷런은 일단 돌아가는 기본 시스템을 빠르게 만들 수 있도록 대부분의 매개변수에 합

리적인 기본값을 지정해두었습니다.

2.5.2 텍스트와 범주형 특성 다루기 앞서 범주형 특성 ocean_proximity가 텍스트라 중간값을 계산할 수 없어서 그냥 남겨뒀습니다.

>>> >>>

housing_cat = housing["ocean_proximity"] housing_cat.head(10)

<1H OCEAN 17606 <1H OCEAN 18632 14650 NEAR OCEAN 3230 INLAND <1H OCEAN 3555 19480 INLAND <1H OCEAN 8879 13685 INLAND <1H OCEAN 4937 <1H OCEAN 4861 Name: ocean_proximity, dtype: object

36 어떤 예측기는 예측의 확신을 측정하는 메서드도 제공합니다. 옮긴이_ 분류 모델이 제공하는 predict_proba ( ) 나 decision_ function ( ) 메서드를 말합니다. 이 메서드들은 3장에서 자세히 소개합니다. 37 옮긴이_ 사실 파이썬에는 비공개(private ) 인스턴스 변수가 없습니다. 따라서 모든 인스턴스 변수는 직접 참조가 가능합니다.

102 1부 머신러닝


대부분의 머신러닝 알고리즘은 숫자형을 다루므로 이 카테고리를 텍스트에서 숫자로 바꾸도록 하겠습니다. 이를 위해 각 카테고리를 다른 정숫값으로 매핑해주는 판다스의 factorize ( ) 메 서드를 사용합니다. housing_cat_encoded, housing_categories = housing_cat.factorize() housing_cat_encoded[:10] array([0, 0, 1, 2, 0, 2, 0, 2, 0, 0])

>>> >>>

훨씬 나아졌네요. 이제 housing_cat_encoded는 완전히 숫자입니다. factorize ( ) 메서드는 카테고리 리스트도 반환해줍니다(‘<1H OCEAN ’은 0으로 매핑되고, ‘NEAR OCEAN’은 1로 매핑되고, 등등). housing_categories Index(['<1H OCEAN', 'NEAR OCEAN', 'INLAND', 'NEAR BAY', 'ISLAND'], dtype='object')

>>>

이 표현 방식의 문제는 머신러닝 알고리즘이 가까이 있는 두 값이 떨어져 있는 두 값보다 더 비슷하다고 생각한다는 점입니다. 실제로는 그렇지 않습니다(예를 들어 카테고리 0과 1보다 카테고리 0과 4가 더 비슷합니다). 이 문제는 일반적으로 카테고리별 이진 특성을 만들어 해 결합니다. 카테고리가 ‘<1H OCEAN ’일 때 한 특성이 1이고(그 외 특성은 0 ), 카테고리가 ‘INLAND’일 때 다른 한 특성이 1이 되는(역시 그 외에는 0 ) 식입니다. 한 특성만 1이고(핫) 나머지는 0이므로 이를 원-핫 인코딩 one-hot encoding 이라고 부릅니다. 사이킷런은 숫자로 된 범주형 값을 원-핫 벡터로 바꿔주는 OneHotEncoder를 제공합니다. 카 테고리들을 원-핫 벡터로 인코딩해보겠습니다. from sklearn.preprocessing import OneHotEncoder encoder = OneHotEncoder() >>> housing_cat_1hot = encoder.fit_transform(housing_cat_encoded.reshape(-1,1)) >>> housing_cat_1hot <16512x5 sparse matrix of type '<class 'numpy.float64'>' with 16512 stored elements in Compressed Sparse Row format> >>> >>>

2장 머신러닝 프로젝트 처음부터 끝까지 103


fit_transform ( ) 메서드는 2차원 배열을 넣어줘야 하는데 housing_cat_encoded는 1차원

배열이므로 구조를 바꿔야 합니다.38 또한 출력을 보면 넘파이 배열이 아니고 사이파이 SciPy 희 소 행렬 sparse matrix 입니다. 이는 수천 개의 카테고리가 있는 범주형 특성일 경우 매우 효율적입 니다. 이런 특성을 원-핫 인코딩하면 열이 수천 개인 행렬로 변하고 각 행은 1이 하나뿐이고 그 외에는 모두 0으로 채워져 있을 것입니다. 0을 모두 메모리에 저장하는 것은 낭비이므로 희 소 행렬은 0이 아닌 원소의 위치만 저장합니다. 이 행렬을 거의 일반적인 2차원 배열처럼 사용 할 수 있지만 39 (밀집된) 넘파이 배열로 바꾸려면 toarray ( ) 메서드를 호출하면 됩니다. housing_cat_1hot.toarray() array([[ 1., 0., 0., 0., 0.], [ 1., 0., 0., 0., 0.], [ 0., 1., 0., 0., 0.], ..., [ 0., 0., 1., 0., 0.], [ 1., 0., 0., 0., 0.], [ 0., 0., 0., 1., 0.]]) >>>

텍스트 카테고리를 숫자 카테고리로, 숫자 카테고리를 원-핫 벡터로 바꿔주는 이 두 가지 변환 을 CategoricalEncoder를 사용하여 한번에 처리할 수 있습니다.40 이 파이썬 클래스는 사이킷 런 0.19.0과 그 이전 버전에는 포함되어 있지 않습니다. 하지만 곧 추가될 예정이라 아마 이 책 을 읽을 때쯤이면 이미 포함되어 있을 가능성이 많습니다. 그렇지 않다면 이 장의 주피터 노트북 에서 가져와 사용할 수 있습니다(이 코드는 #9151 풀 리퀘스트 Pull Request 41에서 복사한 것입니 다). 이 클래스를 사용하는 방법은 다음과 같습니다.

>>> >>> >>>

from sklearn.preprocessing import CategoricalEncoder # 또는 노트북에서 가져옵니다. cat_encoder = CategoricalEncoder() housing_cat_reshaped = housing_cat.values.reshape(-1, 1)

38 넘파이의 reshape ( ) 함수에서 -1은 차원을 지정하지 않는다는 뜻입니다. 해당 차원의 크기는 전체 배열에서 다른 차원이 정해지고 남은 크기가 됩니다. 39 자세한 내용은 사이파이 문서를 참고하세요. 옮긴이_ housing_cat_1hot은 사이파이가 지원하는 희소 행렬 중 행을 압축하는 csr_ matrix입니다. csr_matrix에서 지원하는 메서드는 다음 주소를 참고하세요. https://goo.gl/rakTep 40 옮긴이_ housing이 판다스 데이터프레임이므로 pd.get_dummies (housing ) 처럼 텍스트 특성을 원-핫 벡터로 간단하게 변환할 수 있습니다. get_dummies ( ) 함수는 데이터프레임에서 텍스트 특성을 가진 열을 찾아 자동으로 원-핫 인코딩을 적용하고 변환된 데 이터프레임을 반환합니다. 41 옮긴이_ #9151 풀 리퀘스트는 마스터 브랜치에 머지되었고 0.20 릴리스에 포함될 예정입니다.

104 1부 머신러닝


housing_cat_1hot = cat_encoder.fit_transform(housing_cat_reshaped) housing_cat_1hot <16512x5 sparse matrix of type '<class 'numpy.float64'>' with 16512 stored elements in Compressed Sparse Row format> >>> >>>

기본적으로 CategoricalEncoder는 희소 행렬을 출력하지만 밀집 행렬 dense matrix 을 원할 경우 에는 encoding 매개변수를 "onehot-dense"로 지정할 수 있습니다. cat_encoder = CategoricalEncoder(encoding="onehot-dense") housing_cat_1hot = cat_encoder.fit_transform(housing_cat_reshaped) >>> housing_cat_1hot array([[ 1., 0., 0., 0., 0.], [ 1., 0., 0., 0., 0.], [ 0., 0., 0., 0., 1.], ..., [ 0., 1., 0., 0., 0.], [ 1., 0., 0., 0., 0.], [ 0., 0., 0., 1., 0.]]) >>> >>>

categories_ 인스턴스 변수를 사용해 카테고리 리스트를 얻을 수 있습니다. 이 리스트는 카테

고리 특성마다 1D 카테고리 배열을 담고 있습니다(여기에서는 하나의 카테고리 특성만 있기 때문에 배열 하나만을 담고 있는 리스트입니다). cat_encoder.categories_ [array(['<1H OCEAN', 'INLAND', 'ISLAND', 'NEAR BAY', 'NEAR OCEAN'], dtype=object)]

>>>

TIP

카테고리 특성이 담을 수 있는 카테고리 수가 많다면(예를 들면 국가 코드, 직업, 생물 종류 등) 원-핫 인코딩 은 많은 수의 입력 특성을 만듭니다. 이는 훈련을 느리게 하고 성능을 감소시킬 수 있습니다. 이런 경우에는 임 베딩 embedding 이라고 하는 조금 더 조밀한 표현을 사용할 수 있지만 신경망에 대한 이해가 필요합니다(자세한 내용은 14장에서 설명합니다).

2.5.3 나만의 변환기 사이킷런이 유용한 변환기를 많이 제공하지만 특별한 정제 작업이나 어떤 특성들을 조합하는 등 의 작업을 위해 자신만의 변환기를 만들어야 할 때가 있습니다. 내가 만든 변환기를 (파이프라

2장 머신러닝 프로젝트 처음부터 끝까지 105


인과 같은) 사이킷런의 기능과 매끄럽게 연동하고 싶을 것입니다. 사이킷런은 (상속이 아닌) 덕 타이핑 duck typing 42을 지원하므로 fit ( ) (self를 반환), transform ( ), fit_transform ( ) 메서드를 구현한 파이썬 클래스를 만들면 됩니다. 마지막 메서드는 TransformerMixin을 상 속하면 자동으로 생성됩니다.43 또한 BaseEstimator를 상속하면(그리고 생성자에 *args 나 **kargs를 사용하지 않으면) 하이퍼파라미터 튜닝에 필요한 두 메서드(get_params ( )와 set_params ( ) )를 추가로 얻게 됩니다.44 예를 들어 다음은 앞서 이야기한 조합 특성을 추가

하는 간단한 변환기입니다. from sklearn.base import BaseEstimator, TransformerMixin rooms_ix, bedrooms_ix, population_ix, household_ix = 3, 4, 5, 6 class CombinedAttributesAdder(BaseEstimator, TransformerMixin): def __init__(self, add_bedrooms_per_room = True): # *args나 **kargs가 아닙니다. self.add_bedrooms_per_room = add_bedrooms_per_room def fit(self, X, y=None): return self # 더 할 일이 없습니다. def transform(self, X, y=None): rooms_per_household = X[:, rooms_ix] / X[:, household_ix] population_per_household = X[:, population_ix] / X[:, household_ix] if self.add_bedrooms_per_room: bedrooms_per_room = X[:, bedrooms_ix] / X[:, rooms_ix] return np.c_[X, rooms_per_household, population_per_household, bedrooms_per_room] else: return np.c_[X, rooms_per_household, population_per_household] attr_adder = CombinedAttributesAdder(add_bedrooms_per_room=False) housing_extra_attribs = attr_adder.transform(housing.values)

이 경우에는 변환기가 add_bedrooms_per_room 하이퍼파라미터 하나를 가지고 있고 기본값을

42 옮긴이_ 덕 타이핑은 상속이나 인터페이스 구현이 아니라 객체의 속성이나 메서드가 객체의 유형을 결정하는 방식을 말합니다. 43 옮긴이_ 파이썬에서 이름에 Mixin이 있으면 객체의 기능을 확장하려는 목적으로 만들어진 클래스를 나타냅니다. TransformerMixin 은 fit_transform ( ) 메서드 하나를 가지고 있으며 이를 상속하는 모든 파이썬 클래스에 이 메서드를 제공합니다. Transformer Mixin의 fit_transform ( ) 메서드는 단순히 fit ( )과 transform ( )을 메서드 연결(method chaining )한 것입니다. 44 옮긴이_ get_params ( ) 와 set_params ( ) 함수는 사이킷런의 파이프라인과 그리드 탐색에 꼭 필요한 메서드이므로 모든 추정기 와 변환기는 BaseEstimator를 상속해야 합니다. 이 두 메서드는 생성자에 명시된 매개변수만을 참조하므로 *args나 **kargs는 사용할 수 없습니다. 더 자세한 내용은 사이킷런 문서를 참고하세요. https://goo.gl/fkQWsN

106 1부 머신러닝


True로 지정합니다(합리적인 기본값을 주는 것이 좋습니다). 이 특성을 추가하는 것이 머신러

닝 알고리즘에 도움이 될지 안 될지 이 하이퍼파라미터로 쉽게 확인해볼 수 있습니다. 일반적으 로 100% 확신이 없는 모든 데이터 준비 단계에 대해 하이퍼파라미터를 추가할 수 있습니다. 이 런 데이터 준비 단계를 자동화할수록 더 많은 조합을 자동으로 시도해볼 수 있고 최상의 조합을 찾을 가능성을 매우 높여줍니다(그리고 시간도 많이 절약됩니다).

2.5.4 특성 스케일링 데이터에 적용할 가장 중요한 변환 중 하나가 특성 스케일링 feature scaling 입니다. 몇 가지를 빼고 는,45 머신러닝 알고리즘은 입력 숫자 특성들의 스케일이 많이 다르면 잘 작동하지 않습니다. 주 택 가격 데이터도 이에 해당합니다. 즉, 전체 방 개수의 범위는 6에서 39,320인 반면 중간 소득 의 범위는 0에서 15까지입니다. 타깃 값에 대한 스케일링은 일반적으로 불필요합니다. 모든 특성의 범위를 같도록 만들어주는 방법으로 min-max 스케일링과 표준화 standardization 가 널리 사용됩니다.

min-max 스케일링은 매우 간단합니다(많은 사람이 이를 정규화 normalization 46 라고 부릅니 다. 0~1 범위에 들도록 값을 이동하고 스케일을 조정하면 됩니다. 데이터에서 최솟값을 뺀 후 최댓값과 최솟값의 차이로 나누면 이렇게 할 수 있습니다. 사이킷런에는 이에 해당하는 MinMaxScaler 변환기를 제공합니다. 0~1 사이를 원하지 않는다면 feature_range 매개변수

로 범위를 변경할 수 있습니다. 표준화는 많이 다릅니다. 먼저 평균을 뺀 후(그래서 표준화를 하면 항상 평균이 0이 됩니다) 표 준편차로 나누어 결과 분포의 분산이 1이 되도록 합니다. min-max 스케일링과는 달리 표준화 는 범위의 상한과 하한이 없어 어떤 알고리즘에서는 문제가 될 수 있습니다(예를 들어 신경망 은 종종 입력값의 범위로 0에서 1 사이를 기대합니다). 그러나 표준화는 이상치에 영향을 덜 받 습니다. 예를 들어 중간 소득을 (잘못해서) 100이라 입력한 구역을 가정해봅시다. min-max 스케일링은 0~15 사이의 모든 다른 값을 0~0.15로 만들어버리겠지만, 표준화는 크게 영향받 지 않습니다. 사이킷런에는 표준화를 위한 StandardScaler 변환기가 있습니다. 45 옮긴이_ 6장과 7장에서 다루는 트리 기반 알고리즘이 이에 해당합니다. 46 옮긴이_ 사이킷런에는 입력 데이터에서 각 행의 2 노름이 1이 되도록 조정하는 Normalizer라는 전처리 기능이 있으며 min-max 스케일링과는 전혀 다른 결과를 만듭니다. 정규화는 여러 의미로 다양하게 사용되므로 혼동하지 마세요.

2장 머신러닝 프로젝트 처음부터 끝까지 107


CAUTION_ 모든 변환기에서 스케일링은 (테스트 세트가 포함된) 전체 데이터가 아니고 훈련 데이터에 대해

서만 fit ( ) 메서드를 적용해야 합니다. 그런 다음 훈련 세트와 테스트 세트(그리고 새로운 데이터)에 대해 transform ( ) 메서드를 사용합니다.

2.5.5 변환 파이프라인 앞서 보았듯이 변환 단계가 많으며 정확한 순서대로 실행되어야 합니다. 다행히 사이킷런에는 연속된 변환을 순서대로 처리할 수 있도록 도와주는 Pipeline 클래스가 있습니다. 다음은 숫 자 특성을 처리하는 간단한 파이프라인입니다. from sklearn.pipeline import Pipeline from sklearn.preprocessing import StandardScaler num_pipeline = Pipeline([ ('imputer', Imputer(strategy="median")), ('attribs_adder', CombinedAttributesAdder()), ('std_scaler', StandardScaler()), ]) housing_num_tr = num_pipeline.fit_transform(housing_num)

Pipeline은 연속된 단계를 나타내는 이름/추정기 쌍의 목록을 입력으로 받습니다. 마지막 단

계에는 변환기와 추정기를 모두 사용할 수 있고 그 외에는 모두 변환기여야 합니다(즉, fit_ transform ( ) 메서드를 가지고 있어야 합니다 47 ). 이름은 무엇이든 상관없지만, 이중 밑줄 문

자(__ )는 포함하지 않아야 합니다. 파이프라인의 fit ( ) 메서드를 호출하면 모든 변환기의 fit_transform ( ) 메서드를 순서대로 호출하면서 48 한 단계의 출력을 다음 단계의 입력으로 전달합니다. 마지막 단계에서는 fit ( ) 메서드만 호출합니다. 파이프라인 객체는 마지막 추정기와 동일한 메서드를 제공합니다. 이 예에서는 마지막 추정기 가 변환기 StandardScaler이므로 파이프라인이 데이터에 대해 모든 변환을 순서대로 적용하 47 옮긴이_ 또는 fit ( ) 과 transform ( ) 메서드만 가지고 있어도 됩니다. 48 옮긴이_ fit_transform ( ) 메서드가 없다면 fit ( ) 과 transform ( ) 을 차례로 호출합니다.

108 1부 머신러닝


는 transform ( ) 메서드를 가지고 있습니다(또한 fit ( )과 transform ( )을 차례대로 호출하 는 대신에 사용할 수 있는 fit_transform ( ) 메서드도 가지고 있습니다). 수치형 컬럼을 넘파이 배열로 추출하는 대신 판다스의 데이터프레임을 파이프라인에 직접 주 입할 수 있다면 좋을 것입니다. 사이킷런이 판다스의 데이터프레임을 다룰 수는 없지만 49 이를 처리하는 변환기를 직접 만들 수는 있습니다. from sklearn.base import BaseEstimator, TransformerMixin class DataFrameSelector(BaseEstimator, TransformerMixin): def __init__(self, attribute_names): self.attribute_names = attribute_names def fit(self, X, y=None): return self def transform(self, X): return X[self.attribute_names].values

DataFrameSelector는 나머지는 버리고 필요한 특성을 선택하여 데이터프레임을 넘파이 배열

로 바꾸는 식으로 데이터를 변환합니다. 이를 이용해 데이터프레임을 받아 수치형만 다루는 파 이프라인을 손쉽게 만들 수 있습니다. 수치형 특성을 선택한 DataFrameSelector로 파이프라 인을 시작해서 앞서 이야기한 다른 전처리 단계들을 나열합니다. 범주형 특성을 다루는 또 다 른 파이프라인도 DataFrameSelector로 범주형 특성을 선택하고 CategoricalEncoder를 적 용하면 간단히 만들 수 있습니다. num_attribs = list(housing_num) cat_attribs = ["ocean_proximity"] num_pipeline = Pipeline([ ('selector', DataFrameSelector(num_attribs)), ('imputer', Imputer(strategy="median")), ('attribs_adder', CombinedAttributesAdder()), ('std_scaler', StandardScaler()), ])

49 하지만 사이킷런 깃허브의 #3886 풀 리퀘스트(Pull Request #3886 )를 보면 특성별 변환을 수행할 수 있는 ColumnTransformer 가 준비되고 있습니다. pip3 install sklearn-pandas 명령으로 비슷한 목적을 가진 DataFrameMapper를 얻을 수도 있습니 다. 옮긴이_ #3886 풀 리퀘스트는 #9012로 이어져 마스터 브랜치에 병합되었고 0.20 릴리스에 포함될 예정입니다.

2장 머신러닝 프로젝트 처음부터 끝까지 109


cat_pipeline = Pipeline([ ('selector', DataFrameSelector(cat_attribs)), ('cat_encoder', CategoricalEncoder(encoding="onehot-dense")), ])

하지만 어떻게 이 두 파이프라인을 하나의 파이프라인으로 합칠 수 있을까요? 정답은 사이킷 런의 FeatureUnion입니다. 변환기 목록(또는 모두 변환기로 이뤄진 파이프라인)을 전달하 고 transform ( ) 메서드를 호출하면 각 변환기의 transform ( ) 메서드를 병렬로 실행합니다. 그런 다음 각 변환기의 결과를 합쳐 반환합니다(물론 fit ( ) 메서드를 호출하면 각 변환기의 fit ( ) 메서드를 실행합니다). 숫자형과 범주형 특성을 모두 다루는 전체 파이프라인은 다음

과 같습니다. from sklearn.pipeline import FeatureUnion full_pipeline = FeatureUnion(transformer_list=[ ("num_pipeline", num_pipeline), ("cat_pipeline", cat_pipeline), ])

전체 파이프라인을 간단하게 실행할 수 있습니다. housing_prepared = full_pipeline.fit_transform(housing) housing_prepared array([[-1.15604281, 0.77194962, 0.74333089, ..., 0. 0. , 0. ], [-1.17602483, 0.6596948 , -1.1653172 , ..., 0. 0. , 0. ], [...] >>> housing_prepared.shape (16512, 16) >>> >>>

, ,

2.6 모델 선택과 훈련 드디어 마지막입니다! 문제를 정의한 후 데이터를 읽어 들이고 탐색했습니다. 그리고 훈련 세

110 1부 머신러닝


트와 테스트 세트로 나누고 머신러닝 알고리즘에 주입할 데이터를 자동으로 정제하고 준비하 기 위해 변환 파이프라인을 작성했습니다. 이제 머신러닝 모델을 선택하고 훈련시킬 준비가 되 었습니다.

2.6.1 훈련 세트에서 훈련하고 평가하기 이전 단계의 작업 덕분에 생각보다 훨씬 간단해졌습니다. 먼저 앞 장에서 했던 것처럼 선형 회 귀 모델을 훈련시켜보겠습니다. from sklearn.linear_model import LinearRegression lin_reg = LinearRegression() lin_reg.fit(housing_prepared, housing_labels)

이게 끝입니다! 완전히 작동하는 선형 회귀 모델을 만들었습니다. 훈련 세트에 있는 몇 개 샘플 에 대해 적용해보겠습니다. some_data = housing.iloc[:5] some_labels = housing_labels.iloc[:5] >>> some_data_prepared = full_pipeline.transform(some_data) >>> print("예측: ", lin_reg.predict(some_data_prepared)) 예측: [ 210644.6045 317768.8069 210956.4333 59218.9888 189747.5584] >>> print("레이블: ", list(some_labels)) 레이블: [286600.0, 340600.0, 196900.0, 46300.0, 254500.0] >>> >>>

아주 정확한 예측은 아니지만(예를 들어 첫 번째 예측은 40% 가까이 벗어났습니다) 작동은 합 니다. 사이킷런의 mean_square_error 함수를 사용해 전체 훈련 세트에 대한 이 회귀 모델의

RMSE를 측정해보겠습니다. from sklearn.metrics import mean_squared_error housing_predictions = lin_reg.predict(housing_prepared) >>> lin_mse = mean_squared_error(housing_labels, housing_predictions) >>> lin_rmse = np.sqrt(lin_mse) >>> lin_rmse 68628.198198489219 >>> >>>

2장 머신러닝 프로젝트 처음부터 끝까지 111


좋습니다. 없는 것보다는 낫지만 확실히 좋은 점수는 아닙니다. 대부분 구역의 중간 주택 가격은 $120,000에서 $265,000 사이입니다. 그러므로 예측 오차가 $68,628인 것은 매우 만족스럽지 못합니다. 이는 모델이 훈련 데이터에 과소적합된 사례입니다. 이런 상황은 특성들이 좋은 예 측을 만들만큼 충분한 정보를 제공하지 못했거나 모델이 충분히 강력하지 못하다는 사실을 말 해줍니다. 앞 장에서 보았듯이 과소적합을 해결하는 주요 방법은 더 강력한 모델을 선택하거나 훈련 알고리즘에 더 좋은 특성을 주입하거나 모델의 규제를 감소시키는 것입니다. 이 모델은 규 제를 사용하지 않았으므로 마지막 옵션은 제외됩니다. 특성을 더 많이 추가할 수 있지만(예를 들면 로그 스케일된 인구), 먼저 더 복잡한 모델을 시도해서 어떻게 되는지 보겠습니다. DecisionTreeRegressor를 훈련시켜보겠습니다. 이 모델은 강력하고 데이터에서 복잡한 비선

형 관계를 찾을 수 있습니다(결정 트리에 대해서는 6장에서 자세히 설명합니다). 다음 코드는 이전과 비슷합니다. from sklearn.tree import DecisionTreeRegressor tree_reg = DecisionTreeRegressor() tree_reg.fit(housing_prepared, housing_labels)

모델을 훈련시켰으니 훈련 세트로 평가해보겠습니다.

>>> >>> >>> >>>

housing_predictions = tree_reg.predict(housing_prepared) tree_mse = mean_squared_error(housing_labels, housing_predictions) tree_rmse = np.sqrt(tree_mse) tree_rmse

0.0

잠깐만요, 뭐죠!? 오차가 전혀 없나요? 이 모델이 진짜 완벽할 수 있나요? 물론 이는 모델이 데이터에 너무 심하게 과대적합된 것으로 보입니다. 어떻게 확신할 수 있죠? 앞서 이야기했듯 이 여러분은 확신이 드는 모델이 론칭할 준비가 되기 전까지 테스트 세트는 사용하지 않으려 하 므로 훈련 세트의 일부분으로 훈련을 하고 다른 일부분은 모델 검증에 사용해야 합니다.

112 1부 머신러닝


2.6.2 교차 검증을 사용한 평가 결정 트리 모델을 평가하는 방법을 생각해보겠습니다. 우선 train_test_split 함수를 사용해 훈련 세트를 더 작은 훈련 세트와 검증 세트로 나누고, 더 작은 훈련 세트에서 모델을 훈련시키 고 검증 세트로 모델을 평가하는 방법이 있습니다. 조금 수고스럽지만 너무 어렵지 않으며 매 우 잘 작동합니다. 훌륭한 대안으로 사이킷런의 교차 검증 기능을 사용하는 방법도 있습니다. 다음 코드는 K-겹 교차 검증 K-fold cross-validation 을 수행합니다. 훈련 세트를 폴드 fold 라 불리는 10개의 서브셋으로 무작위로 분할합니다. 그런 다음 결정 트리 모델을 10번 훈련하고 평가하는데, 매번 다른 폴드 를 선택해 평가에 사용하고 나머지 9개 폴드는 훈련에 사용합니다. 10개의 평가 점수가 담긴 배 열이 결과가 됩니다.50 from sklearn.model_selection import cross_val_score scores = cross_val_score(tree_reg, housing_prepared, housing_labels, scoring="neg_mean_squared_error", cv=10) tree_rmse_scores = np.sqrt(-scores)

CAUTION_ 사이킷런의 교차 검증 기능은 scoring 매개변수에 (낮을수록 좋은) 비용 함수가 아니라 (클

수록 좋은) 효용 함수를 기대합니다. 그래서 평균 제곱 오차(MSE )의 반댓값(즉, 음숫값)을 계산하는 neg_ mean_squared_error 함수를 사용합니다. 이런 이유로 앞선 코드에서 제곱근을 계산하기 전에 -scores 로 부호를 바꿨습니다.50

결과를 살펴보겠습니다.

>>>

... ... ... ... >>>

def display_scores(scores): print("Scores:", scores) print("Mean:", scores.mean()) print("Standard deviation:", scores.std()) display_scores(tree_rmse_scores)

50 옮긴이_ 평균 제곱 오차가 작을수록 좋은 비용 함수이므로 부호가 반대가 되어야 scoring 매개변수 정의에 맞습니다. 회귀 모델에서 scoring 매개변수를 지정하지 않으면 기본적으로 0~1 사이의 값을 가지는 r2_score가 사용됩니다. scoring 매개변수에 사용할 수 있는 전체 목록은 다음 주소를 참고하세요. https://goo.gl/C7kSgU

2장 머신러닝 프로젝트 처음부터 끝까지 113


Scores: [ 70232.0136482 66828.46839892 72444.08721003 71125.52697653 75581.29319857 70169.59286164 75370.49116773 71222.39081244] Mean: 71379.0744771 Standard deviation: 2458.31882043

70761.50186201 70055.37863456

결정 트리 결과가 이전만큼 좋아 보이지 않습니다. 실제로 선형 회귀 모델보다 나쁩니다! 교차 검증으로 모델의 성능을 추정하는 것뿐만 아니라 이 추정이 얼마나 정확한지(즉, 표준편차) 측 정할 수 있습니다. 결정 트리 점수가 대략 평균 71,379에서 ±2,458 사이입니다. 검증 세트를 하나만 사용했다면 이런 정보를 얻지 못했을 것입니다. 하지만 모델을 여러 번 훈련시켜야 해 서 비용이 비싸므로 교차 검증을 언제나 쓸 수 있는 것은 아닙니다. 비교를 위해 선형 회귀 모델의 점수를 계산해보겠습니다. lin_scores = cross_val_score(lin_reg, housing_prepared, housing_labels, scoring="neg_mean_squared_error", cv=10) ... ... >>> lin_rmse_scores = np.sqrt(-lin_scores) >>> display_scores(lin_rmse_scores) Scores: [ 66760.97371572 66962.61914244 70349.94853401 74757.02629506 68031.13388938 71193.84183426 64968.13706527 68261.95557897 71527.64217874 67665.10082067] Mean: 69047.8379055 Standard deviation: 2735.51074287 >>>

확실히 결정 트리 모델이 과대적합되어 선형 회귀 모델보다 성능이 나쁩니다. 마지막으로 RandomForestRegressor 모델을 하나 더 시도해보겠습니다. 7장에서 보게 되겠지 만 랜덤 포레스트는 특성을 무작위로 선택해서 많은 결정 트리를 만들고 그 예측을 평균 내는 방식으로 작동합니다. 여러 다른 모델을 모아서 하나의 모델을 만드는 것을 앙상블 학습이라고 하며 머신러닝 알고리즘의 성능을 극대화하는 방법 중 하나입니다. 다른 모델들과 기본적으로 비슷하므로 코드 설명은 대부분 건너뛰도록 하겠습니다.

>>> >>> >>> >>>

from sklearn.ensemble import RandomForestRegressor forest_reg = RandomForestRegressor() forest_reg.fit(housing_prepared, housing_labels) [...]

114 1부 머신러닝


forest_rmse 21941.911027380233 >>> display_scores(forest_rmse_scores) Scores: [ 51650.94405471 48920.80645498 52979.16096752 50861.29381163 56488.55699727 51866.90120786 55399.50713191 53309.74548294] Mean: 52564.1902524 Standard deviation: 2301.87380392 >>>

54412.74042021 49752.24599537

오, 훨씬 좋네요. 랜덤 포레스트는 매우 훌륭해 보입니다. 하지만 훈련 세트에 대한 점수가 검증 세트에 대한 점수보다 훨씬 낮으므로 이 모델도 여전히 훈련 세트에 과대적합되어 있습니다. 과 대적합을 해결하는 방법은 모델을 간단히 하거나, 제한을 하거나(즉, 규제), 더 많은 훈련 데 이터를 모으는 것입니다. 그러나 랜덤 포레스트를 더 깊이 들어가기 전에, 여러 종류의 머신러 닝 알고리즘으로 하이퍼파라미터 조정에 너무 많은 시간을 들이지 않으면서 다양한 모델(다양 한 커널의 서포트 벡터 머신, 신경망 등)을 시도해봐야 합니다. 가능성 있는 2~5개 정도의 모 델을 선정하는 것이 목적입니다. TIP

실험한 모델을 모두 저장해두면 필요할 때 쉽게 모델을 복원할 수 있습니다. 교차 검증 점수와 실제 예측값은 물론 하이퍼파라미터와 훈련된 모델 파라미터 모두 저장해야 합니다. 이렇게 하면 여러 모델의 점수와 모델이 만든 오차를 쉽게 비교할 수 있습니다. 파이썬의 pickle 패키지나 (넘파이 배열을 저장하는 데 아주 효율적 인) sklearn.externals.joblib을 사용하여 사이킷런 모델을 간단하게 저장할 수 있습니다. from sklearn.externals import joblib joblib.dump(my_model, "my_model.pkl") # 그리고 나중에... my_model_loaded = joblib.load("my_model.pkl")

2.7 모델 세부 튜닝 가능성 있는 모델들을 추렸다고 가정하겠습니다. 이제 이 모델들을 세부 튜닝해야 합니다. 그 방법을 몇 개 살펴봅시다.

2장 머신러닝 프로젝트 처음부터 끝까지 115


2.7.1 그리드 탐색 가장 단순한 방법은 만족할 만한 하이퍼파라미터 조합을 찾을 때까지 수동으로 하이퍼파라미터 를 조정하는 것입니다. 이는 매우 지루한 작업이고 많은 경우의 수를 탐색하기에는 시간이 부족 할 수도 있습니다. 대신 사이킷런의 GridSearchCV를 사용하는 것이 좋습니다. 탐색하고자 하는 하이퍼파라미터 와 시도해볼 값을 지정하기만 하면 됩니다. 그러면 가능한 모든 하이퍼파라미터 조합에 대해 교 차 검증을 사용해 평가하게 됩니다. 예를 들어 다음 코드는 RandomForestRegressor에 대한 최 적의 하이퍼파라미터 조합을 탐색합니다. from sklearn.model_selection import GridSearchCV param_grid = [ {'n_estimators': [3, 10, 30], 'max_features': [2, 4, 6, 8]}, {'bootstrap': [False], 'n_estimators': [3, 10], 'max_features': [2, 3, 4]}, ] forest_reg = RandomForestRegressor() grid_search = GridSearchCV(forest_reg, param_grid, cv=5, scoring='neg_mean_squared_error', return_train_score=True) grid_search.fit(housing_prepared, housing_labels)

TIP

어떤 하이퍼파라미터 값을 지정해야 할지 모를 때는 연속된 10의 거듭제곱 수로 시도해보는 것도 좋습니다 (더 세밀하게 탐색하려면 위 예제의 n_estimators 하이퍼파라미터처럼 더 작은 값을 지정합니다).

param_grid 설정에 따라 사이킷런이 먼저 첫 번째 dict에 있는 n_estimators와 max_features

하이퍼파라미터의 조합인 3 × 4 = 12개를 평가하고(지금은 이 하이퍼파라미터가 무엇을 의미 하는지 걱정하지 않아도 됩니다. 7장에서 설명하겠습니다), 그런 다음 두 번째 dict에 있는 하 이퍼파라미터의 조합인 2 × 3 = 6개를 시도합니다. 하지만 두 번째는 bootstrap 하이퍼파라미 터를 True (기본값)가 아니라 False로 설정합니다. 모두 합하면 그리드 탐색이 RandomForestRegressor 하이퍼파라미터 값의 12 + 6 = 18개 조 합을 탐색하고, 각각 다섯 번 모델을 훈련시킵니다(5-겹 교차 검증을 사용하기 때문에). 다시

116 1부 머신러닝


말해 전체 훈련 횟수는 18 × 5 = 90이 됩니다! 이는 시간이 꽤 오래 걸리지만 다음과 같이 최적 의 조합을 얻을 수 있습니다. grid_search.best_params_ {'max_features': 8, 'n_estimators': 30}

>>>

TIP

8과 30은 탐색 범위의 최댓값이기 때문에 계속 점수가 향상될 가능성이 있으므로 더 큰 값으로 다시 검색해 야 합니다.

최적의 추정기에 직접 접근할 수도 있습니다. grid_search.best_estimator_ RandomForestRegressor(bootstrap=True, criterion='mse', max_depth=None, max_features=8, max_leaf_nodes=None, min_impurity_split=1e-07, min_samples_leaf=1, min_samples_split=2, min_weight_fraction_leaf=0.0, n_estimators=30, n_jobs=1, oob_score=False, random_state=42, verbose=0, warm_start=False)

>>>

NOTE_ GridSearchCV가 (기본값인) refit=True로 초기화되었다면 교차 검증으로 최적의 추정기를 찾

은 다음 전체 훈련 세트로 다시 훈련시킵니다. 일반적으로 데이터가 많을수록 성능이 향상되므로 좋은 방법 입니다.

물론 평가 점수도 확인할 수 있습니다. cvres = grid_search.cv_results_ for mean_score, params in zip(cvres["mean_test_score"], cvres["params"]): print(np.sqrt(-mean_score), params) ... ... 63825.0479302 {'max_features': 2, 'n_estimators': 3} 55643.8429091 {'max_features': 2, 'n_estimators': 10} 53380.6566859 {'max_features': 2, 'n_estimators': 30} 60959.1388585 {'max_features': 4, 'n_estimators': 3} 52740.5841667 {'max_features': 4, 'n_estimators': 10} 50374.1421461 {'max_features': 4, 'n_estimators': 30} 58661.2866462 {'max_features': 6, 'n_estimators': 3} 52009.9739798 {'max_features': 6, 'n_estimators': 10}

>>> >>>

2장 머신러닝 프로젝트 처음부터 끝까지 117


50154.1177737 {'max_features': 6, 'n_estimators': 30} 57865.3616801 {'max_features': 8, 'n_estimators': 3} 51730.0755087 {'max_features': 8, 'n_estimators': 10} 49694.8514333 {'max_features': 8, 'n_estimators': 30} 62874.4073931 {'max_features': 2, 'n_estimators': 3, 'bootstrap': False} 54561.9398157 {'max_features': 2, 'n_estimators': 10, 'bootstrap': False} 59416.6463145 {'max_features': 3, 'n_estimators': 3, 'bootstrap': False} 52660.245911 {'max_features': 3, 'n_estimators': 10, 'bootstrap': False} 57490.0168279 {'max_features': 4, 'n_estimators': 3, 'bootstrap': False} 51093.9059428 {'max_features': 4, 'n_estimators': 10, 'bootstrap': False}

이 예에서는 max_features 하이퍼파라미터가 8, n_estimators 하이퍼파라미터가 30일 때 최 적의 솔루션입니다. 이때 RMSE 점수가 49,694로 앞서 기본 하이퍼파라미터 설정으로 얻은

52,564점보다 조금 더 좋습니다. 축하합니다. 성공적으로 최적의 모델을 찾았습니다. 데이터 준비 단계를 하나의 하이퍼파라미터처럼 다룰 수 있습니다. 예를 들면 그리드 탐색이 확실하지 않은 특

TIP

성을 추가할지 말지 자동으로 정할 수 있습니다(예를 들어 CombinedAttributesAdder 변환기의 add_

bedrooms_per_room 하이퍼파라미터를 사용하여 특성을 추가할지 결정합니다). 비슷하게 이상치나 값이 빈 특성을 다루거나 특성 선택 등을 자동으로 처리하는 데 그리드 탐색을 사용합니다.51

2.7.2 랜덤 탐색 그리드 탐색 방법은 이전 예제와 같이 비교적 적은 수의 조합을 탐구할 때 괜찮습니다. 하지 만 하이퍼파라미터 탐색 공간이 커지면 RandomizedSearchCV를 사용하는 편이 더 좋습니다.52 RandomizedSearchCV는 GridSearchCV와 거의 같은 방식으로 사용하지만 가능한 모든 조합을

시도하는 대신 각 반복마다 하이퍼파라미터에 임의의 수를 대입하여 지정한 횟수만큼 평가합 니다. 이 방식의 주요 장점은 다음 두 가지입니다. 랜덤 탐색을 1,000회 반복하도록 실행하면 하이퍼파라미터마다 각기 다른 1,000개의 값을 탐색합니다(그

리드 탐색에서는 하이퍼파라미터마다 몇 개의 값만 탐색합니다). 단순히 반복 횟수를 조절하는 것만으로 하이퍼파라미터 탐색에 투입할 컴퓨팅 자원을 제어할 수 있습니다.

51 옮긴이_ 데이터 준비 단계와 모델을 연결한 파이프라인을 그리드 탐색에 적용할 때 데이터 준비 단계를 캐싱하면 탐색 시간을 줄일 수 있습니다. 파이프라인 캐싱에 대한 간단한 예는 옮긴이의 블로그를 참고하세요( https://goo.gl/cq9Nyb ). 52 옮긴이_ 특히 규제처럼 설정값이 연속형인 경우 랜덤 탐색이 권장됩니다. 랜덤 탐색을 10회 반복하여 찾은 최적의 하이퍼파라미터는 n_estimators가 180, max_features가 7입니다. 깃허브의 주피터 노트북에서 랜덤 탐색 예제를 확인할 수 있습니다.

118 1부 머신러닝


2.7.3 앙상블 방법 모델을 세밀하게 튜닝하는 또 다른 방법은 최상의 모델을 연결해보는 것입니다. (결정 트리의 앙상블인 랜덤 포레스트가 결정 트리 하나보다 더 성능이 좋은 것처럼) 모델의 그룹(또는 앙상 블 emsemble )이 최상의 단일 모델보다 더 나은 성능을 발휘할 때가 많습니다. 특히 개개의 모델 이 각기 다른 형태의 오차를 만들 때 그렇습니다. 이 주제는 7장에서 자세히 살펴보겠습니다.

2.7.4 최상의 모델과 오차 분석 최상의 모델을 분석하면 문제에 대한 좋은 통찰을 얻는 경우가 많습니다. 예를 들어 RandomFor estRegressor가 정확한 예측을 만들기 위한 각 특성의 상대적인 중요도를 알려줍니다.

feature_importances = grid_search.best_estimator_.feature_importances_ feature_importances array([ 7.33442355e-02, 6.29090705e-02, 4.11437985e-02, 1.46726854e-02, 1.41064835e-02, 1.48742809e-02, 1.42575993e-02, 3.66158981e-01, 5.64191792e-02, 1.08792957e-01, 5.33510773e-02, 1.03114883e-02, 1.64780994e-01, 6.02803867e-05, 1.96041560e-03, 2.85647464e-03])

>>> >>>

중요도 다음에 그에 대응하는 특성 이름을 표시해보겠습니다. extra_attribs = ["rooms_per_hhold", "pop_per_hhold", "bedrooms_per_room"] cat_one_hot_attribs = list(encoder.classes_) >>> attributes = num_attribs + extra_attribs + cat_one_hot_attribs >>> sorted(zip(feature_importances, attributes), reverse=True) [(0.36615898061813418, 'median_income'), (0.16478099356159051, 'INLAND'), (0.10879295677551573, 'pop_per_hhold'), (0.073344235516012421, 'longitude'), (0.062909070482620302, 'latitude'), (0.056419179181954007, 'rooms_per_hhold'), (0.053351077347675809, 'bedrooms_per_room'), (0.041143798478729635, 'housing_median_age'), (0.014874280890402767, 'population'), (0.014672685420543237, 'total_rooms'), (0.014257599323407807, 'households'), >>> >>>

2장 머신러닝 프로젝트 처음부터 끝까지 119


(0.014106483453584102, 'total_bedrooms'), (0.010311488326303787, '<1H OCEAN'), (0.0028564746373201579, 'NEAR OCEAN'), (0.0019604155994780701, 'NEAR BAY'), (6.0280386727365991e-05, 'ISLAND')]

이 정보를 바탕으로 덜 중요한 특성들을 제외할 수 있습니다(예를 들어 ocean_proximity 카 테고리 중 하나만 실제로 유용하므로 다른 카테고리는 제외할 수 있습니다). 시스템이 특정한 오차를 만들었다면 왜 그런 문제가 생겼는지 이해하고 문제를 해결하는 방법 이 무엇인지 찾아야 합니다(추가 특성을 포함시키거나, 반대로 불필요한 특성을 제거하거나, 이상치를 제외하는 등).

2.7.5 테스트 세트로 시스템 평가하기 어느 정도 모델을 튜닝하면 마침내 만족할 만한 모델을 얻게 됩니다. 그럼 이제 테스트 세트에서 최종 모델을 평가할 차례입니다. 이 과정에 특별히 다른 점은 없습니다. 테스트 세트에서 예측 변수와 레이블을 얻은 후 full_pipeline을 사용해 데이터를 변환하고( fit_transform ( )이 아니라 transform ( )을 호출해야 합니다!) 테스트 세트에서 최종 모델을 평가합니다. final_model = grid_search.best_estimator_ X_test = strat_test_set.drop("median_house_value", axis=1) y_test = strat_test_set["median_house_value"].copy() X_test_prepared = full_pipeline.transform(X_test) final_predictions = final_model.predict(X_test_prepared) final_mse = mean_squared_error(y_test, final_predictions) final_rmse = np.sqrt(final_mse) # => 47,766.0 출력

하이퍼파라미터 튜닝을 많이 했다면 교차 검증을 사용해 측정한 것보다 조금 성능이 낮은 것이 보통입니다(우리 시스템이 검증 데이터에서 좋은 성능을 내도록 세밀하게 튜닝되었기 때문에 새로운 데이터셋에는 잘 작동하지 않을 가능성이 큽니다). 이 예제에서는 성능이 낮아지진 않

120 1부 머신러닝


았지만, 이런 경우가 생기더라도 테스트 세트에서 성능 수치를 좋게 하려고 하이퍼파라미터를 튜 닝하려 시도해서는 안 됩니다. 그렇게 향상된 성능은 새로운 데이터에 일반화되기 어렵습니다. 이제 프로젝트 론칭 직전 단계에 왔습니다. (학습한 것, 한 일과 하지 않은 일, 수립한 가정, 시 스템 제한사항 등을 강조하면서) 솔루션과 문서를 출시하고, 깔끔한 도표와 기억하기 쉬운 제 목으로(예를 들면 ‘수입의 중간값이 주택 가격 예측의 가장 중요한 지표다’) 멋진 발표 자료를 만들어야 합니다.

2.8 론칭, 모니터링, 그리고 시스템 유지 보수 완벽합니다. 솔루션 론칭 허가를 받았습니다! 이제 제품 시스템에 적용하기 위한 준비를 해야 합니다. 특히 입력 데이터 소스를 우리 시스템에 연결하고 테스트 코드를 작성해야 합니다. 또한 일정 간격으로 시스템의 실시간 성능을 체크하고 성능이 떨어졌을 때 알람을 통지할 수 있는 모니터링 코드를 작성해야 합니다. 이는 갑작스런 오작동뿐만 아니라 성능이 감소되는 상 황을 잡아내기 위해서도 아주 중요합니다. 새로운 데이터를 사용해 주기적으로 훈련시키지 않 으면 데이터가 오래됨에 따라 모델도 함께 낙후되는 것이 일반적입니다. 시스템의 성능을 평가하려면 시스템의 예측을 샘플링해서 평가해야 합니다. 일반적으로 이런 과 정에는 사람의 분석이 필요합니다. 이런 분석가는 해당 분야의 전문가이거나 크라우드 소싱 플 랫폼(아마존의 Mechanical Turk나 CrowdFlower )에서 구한 인력일 수 있습니다. 어느 쪽 이든 사람의 분석 파이프라인과 시스템을 연결해야 합니다. 시스템의 입력 데이터 품질 역시 평가해야 합니다. 가끔 품질 낮은 시그널(예를 들어 오작동하 는 센서가 예측 불허의 값을 보낸다거나 다른 팀의 출력이 멈춰 있는 경우) 때문에 성능이 조금 감소하지만 알람이 울릴 정도로 감소되기까지 다소 시간이 걸립니다. 시스템의 입력을 모니터 링하면 이보다 일찍 알 수 있습니다. 특히 온라인 학습 시스템에서는 입력을 모니터링하는 일이 중요합니다. 마지막으로 새로운 데이터를 사용해 정기적으로 모델을 훈련시켜야 합니다. 가능하면 이 과정 을 자동화해야 합니다. 그렇지 않으면 (기껏해야) 6개월마다 모델을 갱신하게 될 것이고, 시 스템의 성능이 시간에 따라 심하게 출렁일 것입니다. 온라인 학습 시스템이라면 일정 간격으로 시스템의 상태를 스냅샷으로 저장해서 이전 상태로 쉽게 되돌릴 수 있도록 해야 합니다.

2장 머신러닝 프로젝트 처음부터 끝까지 121


2.9 직접 해보세요! 이 장에서 머신러닝 프로젝트가 무엇인지 전반적인 개념을 얻고 멋진 시스템을 만드는 데 필요 한 도구들을 알게 되었기 바랍니다. 살펴봤듯이 대부분의 작업은 데이터 준비 단계, 모니터링 도구 구축, 사람의 평가 파이프라인 세팅, 주기적인 모델 학습 자동화로 이루어집니다. 물론 머 신러닝 알고리즘도 중요하지만 전체 프로세스에 익숙해져야 합니다. 고수준 알고리즘을 탐색 하느라 시간을 모두 허비해서 전체 프로세스 구축에 충분한 시간을 투자하지 못하는 것보다 서 너 개의 알고리즘 만으로라도 전체 프로세스를 올바로 구축하는 편이 더 낫다는 것을 알아야 합니다. 아직 한 번도 해보지 못했다면 노트북을 집어 들고 관심 있는 데이터셋을 선택해서 A부터 Z까 지 전체 프로세스를 만들어보세요. 캐글(http://kaggle.com ) 같은 경연 사이트가 시작하기 좋 습니다. 데이터셋이 준비되어 있고 목표가 명확하며 다른 사람의 경험을 들을 수 있습니다.

2.10 연습문제 이 장에서 소개한 주택 가격 데이터셋을 사용해 문제를 푸세요.

1. 서포트 벡터 머신 회귀(sklearn.svm.SVR )를 kernel="linear" (하이퍼파라미터 C를 바 꿔가며)나 kernel="rbf" (하이퍼파라미터 C와 gamma를 바꿔가며) 등의 다양한 하이퍼파 라미터 설정으로 시도해보세요. 지금은 이 하이퍼파라미터가 무엇을 의미하는지 너무 신경 쓰지 마세요. 최상의 SVR 모델은 무엇인가요?

2. GridSearchCV를 RandomizedSearchCV로 바꿔보세요. 3. 가장 중요한 특성을 선택하는 변환기를 준비 파이프라인에 추가해보세요. 4. 전체 데이터 준비 과정과 최종 예측을 하나의 파이프라인으로 만들어보세요. 5. GridSearchCV를 사용해 준비 단계의 옵션을 자동으로 탐색해보세요. 연습문제의 정답은 https://github.com/rickiepark/handson-ml에 있는 주피터 노트북에서 확인할 수 있습니다.

122 1부 머신러닝


CHAPTER

3

분류

1장에서는 가장 일반적인 지도 학습 작업이 회귀(값 예측)와 분류(클래스 예측)라고 했습니 다. 2장에서는 주택 가격을 예측하는 회귀 작업을 살펴보면서 선형 회귀, 결정 트리, 랜덤 포레 스트(7장에서 더 자세히 설명합니다) 같은 여러 알고리즘을 보았습니다. 이 장에서는 분류 시 스템을 집중적으로 다루겠습니다.

3.1 MNIST 이 장에서는 고등학생과 미국 인구조사국 직원들이 손으로 쓴 70,000개의 작은 숫자 이미지 를 모은 MNIST 데이터셋을 사용하겠습니다. 각 이미지에는 어떤 숫자를 나타내는지 레이블 되어 있습니다. 이 데이터셋은 학습용으로 아주 많이 사용되기 때문에 머신러닝 분야의 ‘Hello

World’라고 불립니다. 새로운 분류 알고리즘이 나올 때마다 MNIST 데이터셋에서 얼마나 잘 작동하는지 봅니다. 머신러닝을 배우는 사람이라면 머지않아 MNIST 데이터셋을 맞닥뜨리게 될 것입니다. 사이킷런에서 제공하는 여러 헬퍼 함수를 사용해 잘 알려진 데이터셋을 내려받을 수 있습니다.

MNIST도 그중 하나입니다. 다음은 MNIST 데이터셋을 내려받는 코드입니다.1

1 기본적으로 사이킷런은 내려받은 데이터셋을 $HOME/scikit_learn_data 디렉터리에 캐싱합니다.

3장 분류 123


from sklearn.datasets import fetch_mldata mnist = fetch_mldata('MNIST original') >>> mnist {'COL_NAMES': ['label', 'data'], 'DESCR': 'mldata.org dataset: mnist-original', 'data': array([[0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], ..., [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0]], dtype=uint8), 'target': array([ 0., 0., 0., ..., 9., 9., >>> >>>

9.])}

사이킷런에서 읽어 들인 데이터셋들은 일반적으로 비슷한 딕셔너리 구조를 가지고 있습니다. 데이터셋을 설명하는 DESCR 키

샘플이 하나의 행, 특성이 하나의 열로 구성된 배열을 가진 data 키

레이블 배열을 담고 있는 target 키

이 배열들을 살펴보겠습니다. X, y = mnist["data"], mnist["target"] X.shape (70000, 784) >>> y.shape (70000,) >>> >>>

이미지가 70,000개 있고 각 이미지에는 784개의 특성이 있습니다. 이미지가 28 × 28 픽셀이 기 때문이죠. 개개의 특성은 단순히 0 (흰색)부터 255 (검은색)까지의 픽셀 강도를 나타냅니 다. 데이터셋에서 이미지 하나를 확인해보겠습니다. 샘플의 특성 벡터를 추출해서 28 × 28 배 열로 크기를 바꾸고 맷플롯립의 imshow ( ) 함수를 사용해 그리면 됩니다. %matplotlib inline import matplotlib import matplotlib.pyplot as plt some_digit = X[36000] some_digit_image = some_digit.reshape(28, 28)

124 1부 머신러닝


plt.imshow(some_digit_image, cmap = matplotlib.cm.binary, interpolation="nearest") plt.axis("off") plt.show()

이 그림은 숫자 5로 보이는데, 실제 레이블을 확인해보겠습니다. >>>

y[36000]

5.0

[그림 3-1]에서 MNIST 이미지 샘플을 더 확인해보면 분류 작업이 얼마나 어려운지 느낄 수 있을 것입니다. 그림 3-1 MNIST 데이터셋에서 추출한 숫자 이미지

3장 분류 125


하지만 잠깐만요! 데이터를 자세히 조사하기 전에 항상 테스트 세트를 만들고 따로 떼어놓아야 합니다. 사실 MNIST 데이터셋은 이미 훈련 세트(앞쪽 60,000개 이미지)와 테스트 세트(뒤 쪽 10,000개 이미지)로 나누어 놓았습니다. X_train, X_test, y_train, y_test = X[:60000], X[60000:], y[:60000], y[60000:]

훈련 세트를 섞어서 모든 교차 검증 폴드가 비슷해지도록 만들겠습니다(하나의 폴드라도 특정 숫자가 누락되면 안 됩니다). 더군다나 어떤 학습 알고리즘은 훈련 샘플의 순서에 민감해서 많 은 비슷한 샘플이 연이어 나타나면 성능이 나빠집니다. 데이터셋을 섞으면 이런 문제를 방지할 수 있습니다.2 import numpy as np shuffle_index = np.random.permutation(60000) X_train, y_train = X_train[shuffle_index], y_train[shuffle_index]

3.2 이진 분류기 훈련 문제를 단순화해서 하나의 숫자, 예를 들면 숫자 5만 식별해보겠습니다. 이 ‘5-감지기’는 ‘5’와 ‘5 아님’ 두 개의 클래스를 구분할 수 있는 이진 분류기 binary classifier 의 한 예입니다. 분류 작업을 위해 타깃 벡터를 만들어보겠습니다. y_train_5 = (y_train == 5) y_test_5 = (y_test == 5)

# 5는 True고, 다른 숫자는 모두 False

좋습니다. 이제 분류 모델을 하나 선택해서 훈련시켜보겠습니다. 사이킷런의 SGDClassifier 클래스를 사용해 확률적 경사 하강법 Stochastic Gradient Descent (SGD ) 분류기로 시작해보는 것도 나

2 어떤 경우에는 섞는 것이 좋지 않습니다. 예를 들면 (주식가격이나 날씨 예보 같은) 시계열 데이터를 다룰 때입니다. 다음 장에서 이런 경 우를 살펴보겠습니다. 옮긴이_ SGD가 샘플을 섞어야 하는 대표적인 경우입니다. 사이킷런의 SGDClassifier와 SGDRegressor는 기본적으로 에포크(max_iter )마다 훈련 데이터를 다시 섞습니다.

126 1부 머신러닝


쁘지 않습니다. 이 분류기는 매우 큰 데이터셋을 효율적으로 처리하는 장점을 지니고 있습니다. 나중에 보겠지만 SGD가 한 번에 하나씩 훈련 샘플을 독립적으로 처리하기 때문입니다(그래 서 SGD가 온라인 학습에 잘 들어맞습니다). SGDClassifier 모델을 만들고 전체 훈련 세트를 사용해 훈련시켜보겠습니다. from sklearn.linear_model import SGDClassifier sgd_clf = SGDClassifier(max_iter=5, random_state=42) sgd_clf.fit(X_train, y_train_5)

TIP

SGDClassifier는 훈련하는 데 무작위성을 사용합니다(그래서 이름에 ‘확률적’이 붙었습니다). 결과를 재현 하고 싶다면 random_state 매개변수를 지정해야 합니다.

이제 이 모델을 사용해 숫자 5의 이미지를 감지해보겠습니다. sgd_clf.predict([some_digit]) array([ True], dtype=bool)

>>>

분류기는 이 이미지가 5를 나타낸다고 추측했습니다(True ). 이 경우엔 특별하게 정확히 맞춘 것 같습니다! 그럼 모델의 성능을 평가해봅시다.

3.3 성능 측정 분류기 평가는 회귀 모델보다 훨씬 어렵기 때문에 이 장에서는 이 주제에 많은 지면을 할애할 것 입니다. 사용할 수 있는 성능 지표가 많습니다. 커피 한 잔 더 하면서 여러 가지 새로운 개념과 용어를 배워보죠!

3.3.1 교차 검증을 사용한 정확도 측정 2장에서 한 것처럼 교차 검증은 모델을 평가하는 좋은 방법입니다.

3장 분류 127


교차 검증 구현 가끔 사이킷런이 제공하는 기능보다 교차 검증 과정을 더 많이 제어해야 할 필요가 있습니다. 이 때는 교차 검증 기능을 직접 구현하면 됩니다. 이 기능은 매우 직관적입니다. 다음 코드는 사이킷 런의 cross_val_score ( ) 함수와 거의 같은 작업을 수행하고 동일한 결과를 출력합니다. from sklearn.model_selection import StratifiedKFold from sklearn.base import clone skfolds = StratifiedKFold(n_splits=3, random_state=42) for train_index, test_index in skfolds.split(X_train, y_train_5): clone_clf = clone(sgd_clf) X_train_folds = X_train[train_index] y_train_folds = y_train_5[train_index] X_test_fold = X_train[test_index] y_test_fold = y_train_5[test_index] clone_clf.fit(X_train_folds, y_train_folds) y_pred = clone_clf.predict(X_test_fold) n_correct = sum(y_pred == y_test_fold) print(n_correct / len(y_pred)) # 0.9502, 0.96565, 0.96495 출력

StratifiedKFold는 ( 2장에서 설명한 것처럼) 클래스별 비율이 유지되도록 폴드를 만들기 위해

계층적 샘플링을 수행합니다. 매 반복에서 분류기 객체를 복제하여 훈련 폴드로 훈련시키고 테 스트 폴드로 예측을 만듭니다. 그런 다음 올바른 예측의 수를 세어 정확한 예측의 비율을 출력합 니다.

cross_val_score ( ) 함수로 폴드가 3개인 K-겹 교차 검증을 사용해 SGDClassifier 모델을

평가해보겠습니다. K-겹 교차 검증은 훈련 세트를 K개(여기서는 3개)의 폴드로 나누고, 각 폴드에 대해 예측을 만들고 평가하기 위해 나머지 폴드로 훈련시킨 모델을 사용한다는 것을 기 억하세요(2장 참조). from sklearn.model_selection import cross_val_score cross_val_score(sgd_clf, X_train, y_train_5, cv=3, scoring="accuracy") array([ 0.9502 , 0.96565, 0.96495])

>>>

>>>

128 1부 머신러닝


CHAPTER

4

모델 훈련

지금까지는 머신러닝 모델과 훈련 알고리즘을 블랙박스처럼 취급했습니다. 앞 장의 연습문제 를 풀어봤다면 내부가 어떻게 작동하는지 몰라도 많은 일을 처리할 수 있다는 점에 놀랐을 것입 니다. 회귀 시스템을 최적화하고 숫자 이미지 분류기를 개선했으며 스팸 분류기를 처음부터 구 축했지만 실제로 어떻게 작동하는지는 모릅니다. 많은 경우 구현의 상세사항을 실제로 알아야 할 필요는 없습니다. 하지만 어떻게 작동하는지 잘 이해하고 있으면 적절한 모델, 올바른 훈련 알고리즘, 작업에 맞는 좋은 하이퍼파라미터를 빠르게 찾을 수 있습니다. 작동 원리를 이해하고 있으면 디버깅이나 에 러를 효율적으로 분석하는 데 도움이 됩니다. 이 장에서 언급하는 대부분의 주제는 신경망 neural network

(2부에서 설명합니다)을 이해하고 구축하고 훈련시키는 데 필수입니다.

이 장에서는 가장 간단한 모델 중 하나인 선형 회귀부터 시작합니다. 이 모델을 훈련시키는 두 가지 방법을 설명하겠습니다. ●

직접 계산할 수 있는 공식을 사용하여 훈련 세트에 가장 잘 맞는 모델 파라미터(즉, 훈련 세트에 대해 비용 함 수를 최소화하는 모델 파라미터)를 해석적으로 구합니다.

경사 하강법(GD )이라 불리는 반복적인 최적화 방식을 사용하여 모델 파라미터를 조금씩 바꾸면서 비용 함 수를 훈련 세트에 대해 최소화시킵니다. 결국에는 앞의 방법과 동일한 파라미터로 수렴합니다. 경사 하강법의 변종으로 2부에서 신경망을 공부할 때 계속 사용하게 될 배치 Batch 경사 하강법, 미니배치 Mini-batch 경사 하강 법, 확률적 Stochastic 경사 하강법(SGD )도 살펴보겠습니다.

4장 모델 훈련 155


그다음에는 비선형 데이터셋에 훈련시킬 수 있는 조금 더 복잡한 모델인 다항 회귀를 살펴보겠 습니다. 이 모델은 선형 회귀보다 파라미터가 많아서 훈련 데이터에 과대적합되기 더 쉽습니다. 따라서 학습 곡선 learning curve 을 사용해 모델이 과대적합되는지 감지하는 방법도 살펴보겠습니 다. 그런 다음 훈련 세트의 과대적합을 감소시킬 수 있는 규제 기법을 몇 가지 알아보겠습니다. 마지막으로 분류 작업에 널리 사용하는 모델인 로지스틱 회귀와 소프트맥스 회귀를 살펴보겠 습니다. CAUTION_ 이 장에는 기초적인 선형대수와 미분 기호를 사용한 수학 방정식이 꽤 나옵니다. 이 식들을 이해

하려면 벡터와 행렬, 전치 transpose, 점곱 dot product, 역행렬 inverse matrix, 편미분 partial derivative 에 대해 알아야 합니 다. 이 개념들이 익숙하지 않다면 주피터 노트북으로 만든 선형대수와 미분에 대한 기초 튜토리얼을 깃허브 에서 살펴보세요. 정말 수학이 싫다면 이 장을 읽되 방정식은 건너뛰세요. 본문만으로도 대부분의 개념을 이 해하는 데 충분히 도움 될 것입니다.

4.1 선형 회귀 다음은 1장에서 본 삶의 만족도에 대한 간단한 선형 회귀 모델입니다. 삶의 만족도

= θ 0 + θ 1 × 1인당_GDP

이 모델은 입력 특성인 1인당_GDP에 대한 선형 함수입니다. θ 0 과 θ 1 이 모델 파라미터입니다. 더 일반적으로 선형 모델은 [식 4-1]에서처럼 입력 특성의 가중치 합과 편향 bias (또는 절편 intercept

)이라는 상수를 더해 예측을 만듭니다.

식 4-1 선형 회귀 모델의 예측

ŷ = θ 0 + θ 1 x1 + θ 2 x2 +  + θ n xn ŷ 은 예측값입니다.

n 은 특성의 수입니다.

x i 는 i 번째 특성값입니다.

θ j 는 j 번째 모델 파라미터입니다(편향 θ 0과 특성의 가중치 θ 1 , θ 2 , ... , θ n 을 포함합니다).

156 1부 머신러닝


이 식은 [식 4-2]처럼 벡터 형태로 더 간단하게 쓸 수 있습니다. 식 4-2 선형 회귀 모델의 예측(벡터 형태)

yˆ = hθ (x) = θ T ⋅ x θ 는 편향 θ 0 과 θ 1 에서 θ n 까지의 특성 가중치를 담고 있는 모델의 파라미터 벡터입니다.

θ T 는 θ 의 전치입니다(열 벡터가 아니고 행 벡터).

x 는 x0 에서 xn 까지 담고 있는 샘플의 특성 벡터입니다. x0 는 항상 1입니다.1

θ T ⋅ x 는 θ T 와 x의 점곱입니다.

h θ 는 모델 파라미터 θ 를 사용한 가설 hypothesis 함수입니다.

이것이 선형 회귀 모델입니다. 그러면 이제 훈련시켜 볼까요? 모델을 훈련시킨다는 것은 모델이 훈련 세트에 가장 잘 맞도록 모델 파라미터를 설정하는 것입니다. 이를 위해 먼저 모델이 훈련 데이터에 얼마나 잘 들어맞는지 측정해야 합니다. 2장에서 회귀에 가장 널리 사용되는 성능 측 정 지표는 평균 제곱근 오차(RMSE )라고 언급했습니다(식 2-1 ). 그러므로 선형 회귀 모델을 훈련시키려면 RMSE를 최소화하는 θ 를 찾아야 합니다. 실제로는 RMSE보다 평균 제곱 오차 Mean Square Error

(MSE )를 최소화하는 것이 같은 결과를 내면서(어떤 함수를 최소화하는 것은 그

함수의 제곱근을 최소화하는 것과 같으므로) 더 간단합니다.2 훈련 세트 X에 대한 선형 회귀 가설 hθ 의 MSE는 [식 4-3]처럼 계산합니다. 식 4-3 선형 회귀 모델의 MSE 비용 함수

MSE ( X, hθ ) =

1 m T (i ) 2 ∑ (θ ⋅ x − y (i ) ) m i =1

이 표기법의 대부분은 2장에서 설명했습니다(2.2.2절 ‘성능 측정 지표 선택’의 ‘표기법’ 상자글 을 참조하세요). 딱 하나의 차이는 모델이 파라미터 벡터 θ 를 가진다는 것을 명확히 하려고 h 대신 hθ 를 사용한 것뿐입니다. 간단하게 표시하기 위해 MSE ( X, hθ ) 대신 MSE (θ )라고 쓰겠 습니다.

1 옮긴이_ 편의상 벡터 표현으로 모델 파라미터와 특성을 모두 표현하기 위해 편향 θ 0에 가상의 특성 x0 = 1이 곱해졌다고 생각합니다. 2 최종 모델을 평가하는 데 사용하는 성능 측정 지표 말고 학습 알고리즘이 다른 함수를 최적화하는 경우가 종종 있습니다. 일반적으로 성능 측정 지표에는 없는 유용한 미분 특성이 있어서 이런 함수가 계산하기 더 쉽거나, (4.5절 ‘규제가 있는 선형 모델’에서 규제를 설명할 때 보겠지만) 훈련하는 동안 모델에 제약을 가하기 위해 사용합니다.

4장 모델 훈련 157


4.1.1 정규방정식 비용 함수를 최소화하는 θ 값을 찾기 위한 해석적인 방법이 있습니다. 다른 말로 하면 바로 결과를 얻을 수 있는 수학 공식이 있습니다. 이를 정규방정식 Normal Equation 이라고 합니다(식

4-4 ).3 식 4-4 정규방정식

θˆ = (XT ⋅ X ) ⋅ XT ⋅ y −1

θ ˆ 은 비용 함수를 최소화하는 θ 값입니다.

y 는 y (1 )부터 y ( m ) 까지 포함하는 타깃 벡터입니다.

이 공식을 테스트하기 위해 선형처럼 보이는 데이터를 생성하겠습니다(그림 4-1 ). import numpy as np X = 2 * np.random.rand(100, 1) y = 4 + 3 * X + np.random.randn(100, 1)

그림 4-1 무작위로 생성한 선형 데이터셋

3 이 식이 비용 함수를 최소화하는 θ 를 만드는지 증명하는 것은 이 책의 범위를 벗어납니다. 옮긴이_ 선형 최소 제곱법을 설명하는 위키백 과 문서(https://goo.gl/Lf8VHJ )를 참고하세요.

158 1부 머신러닝


그럼 이제 정규방정식을 사용해 θˆ 을 계산해보겠습니다. 넘파이 선형대수 모듈( np.linalg ) 에 있는 inv ( ) 함수를 사용해 역행렬을 계산하고 dot ( ) 메서드를 사용해 행렬 곱셈을 하겠습 니다.4 X_b = np.c_[np.ones((100, 1)), X] # 모든 샘플에 x0 = 1을 추가합니다. theta_best = np.linalg.inv(X_b.T.dot(X_b)).dot(X_b.T).dot(y)

이 데이터를 생성하기 위해 사용한 실제 함수는 y = 4 + 3x1 + 가우시안_노이즈입니다. 정규방정식 으로 계산한 값을 확인해보겠습니다. theta_best array([[ 4.21509616], [ 2.77011339]])

>>>

θ 0 = 4.215와 θ 1 = 2.770 대신 θ 0 = 4와 θ 1 = 3을 기대했었습니다. 매우 비슷하지만 노이즈 때문 에 원래 함수의 파라미터를 정확하게 재현하지 못했습니다.

θˆ 을 사용해 예측을 해보겠습니다. X_new = np.array([[0], [2]]) X_new_b = np.c_[np.ones((2, 1)), X_new] >>> y_predict = X_new_b.dot(theta_best) >>> y_predict array([[ 4.21509616], [ 9.75532293]]) >>> >>>

# 모든 샘플에 x0 = 1을 추가합니다.

모델의 예측을 그래프에 나타내보겠습니다(그림 4-2 ). plt.plot(X_new, y_predict, "r-") plt.plot(X, y, "b.") plt.axis([0, 2, 0, 15]) plt.show()

4 옮긴이_ SVD를 사용하여 유사 역행렬을 구하는 넘파이 pinv ( ) 함수를 사용하면 np.linalg.pinv (X_b ).dot (y ) 와 같이 간단 하게 계산할 수 있습니다.

4장 모델 훈련 159


그림 4-2 선형 회귀 모델의 예측

예측

같은 작업을 하는 사이킷런 코드는 다음과 같습니다.5 from sklearn.linear_model import LinearRegression lin_reg = LinearRegression() >>> lin_reg.fit(X, y) >>> lin_reg.intercept_, lin_reg.coef_ (array([ 4.21509616]), array([[ 2.77011339]])) >>> lin_reg.predict(X_new) array([[ 4.21509616], [ 9.75532293]]) >>> >>>

4.1.2 계산 복잡도 정규방정식은 ( n + 1 ) × ( n + 1 ) 크기가 되는 XT ⋅ X 의 역행렬을 계산합니다( n 은 특성 수). 역행렬을 계산하는 계산 복잡도 computational complexity 는 일반적으로 O (n2.4 )에서 O (n3 ) 사이입 니다(구현 방법에 따라 차이가 있습니다). 다시 말해 특성 수가 두 배로 늘어나면 계산 시간이 대략 2 2.4 = 5.3에서 2 3 = 8배로 증가합니다.6 5 사이킷런은 특성의 가중치(coef_ )와 편향(intercept_ )을 분리하여 저장합니다. 6 옮긴이_ 역행렬을 계산하는 알려진 가장 빠른 방법은 코퍼스미스-위노그라드(Coppersmith - Winograd ) 알고리즘을 사용한 방식입 니다. 사이킷런의 LinearRegression에서 사용하는 scipy.linalg.lstsq 함수는 SVD 방법을 사용하여 유사 역행렬을 계산하며 O (n 2 )의 복잡도를 가집니다.

160 1부 머신러닝


CHAPTER

5

서포트 벡터 머신

서포트 벡터 머신 Support Vector Machine (SVM )은 매우 강력하고 선형이나 비선형 분류, 회귀, 이상 치 탐색에도 사용할 수 있는 다목적 머신러닝 모델입니다. 머신러닝에서 가장 인기 있는 모델에 속하고 머신러닝에 관심 있는 사람이라면 반드시 알고 있어야 하는 모델입니다. SVM은 특히 복 잡한 분류 문제에 잘 들어맞으며 작거나 중간 크기의 데이터셋에 적합합니다. 이 장에서는 SVM의 핵심 개념을 설명하고 사용 방법과 작동 원리를 살펴보겠습니다.

5.1 선형 SVM 분류 SVM의 기본 아이디어는 그림으로 설명하는 것이 가장 좋습니다. [그림 5-1]에 4장 끝에서 소 개한 붓꽃 데이터셋의 일부를 나타냈습니다. 두 클래스가 직선으로 확실히 잘 나뉘어 있습니다 (선형적으로 구분됩니다). 왼쪽 그래프에 세 개의 선형 분류기에서 만들어진 결정 경계가 보 입니다.1 점선으로 나타난 결정 경계를 만든 모델은 클래스를 적절하게 분류하지 못하고 있습 니다. 다른 두 모델은 훈련 세트에 대해 완벽하게 동작합니다. 하지만 결정 경계가 샘플에 너무 가까워 새로운 샘플에 대해서는 아마 잘 작동하지 못할 것입니다. 오른쪽 그래프에 있는 실선은

SVM 분류기의 결정 경계입니다. 이 직선은 두 개의 클래스를 나누고 있을 뿐만 아니라 제일 가까운 훈련 샘플로부터 가능한 한 멀리 떨어져 있습니다. SVM 분류기를 클래스 사이에 가장 1 옮긴이_ 왼쪽 그래프의 결정 경계는 설명을 위해 임의의 직선을 그은 것입니다.

5장 서포트 벡터 머신 201


폭이 넓은 도로를 찾는 것으로 생각할 수 있습니다. 그래서 라지 마진 분류 large margin classification 라 고 합니다.

꽃잎 너비

그림 5-1 라지 마진 분류

꽃잎 길이

꽃잎 길이

도로 바깥쪽에 훈련 샘플을 더 추가해도 결정 경계에는 전혀 영향을 미치지 않습니다. 도로 경계 에 위치한 샘플에 의해 전적으로 결정(또는 의지)됩니다. 이런 샘플을 서포트 벡터 support vector 라고 합니다([그림 5-1]에 동그라미로 표시했습니다). CAUTION_ SVM은 특성의 스케일에 민감합니다. [그림 5-2]의 왼쪽 그래프에서는 수직축의 스케일이 수평

축의 스케일보다 훨씬 커서 가장 넓은 도로가 거의 수평에 가깝게 됩니다. 특성의 스케일을 조정하면(예를 들 면 사이킷런의 StandardScaler를 사용하여) 결정 경계가 훨씬 좋아집니다(오른쪽 그래프).

그림 5-2 특성 스케일에 따른 민감성 스케일되지 않음

스케일됨

5.1.1 소프트 마진 분류 모든 샘플이 도로 바깥쪽에 올바르게 분류되어 있다면 이를 하드 마진 분류 hard margin classification 라고 합니다. 하드 마진 분류에는 두 가지 문제점이 있습니다. 데이터가 선형적으로 구분될 수 있어야 제대로 작동하며, 이상치에 민감합니다. [그림 5-3]을 보면 붓꽃 데이터셋에 이상치가

202 1부 머신러닝


하나 있습니다. 왼쪽 그래프에서는 하드 마진을 찾을 수 없습니다. 오른쪽 그래프의 결정 경계 는 이상치가 없던 [그림 5-1]의 결정 경계와 매우 다르고 일반화가 잘될 것 같지 않습니다.2 그림 5-3 이상치에 민감한 하드 마진

꽃잎 너비

이상치 불가능! 이상치 꽃잎 길이

꽃잎 길이

이런 문제를 피하려면 좀 더 유연한 모델이 필요합니다. 도로의 폭을 가능한 한 넓게 유지하는 것과 마진 오류 margin violation (즉, 샘플이 도로 중간이나 심지어 반대쪽에 있는 경우) 사이에 적 절한 균형을 잡아야 합니다. 이를 소프트 마진 분류 soft margin classification 라고 합니다. 사이킷런의 SVM 모델에서는 C 하이퍼파라미터를 사용해 이 균형을 조절할 수 있습니다. C 값 을 줄이면 도로의 폭이 넓어지지만 마진 오류도 커집니다. [그림 5-4]는 선형적으로 구분되지 않 는 데이터셋에 두 개의 소프트 마진 SVM 분류기로 만든 결정 경계와 마진을 보여줍니다. 왼쪽 을 보면 큰 C 값을 사용해 분류기가 마진 오류를 적게 냈지만 마진이 좁아졌습니다. 오른쪽에서 는 작은 C 값을 사용해 마진이 넓어졌지만 많은 샘플이 도로 안에 포함되었습니다. 그러나 두 번 째 분류기가 더 잘 일반화될 것 같아 보입니다. 사실 대부분의 마진 오류는 결정 경계를 기준으 로 올바른 클래스로 분류되기 때문에 이 훈련 세트에서 예측 에러는 마진 오류보다 작습니다.

꽃잎 너비

그림 5-4 좁은 마진과 넓은 마진

꽃잎 길이

TIP

꽃잎 길이

SVM 모델이 과대적합이라면 C를 감소시켜 모델을 규제할 수 있습니다.

2 옮긴이_ [그림 5-3]의 왼쪽과 오른쪽 그래프에 있는 이상치는 설명을 위해 임의로 추가한 것입니다.

5장 서포트 벡터 머신 203


다음 사이킷런 코드는 붓꽃 데이터셋을 적재하고, 특성 스케일을 변경하고, Iris-Virginia 품종 을 감지하기 위해 선형 SVM 모델을 훈련시킵니다(C = 1과 잠시 후에 설명할 힌지 손실 hinge loss 함수를 적용한 LinearSVC 클래스를 사용합니다). [그림 5-4]의 오른쪽 그래프가 이 코드로 만 들어진 것입니다. import numpy as np from sklearn import datasets from sklearn.pipeline import Pipeline from sklearn.preprocessing import StandardScaler from sklearn.svm import LinearSVC iris = datasets.load_iris() X = iris["data"][:, (2, 3)] # 꽃잎 길이, 꽃잎 너비 y = (iris["target"] == 2).astype(np.float64) # Iris-Virginica svm_clf = Pipeline([ ("scaler", StandardScaler()), ("linear_svc", LinearSVC(C=1, loss="hinge")), ]) svm_clf.fit(X, y)

그런 다음 이 모델을 사용해 예측을 할 수 있습니다.3 svm_clf.predict([[5.5, 1.7]]) array([ 1.]) >>>

NOTE_ SVM 분류기는 로지스틱 회귀 분류기와는 다르게 클래스에 대한 확률을 제공하지 않습니다.3

다른 방법으로는 SVC (kernel="linear", C=1 ) 과 같이 SVC 모델을 사용할 수 있습니 다. 하지만 큰 훈련 세트에서는 속도가 매우 느리므로 권장하지 않습니다. 또 다른 방법은 SGDClassifier (loss="hinge", alpha=1/(m*C ) )4 와 같이 SGDClassifier 모델을 사용하는 3 옮긴이_ 사이킷런의 LinearSVC는 predict_proba ( ) 메서드를 제공하지 않지만, SVC 모델은 probability=True로 매개변수 를 지정하면 predict_proba ( ) 메서드를 제공합니다. SVC의 probability 매개변수 기본값은 False입니다. 4 옮긴이_ 이 식에서 m 은 샘플 수입니다. 확률적 경사 하강법은 샘플 하나씩 그래디언트를 계산하여 모델 파라미터를 갱신하기 때문에 훈련 세트 수에 반비례해야 비슷한 규제를 적용할 수 있습니다.

204 1부 머신러닝


것입니다. 이는 선형 SVM 분류기를 훈련시키기 위해 (4장에서 본) 일반적인 확률적 경사 하강 법을 적용합니다. LinearSVC 만큼 빠르게 수렴하지는 않지만 데이터셋이 아주 커서 메모리에 적재할 수 없거나(외부 메모리 훈련), 온라인 학습으로 분류 문제를 다룰 때는 유용합니다. TIP

LinearSVC는 규제에 편향을 포함시킵니다. 그래서 훈련 세트에서 평균을 빼서 중앙에 맞춰야 합니다. StandardScaler를 사용하여 데이터 스케일을 맞추면 자동으로 이렇게 됩니다. 그리고 loss 매개변수를 "hinge"로 지정해야 합니다.5 마지막으로 훈련 샘플보다 특성이 많지 않다면 성능을 높이기 위해 dual 매개 변수를 False로 지정해야 합니다(이 장 뒷부분에서 쌍대 duality 문제에 대해 자세히 설명하겠습니다).

5.2 비선형 SVM 분류 선형 SVM 분류기가 효율적이고 많은 경우에 아주 잘 작동하지만, 선형적으로 분류할 수 없는 데이터셋이 많습니다. 비선형 데이터셋을 다루는 한 가지 방법은 (4장에서처럼) 다항 특성과 같은 특성을 더 추가하는 것입니다. 이렇게 하면 선형적으로 구분되는 데이터셋이 만들어질 수 있습니다. [그림 5-5]의 왼쪽 그래프는 하나의 특성 x1 만을 가진 간단한 데이터셋을 나타냅니 다. 그림에서 볼 수 있듯이 이 데이터셋은 선형적으로 구분이 안 됩니다. 하지만 두 번째 특성

x2 = (x1 ) 2 을 추가하여 만들어진 2차원 데이터셋은 완벽하게 선형적으로 구분할 수 있습니다. 그림 5-5 특성을 추가하여 선형적으로 구분되는 데이터셋 만들기

5 옮긴이_ 이 내용은 SVC (kernel="linear") 에 상응하는 LinearSVC의 설정을 설명하는 것입니다. LinearSVC는 보통의 SVM 구현과 달리 규제에 편향을 포함하고 있어서 데이터의 스케일을 맞추지 않고 SVC 모델과 비교하면 큰 차이가 납니다. LinearSVC 의 loss 매개변수의 기본값은 "squared_hinge"입니다. [그림 5-4]의 그래프는 StandardScaler로 데이터 스케일을 변경하고 LinearSVC로 결정 경계를 찾은 후 원본 좌표 공간으로 가중치와 편향의 스케일을 복원하여 나타낸 것입니다.

5장 서포트 벡터 머신 205


사이킷런을 사용하여 이를 구현하려면 (4.3절 ‘다항 회귀’에서 소개한) PolynomialFeatures 변환기와 StandardScaler, LinearSVC를 연결하여 Pipeline을 만들면 좋습니다. 이를 moons 데이터셋 6에 적용해보겠습니다(그림 5-6 ). from sklearn.datasets import make_moons from sklearn.pipeline import Pipeline from sklearn.preprocessing import PolynomialFeatures X, y = make_moons(n_samples=100, noise=0.15, random_state=42) polynomial_svm_clf = Pipeline([ ("poly_features", PolynomialFeatures(degree=3)), ("scaler", StandardScaler()), ("svm_clf", LinearSVC(C=10, loss="hinge")) ]) polynomial_svm_clf.fit(X, y)

그림 5-6 다항 특성을 사용한 선형 SVM 분류기

6 옮긴이_ moons 데이터셋은 사이킷런의 make_moons 함수를 사용해서 만든 두 개의 반달 모양 데이터셋입니다.

206 1부 머신러닝


CHAPTER

6

결정 트리

SVM처럼 결정 트리 Decision Tree 는 분류와 회귀 작업 그리고 다중출력 작업도 가능한 다재다능한 머신러닝 알고리즘입니다. 또한 매우 복잡한 데이터셋도 학습할 수 있는 강력한 알고리즘입니다. 예를 들어 2장에서 캘리포니아 주택 가격 데이터셋을 완벽하게 맞추는 DecisionTreeRegressor 모델을 훈련시켰습니다(사실 과대적합입니다). 결정 트리는 최근에 자주 사용되는 가장 강력한 머신러닝 알고리즘 중 하나인 랜덤 포레스트(7 장 참조)의 기본 구성 요소이기도 합니다. 이 장에서는 결정 트리의 훈련, 시각화, 예측 방법에 대해 먼저 살펴보겠습니다. 그런 다음 사이 킷런의 CART 훈련 알고리즘을 둘러보고 트리에 규제를 가하는 방법과 회귀 문제에 적용하는 방법을 배우도록 하겠습니다. 마지막으로 결정 트리의 제약사항에 관해 이야기하겠습니다.

6.1 결정 트리 학습과 시각화 결정 트리를 이해하기 위해 일단 하나를 만들어서 어떻게 예측을 하는지 살펴보겠습니다. 다음 은 붓꽃 데이터셋(4장 참조)에 DecisionTreeClassifier를 훈련시키는 코드입니다.

6장 결정 트리 225


from sklearn.datasets import load_iris from sklearn.tree import DecisionTreeClassifier iris = load_iris() X = iris.data[:, 2:] y = iris.target

# 꽃잎의 길이와 너비

tree_clf = DecisionTreeClassifier(max_depth=2) tree_clf.fit(X, y)

export_graphviz ( ) 함수를 사용해 그래프 정의를 iris_tree.dot 파일로 출력하여 훈련된 결

정 트리를 시각화할 수 있습니다. from sklearn.tree import export_graphviz export_graphviz( tree_clf, out_file=image_path("iris_tree.dot"), feature_names=iris.feature_names[2:], class_names=iris.target_names, rounded=True, filled=True )

이 .dot 파일을 graphviz 패키지 1에 있는 dot 명령줄 도구로 PDF나 PNG 같은 포맷으로 변 경합니다. 다음 명령은 .dot 파일을 .png 이미지로 바꿉니다. $ dot -Tpng iris_tree.dot -o iris_tree.png

우리가 만든 첫 번째 결정 트리는 [그림 6-1]과 같습니다.

1 Graphviz (http://www.graphviz.org )는 오픈소스 그래프 시각화 소프트웨어 패키지입니다. 옮긴이_ 아나콘다 배포판을 사용하고 있다면 conda install python-graphviz 명령으로 간단하게 파이썬 패키지와 함께 graphviz를 설치하여 주피터 노트북에서 트 리 그래프를 직접 그릴 수 있습니다. 옮긴이의 깃허브에서 6장의 주피터 노트북을 참고하세요.

226 1부 머신러닝


그림 6-1 붓꽃 결정 트리

꽃잎 길이

꽃잎 너비

6.2 예측하기 [그림 6-1]의 트리가 어떻게 예측을 만들어내는지 살펴보겠습니다. 새로 발견한 붓꽃의 품종을 분류하려 한다고 가정하겠습니다. 먼저 루트 노드 root node (깊이가 0인 맨 꼭대기의 노드)에서 시작합니다. 이 노드는 꽃잎의 길이가 2.45cm보다 짧은지 검사합니다. 만약 그렇다면 루트 노 드에서 왼쪽의 자식 노드 child node (깊이 1, 왼쪽 노드)로 이동합니다. 이 경우 이 노드가 리프 노 드 leaf node (즉, 자식 노드를 가지지 않는 노드)이므로 추가적인 검사를 하지 않습니다. 그냥 노드 에 있는 예측 클래스를 보고 결정 트리가 새로 발견한 꽃의 품종을 Iris-Setosa (class=setosa ) 라고 예측합니다. 또 다른 꽃을 발견했는데 이번에는 꽃잎의 길이가 2.45cm보다 깁니다. 이번에는 루트 노드의 오른쪽 자식 노드로 이동해야 합니다. 이 노드는 리프 노드가 아니라서 추가로 ‘꽃잎의 너비가

1.75cm보다 작은지’ 검사합니다. 만약 그렇다면 이 꽃은 아마도 Iris-Versicolor (깊이 2, 왼

6장 결정 트리 227


쪽)일 것입니다. 그렇지 않다면 Iris-Virginica (깊이 2, 오른쪽)일 것입니다. 아주 간단명료하 네요. NOTE_ 결정 트리의 여러 장점 중 하나는 데이터 전처리가 거의 필요하지 않다는 것입니다. 특히 특성의 스

케일을 맞추거나 평균을 원점에 맞추는 작업이 필요하지 않습니다.

노드의 sample 속성은 얼마나 많은 훈련 샘플이 적용되었는지 헤아린 것입니다. 예를 들어

100개의 훈련 샘플의 꽃잎 길이가 2.45cm보다 길고(깊이 1, 오른쪽), 그중 54개 샘플의 꽃 잎 너비가 1.75cm보다 짧습니다(깊이 2, 왼쪽). 노드의 value 속성은 노드에서 각 클래스에 얼마나 많은 훈련 샘플이 있는지 알려줍니다. 예를 들어 맨 오른쪽 아래 노드는 Iris-Setosa가

0개이고, Iris-Versicolor가 1개, Iris-Virginica가 45개 있습니다. 마지막으로 노드의 gini 속성은 불순도 impurity 를 측정합니다. 한 노드의 모든 샘플이 같은 클래스에 속해 있다면 이 노 드를 순수(gini=0 )하다고 합니다. 예를 들어 깊이 1의 왼쪽 노드는 Iris-Setosa 훈련 샘플만 가지고 있으므로 순수 노드이고 gini 점수가 0입니다. [식 6-1]은 훈련 알고리즘이 i번째 노드 의 gini 점수 Gi를 계산하는 방법을 보여줍니다. 예를 들어 깊이 2의 왼쪽 노드의 gini 점수는

1 − (0 / 54 ) − (49 / 54 ) ≈ 0.168 입니다. 불순도를 측정하는 또 다른 방법은 잠시 후에 설명하 2

2

겠습니다. 식 6-1 지니 불순도 n

Gi = 1 − ∑ pi , k

2

k =1

p i ,k 는 i 번째 노드에 있는 훈련 샘플 중 클래스 k 에 속한 샘플의 비율입니다.

NOTE_ 사이킷런은 이진 트리만 만드는 CART 알고리즘을 사용합니다. 그러므로 리프 노드 외의 모든 노드

는 자식 노드를 두 개씩 가집니다(즉, 질문의 답은 ‘예’ 또는 ‘아니오’입니다). 하지만 ID3 같은 알고리즘은 둘 이상의 자식 노드를 가진 결정 트리를 만들 수 있습니다.

[그림 6-2]는 이 결정 트리의 결정 경계를 보여줍니다. 굵은 수직선이 루트 노드(깊이 0 )의 결 정 경계(꽃잎 길이 = 2.45cm )를 나타냅니다. 왼쪽 영역은 순수 노드(Iris-Setosa만 있음)이 기 때문에 더 이상 나눌 수 없습니다. 하지만 오른쪽 영역은 순수 노드가 아니므로 깊이 1의 오 른쪽 노드는 꽃잎 너비 = 1.75cm에서 나누어집니다(파선). max_depth를 2로 설정했기 때문 228 1부 머신러닝


에 결정 트리는 더 분할되지 않았습니다. 하지만 max_depth를 3으로 하면 깊이 2의 두 노드가 각각 결정 경계를 추가로 만듭니다(점선). 그림 6-2 결정 트리의 결정 경계

꽃잎 너비

깊이=1

깊이=0

깊이=2

꽃잎 길이

모델 해석: 화이트박스와 블랙박스 여기에서 볼 수 있듯이 결정 트리는 매우 직관적이고 결정 방식을 이해하기 쉽습니다. 이런 모델 을 화이트박스 white box 모델이라고 합니다. 반대로 앞으로 보게 될 랜덤 포레스트나 신경망은 블 랙박스black box 모델입니다. 이 알고리즘들은 성능이 뛰어나고 예측을 만드는 연산 과정을 쉽게 확인할 수 있습니다. 그렇지만 왜 그런 예측을 만드는지는 쉽게 설명하기 어렵습니다. 예를 들어 신경망이 어떤 사람이 사진에 있다고 판단했을 때 무엇이 이런 예측을 낳게 했는지 파악하기 매 우 어렵습니다. 모델이 그 사람의 눈을 인식한 걸까요? 아니면 입 또는 코 또는 신발일까요? 아 니면 그 사람이 앉아 있는 소파 때문일까요? 반면에 결정 트리는 필요하다면 (예를 들면 붓꽃 분 류를 위해) 수동으로 직접 따라 해볼 수도 있는 간단하고 명확한 분류 방법을 사용합니다.

6.3 클래스 확률 추정 결정 트리는 한 샘플이 특정 클래스 k 에 속할 확률을 추정할 수도 있습니다. 먼저 이 샘플에 대 해 리프 노드를 찾기 위해 트리를 탐색하고 그 노드에 있는 클래스 k 의 훈련 샘플의 비율을 반

6장 결정 트리 229


환합니다. 예를 들어 길이가 5cm이고 너비가 1.5cm인 꽃잎을 발견했다고 가정합시다. 이 에 해당하는 리프 노드는 깊이 2에서 왼쪽 노드이므로 결정 트리는 그에 해당하는 확률을 출 력합니다. 즉, Iris-Setosa는 0%(0/54 ), Iris-Versicolor는 90.7%(49/54 ), Iris-Virginica 는 9 .3 %( 5 /54 )입니다. 당연히 클래스를 하나 예측한다면 가장 높은 확률을 가진 Iris -

Versicolor (클래스 1 )를 출력할 것입니다. 확인해봅시다. tree_clf.predict_proba([[5, 1.5]]) array([[ 0. , 0.90740741, 0.09259259]]) >>> tree_clf.predict([[5, 1.5]]) array([1]) >>>

정확하네요! 추정된 확률은 [그림 6-2]의 오른쪽 아래 사각형 안에서는 어느 위치든 동일합니 다.2 예를 들어 길이가 6cm이고 너비가 1.5cm인 꽃잎도 확률이 같습니다(사실 이 경우에는

Iris-Virginica에 더 가까워 보입니다).

6.4 CART 훈련 알고리즘 사이킷런은 결정 트리를 훈련시키기 위해(즉, 트리를 성장시키기 위해) CART Classification And Regression Tree

알고리즘을 사용합니다. 이 알고리즘의 아이디어는 매우 간단합니다. 먼저 훈련

세트를 하나의 특성 k 의 임곗값 tk 를 사용해 두 개의 서브셋으로 나눕니다(예를 들면 꽃잎의 길이 ≤ 2.45cm ). 어떻게 k 와 tk 를 고를까요? (크기에 따른 가중치가 적용된) 가장 순수한 서 브셋으로 나눌 수 있는 ( k , tk ) 짝을 찾습니다. 이 알고리즘이 최소화해야 하는 비용 함수는 [식

6-2]와 같습니다. 식 6-2 분류에 대한 CART 비용 함수

J (k , t k ) = 여기서

m mleft Gleft + right Gright m m

Gleft/right 는 왼쪽 /오른쪽 서브셋의 불순도  mleft/right 는 왼쪽 /오른쪽 서브셋의 샘플 수

2 옮긴이_ 이 영역은 [그림 6-2]에서 깊이= 1로 표시된 파선 밑의 사각형을 말합니다.

230 1부 머신러닝


CHAPTER

7

앙상블 학습과 랜덤 포레스트

무작위로 선택된 수천 명의 사람에게 복잡한 질문을 하고 대답을 모은다고 가정합시다. 많은 경 우 이렇게 모은 답이 전문가의 답보다 낫습니다. 이를 대중의 지혜 wisdom of the crowd 라고 합니다. 이와 비슷하게 일련의 예측기(즉, 분류나 회귀 모델)로부터 예측을 수집하면 가장 좋은 모델 하나보다 더 좋은 예측을 얻을 수 있을 것입니다. 일련의 예측기를 앙상블이라고 부르기 때문에 이를 앙상블 학습 Ensemble Learning 이라고 하며, 앙상블 학습 알고리즘을 앙상블 방법 Ensemble method 이라고 합니다. 예를 들어 훈련 세트로부터 무작위로 각기 다른 서브셋을 만들어 일련의 결정 트리 분류기를 훈련시킬 수 있습니다. 예측을 하려면 모든 개별 트리의 예측을 구하면 됩니다. 그런 다음 가장 많은 선택을 받은 클래스를 예측으로 삼습니다(6장의 마지막 연습문제를 참조하세요). 결정 트 리의 앙상블을 랜덤 포레스트 Random Forest 라고 합니다. 간단한 방법임에도 랜덤 포레스트는 오 늘날 가장 강력한 머신러닝 알고리즘 중 하나입니다. 게다가 (2장에서 언급한 것처럼) 프로젝트의 마지막에 다다르면 흔히 앙상블 방법을 사용하여 이미 만든 여러 괜찮은 예측기를 연결하여 더 좋은 예측기를 만듭니다. 사실 머신러닝 경연 대회 에서 우승하는 솔루션은 여러 가지 앙상블 방법을 사용한 경우가 많습니다. 이는 특히 넷플릭스 대회(http://netflixprize.com/ )에서 가장 인기 있습니다. 이 장에서는 배깅, 부스팅, 스태킹 등 가장 인기 있는 앙상블 방법을 설명하겠습니다. 랜덤 포 레스트도 다룰 것입니다.

7장 앙상블 학습과 랜덤 포레스트 241


7.1 투표 기반 분류기 정확도가 80%인 분류기 여러 개를 훈련시켰다고 가정합시다. 아마도 로지스틱 회귀 분류기,

SVM 분류기, 랜덤 포레스트 분류기, K-최근접 이웃 분류기 등을 가지고 있을 수 있습니다(그 림 7-1 참조). 그림 7-1 여러 분류기 훈련시키기 로지스틱 회귀

SVM 분류기

랜덤 포레스트 분류기

기타... 다양한 예측기들

더 좋은 분류기를 만드는 매우 간단한 방법은 각 분류기의 예측을 모아서 가장 많이 선택된 클 래스를 예측하는 것입니다. 이렇게 다수결 투표로 정해지는 분류기를 직접 투표 hard voting 분류기 라고 합니다(그림 7-2 ). 그림 7-2 직접 투표 분류기의 예측 앙상블의 예측 (예: 다수결 투표)

예측

다양한 분류기들

새로운 인스턴스

242 1부 머신러닝


조금 놀랍게도 이 다수결 투표 분류기가 앙상블에 포함된 개별 분류기 중 가장 뛰어난 것보다 도 정확도가 높을 경우가 많습니다. 사실 각 분류기가 약한 학습기 weak learner (즉, 랜덤 추측보다 조금 더 높은 성능을 내는 분류기)일지라도 충분하게 많고 다양하다면 앙상블은 (높은 정확도 를 내는) 강한 학습기 strong learner 가 될 수 있습니다. 이게 어떻게 가능할까요? 다음 설명이 이 미스터리를 조금 밝혀줄 것입니다. 동전을 던졌을 때 앞면이 51%, 뒷면이 49%가 나오는 조금 균형이 맞지 않는 동전이 있다고 가정하겠습니다. 이 동전을 1,000번 던진다면 대략 510번은 앞면, 490번은 뒷면이 나올 것이므로 다수는 앞면이 됩니다. 수학적으로 계산해보면 1,000번을 던진 후 앞면이 다수가 될 확률은 75%에 가깝다는 것을 확인할 수 있습니다. 더 많이 던질수록 확률은 증가합니다(예를 들어 10,000번 던지면 확률이 97% 이상으로 올라갑니다 1 ). 이는 큰 수의 법칙 law of large numbers 때문입니다. 동전을 자꾸 던질수록 앞면이 나오는 비율은 점점 더 앞면이 나올 확률(51%)에 가까워집니다. [그림

7-3]은 균형이 틀어진 동전을 10번 실험한 그래프입니다. 던진 횟수가 증가할수록 앞면이 나 올 확률 51%에 가까워집니다. 결국 10번의 실험 모두 50%보다 높게 유지되며 51%에 수렴하 면서 끝나고 있습니다.

앞면이 나온 비율

그림 7-3 큰 수의 법칙

동전을 던진 횟수

1 옮긴이_ 이 확률은 이항 분포(binomial distribution )의 확률 질량 함수(probability mass function )로 계산할 수 있습니다. 확률이 n ( n−k ) 입니다. 성공 확률이 51%인 동전을 1,000번 던져서 앞면이 한 p 인 이항 분포에서 n 번의 시도 중 k 번 성공할 확률은 p k (1 − p ) k

(1000−1) 번만 나올 확률은 1000 0.511 (1 − 0.51) = 1.6 × 10 −307 이 됩니다. 이런 식으로 1,000의 과반 직전인 499까지의 확률을 더하여 전 1 체 확률 1에서 빼면 1,000번 던져 앞면이 절반 이상 나올 확률이 됩니다. 사이파이에는 이항 분포의 누적 분포 함수가 있어 다음과 같이

손쉽게 계산할 수 있습니다. 1- scipy.stats.binom.cdf (499, 1000, 0.51 ) = 0.747입니다. 또한 10,000번을 던져서 앞면 이 절반 이상 나올 확률은 1- scipy.stats.binom.cdf (4999, 10000, 0.51 ) = 0.978입니다.

7장 앙상블 학습과 랜덤 포레스트 243


이와 비슷하게 (무작위 추측보다 조금 더 나은) 51% 정확도를 가진 1,000개의 분류기로 앙상 블 모델을 구축한다고 가정합시다. 가장 많은 클래스를 예측으로 삼는다면 75%의 정확도를 기 대할 수 있습니다! 하지만 이런 가정은 모든 분류기가 완벽하게 독립적이고 오차에 상관관계가 없어야 가능합니다. 하지만 여기서는 같은 데이터로 훈련시키기 때문에 이런 가정이 맞지 않습 니다. 분류기들이 같은 종류의 오차를 만들기 쉽기 때문에 잘못된 클래스가 다수인 경우가 많 고 앙상블의 정확도가 낮아집니다. TIP

앙상블 방법은 예측기가 가능한 한 서로 독립적일 때 최고의 성능을 발휘합니다. 다양한 분류기를 얻는 한 가 지 방법은 각기 다른 알고리즘으로 학습시키는 것입니다. 이렇게 하면 매우 다른 종류의 오차를 만들 가능성이 높기 때문에 앙상블 모델의 정확도를 향상시킵니다.

다음은 여러 분류기를 조합하여 사이킷런의 투표 기반 분류기(VotingClassifier )를 만들고 훈련시키는 코드입니다(훈련 세트는 5장에서 소개한 moons 데이터셋입니다). from from from from

sklearn.ensemble import RandomForestClassifier sklearn.ensemble import VotingClassifier sklearn.linear_model import LogisticRegression sklearn.svm import SVC

log_clf = LogisticRegression() rnd_clf = RandomForestClassifier() svm_clf = SVC() voting_clf = VotingClassifier( estimators=[('lr', log_clf), ('rf', rnd_clf), ('svc', svm_clf)], voting='hard') voting_clf.fit(X_train, y_train)

각 분류기의 테스트셋 정확도를 확인해봅시다. from sklearn.metrics import accuracy_score for clf in (log_clf, rnd_clf, svm_clf, voting_clf): clf.fit(X_train, y_train) ... y_pred = clf.predict(X_test) ... print(clf.__class__.__name__, accuracy_score(y_test, y_pred)) ... ... LogisticRegression 0.864 >>> >>>

244 1부 머신러닝


RandomForestClassifier 0.872 SVC 0.888 VotingClassifier 0.896

예상대로입니다! 투표 기반 분류기가 다른 개별 분류기보다 성능이 조금 더 높습니다. 모든 분류기가 클래스의 확률을 예측할 수 있으면(즉, predict_proba ( ) 메서드가 있으면), 개별 분류기의 예측을 평균 내어 확률이 가장 높은 클래스를 예측할 수 있습니다. 이를 간접 투 표 soft voting 라고 합니다. 이 방식은 확률이 높은 투표에 비중을 더 두기 때문에 직접 투표 방식 보다 성능이 높습니다. 이 방식을 사용하기 위해서는 voting="hard"를 voting="soft"로 바 꾸고 모든 분류기가 클래스의 확률을 추정할 수 있으면 됩니다. SVC는 기본값에서는 클래스 확 률을 제공하지 않으므로 probability 매개변수를 True로 지정해야 합니다(이렇게 하면 클래 스 확률을 추정하기 위해 교차 검증을 사용하므로 훈련 속도가 느려지지만 SVC에서 predict_ proba ( ) 메서드를 사용할 수 있습니다 ). 앞의 코드를 간접 투표 방식을 사용하도록 변경하면

91%의 정확도를 얻을 것입니다.

7.2 배깅과 페이스팅 앞서 말했듯이 다양한 분류기를 만드는 한 가지 방법은 각기 다른 훈련 알고리즘을 사용하는 것입니다. 또 다른 방법은 같은 알고리즘을 사용하지만 훈련 세트의 서브셋을 무작위로 구성하 여 분류기를 각기 다르게 학습시키는 것입니다. 훈련 세트에서 중복을 허용하여 샘플링하는 방 식을 배깅 bagging 2 (bootstrap aggregating의 줄임말 3 )이라 하며, 중복을 허용하지 않고 샘플 링하는 방식을 페이스팅 pasting 4이라고 합니다. 다시 말해 배깅과 페이스팅에서는 같은 훈련 샘플을 여러 개의 예측기에 걸쳐 사용할 수 있습 니다. 하지만 배깅만이 한 예측기를 위해 같은 훈련 샘플을 여러 번 샘플링할 수 있습니다. 이 샘플링과 훈련 과정을 [그림 7-4]에 나타냈습니다.

2 「Bagging Predictors」, L . Breiman (1996 ), http://goo.gl/o42tml 3 통계학에서는 중복을 허용한 리샘플링(resampling )을 부트스트래핑(bootstrapping )이라고 합니다. 4 「Pasting small votes for classification in large databases and on - line」, L . Breiman (1999 ), http://goo.gl/BXm0pm

7장 앙상블 학습과 랜덤 포레스트 245


그림 7-4 페이스팅/배깅의 훈련 세트 샘플링과 훈련

예측기 (예: 분류기) 훈련

무작위 샘플링 (중복 허용 = 부트스트랩)

훈련 세트

모든 예측기가 훈련을 마치면 앙상블은 모든 예측기의 예측을 모아서 새로운 샘플에 대한 예측 을 만듭니다. 수집 함수는 전형적으로 분류일 때는 통계적 최빈값 statistical mode (즉, 직접 투표 분 류기처럼 가장 많은 예측 결과)이고 회귀에 대해서는 평균을 계산합니다. 개별 예측기는 원본 훈련 세트로 훈련시킨 것보다 훨씬 크게 편향되어 있지만 수집 함수를 통과하면 편향과 분산이 모두 감소합니다.5 일반적으로 앙상블의 결과는 원본 데이터셋으로 하나의 예측기를 훈련시킬 때와 비교해 편향은 비슷하지만 분산은 줄어듭니다. [그림 7-4]에서 볼 수 있듯이 예측기는 모두 동시에 다른 CPU 코어나 서버에서 병렬로 학습시 킬 수 있습니다. 이와 유사하게 예측도 병렬로 수행할 수 있습니다. 이런 확장성 덕분에 배깅과 페이스팅의 인기가 높습니다.

7.2.1 사이킷런의 배깅과 페이스팅 사이킷런은 배깅과 페이스팅을 위해 간편한 API로 구성된 BaggingClassifier (회귀의 경우 에는 BaggingRegressor )를 제공합니다. 다음은 결정 트리 분류기 500개의 앙상블을 훈련시 키는 코드입니다.6 각 분류기는 훈련 세트에서 중복을 허용하여 무작위로 선택된 100개의 샘 5 편향과 분산은 4장에서 소개했습니다. 6 max_samples 매개변수는 0.0~1.0 사이의 실수로 지정할 수도 있습니다. 이렇게 지정하면 샘플링되는 데이터 수는 훈련 세트의 크기 에 max_samples를 곱한 값이 됩니다.

246 1부 머신러닝


CHAPTER

8

차원 축소

많은 경우 머신러닝 문제는 훈련 샘플 각각이 수천 심지어 수백만 개의 특성을 가지고 있습니 다. 이는 훈련을 느리게 할 뿐만 아니라, 앞으로 보게 되겠지만 좋은 솔루션을 찾기 어렵게 만 듭니다. 이런 문제를 종종 차원의 저주 curse of dimensionality 라고 합니다. 다행히도 실전문제에서는 특성 수를 크게 줄여서 불가능한 문제를 가능한 범위로 변경할 수 있 는 경우가 많습니다. 예를 들어 (3장에서 소개한) MNIST 이미지를 생각해보세요. 이미지 경계 에 있는 픽셀은 거의 항상 흰색이므로 훈련 세트에서 이런 픽셀을 완전히 제거해도 많은 정보를 잃지 않습니다. [그림 7- 6]을 보면 이런 픽셀들이 분류 문제에 크게 중요하지 않다는 것을 알 수 있습니다. 게다가 인접한 두 픽셀은 종종 많이 연관되어 있습니다. 두 픽셀을 하나의 픽셀로 합치더라도(예를 들어 두 픽셀 강도를 평균 냄으로써) 잃는 정보가 많지 않을 것입니다. CAUTION_ 차원을 축소시키면 일부 정보가 유실됩니다( JPEG로 이미지를 압축하면 품질이 감소되는 것처

럼). 그래서 훈련 속도가 빨라질 수는 있지만 시스템의 성능이 조금 나빠질 수 있습니다. 또한 작업 파이프라 인이 조금 더 복잡하게 되고 유지 관리가 어려워집니다. 그러므로 차원 축소를 고려하기 전에 훈련이 너무 느 린지 먼저 원본 데이터로 시스템을 훈련시켜 봐야 합니다. 그러나 어떤 경우에는 훈련 데이터의 차원을 축소 시키면 잡음이나 불필요한 세부사항을 걸러내므로 성능을 높일 수 있습니다(일반적으로는 훈련 속도만 빨라 집니다).

훈련 속도를 높이는 것 외에 차원 축소는 데이터 시각화 data visualization (또는 DataViz )에도 아 주 유용합니다. 차원 수를 둘로(또는 셋으로) 줄이면 고차원 훈련 세트를 하나의 그래프로 그 릴 수 있고 군집 같은 시각적인 패턴을 감지해 중요한 통찰을 얻는 경우가 많습니다.

8장 차원 축소 269


이 장에서는 차원의 저주에 대해 논의하고 고차원 공간에서 어떤 일이 일어나는지 알아보겠습 니다. 그런 다음 차원 축소에 사용되는 두 가지 주요 접근 방법(투영 projection 과 매니폴드 학습 Manifold Learning

)을 소개하겠습니다. 그리고 가장 인기 있는 차원 축소 기법인 PCA, 커널 PCA,

LLE를 다루도록 하겠습니다.

8.1 차원의 저주 우리는 3차원 1 세계에서 살고 있어서 고차원 공간을 직관적으로 상상하기 어렵습니다. 1,000차 원의 공간에서 휘어져 있는 200차원의 타원체는 고사하고 기본적인 4차원 초입방체 hypercube 조 차도 머릿속에 그리기 어렵습니다(그림 8-1 ). 그림 8-1 점, 선, 정사각형, 정육면체, 테서랙트(0차원에서 4차원까지의 초입방체) 2

차원

고차원 공간에서는 많은 것이 상당히 다르게 작동합니다. 예를 들어 단위 면적(1 × 1 사각형) 안에 있는 점을 무작위로 선택한다면 경계선에서 0.001 이내에 위치할 가능성은 0.4%입니다

1 시간까지 고려하면 4차원이고 끈 이론가라면 더 늘어날 수 있습니다. 옮긴이_ 대표적으로 초끈(superstring ) 이론은 물질의 구성 요소 를 소립자가 아니라 10-33cm라는 극히 작은 고무줄 같은 끈이라고 생각합니다. 여기서는 3차원 공간의 모든 점에 6차원 너비의 공간이 있다고 가정하여 9차원의 세계를 생각합니다. (『Newton Highlight 블랙홀 화이트홀』, 뉴턴코리아, 2009 ) 2 3차원 공간에 투영시킨 회전하는 테서랙트(tesseract )를 http://goo.gl/OM7ktJ에서 확인해보세요. [그림 8-1]의 이미지는 위키백 과 사용자 NerdBoy1392가 제작한 것으로 https://en.wikipedia.org/wiki/Tesseract에서 인용했습니다(크리에이티브 커 먼즈 BY-SA 3.0 ). 옮긴이_ 테서랙트는 3차원에 시간이 추가된 4차원의 초입방체입니다. 영화 인터스텔라에서 주인공 쿠퍼가 블랙홀에 떨어진 후 특이점 경계에서 ‘그들’이 준비한 테서렉트에 구조되고 딸 머피에게 중력 방정식을 알려준 다음 5차원 공간인 벌크(bulk )를 이 동하여 토성 근처로 돌아오게 됩니다. (『인터스텔라의 과학』, 까치글방, 2015 )

270 1부 머신러닝


(다른 말로 하면 어느 방향으로든 거의 끝부분에 있는 점을 선택할 가능성은 매우 낮습니다).3 하지만 10,000차원의 단위 면적을 가진 초입방체(1 × 1 × … × 1인 입방체, 즉 1을 만 번 곱한 것)에서는 이 가능성이 99.999999%보다 커집니다.4 고차원 초입방체에 있는 대다수의 점은 경계와 매우 가까이 있습니다.5 여기에 더 심각한 차이점이 있습니다. 단위 면적에서 임의의 두 점을 선택하면 두 점 사이의 거리는 평균적으로 대략 0.52가 됩니다. 3차원 큐브에서 임의의 두 점을 선택하면 평균 거리 는 대략 0.66입니다. 만약 1,000,000차원의 초입방체에서 두 점을 무작위로 선택하면 어떨까 요? 믿거나 말거나 평균 거리는 약 428.25 (대략 1,000,000 / 6 )입니다! 6 이는 매우 직관적 이지 않습니다. 두 점이 단위 초입방체에 같이 놓여 있는데 어떻게 이렇게 멀리 떨어져 있는 걸 까요? 이 사실은 고차원의 데이터셋이 매우 희박한 상태일 수 있음을 의미합니다. 즉, 대부분 의 훈련 데이터가 서로 멀리 떨어져 있습니다. 물론 이는 새로운 샘플도 훈련 샘플과 멀리 떨어 져 있을 가능성이 높다는 뜻입니다. 이 경우 예측을 위해 훨씬 많은 외삽 extrapolation 을 해야 하 기 때문에 저차원일 때보다 예측이 더 불안정합니다. 간단히 말해 훈련 세트의 차원이 클수록 과대적합 위험이 커집니다. 이론적으로 차원의 저주를 해결하는 해결책 하나는 훈련 샘플의 밀도가 충분히 높아질 때까지 훈련 세트의 크기를 키우는 것입니다. 불행하게도 실제로는 일정 밀도에 도달하기 위해 필요한 훈련 샘플 수는 차원 수가 커짐에 따라 기하급수적으로 늘어납니다. 특성 수가 (MNIST 문제보 다 훨씬 적은) 단 100개라고 생각해도, 모든 차원에 걸쳐 균일하게 퍼져 있다고 가정하고 훈련 샘플을 서로 평균 0.1 이내에 위치시키려면 관측 가능한 우주에 있는 원자 수 모두를 합친 것 보다 더 많은 훈련 샘플을 모아야 합니다.7

3 옮긴이_ 1 × 1 사각형에서 테두리 0.001을 제외한 안쪽 사각형의 너비는 (1 - 0.001 × 2 )2 = 0.996004입니다. 따라서 두께 0.001 인 테두리의 너비는 1 - 0.996004 = 0.003996이므로 단위 면적의 약 0.4%가 됩니다. 4 옮긴이_ 테두리를 제외한 초입방체의 부피를 같은 방식으로 계산하면 (1 - 0.001 × 2 )10000 ≈ 0.000000002가 되므로 테두리의 공 간은 1 - 0.000000002 = 0.999999998이 됩니다. 5 재미있는 사실: 충분히 많은 차원이 있다는 점을 고려하면 누구나 적어도 한 가지 면에서는 극단주의 성향이 있을 가능성이 높습니다(예 를 들면 커피에 넣는 설탕의 양).

6 옮긴이_ 무작위로 선택한 두 점 사이의 평균 거리는 적분을 이용해 계산합니다. 2차원일 때 평균 거리는 15 ( 2 + 2 + 5 ln (1 + 2 )) = 0.521405 n 2 + 2 + 5 ln (1 + 2 )) = 0.521405 이며 n 차원일 때 평균 거리는 최대 6 을 넘지 않습니다. 따라서 1,000,000차원 초입방체에서 임의의 두 점 사이의 평균 거 1,000, 000 리는 대략 이라고 할 수 있습니다. 6 1

1 15

(

7 옮긴이_ 크기가 1인 2차원 평면에 0.1 거리 이내에 훈련 샘플을 모두 놓으려면 최소한 10 × 10개의 샘플이 필요합니다. 이를 100개의 차원으로 확장하면 10 × 10 × … × 10 = 10100개의 훈련 샘플이 필요합니다. 우주에 존재하는 원자 수는 관측 가능한 우주의 질량을 수 소 원자의 질량으로 나눠 계산할 수 있는데, 대략 1080 개로 알려져 있습니다.

8장 차원 축소 271


8.2 차원 축소를 위한 접근 방법 구체적인 차원 축소 알고리즘을 알아보기 전에 차원을 감소시키는 두 가지 주요한 접근법인 투 영 projection 과 매니폴드 학습 Manifold Learning 을 살펴보겠습니다.

8.2.1 투영 대부분의 실전문제는 훈련 샘플이 모든 차원에 걸쳐 균일하게 퍼져 있지 않습니다. 많은 특성 은 거의 변화가 없는 반면, (앞서 말한 MNIST의 경우처럼) 다른 특성들은 서로 강하게 연관되 어 있습니다.8 결과적으로 모든 훈련 샘플이 사실 고차원 공간 안의 저차원 부분 공간 subspace 에 (또는 가까이) 놓여 있습니다.9 너무 추상적인 말이라 예를 들어 살펴보겠습니다. [그림 8-2] 에 원 모양을 띤 3차원 데이터셋이 있습니다. 그림 8-2 2차원에 가깝게 배치된 3차원 데이터셋

8 옮긴이_ MNIST 이미지의 테두리는 거의 항상 흰색이고 중심부의 픽셀들은 인접 픽셀과 강하게 연관되었다는 점을 이 장의 서두에서 설 명했습니다. 9 옮긴이_ 거의 모두 흰색인 테두리 부분을 떼어놓고 생각하면 대부분의 이미지가 더 낮은 차원(적은 픽셀)인 부분 공간에 놓여 있다고 말 할 수 있습니다.

272 1부 머신러닝


모든 훈련 샘플이 거의 평면 형태로 놓여 있습니다. 이것이 고차원(3D ) 공간에 있는 저차원 (2D ) 부분 공간입니다. 여기서 모든 훈련 샘플을 이 부분 공간에 수직으로(즉, 샘플과 평면 사이의 가장 짧은 직선을 따라) 투영하면 [그림 8-3]과 같은 2D 데이터셋을 얻습니다. 짜잔! 우리는 방금 데이터셋의 차원을 3D에서 2D로 줄였습니다. 각 축은 (평면에 투영된 좌표인) 새로운 특성 z1 과 z2 에 대응됩니다. 그림 8-3 투영하여 만들어진 새로운 2D 데이터셋

그러나 차원 축소에 있어서 투영이 언제나 최선의 방법은 아닙니다. 많은 경우 [그림 8-4]에 표 현된 스위스 롤 Swiss roll 10 데이터셋처럼 부분 공간이 뒤틀리거나 휘어 있기도 합니다.

10 옮긴이_ 스위스 롤은 크림이나 잼을 넣어 돌돌 말은 형태의 케이크를 말합니다. 중부 유럽에서 유래한 것으로 추측되며 우리에게는 롤케 이크로 널리 알려져 있습니다.

8장 차원 축소 273


그림 8-4 스위스 롤 데이터셋

그냥 평면에 투영시키면(예를 들면 x3를 버리고) [그림 8-5]의 왼쪽처럼 스위스 롤의 층이 서 로 뭉개집니다. 하지만 우리가 원하는 것은 스위스 롤을 펼쳐서 오른쪽처럼 2D 데이터셋을 얻 는 것입니다. 그림 8-5 평면에 그냥 투영시켜서 뭉개진 것(왼쪽)과 스위스 롤을 펼쳐놓은 것(오른쪽)

274 1부 머신러닝


Part

II

신경망과 딥러닝


Part II

신경망과 딥러닝

9장 텐서플로 시작하기 공 신경망 소개 10장 인 11장 심층 신경망 훈련

중 머신과 장치를 위한 분산 텐서플로 12장 다 성곱 신경망 13장 합 환 신경망 14장 순 토인코더 15장 오 화 학습 16장 강


CHAPTER

9

텐서플로 시작하기

텐서플로 TensorFlow 는 수치 계산을 위한 강력한 오픈소스 소프트웨어 라이브러리로 특히 대규모 머신러닝에 맞춰 세밀하게 튜닝되어 있습니다. 기본 원리는 간단합니다. 먼저 파이썬으로 수 행할 계산 그래프 computation graph (예를 들면 [그림 9-1])를 정의한 다음, 텐서플로가 최적화된

C++ 코드를 사용해 이 그래프를 효율적으로 실행시킵니다.1 그림 9-1 간단한 계산 그래프

연산

변수

상수

무엇보다도 계산 그래프를 여러 부분으로 나누어 여러 CPU나 GPU에서 병렬로 실행할 수 있 습니다(그림 9-2 ). 텐서플로는 분산 컴퓨팅도 지원하므로 수백 대의 서버에 계산을 나누어 납 1 옮긴이_ [그림 9 -1]의 계산 그래프에서 타원과 사각형으로 표시된 것을 노드(node ), 노드 사이를 잇는 선을 에지(edge )라고 합니다.

9장 텐서플로 시작하기 295


득할만한 시간 안에 대규모 데이터셋으로 거대한 신경망을 훈련시킬 수 있습니다(9장 참조). 또한 수백만 개의 특성을 가진 수십억 개의 샘플로 구성된 데이터셋에서 수백만 개의 파라미터 를 가진 네트워크를 훈련시킬 수 있습니다. 이는 놀라운 일이 아닙니다. 텐서플로는 구글 브레 인 Google Brain 팀에서 개발했고 구글 클라우드 스피치 Google Cloud Speech, 구글 포토 Google Photos, 구 글 검색 Google Search 같은 구글의 대규모 서비스를 지원하고 있기 때문입니다. 그림 9-2 여러 CPU, GPU, 서버에서 병렬 계산

텐서플로가 2015년 11월에 오픈소스로 공개되었을 때 이미 인기 있는 오픈소스 딥러닝 라이 브러리들이 있었습니다(그중 일부를 [표 9-1]에서 확인할 수 있습니다). 그리고 텐서플로의 기능 대부분은 이미 다른 라이브러리에서도 제공했습니다. 그럼에도 (구글의 명성에 대해선 말할 것도 없고) 텐서플로의 깔끔한 설계, 확장성, 유연성 2과 잘 정돈된 문서 덕분에 단숨에

2 텐서플로는 신경망이나 머신러닝에 국한되지 않습니다. 필요하다면 양자 물리 시뮬레이션을 실행할 수도 있습니다. 옮긴이_ 머신러닝은 양자 역학 등 물리학의 여러 분야에 많이 활용됩니다. 유럽 입자 물리 연구소(CERN ) 제임스 비컴(James Beacham ) 박사의 입자 물 리에 관한 멋진 테드 강연을 참고하세요(https://goo.gl/WQ6Hn5 ).

296 2부 신경망과 딥러닝


가장 높은 인기를 얻었습니다. 간단하게 말해서 텐서플로는 유연하고 확장성 있으며 제품에 바 로 적용할 수 있도록 설계되었습니다. 기존의 프레임워크들은 이 가운데 한두 가지만 지원했습 니다. 다음은 텐서플로의 주요 기능입니다. 윈도우, 리눅스, macOS뿐만 아니라 iOS와 안드로이드 같은 모바일 기기에서도 실행됩니다.

사이킷런과 호환되는 매우 간결한 파이썬 API 인 TF .Learn 3 을 제공합니다(tensorflow.contrib. learn ). 앞으로 보게 되겠지만 여러 종류의 신경망을 몇 줄의 코드로 훈련시킬 수 있습니다. 이 라이브러리는

이전에는 Scikit Flow (또는 skflow )라는 독립된 프로젝트였습니다. 신경망의 구축, 훈련, 평가를 단순화한 TF -slim이라는 또 다른 간편한 API도 제공합니다(tensorflow.

contrib.slim ). (이제는 tensorflow.keras에 포함된) 케라스 Keras (http ://keras.io )나 프리티 텐서 Pretty Tensor

(http ://github.com/google/prettytensor )와 같은 여러 가지 고수준 API가 텐서플로를 기반으로 독 립적으로 구축되었습니다. 기본 파이썬 API는 (복잡도가 높긴 하지만) 훨씬 유연합니다. 생각하는 어떤 신경망 구조는 물론 모든 종류의

계산 그래프를 만들 수 있습니다. 머신러닝 연산, 특히 신경망을 만드는 데 필요한 연산을 C++로 매우 효율적으로 구현했습니다. 또한 C++

API도 제공하고 있어서 자신만의 고성능 연산을 만들 수도 있습니다. 비용 함수를 최소화하는 모델 파라미터를 찾기 위한 여러 가지 고수준의 최적화 노드4 를 제공합니다. 텐서플

로는 우리가 정의한 함수의 그래디언트를 자동으로 계산해주기 때문에 사용하기 매우 쉽습니다. 이를 자동 미 분 automatic differentiation (또는 autodiff )이라고 합니다. 텐서보드 TensorBoard 라는 훌륭한 시각화 도구를 사용해 계산 그래프와 학습 곡선 등을 웹 브라우저로 확인할

수 있습니다. 구글은 텐서플로의 계산 그래프를 실행할 수 있는 클라우드 서비스도 론칭했습니다(https ://cloud.

google.com/ml ). 또 다른 중요한 요소는, 열정적이고 훌륭한 개발자들로 구성된 전담 팀이 있고 이 오픈소스에 기여하는 커뮤

니티가 성장하고 있다는 것입니다. 텐서플로는 깃허브에서 가장 인기 있는 오픈소스 프로젝트 중 하나이고, 점 점 더 많은 멋진 프로젝트가 텐서플로 위에 구축되고 있습니다(사례를 보려면 https ://www.tensorflow. org/의 리소스 페이지나 https ://github.com/jtoy/awesome -tensorflow를 확인해보세요). 기술적 으로 궁금하다면 http ://stackoverflow.com/에 질문을 올리고 ‘tensorflow’라고 태그하면 됩니다. 깃 허브를 통해 버그를 신고하거나 기능을 요청할 수 있습니다. 일반적인 의견은 구글 그룹스 Google Groups 를 이용 하세요(http ://goo.gl/N7kRF9 ). 3 독립 프로젝트인 TFLearn 라이브러리와 혼동하지 마세요. 옮긴이_ TFLearn (http://tflearn.org )은 TensorFlow-Examples 깃허브 저장소(https://goo.gl/36G94E )로 잘 알려진 에메릭 다미엥( Aymeric Damien )이 만든 서드파티 텐서플로 라이브러리입 니다. 4 옮긴이_ 텐서플로에서 제공하는 연산은 계산 그래프에서 노드로 표현됩니다. 이 책에서는 종종 노드와 연산을 같은 의미로 혼용하여 사용 합니다.

9장 텐서플로 시작하기 297


이 장에서는 설치에서부터 간단한 계산 그래프의 생성, 실행, 저장, 시각화까지 다루겠습니다. (다음 장에서) 첫 번째 신경망을 만들어보기 전에 기본적인 내용을 확실히 이해하는 것이 중요 합니다. 표 9-1 오픈소스 딥러닝 라이브러리(전체 목록은 아닙니다) 5 라이브러리 카페

Caffe

딥러닝4j

API

플랫폼

개발

파이썬, C++, 리눅스, macOS, 윈도우

양칭 지아

매트랩

캠퍼스 버클리 비전 및 학습 센터(BVLC )

자바, 스칼라, 클로저

Clojure

리눅스, macOS, 윈도우,

, 캘리포니아대학교 버클리

2013

아담 깁슨 Adam Gibson, 조쉬 패터슨 Josh Patterson

2014

H2O.ai

2014

DMLC

2015

구글

2015

안드로이드

H2O

파이썬, R

MXNet

파이썬, C++, 리눅스, macOS, 윈도우,

텐서플로

년도 Yangqing Jia

리눅스, macOS, 윈도우

그외

iOS, 안드로이드

파이썬, C++

리눅스, macOS, 윈도우,

iOS, 안드로이드 씨아노 Theano

파이썬

리눅스, macOS, iOS

몬트리올 대학

2010

토치 Torch

C++, 루아 Lua

리눅스, macOS, iOS,

로난 콜로버트 Ronan Collobert, 코레이 카푸추글

2002

안드로이드

루 Koray Kavukcuoglu, 클레멘트 파라벳 Clement Farabet

9.1 설치 그럼 시작해보겠습니다! 2장의 설치 안내를 따라서 주피터와 사이킷런을 설치했다면 pip 명령 으로 쉽게 텐서플로를 설치할 수 있습니다. virtualenv를 사용해 분리된 환경을 만들었다면 먼 저 이 환경을 활성화해야 합니다. $ cd $ML_PATH $ source env/bin/activate

# 머신러닝 작업 디렉터리(예를 들면 $HOME/ml)

5 옮긴이_ 씨아노는 버전 1.0을 끝으로 개발이 중단됩니다. 이 외에도 최근에 관심을 많이 받고 있는 딥러닝 라이브러리로는 2016년 에 발표한 마이크로소프트의 코그니티브 툴킷( Cognitive Toolkit , https://goo.gl/YSCqNn )과 페이스북의 파이토치( PyTorch , http://pytorch.org/ ), 카페2 (Caffe2, https://caffe2.ai/ ) 등이 있습니다. [표 9 -1]의 라이브러리를 포함해서 최근 딥러닝 툴킷의 공통된 특징은 모두 파이썬 API를 주력으로 한다는 점입니다.

298 2부 신경망과 딥러닝


그다음에는 텐서플로를 설치합니다. $ pip3 install --upgrade tensorflow

NOTE_ GPU를 사용하려면 tensorflow 대신 tensorflow-gpu를 설치해야 합니다. 더 자세한 내용은

12장을 참조하세요.

설치가 잘되었는지 확인하려면 다음 명령을 실행합니다. 설치한 텐서플로의 버전이 출력되어야 합니다. $ python3 -c 'import tensorflow; print(tensorflow.__version__)' 1.7.0

9.2 첫 번째 계산 그래프를 만들어 세션에서 실행하기 다음 코드는 [그림 9-1]의 계산 그래프를 만듭니다. import tensorflow as tf x = tf.Variable(3, name="x") y = tf.Variable(4, name="y") f = x*x*y + y + 2

이게 전부입니다! 꼭 이해해야 할 중요한 점은 이 코드가(특히 마지막 줄에서) 뭔가 계산하는 것 같아 보이지만 실제로 어떤 계산도 수행하지 않는다는 사실입니다. 단지 계산 그래프만 만 들 뿐입니다. 사실 변수조차도 초기화되지 않습니다. 이 계산 그래프를 평가 6하려면 텐서플로 세션을 시작하고 변수를 초기화한 다음 f를 평가해야 합니다. 텐서플로 세션은 연산을 CPU나

6 옮긴이_ 계산 그래프나 노드를 실행(run , execute )하여 연산의 값을 계산한다는 의미로 종종 평가(evaluation )라는 용어를 사용하기 도 합니다. 머신러닝에서 모델을 테스트 세트로 평가하는 것과는 다른 의미이므로 혼동하지 마세요.

9장 텐서플로 시작하기 299


GPU 같은 장치에 올리고 실행하는 것을 도와주며 모든 변숫값을 가지고 있습니다.7 다음 코 드는 세션을 만들고 변수를 초기화한 다음 f를 평가하고 세션을 닫습니다(즉, 자원을 해제합니 다).

>>> >>> >>> >>> >>>

sess = tf.Session() sess.run(x.initializer) sess.run(y.initializer) result = sess.run(f) print(result)

42 >>>

sess.close()

매번 sess.run ( )을 반복하면 번거로운데, 다행히 더 나은 방법이 있습니다. with tf.Session() as sess: x.initializer.run() y.initializer.run() result = f.eval()

with 블록 안에서는 with 문에서 선언한 세션이 기본 세션으로 지정됩니다. x.initializer. run ( ) 을 호출하는 것은 tf.get_default_session ( ).run (x.initializer ) 를 호출하는 것

과 동일합니다. 비슷하게 f.eval ( )은 tf.get_default_session ( ).run (f )를 호출하는 것과 동일합니다.8 이렇게 쓰면 코드를 읽기가 수월해집니다. 그리고 세션은 with 블록이 끝나면 자 동으로 종료됩니다. 각 변수의 초기화를 일일이 실행하는 대신 global_variables_initializer ( ) 함수를 사용할 수 있습니다. 이 함수는 초기화를 바로 수행하지 않고 계산 그래프가 실행될 때 모든 변수를 초 기화할 노드를 생성합니다. init = tf.global_variables_initializer()

# init 노드 준비

with tf.Session() as sess:

7 12장에서 볼 텐서플로 분산 환경에서는 변숫값이 세션이 아니라 서버에 저장됩니다. 8 옮긴이_ x.initializer와 같이 tf.Operation의 객체는 run ( ) 메서드를 사용하며 텐서(tf.Tensor ) 객체는 eval ( ) 메서드 를 사용합니다. 실제 eval ( ) 메서드에서 하는 작업은 본문의 예와 같이 디폴트 세션의 run ( ) 메서드를 호출하는 일입니다.

300 2부 신경망과 딥러닝


CHAPTER

10

인공 신경망 소개

사람들이 새를 보고 비행기에 대한 영감을 얻었고, 산우엉에서 찍찍이에 대한 영감을 얻었듯 이1 많은 발명품이 자연으로부터 영감을 받았습니다. 그렇다면 지능적인 기계에 대한 영감 을 얻기 위해서는 뇌의 구조를 살펴보는 것이 합리적입니다. 이것이 인공 신경망 artificial neural networks

(ANN )을 만들어낸 핵심 아이디어입니다. 그러나 새를 보고 비행기에 대한 영감을 얻

었다 하더라도 비행기의 날개를 펄럭거릴 필요는 없습니다. 비슷하게 인공 신경망도 생물학적 뉴런(신경 세포)에서부터 점점 멀어지고 있습니다. 우리가 만든 시스템이 생물학적으로 그럴 듯한 것에 국한되지 않도록 어떤 연구자들은 생물학적 비교를 모두 버려야 한다고 주장하기도 합니다(예를 들면 ‘뉴런’ 대신 ‘유닛’으로 부릅니다).2 인공 신경망은 딥러닝의 핵심입니다. 인공 신경망은 다재다능하고 강력하고 확장성이 좋아서 수백만 개의 이미지를 분류하거나(예를 들면 구글 이미지), 음성 인식 서비스의 성능을 높이 거나(예를 들면 애플의 시리 Siri ), 매일 수억 명의 사용자에게 가장 좋은 비디오를 추천해주거 나(예를 들면 유튜브), 바둑 세계챔피언을 이기기 위해 수백만 개의 기보를 익히고 자기 자신 과 게임하면서 학습하는(딥마인드의 알파고) 경우 등 아주 복잡한 대규모 머신러닝 문제를 다

1 옮긴이_ 1941년 스위스 엔지니어 게오르그 데 메스트랄(George de Mestral )은 우연히 산우엉(도꼬마리)의 씨가 갈고리 모양임을 발견하고 한쪽 면에 갈고리를 빽빽이 채워 섬유에 강력하게 접착되는 찍찍이를 발명하였습니다. 2 생물학적으로 비현실적인 모델이 만들어지더라도 도움이 된다면 생물학적 영감을 받아들여 양쪽 분야의 장점을 취할 수 있습니다. 옮긴 이_ 인공 신경망이 뇌의 구조에서 영감을 얻었지만 뇌처럼 작동한다거나 뇌를 모델링한 것은 아닙니다. 우리 뇌가 어떤 방식으로 학습하 는지 아직 정확히 알지 못합니다. 생물학적 뉴런에 대한 비유로 신경망 알고리즘을 신비롭고 어려운 대상으로 인식하는 것보다 그냥 데이 터에서 패턴을 학습하는 수학 모델로 생각하는 것이 낫습니다.

10장 인공 신경망 소개 327


루는 데 적합합니다.3 이 장에서는 인공 신경망의 초창기 구조를 간단히 소개하는 것으로 시작합니다. 그런 다음 다층 퍼셉트론 Multi-Layer Perceptron (MLP )을 설명하고 (3장에서 소개한) MNIST 숫자 분류 문제를 텐 서플로를 사용해 구현해보겠습니다.

10.1 생물학적 뉴런에서 인공 뉴런까지 놀랍게도 인공 신경망은 꽤 오래전부터 있었습니다. 1943년 신경생리학자 워런 맥컬록 Warren McCulloch

과 수학자 월터 피츠 Walter Pitts 가 이를 처음 소개했습니다. 독보적인 이 논문 4에서 명제

논리를 사용해 동물 뇌의 생물학적 뉴런이 복잡한 계산을 위해 어떻게 상호작용하는지에 대한 간단한 계산 모델을 제시했습니다. 이것이 최초의 인공 신경망 구조였습니다. 그 후 앞으로 보 게 될 여러 다른 구조가 많이 발명되었습니다.

1960년대까지 인공 신경망의 초기 성공은 곧 지능을 가진 기계와 대화를 나눌 수 있을 것이란 믿음을 널리 퍼뜨렸습니다. 이 약속이 (적어도 꽤 오랫동안) 지켜질 수 없다는 것이 명백해지면 서 다른 분야로 투자가 옮겨갔고 인공 신경망은 긴 침체기에 들어서게 됩니다. 1980년대 초에 새 로운 네트워크 구조가 발명되고 더 나은 훈련 기법이 개발되면서 인공 신경망에 대한 관심이 다 시 살아났습니다. 하지만 1990년대까지는 대부분의 연구자가 서포트 벡터 머신(5장 참고) 같 은 다른 강력한 머신러닝 기법을 선호했습니다. 이런 방법들이 더 나은 결과를 만들어주는 것 같 았고 이론적 기반이 탄탄했기 때문입니다. 결국 우리는 지금 인공 신경망의 또 다른 부흥을 목격 하고 있습니다. 이 흐름이 이전처럼 사라지게 될까요? 예전과는 다르게 이번에는 우리 생활에 훨씬 커다란 영향을 줄 것이라는 좋은 근거가 몇 가지 있습니다. 요즘엔 신경망을 훈련시키기 위한 데이터가 엄청나게 많습니다. 인공 신경망은 종종 규모가 크고 복잡한 문제

에서 다른 머신러닝 기법보다 좋은 성능을 냅니다.

3 옮긴이_ 2017년 10월 딥마인드는 기보 없이 스스로 학습하여 기존 알파고의 실력을 뛰어넘은 ‘알파고 제로’를 공개했습니다(https:// goo.gl/pKuFgB ). 4 「A Logical Calculus of Ideas Immanent in Nervous Activity」, W. McCulloch와 W. Pitts ( 1943 ), https://goo.gl/

Ul4mxW

328 2부 신경망과 딥러닝


1 990년대 이후 크게 발전된 컴퓨터 하드웨어의 성능 덕분에 납득할 만한 시간 안에 대규모 신경망을 훈련시

킬 수 있습니다. 이는 어느 정도 무어의 법칙 Moore’s Law 덕분이지만 수백만 개의 강력한 GPU 카드를 생산해 내는 게임 산업 덕분이기도 합니다. 훈련 알고리즘이 향상되었습니다. 1990년대와 비교해서 조금만 변경된 것이 사실이지만 이 작은 변화가 커

다란 영향을 끼쳤습니다. 일부 인공 신경망의 이론상 제한이 실전에서는 문제가 되지 않는다고 밝혀졌습니다. 예를 들어 많은 사람은

인공 신경망 훈련 알고리즘이 지역 최적점에 갇히기 때문에 해결책을 찾지 못할 것으로 생각했습니다. 하지만 실제로는 이런 일이 매우 드뭅니다(또는 지역 최적점에 도달하더라도 일반적으로 전역 최적점에 매우 가깝습 니다).5 인공 신경망이 투자와 진보의 선순환에 들어간 것으로 보입니다. 인공 신경망을 기반으로 한 놀라운 제품들이

주기적으로 뉴스 헤드라인을 장식하고 있습니다. 이로 인해 더 많은 관심과 투자가 일어나서 기술이 더욱더 향상될 것이며 결국 더 놀라운 제품을 만들어낼 것입니다.

10.1.1 생물학적 뉴런 인공 뉴런에 관해 이야기하기 전에 생물학적 뉴런을 간단히 살펴보도록 하겠습니다(그림 10-

1 ). 이 이상하게 생긴 세포는 대부분 동물의 대뇌 피질(예를 들면 우리의 뇌)에서 발견되며 핵 을 포함하는 세포체 cell body 와 세포의 복잡한 구성 요소로 이루어져 있습니다. 그리고 수상돌 기 dendrite 라는 나뭇가지 모양의 돌기와 축삭돌기 axon 라는 아주 긴 돌기 하나를 가지고 있습니 다. 축삭돌기의 길이는 세포체의 몇 배 정도에서 4만 배까지 되기도 합니다.6 축삭돌기의 끝 은 축삭끝가지 telodendria 라 불리는 여러 개의 가지로 나뉘고, 이 가지의 끝은 시냅스 말단 synaptic terminals

(또는 간단히 시냅스 synapse )이라 불리는 미세한 구조이고 다른 뉴런의 수상돌기와(또는

세포체에 직접) 연결되어 있습니다. 생물학적 뉴런은 이런 시냅스를 통해 다른 뉴런으로부터 짧은 전기 자극 신호 signal 를 받습니다. 한 뉴런이 천 분의 몇 초 동안 다른 뉴런으로부터 충분한 횟수의 신호를 받으면 자체적인 신호를 발생시킵니다.

5 옮긴이_ 「Identifying and attacking the saddle point problem in high-dimensional non-convex optimization」, Yann Dauphin , et al . (2014 , https://goo.gl/X2FTso )에서 고차원 공간은 대부분 말안장(saddle point ) 같으며 지역 최적점은 매우 드물고 만약 있다면 전역 최적점에 가까운 값임을 설명하고 있습니다. 6 옮긴이_ 척추의 끝에서 시작하여 양발의 엄지발가락까지 이어지는 좌골신경이 인체에서 가장 긴 축삭돌기를 가지고 있습니다.

10장 인공 신경망 소개 329


그림 10-1 생물학적 뉴런 7 세포체

축삭돌기

축삭끝가지

축삭 둔덕

시냅스 말단

골지체 소포체 미토콘드리아

수상돌기 수상돌기 가지

따라서 개개의 생물학적 뉴런은 아주 단순하게 동작하지만, 수십억 개의 뉴런으로 구성된 거대 한 네트워크로 조직되어 있고 각 뉴런은 보통 수천 개의 다른 뉴런과 연결되어 있습니다. 복잡 한 개미탑이 개미들의 작은 노력이 모여서 이뤄진 것처럼 매우 복잡한 계산이 단순한 뉴런으로 구성된 거대한 네트워크에 의해 수행될 수 있습니다. 생물학적 신경망 biological neural networks 8의 구조는 여전히 활발히 연구가 진행되는 분야입니다. 뇌의 일부는 그 지도가 그려져 있는데 [그 림 10-2]처럼 뉴런들이 연속된 층으로 조직화되어 있는 것으로 보입니다. 그림 10-2 생물학적 신경망의 여러 층(인간 피질) 9

7 위키백과 사용자 BruceBlaus의 이미지(크리에이티브 커먼즈 3.0, https://creativecommons.org/licenses/by/3.0/ )로, https://en.wikipedia.org/wiki/Neuron에서 가져왔습니다. 8 머신러닝 분야에서 ‘신경망’이라고 하면 보통 생물학적 신경망이 아니라 인공 신경망을 말합니다. 9 S. 라몬 이 카할( S. Ramon y Cajal )의 외피 박판 그림(퍼블릭 도메인). https://en.wikipedia.org/wiki/Cerebral_ cortex에서 가져왔습니다. 옮긴이_ 왼쪽 끝 외피에서부터 깊이가 깊어지면서 뉴런이 층을 이루고 있는 것을 볼 수 있습니다.

330 2부 신경망과 딥러닝


10.1.2 뉴런을 사용한 논리 연산 워런 맥컬록과 월터 피츠는 매우 단순한 생물학적 뉴런 모델을 제안했는데, 나중에 이것이 인공 뉴런 artificial neuron 이 되었습니다.10 이 모델은 하나 이상의 이진(on/off ) 입력과 하나의 이진 출력을 가집니다. 인공 뉴런은 단순히 일정 개수의 입력이 활성화되었을 때 출력을 내보냅니 다. 맥컬록과 피츠는 이런 간단한 모델을 가지고 인공 뉴런의 네트워크를 만들어 어떤 논리 명 제도 계산할 수 있다는 것을 보였습니다. 예를 들어 여러 가지 논리 연산을 수행하는 인공 신경 망을 몇 개 만들어보겠습니다(그림 10-3 ). 여기서는 적어도 두 개의 입력이 준비되어야 뉴런이 활성화된다고 가정하겠습니다. 그림 10-3 간단한 논리 연산을 수행하는 인공 신경망

뉴런

연결

논리곱 논리합 논리부정

왼쪽 첫 번째 네트워크는 간단한 항등 함수입니다. 뉴런 A가 활성화되면 (뉴런 A로부터 두 개의 입력 신호를

받기 때문에) 뉴런 C도 활성화됩니다. 하지만 뉴런 A가 꺼지면 뉴런 C도 꺼집니다.11 두 번째 네트워크는 논리곱 연산을 수행합니다. 뉴런 A와 B가 모두 활성화될 때만 뉴런 C가 활성화됩니다(입

력 신호 하나만으로는 뉴런 C를 활성화시키지 못합니다). 세 번째 네트워크는 논리합 연산을 수행합니다. 뉴런 A와 B 중 하나가(혹은 둘 다) 활성화되면 뉴런 C가 활

성화됩니다. (생물학적 뉴런처럼) 어떤 입력이 뉴런의 활성화를 억제할 수 있다고 가정하면 네 번째 네트워크는 조금 더

복잡한 논리 명제를 계산할 수 있습니다. 뉴런 A가 활성화되고 뉴런 B가 비활성화될 때 뉴런 C가 활성화됩니 다. 만약 뉴런 A가 항상 활성화되어 있다면 이 네트워크는 논리 부정 연산이 됩니다. 즉, 뉴런 B가 비활성화될 때 뉴런 C가 활성화되고, 또는 정반대로 뉴런 B가 활성화될 때 뉴런 C가 비활성화됩니다.

10 옮긴이_ 맥컬록과 피츠의 이름을 따서 MCP 뉴런이라고도 합니다. 인공 신경망을 설명하면서 인공 뉴런 혹은 뉴런이란 말을 많이 사용 합니다. 나중에 보게 되겠지만 실제로 뉴런은 어떤 객체를 만드는 것이 아니며 행렬 계산의 일부로 표현되는 것이 전부입니다. 뉴런이라 하여 뭔가 특별하거나 심오한 것으로 오해하지 마세요. 11 옮긴이_ [그림 10-3]의 네트워크에서 입력 뉴런이 활성화될 때는 1이, 꺼질 때는 0이 뉴런 C로 입력된다고 생각하면 이해하기 쉽습니다.

10장 인공 신경망 소개 331


복잡한 논리 표현식을 계산하기 위해 이런 네트워크들을 어떻게 연결할 수 있는지 쉽게 상상할 수 있을 것입니다(이 장의 끝에 있는 연습문제를 참조하세요).

10.1.3 퍼셉트론 퍼셉트론 Perceptron 은 가장 간단한 인공 신경망 구조 중 하나로 1957년에 프랑크 로젠블라트 Frank Rosenblatt

가 제안했습니다. 퍼셉트론은 TLU threshold logic unit 라는 조금 다른 형태의 인공 뉴

런을 기반으로 합니다(그림 10-4 ). 입력과 출력이 (이진 on/off 값이 아니라) 어떤 숫자 고 각각의 입력 연결은 가중치와 연관되어 있습니다. TLU는 입력의 가중치 합을 계산하고 ( z = w1 x1 + w2 x2 +  + wn xn = w T ⋅ x ), 그런 다음 계산된 합에 계단 함수 step function 를 적용 하여 그 결과를 출력합니다. 즉, hw (x) = step ( z ) = step (w T ⋅ x) 입니다. 그림 10-4 TLU 출력:

계단 함수: 가중치 합:

가중치

입력

퍼셉트론에서 가장 널리 사용되는 계단 함수는 헤비사이드 계단 함수 Heaviside step function 입니다 (식 10-1 ).12 이따금 부호 함수 sign function 를 대신 사용하기도 합니다. 식 10-1 퍼셉트론에서 일반적으로 사용하는 계단 함수

0 z < 0일 때 heaviside ( z ) =  1 z ≥ 0일 때

− 1 z < 0일 때  sgn( z ) = 0 z = 0일 때 + 1 z > 0일 때 

12 옮긴이_ 헤비사이드 계단 함수는 이를 발명한 올리버 헤비사이드(Oliver Heaviside )의 이름에서 따왔으며, 단위 계단 함수(unit step function )라고도 합니다.

332 2부 신경망과 딥러닝


CHAPTER

11

심층 신경망 훈련

앞 장에서 인공 신경망을 소개했고 첫 번째 심층 신경망을 훈련시켰습니다. 하지만 두 개의 은 닉층만 있는 매우 얕은 심층 신경망이었습니다. 고해상도 이미지에서 수백 종의 물체를 감지해 야 하는 것처럼 아주 복잡한 문제를 다뤄야 한다면 어떻게 해야 할까요? 아마도 수백 개의 뉴 런을 가진 10개 층이 수십만 개의 연결로 이어져 있는 훨씬 더 깊은 심층 신경망을 훈련시켜야 할 것입니다. 이건 그리 쉬운 일이 아닙니다. ●

첫째, 까다로운 그래디언트 소실 vanishing gradient (또는 그래디언트 폭주 exploding gradient ) 문제에 직면할 것입니다. 이 현상은 심층 신경망에 영향을 주며 하위층이 훈련하기 매우 어렵게 만듭니다.

둘째, 이런 대규모 신경망에서는 훈련이 극단적으로 느려질 것입니다.

셋째, 수백만 개의 파라미터를 가진 모델은 훈련 세트에 과대적합될 위험이 매우 큽니다.

이 장에서는 이 문제들을 차례대로 살펴보고 해결 방법을 제시하겠습니다. 먼저 그래디언트 소 실 문제를 설명하고 가장 널리 알려진 해결 방법을 살펴보겠습니다. 다음에는 일반 경사 하강 법에 비해서 대규모 모델의 훈련 속도를 크게 높여주는 다양한 최적화 방법을 알아보겠습니다. 마지막으로 대규모 신경망을 위한 규제 기법 중 널리 알려진 몇 가지를 살펴보겠습니다. 이런 도구들을 사용하여 매우 깊은 신경망을 훈련시킬 수 있습니다. 딥러닝의 세계에 오신 걸 환영합니다!

11장 심층 신경망 훈련 353


11.1 그래디언트 소실과 폭주 문제 앞 장에서 이야기한 것처럼 역전파 알고리즘은 출력층에서 입력층으로 오차 그래디언트를 전 파시키면서 진행됩니다. 알고리즘이 신경망의 모든 파라미터에 대한 오차 함수의 그래디언트 를 계산하면 경사 하강법 단계에서 이 그래디언트를 사용하여 각 파라미터를 수정합니다. 안타깝게도 알고리즘이 하위층으로 진행됨에 따라 그래디언트는 점점 작아지는 경우가 많습니 다. 결국 경사 하강법이 하위층의 연결 가중치를 실제 변경되지 않은 채로 둔다면 훈련이 좋은 솔루션으로 수렴되지 않습니다. 이 문제를 그래디언트 소실이라고 합니다. 어떤 경우엔 반대 현상이 일어날 수 있습니다. 그래디언트가 점점 커져 여러 개의 층이 비정상적으로 큰 가중치 로 갱신되면 알고리즘은 발산 diverse 하게 됩니다. 이 문제를 그래디언트 폭주라고 하며 순환 신 경망에서 주로 나타납니다(14장 참조). 일반적으로 심층 신경망은 불안정한 그래디언트에 영 향을 많이 받습니다. 여러 층이 서로 다른 속도로 학습될 수 있기 때문이죠. 이런 좋지 않은 학습 패턴이 꽤 오랫동안 경험적으로 관측되어 왔지만(이것이 심층 신경 망이 오랫동안 거의 방치되었던 이유 중 하나입니다), 2010 년 즈음에 와서야 이에 대한 이해가 많이 진전되었습니다. 세이비어 글로럿 Xavier Glorot 과 요슈아 벤지오 Yoshua Bengio 는 「Understanding the Difficulty of Training Deep Feedforward Neural Networks」 (2010, http://goo.gl/1rhAef ) 논문을 통해 몇 가지 주요한 발견을 발표했는데, 그중에는 많 이 사용되는 로지스틱 시그모이드 활성화 함수와 그 당시 가장 인기 있었던 가중치 초기화 방 법의 조합이 있습니다. 이 초기화 방법은 평균이 0이고 표준편차가 1인 정규분포를 사용한 무 작위 초기화입니다. 즉, 이 활성화 함수와 초기화 방식을 사용했을 때 각 층에서 출력의 분산이 입력의 분산보다 더 크다는 것을 밝혔습니다. 신경망의 위쪽으로 갈수록 층을 지날 때마다 분 산이 계속 커져 가장 높은 층에서는 활성화 함수가 0이나 1로 수렴합니다. 이는 로지스틱 함수 의 평균이 0이 아니고 0.5라는 사실 때문에 더 나빠집니다 1 (하이퍼볼릭 탄젠트 함수는 평균이

0이므로 깊은 신경망에서 로지스틱 함수보다 조금 더 낫습니다). 로지스틱 활성화 함수를 보면(그림 11-1 ) 입력의 절댓값이 크면 0이나 1로 수렴해서 기울기 가 0에 매우 가까워지는 것을 알 수 있습니다. 그래서 역전파가 될 때 사실상 신경망으로 전파 시킬 그래디언트가 거의 없고 조금 있는 그래디언트는 최상위층에서부터 역전파가 진행됨에 1 옮긴이_ 로지스틱 함수는 항상 양수를 출력하므로 출력의 가중치 합이 입력보다 커질 가능성이 높습니다. 이를 편향 이동( bias shift )이 라고도 부릅니다.

354 2부 신경망과 딥러닝


따라 점차 약해져서 실제로 아래쪽 층에는 아무것도 도달하지 않게 됩니다.2 그림 11-1 로지스틱 활성화 함수의 수렴 로지스틱 활성화 함수

수렴

수렴

선형

11.1.1 세이비어 초기화와 He 초기화 글로럿과 벤지오는 그들의 논문에서 이 문제를 크게 완화시키는 방법을 제안합니다. 예측을 할 때는 정방향으로, 그래디언트를 역전파할 때는 역방향으로 양방향 신호가 적절하게 흘러야 합 니다. 신호가 죽거나 폭주 또는 소멸하지 않아야 합니다. 그들은 적절한 신호가 흐르기 위해서는 각 층의 출력에 대한 분산이 입력에 대한 분산과 같아야 한다고 주장합니다.3 그리고 역방향에 서 층을 통과하기 전과 후의 그래디언트 분산이 동일해야 합니다(수학적인 상세 내용에 관심이 있다면 논문을 참고하세요). 사실 층의 입력과 출력 연결 개수가 같지 않다면 이 두 가지를 보 장할 수 없습니다. 하지만 그들은 실전에서 매우 잘 작동한다고 입증된 대안을 제안하였습니다. 연결 가중치를 [식 11-1]에 기술한 방식대로 무작위로 초기화하는 것입니다. 이 식에서 n inputs 와 n outputs 는 가중치를 초기화하려는 층의 입력과 출력 연결의 개수입니다(또는 팬인 fan-in 과 2 옮긴이_ 로지스틱 함수(식 4 -14 )의 도함수는 σ (1 - σ )이므로 함수의 값이 0이나 1에 가까우면 도함수의 결과가 매우 작아지고, 층이 거듭될수록 그 값은 더 작아집니다. 3 비유를 들어 설명하면, 마이크 볼륨 다이얼을 너무 0에 가깝게 하면 목소리가 들리지 않을 것입니다. 반대로 최대치에 너무 가깝게 하면 목소리가 포화되어 무슨 말을 하는지 사람들이 이해하지 못할 것입니다. 이런 증폭기들이 연결되어 있을 때 마지막 스피커에서 목소리가 크고 명확히 들리게 하려면 모든 증폭기가 순서대로 적절하게 설정되어 있어야 합니다. 그래서 각 증폭기의 출력 크기는 입력되는 목소리 와 같아야 합니다.

11장 심층 신경망 훈련 355


팬아웃 fan-out 으로 부릅니다). 이 초기화 전략을 (저자의 이름을 따서) 세이비어 초기화 Xavier initialization

또는 글로럿 초기화 Glorot initialization 라고 합니다.

식 11-1 세이비어 초기화(로지스틱 활성화 함수를 사용했을 때)

평균이 0이고 표준편차 σ = 또는 r =

2 인 정규분포 ninputs + noutputs

6 일 때 - r 과 + r 사이의 균등분포 ninputs + noutputs

입력의 연결 개수가 대략 출력의 연결 개수와 비슷하면 더 간단한 공식을 사용합니다(예를 들 면 σ =1

ninputs 또는 r = 3

ninputs ). 10장에서는 기본 세이비어 초기화 전략을 사용했

4

습니다. 세이비어 초기화 전략을 사용하면 훈련 속도를 상당히 높일 수 있습니다. 이것이 현 재 딥러닝의 성공을 견인한 기술 중 하나입니다. 최근 몇몇 논문 5은 다른 활성화 함수에 대해 [표 11-1]과 같이 비슷한 전략을 제안했습니다. ReLU 활성화 함수(그리고 잠시 후에 설명할

ELU 활성화 함수 같은 ReLU 변종들)를 위한 초기화 전략을 (저자의 이름을 따서) He 초기 화 He initialization 라고 부르기도 합니다. 표 11-1 활성화 함수 종류에 따른 초기화 매개변수 활성화 함수

균등분포 [-r, r]

로지스틱

r=

6 ninputs + noutputs

σ=

하이퍼볼릭 탄젠트

r=4

6 ninputs + noutputs

σ=

ReLU와 그 변종들

r=

6 ninputs + noutputs

σ=

2

정규분포

2 ninputs + noutputs 4

2

2 ninputs + noutputs 2 ninputs + noutputs

4 사실 이 간단한 버전은 훨씬 이전에 이미 제안되었습니다. 예를 들어 1998년에 제네비에브 오르(Genevieve Orr )와 클라우스-로버트 뮐러(Klaus-Robert Müller )가 쓴 ​『Neural Networks : Tricks of the Trade』(Springer )라는 책이 있습니다. 옮긴이_ 출력의 분산 은 입력 연결 수에 비례하여 늘어나므로 가중치의 분산을 1 / n inputs 로 지정하여 입출력의 분산을 맞춥니다. 하지만 역방향일 경우에는 입 출력이 반대로 바뀌어 분산이 1 / n ouputs 이어야 합니다. 글로럿과 벤지오는 이 두 분산의 절충안인 2 / (n inputs + n ouputs )를 가중치의 분산 으로 제안했습니다. 10.3절 ‘텐서플로의 저수준 API로 심층 신경망 훈련하기’에서는 ReLU 활성화 함수를 사용했기 때문에 정규분포를 사용했을 때의 표준편차인 2 ninputs + noutputs 을 사용했습니다(표 11-1 ). 5 예를 들면 「Delving Deep into Rectifiers : Surpassing Human-Level Performance on ImageNet Classification」, K . He et al . (2015 ), http://goo.gl/VHP3pB

356 2부 신경망과 딥러닝


(10장에서 소개한) tf.layer.dense ( ) 함수는 기본적으로 (균등분포로) 세이비어 초기화를 사용합니다. 이를 variance_scaling_initializer ( ) 함수를 사용하여 다음과 같이 He 초기 화 방식으로 바꿀 수 있습니다.6 he_init = tf.contrib.layers.variance_scaling_initializer() hidden1 = tf.layers.dense(X, n_hidden1, activation=tf.nn.relu, kernel_initializer=he_init, name="hidden1")

NOTE_ He 초기화는 세이비어 초기화에서처럼 팬인과 팬아웃의 평균 대신 팬인만 고려합니다. 이것이

variance_scaling_initializer ( ) 함수의 기본값이지만 mod="FAN_AVG" 매개변수로 지정하여 바꿀 수 있습니다.6

11.1.2 수렴하지 않는 활성화 함수 글로럿과 벤지오의 2010년 논문에서 얻은 통찰 중 하나는 활성화 함수를 잘못 선택하면 자칫 그래디언트의 소실이나 폭주로 이어질 수 있다는 것입니다. 그전에는 대부분의 사람이 생물학적 뉴런의 방식과 비슷한 시그모이드 활성화 함수가 최선의 선택일 것이라고 생각했습니다. 하지만 다른 활성화 함수가 심층 신경망에서 훨씬 더 잘 작동한다는 사실이 밝혀졌습니다. 특히 ReLU 함수는 특정 양숫값에 수렴하지 않는다는 커다란 장점이 있습니다(그리고 계산도 빠릅니다). 안타깝게도 ReLU 함수는 완벽하지 않습니다. 죽은 ReLU dying ReLU 로 알려진 문제가 있습니 다. 훈련하는 동안 일부 뉴런이 0 이외의 값을 출력하지 않는다는 의미로 죽었다고 말합니다. 어떤 경우에는, 특히 큰 학습률을 사용하면 신경망의 뉴런 절반이 죽어 있기도 합니다. 훈련 도 중 뉴런의 가중치가 바뀌어 가중치 합이 음수가 되면 그다음부터 0을 출력하기 시작할 것입니 다. ReLU 함수는 입력이 음수면 그래디언트가 0이 되기 때문에 이런 일이 생기면 뉴런이 다시 살아나기 어렵습니다. 6 옮긴이_ variance_scaling_initializer ( ) 함수는 기본값이 각각 factor=2.0, mode='FAN_IN', uniform=False인 세 개의 주요 매개변수를 가지고 있습니다. 정규분포일 경우에는 ( factor × 2) n 를 사용하고 균등분포일 경우에는 ( factor × 6 ) n 을 사용합니다. 여기서 mod='FAN_IN'일 경우 n = n inputs 이고 mod='FAN_AVG'일 경우 n = n inputs + n outputs 입니다. 따라서 이 함수에 mod='FAN_AVG', factor=1.0을 적용하면 [표 11-1]의 로지스틱 공식과 같습니다. 사실 세이비어 초기화도 variance_scaling_ initializer ( ) 함수를 사용합니다. [표 11-1]과 한 가지 다른 점은 텐서플로는 앞 장에서 우리가 직접 초기화했을 때처럼 절단 정규 분포를 사용하기 때문에 이에 대한 보정을 반영하여 (1.3 × factor × 2) n 으로 계산합니다.

11장 심층 신경망 훈련 357


이 문제를 해결하기 위해 LeakyReLU 같은 ReLU 함수의 변종을 사용하게 됩니다. 이 함수 는 LeakyReLUα (z ) = max (α z, z )로 정의됩니다(그림 11-2 ). 하이퍼파라미터 α 가 이 함수가 ‘새는 leaky ’ 정도를 결정합니다. 새는 정도란 z < 0일 때 이 함수의 기울기이며, 일반적으로 0.01 로 설정합니다. 이 작은 기울기가 LeakyReLU를 절대 죽지 않게 만들어줍니다. 뉴런이 혼수 상태에 오래 있을 수는 있지만 다시 깨어날 가능성을 얻게 됩니다. 최근 한 논문 7 에서 여러

ReLU 함수의 변종을 비교해 얻은 결론 하나는 LeakyReLU가 ReLU보다 항상 성능이 높다는 것입니다. 사실 α = 0.2 (많이 통과)로 하는 것이 α = 0.01 (조금 통과)보다 더 나은 성능을 내 는 것으로 보입니다. 이 논문은 훈련하는 동안 주어진 범위에서 α 를 무작위로 선택하고 테스트 시에는 평균을 사용하는 RReLU randomized leaky ReLU 도 평가했습니다. 이 함수도 꽤 잘 작동했 으며 (훈련 세트의 과대적합 위험을 줄이는) 규제의 역할을 하는 것처럼 보였습니다. 마지막 으로 α가 훈련하는 동안 학습되는 PReLU parametric leaky ReLU 도 비교했습니다(즉, 하이퍼파라 미터가 아니고 다른 모델 파라미터와 마찬가지로 역전파에 의해 변경됩니다). 이 함수는 대규 모 이미지 데이터셋에서는 ReLU보다 성능이 크게 앞섰지만, 소규모 데이터셋에서는 훈련 세트 에 과대적합될 위험이 있습니다. 그림 11-2 LeakyReLU LeakyReLU 활성화 함수

통과

또 하나 중요한 함수는 2015년의 한 논문 8에서 제안한 ELU exponential linear unit 라는 새로운 활 성화 함수입니다. 이 함수는 실험에서 다른 모든 ReLU 변종의 성능을 앞질렀습니다. 훈련 시

7 「Empirical Evaluation of Rectified Activations in Convolution Network」, B. Xu et al. (2015 ), https://goo.gl/B1xhKn 8 「Fast and Accurate Deep Network Learning by Exponential Linear Units ( ELUs )」 , D. Clevert , T. Unterthiner, S. Hochreiter (2015 ), http://goo.gl/Sdl2P7

358 2부 신경망과 딥러닝


CHAPTER

12

다중 머신과 장치를 위한 분산 텐서플로

앞 장에서는 더 나은 가중치 초기화, 배치 정규화, 정교한 옵티마이저 등 훈련 속도를 높일 수 있는 여러 기술을 살펴봤습니다. 그러나 이런 기법들을 모두 이용하더라도 대규모 신경망을

CPU가 하나인 컴퓨터 한 대에서 훈련시키려면 며칠 혹은 몇 주가 걸릴 수 있습니다. 이 장에서는 텐서플로를 사용해 연산을 여러 개의 장치(CPU와 GPU )에 분산시켜서 병렬로 실행시키는 방법을 알아보겠습니다(그림 12-1 ). 먼저 연산을 한 대의 머신에서 여러 개의 장치 에 분산시키고, 다음에는 여러 대의 머신에서 여러 개의 장치를 사용해보겠습니다. 그림 12-1 텐서플로 그래프를 여러 장치에 병렬로 실행시키기

12장 다중 머신과 장치를 위한 분산 텐서플로 401


텐서플로의 분산 컴퓨팅 기능은 다른 신경망 프레임워크와 비교되는 주요한 장점입니다.1 계산 그래프를 여러 장치와 머신에 어떻게 분할(또는 복제)시킬지 완전히 제어할 수 있고 연산을 다 양한 방식으로 병렬화하고 동기화할 수 있어서 모든 종류의 병렬화 방식이 사용될 수 있습니다. 여기서는 신경망을 병렬로 실행하고 훈련시키는 데 가장 잘 알려진 몇 가지 방식을 살펴보겠습 니다. 훈련 알고리즘이 끝날 때까지 몇 주를 기다리는 대신 단지 몇 시간만 기다리면 될지도 모 릅니다. 이는 많은 시간을 절약시켜주는 것뿐만 아니라 여러 가지 모델을 훨씬 손쉽게 실험하거 나 새로운 데이터에 기존의 모델을 자주 재훈련시킬 수 있다는 것을 의미합니다. 병렬화의 다른 좋은 사례는 모델을 세밀하게 튜닝하기 위해 아주 큰 하이퍼파라미터 공간을 탐 색하는 것, 대규모 신경망의 앙상블을 효율적으로 실행하는 것 등이 있습니다. 하지만 달리는 법을 배우기 전에 걷는 것부터 배워야 합니다. 먼저 한 대의 머신에 있는 여러 개 의 GPU에 간단한 그래프를 병렬화해 봅시다.

12.1 단일 머신의 다중 장치 한 대의 머신으로 간단하게 성능을 올릴 수 있는 방법은 GPU 카드를 추가하는 것입니다. 사실 많은 경우에 이것으로 충분합니다. 즉, 여러 대의 컴퓨터를 사용할 필요가 전혀 없습니다. 예를 들어 어떤 신경망을 훈련시키는 데 여러 대의 컴퓨터로 나뉜 16개의 GPU보다 한 대의 컴퓨터 에 설치된 8개의 GPU를 사용하는 편이 더 빠를 수 있습니다(다중 머신 환경에서 네트워크 통 신으로 발생되는 지연이 더해지기 때문). 이 절에서는 텐서플로에서 한 대의 컴퓨터에 있는 여러 개의 GPU를 사용하기 위해 어떻게 환 경 설정을 하는지 살펴보겠습니다. 그런 다음 여러 개의 장치에 연산을 분산하고 병렬로 실행하 는 방법을 알아보겠습니다.

12.1.1 설치 텐서플로를 여러 개의 GPU 카드에서 실행하기 위해서는 설치된 GPU 카드가 엔비디아 계산 1 옮긴이_ 비교적 최근에 나온 파이토치(PyTorch ), MXNet , CNTK 같은 프레임워크도 분산 컴퓨팅 기능을 지원합니다.

402 2부 신경망과 딥러닝


능력 Nvidia Compute Capability 을 가지고 있는지 확인해야 합니다(3.0 이상). 여기에는 엔비디아 타 이탄 Titan, 타이탄 X, K20, K40 카드가 포함됩니다(이와 다른 카드라면 https://developer. nvidia.com/cuda-gpus에서 호환성을 확인하세요). TIP

GPU 카드가 없다면 아마존 AWS 같이 GPU를 제공하는 호스팅 서비스를 사용할 수 있습니다. 아마 존 AWS GPU 인스턴스에 파이썬 3.5와 텐서플로 0.9를 설치하는 자세한 설명은 지가 아브섹 Ziga Avsec 의 블로그 포스트를 참고하세요(http://goo.gl/kbge5b ). 최신 텐서플로 버전으로 업데이트하는 것이 그리 어렵지 않습니다.2 또한 구글이 텐서플로 그래프를 실행시킬 수 있는 클라우드 머신러닝 Cloud Machine Learning

(https://cloud.google.com/ml ) 서비스를 시작했습니다. 2016년 5월에는 머신러닝에 최적화되

어 있어서 많은 머신러닝 작업에서 범용 GPU보다 훨씬 빠른 프로세서인 텐서 프로세싱 유닛 tensor processing unit

(TPU )을 장착한 머신이 클라우드에 포함되었다고 발표했습니다. 물론 자신만의 GPU 카드를 구매하는

것도 한 가지 방법입니다. 팀 드머스 Tim Dettmers 가 카드 선택에 도움이 될 만한 좋은 블로그 포스트를 썼으며 (https://goo.gl/pCtSAm ) 정기적으로 업데이트하고 있습니다.

그런 다음 적절한 버전의 CUDA와 cuDNN 라이브러리를 내려받고 설치해야 합니다(텐서 플로 1.0.0의 바이너리를 설치하려면 CUDA 8.0과 cuDNN 5.1을 설치해야 합니다 3 ). 그 리고 텐서플로가 CUDA와 cuDNN을 찾을 수 있도록 몇 가지 환경 변수를 설정해야 합니 다. 세세한 설치 방법은 자주 바뀌는 편이므로 텐서플로 웹사이트의 가이드( https://www. tensorflow.org/install/ )를 따르는 것이 좋습니다.

엔비디아의 CUDA Compute Unified Device Architecture 라이브러리를 사용하면 CUDA 지원 GPU 카 드에서 (그래픽 가속뿐만 아니라) 어떤 계산도 수행할 수 있습니다. 엔비디아의 cuDNN CUDA Deep Neural Network

라이브러리는 DNN을 위한 기초적인 GPU 가속 라이브러리입니다. 이 라이

브러리는 활성화층, 정규화, 전진과 후진 합성곱 연산, 풀링(13장 참조) 등과 같은 일반적인

DNN 연산의 최적화된 구현을 제공합니다. 이들은 엔비디아 딥러닝 SDK의 일부입니다(내려 받기 위해서는 엔비디아 개발자 계정이 필요합니다 4 ). 텐서플로는 GPU 카드를 제어하고 계 산을 가속하기 위해 CUDA와 cuDNN을 사용합니다(그림 12-2 ).

2 옮긴이_ 또는 엔비디아 GPU 클라우드(https://ngc.nvidia.com/ )에서 텐서플로를 포함해 다양한 딥러닝 라이브러리가 설치된 도커(docker ) 이미지를 내려받거나 AWS의 최신 P3 인스턴스에서 구동되는 NVIDIA Volta Deep Learning AMI (https://goo. gl/kUCnup )를 사용할 수 있습니다. AWS 자체적으로도 다양한 딥러닝 라이브러리가 설치된 아마존 리눅스와 우분투 기반의 Deep Learning AMI (https://goo.gl/fYJkTN )를 제공합니다. AWS에서 아마존의 Deep Learning AMI를 사용하는 방법은 옮긴이의 블로그(https://goo.gl/pGhdAh )를 참고하세요. 3 옮긴이_ 텐서플로 1.3.0부터는 cuDNN 6을 설치해야 하고 1.5.0부터는 CUDA 9와 cuDNN 7을 설치해야 합니다. 4 옮긴이_ 엔비디아 개발자 계정은 https://developer.nvidia.com/에서 무료로 가입할 수 있습니다.

12장 다중 머신과 장치를 위한 분산 텐서플로 403


그림 12-2 텐서플로는 GPU 카드를 제어하고 DNN의 속도를 높이기 위해 CUDA와 cuDNN을 사용합니다. 텐서플로

nvidia-smi 명령을 사용하면 CUDA 설치가 잘되었는지 확인할 수 있습니다. 사용 가능한

GPU 카드를 보여주고 각 카드에서 실행 중인 프로세스를 나열합니다. $ nvidia-smi Wed Sep 16 09:50:03 2016 +------------------------------------------------------+ | NVIDIA-SMI 352.63 | Driver Version: 352.63 |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | |===============================+======================+======================| | 0 GRID K520 Off | 0000:00:03.0 Off | N/A | | N/A 27C P8 17W / 125W | 11MiB / 4095MiB | 0% Default | +-------------------------------+----------------------+----------------------+ +-----------------------------------------------------------------------------+ | Processes: GPU Memory | | | GPU PID Type Process name Usage |=============================================================================| | | No running processes found +-----------------------------------------------------------------------------+

마지막으로 GPU를 지원하는 텐서플로를 설치해야 합니다. virtualenv를 사용해 독립된 환경 을 만들었다면 먼저 이를 활성화해야 합니다. $ cd $ML_PATH $ source env/bin/activate

404 2부 신경망과 딥러닝

# 작업 디렉터리(예를 들면 $HOME/ml)


그런 다음 적절한 버전의 GPU용 텐서플로를 설치합니다. $ pip3 install --upgrade tensorflow-gpu

이제 파이썬 쉘을 열어 텐서플로를 임포트하고 세션을 생성해서 CUDA와 cuDNN을 인식하 고 사용할 수 있는지 확인합니다. import tensorflow as tf [...]/dso_loader.cc:108] successfully opened CUDA library libcublas.so locally [...]/dso_loader.cc:108] successfully opened CUDA library libcudnn.so locally [...]/dso_loader.cc:108] successfully opened CUDA library libcufft.so locally [...]/dso_loader.cc:108] successfully opened CUDA library libcuda.so.1 locally [...]/dso_loader.cc:108] successfully opened CUDA library libcurand.so locally >>> sess = tf.Session() [...] I [...]/gpu_init.cc:102] Found device 0 with properties: name: GRID K520 major: 3 minor: 0 memoryClockRate (GHz) 0.797 pciBusID 0000:00:03.0 Total memory: 4.00GiB Free memory: 3.95GiB I [...]/gpu_init.cc:126] DMA: 0 I [...]/gpu_init.cc:136] 0: Y I [...]/gpu_device.cc:839] Creating TensorFlow device (/gpu:0) -> (device: 0, name: GRID K520, pci bus id: 0000:00:03.0) >>>

I I I I I

성공입니다! 텐서플로가 CUDA와 cuDNN 라이브러리를 인식했고, CUDA 라이브러리를 사 용해 GPU 카드(여기서는 엔비디아 그리드 K50 카드)를 인식했습니다.

12.1.2 GPU RAM 관리 기본적으로 텐서플로는 계산 그래프가 처음 실행될 때 가용한 모든 GPU의 RAM을 자동으로 확보합니다. 그러므로 첫 번째 프로그램이 실행 중이면 두 번째 텐서플로 프로그램을 시작할 수 없습니다. 이 경우 다음과 같은 에러가 발생합니다. E [...]/cuda_driver.cc:965] failed to allocate 3.66G (3928915968 bytes) from device: CUDA_ERROR_OUT_OF_MEMORY

12장 다중 머신과 장치를 위한 분산 텐서플로 405


한 가지 해결책은 각 프로그램을 다른 GPU에서 실행하는 것입니다. 이렇게 하는 가장 간단한 방법은 CUDA_VISIBLE_DEVICES 환경 변수를 설정해서 각 프로세스가 자신에게 지정된 GPU 카 드만 보게끔 하는 것입니다. 예를 들어 다음과 같은 식으로 두 개의 프로그램을 시작할 수 있습 니다. $ CUDA_VISIBLE_DEVICES=0,1 python3 program_1.py # 그리고 다른 터미널에서 $ CUDA_VISIBLE_DEVICES=3,2 python3 program_2.py

프로그램 #1은 (각각 0과 1번이 부여된) GPU 카드 #0과 #1만 바라보고, 프로그램 #2는 (각 각 1과 0번이 부여된) GPU 카드 #2와 #3만 바라볼 것입니다. 그러므로 아무 문제없이 잘 작 동될 것입니다(그림 12-3 ). 그림 12-3 프로그램마다 두 개의 GPU 사용 프로그램 #1

프로그램 #2

또 다른 방법은 텐서플로가 메모리 일부만 사용하도록 만드는 것입니다. 예를 들어 텐서플로가

GPU 메모리의 40%만 잡게 하려면 ConfigProto 객체를 만들어서 gpu_options.per_process_ gpu_memory_fraction 옵션을 0.4로 지정하고 이 설정으로 세션을 생성합니다.

config = tf.ConfigProto() config.gpu_options.per_process_gpu_memory_fraction = 0.4 session = tf.Session(config=config)

이제 두 프로그램은 같은 GPU 카드를 사용해 병렬로 실행할 수 있습니다(하지만 3 × 0.4는 1 을 넘기 때문에 3개는 실행하지 못합니다). [그림 12-4]를 참조하세요.

406 2부 신경망과 딥러닝


CHAPTER

13

합성곱 신경망

1996 년에 IBM 의 딥블루 Deep Blue 슈퍼컴퓨터가 체스 세계챔피언인 가리 카스파로프 Garry Kasparov

를 이겼지만, 꽤 최근까지 컴퓨터는 사진에서 강아지를 감지하거나 음성을 인식하는 것

같은 외견상 간단해 보이는 작업을 안정적으로 수행할 수 없었습니다. 왜 사람에게는 이런 작 업이 수월할까요? 사람의 지각 대부분은 의식 영역 밖에 있는 뇌의 특별한 시각, 청각, 그리고 다른 감각기관에서 일어난다는 사실에 해답이 있습니다. 감각의 정보가 우리 의식에 도달할 때 는 이미 고수준의 특성으로 채워져 있습니다. 예를 들어 귀여운 강아지 사진을 보았을 때 강아 지를 보지 않거나 귀여움을 느끼지 않겠다고 선택할 수 없습니다. 또한 어떻게 귀여운 강아지 를 인식했는지 설명할 수도 없습니다. 이는 매우 당연한 사실입니다. 그러므로 사람들은 자신 의 개인적인 경험을 신뢰할 수 없습니다. 즉, 지각은 간단한 문제가 아니며 이를 이해하려면 감 각기관의 작동 원리를 알아야 합니다. 합성곱 신경망 convolutional neural network (CNN )은 대뇌의 시각 피질 cortex 연구로부터 시작되었고

1980년대부터 이미지 인식 분야에 사용되었습니다. 최근 몇 년 동안 컴퓨터 성능의 향상과 많 은 양의 훈련 데이터, 11장에서 본 심층 신경망을 훈련시키기 위한 기술 덕분에 CNN이 일부 복잡한 이미지 처리 문제에서 사람을 능가하는 성능을 달성했습니다. 이 기술은 이미지 검색 서비스, 자율주행 자동차, 영상 자동 분류 시스템 등에 큰 기여를 했습니다. 또한 CNN은 시각 분야에 국한되지 않고 음성 인식 voice recognition 이나 자연어 처리 natural language processing (NLP ) 같 은 다른 작업에도 많이 사용됩니다. 그러나 여기에서는 시각적인 애플리케이션에 초점을 맞추 겠습니다.

13장 합성곱 신경망 451


이 장에서는 CNN이 어디에서 왔는지, 구성 요소는 무엇인지 알아보고 텐서플로를 사용해 구 현하는 방법을 설명하겠습니다. 그런 다음 가장 뛰어난 성능의 CNN 구조 몇 개를 소개하겠습 니다.

13.1 시각 피질의 구조 데이비드 허블 David H. Hubel 과 토르스텐 비셀 Torsten Wiesel 은 1958년 1과 1959년 2에 시각 피질의 구조에 대한 결정적인 통찰을 제공한 고양이 실험을 연속해서 수행했습니다(두 저자는 이 연 구의 공로로 1981년 노벨 생리의학상을 수상했습니다). 그리고 몇 년 뒤에는 원숭이를 대상으 로 실험했습니다.3 특히 그들은 시각 피질 안의 많은 뉴런이 작은 국부 수용장 local receptive field 을 가진다는 것을 보였습니다. 이는 뉴런들이 시야의 일부 범위 안에 있는 시각 자극에만 반응한 다는 뜻입니다(다섯 개 뉴런의 국부 수용장이 파선의 원으로 표현된 [그림 13-1] 참조). 뉴런 의 수용장들은 서로 겹칠 수 있어 합치면 전체 시야를 감싸게 됩니다. 거기에 더해 어떤 뉴런은 수평선의 이미지에만 반응하고 반면 다른 뉴런은 다른 각도의 선분에 반응한다는 점을 보였습 니다(두 뉴런은 동일한 수용장을 가지지만 다른 각도의 선분에 반응합니다). 또한 어떤 뉴런 은 큰 수용장을 가져서 저수준 패턴이 조합된 더 복잡한 패턴에 반응한다는 것을 알았습니다. 이러한 관찰은 고수준 뉴런이 이웃한 저수준 뉴런의 출력에 기반한다는 아이디어를 이끌어냈 습니다([그림 13-1]에서 각 뉴런은 이전 층에 있는 몇 개의 뉴런에만 연결됩니다). 이러한 강 력한 구조가 전체 시야 영역에 포함된 모든 종류의 복잡한 패턴을 감지할 수 있도록 만듭니다.

1 「Single Unit Activity in Striate Cortex of Unrestrained Cats」, D. Hubel과 T. Wiesel (1958 ), http://goo.gl/VLxXf9 2 「Receptive Fields of Single Neurones in the Cat’s Striate Cortex」, D. Hubel과 T. Wiesel ( 1959 ), http://goo.gl/

OYuFUZ 3 「Receptive Fields and Functional Architecture of Monkey Striate Cortex」, D. Hubel and T. Wiesel (1968 ), http://

goo.gl/95F7QH

452 2부 신경망과 딥러닝


그림 13-1 시각 피질의 국부 수용장

시각 피질에 대한 이런 연구는 1980년에 소개된 신인식기 neocognitron 에 영감을 주었고 4 우리가 지금 합성곱 신경망이라고 부르는 것으로 점진적으로 진화되었습니다.5 1998년 얀 르쿤 Yann , 레옹 보토 Léon Bottou, 요슈아 벤지오 Yoshua Bengio 와 패트릭 하프너 Patrick Haffner 의 논문 6이

LeCun

중요한 전환점이 되었습니다. 여기에서 수표에 쓰인 손글씨 숫자를 인식하는 데 널리 사용된 유 명한 LeNet-5 구조를 소개했습니다. 이 구조에는 우리에게 익숙한 완전 연결 층과 시그모이드 활성화 함수 같은 구성 요소가 들어 있지만, 이 외에도 합성곱층 convolution layer 과 풀링층 pooling layer

이란 두 개의 새로운 구성 요소도 소개합니다. 이 두 가지 구성 요소에 대해 살펴보도록 하

겠습니다. 먼저 합성곱층에 대해 알아봅니다. NOTE_ 왜 이미지 인식 문제에 일반적인 완전 연결 층의 심층 신경망을 사용하지 않을까요? 이런 신경망은

작은 이미지(예를 들면 MNIST )에서는 잘 작동하지만 큰 이미지에서는 아주 많은 파라미터가 만들어지기 때문에 문제가 됩니다. 예를 들어 100 × 100 이미지는 10,000개의 픽셀로 이루어져 있습니다. 여기에 (다음 층으로 전달되는 정보의 양을 상당히 줄여서) 첫 번째 은닉층을 1,000개의 뉴런으로 만들어도 총 천만 개의 연결이 생깁니다. 이는 첫 번째 은닉층일 뿐입니다. CNN은 층을 부분적으로 연결하여 이 문제를 해결합니다.

4 「Neocognitron: A Self-organizing Neural Network Model for a Mechanism of Pattern Recognition Unaffected by Shift in Position」, K . Fukushima (1980 ), http://goo.gl/XwiXs9 5 옮긴이_ 쿠니히코 후쿠시마(Kunihiko Fukushima ) 박사가 제안한 신인식기를 소개하는 영상 두 편이 유투브에 공개되어 있습니다 (https://goo.gl/LNQZPz , https://goo.gl/rXNsnN ). 이 영상은 1986년에 만든 것이라 화질은 좋지 않지만 합성곱 신경망을 이해하는 데 많은 도움을 얻을 수 있습니다. 6 「Gradient- Based Learning Applied to Document Recognition」, Y. LeCun et al . (1998 ), http://goo.gl/A347S4

13장 합성곱 신경망 453


13.2 합성곱층 CNN의 가장 중요한 구성 요소는 합성곱층 convolutional layer 7입니다. 첫 번째 합성곱층의 뉴런은 (이전 장에서처럼) 입력 이미지의 모든 픽셀에 연결되는 것이 아니라 합성곱층 뉴런의 수용장 안에 있는 픽셀에만 연결됩니다(그림 13-2 ). 두 번째 합성곱층에 있는 각 뉴런은 첫 번째 층 의 작은 사각 영역 안에 위치한 뉴런에 연결됩니다. 이런 구조는 네트워크가 첫 번째 은닉층에 서는 저수준 특성에 집중하고, 그다음 은닉층에서는 고수준 특성으로 조합해 나가도록 도와줍 니다. 이런 계층적 구조는 실제 이미지에서 흔히 볼 수 있으며, 이는 CNN이 이미지 인식에 잘 작동하는 이유 중 하나입니다. 그림 13-2 사각 형태의 국부 수용장을 가진 CNN 층

합성곱층 2

합성곱층 1

입력층

NOTE_ 지금까지 살펴본 모든 다층 신경망의 층은 한 줄로 길게 늘어선 뉴런으로 구성되었습니다. 그래서 입

력 이미지를 신경망에 주입하기 전에 1D 배열로 펼쳐야 했습니다. 여기서는 각 층이 2D로 표현되므로 뉴런 을 그에 상응하는 입력과 연결하기 더 쉽습니다.

7 합성곱은 한 함수가 다른 함수 위를 이동하면서 원소별 곱셈의 적분을 계산하는 수학 연산입니다. 이 연산은 푸리에 변환( Fourier transform )과 라플라스 변환(Laplace transform )에 깊은 관계가 있으며 신호 처리 분야에서 많이 사용됩니다. 합성곱층은 사실 합 성곱과 매우 유사한 교차 상관(cross-correlation )을 사용합니다(더 자세한 내용은 https://goo.gl/wXXB3Q를 참고하세요). 옮긴 이_ 합성곱 연산의 정의는 두 함수 중 하나를 반전시킵니다(조금 더 자세한 내용은 옮긴이의 블로그를 참고하세요. https://goo.gl/ Gj84MS ). 즉, 입력 이미지나 필터 중 하나는 뒤집어서 연산해야 합니다. 교차 상관은 합성곱에서 반전을 제외한 것으로 모델을 학습할 때 나 예측을 만들 때 필터가 일정하기만 하면 되므로 계산의 편리를 위해 텐서플로를 비롯해 대부분의 딥러닝 프레임워크는 교차 상관으로 구현되어 있습니다. 또한 연산의 성능을 향상시키기 위해 텐서플로 1.3부터는 위노그라드(Winograd , https://goo.gl/vGeKCF ) 알 고리즘이 기본으로 사용됩니다.

454 2부 신경망과 딥러닝


어떤 층의 i 행, j 열에 있는 한 뉴런은 이전 층의 i 에서 i + fh − 1까지의 행과 j 에서 j + fw − 1까지 의 열에 있는 뉴런의 출력에 연결됩니다. 여기서 fh 와 fw 는 이 수용장의 높이와 너비입니다(그 림 13-3 ). 그림에서와 같이 높이와 너비를 이전 층과 같게 하기 위해 입력의 주위에 0을 추가 하는 것이 일반적입니다. 이를 제로 패딩 zero padding 이라고 합니다. 그림 13-3 층과 제로 패딩 사이의 연결

제로 패딩

[그림 13-4]에서처럼 수용장 사이에 간격을 두어 큰 입력층을 훨씬 작은 층에 연결하는 것도 가능합니다. 연속된 두 개의 수용장 사이의 거리를 스트라이드 stride 라고 합니다. 이 그림에서는 (제로 패딩이 적용된) 5 × 7 입력층이 3 × 3 수용장과 스트라이드 2를 사용하여 3 × 4층에 연 결되었습니다(이 예제에서는 가로 세로 방향으로 모두 스트라이드가 동일하지만 꼭 그래야 하 는 것은 아닙니다). 상위층의 i 행, j 열에 있는 뉴런이 이전 층의 i × sh에서 i × sh + fh − 1까지의 행과 j × sw에서 j × sw + fw - 1까지의 열에 위치한 뉴런과 연결됩니다. 여기서 sh 와 sw 는 스트라 이드의 수직 값과 수평 값입니다.8

8 옮긴이_ 스트라이드와 패딩에 대한 자세한 설명과 시뮬레이션은 옮긴이의 블로그에서 ‘딥러닝을 위한 콘볼루션 계산 가이드 ( https:// goo.gl/qvNTyu )’를 참고하세요.

13장 합성곱 신경망 455


그림 13-4 스트라이드를 사용해 차원 축소하기

13.2.1 필터 뉴런의 가중치는 수용장 크기의 작은 이미지로 표현될 수 있습니다. 예를 들어 [그림 13-5]는 필터 filter (또는 합성곱 커널 convolution kernel )라 부르는 두 개의 가중치 세트를 보여줍니다. 첫 번 째 것은 가운데 흰 수직선이 있는 검은 사각형입니다(가운데 열은 1로 채워져 있고 그 외에는 모두 0인 7 × 7 행렬입니다). 이런 가중치를 사용한 뉴런은 가운데 수직선 부분을 제외하고는 수용장에 있는 모든 것을 무시할 것입니다(가운데 위치한 수직선 부분을 제외하고는 입력에 모두 0이 곱해지기 때문에). 두 번째 필터는 가운데 흰 수평선이 있는 검은 사각형입니다. 여 기에서도 이 가중치를 사용한 뉴런은 가운데 수평선 부분을 제외하고는 수용장 안의 모든 것을 무시할 것입니다. 이제 [그림 13-5]의 (하단) 입력 이미지를 네트워크에 주입하고 한 층의 모든 뉴런에 같은 수 직선 필터를(그리고 같은 편향을 9 ) 적용하면 이 층은 왼쪽 위의 이미지를 출력할 것입니다. 흰 수직선은 강조되고 나머지는 희미해졌습니다. 비슷하게 오른쪽 위의 이미지는 모든 뉴런에 수 평선 필터를 적용했을 때 얻은 것입니다. 흰 수평선은 강조되고 나머지는 희미해졌습니다. 그 러므로 같은 필터를 사용한 전체 뉴런의 층은 필터와 유사한 이미지의 영역을 강조하는 특성 9 옮긴이_ 10장의 완전 연결 신경망과 달리 대부분 CNN의 그림에는 편향이 표현되지 않는 경우가 많습니다. CNN에서는 하나의 필터와 편향으로 한 개의 특성 맵이 만들어집니다.

456 2부 신경망과 딥러닝


CHAPTER

14

순환 신경망

야구방망이로 공을 칩니다. 수비수는 즉시 공의 궤적을 예측하면서 달리기 시작합니다. 공에 서 눈을 떼지 않고 몸을 움직여 마침내 공을 잡습니다(큰 박수소리와 함께). 친구의 말을 대 신 마무리하든 아침에 커피 향을 예상하든 미래를 예측하는 것은 우리가 늘 하는 일입니다. 이 장에서는 미래를 예측할 수 있는(물론 어느 정도만) 네트워크인 순환 신경망 recurrent neural networks

(RNN )에 대해 알아보겠습니다. 이 신경망은 주식가격 같은 시계열 time series 데이터를

분석해서 언제 사고팔지 알려줄 수 있습니다. 자율주행 시스템에서는 차의 이동경로를 예측하 고 사고를 피하도록 도울 수 있습니다. 일반적으로 이 신경망은 지금까지 봤던 모든 네트워크 처럼 고정 길이 입력이 아니라 임의 길이를 가진 시퀀스 sequence 를 다룰 수 있습니다. 예를 들어 문장, 문서 또는 오디오 샘플을 입력으로 받을 수 있고, 자동 번역, 스피치 투 텍스트 speech to text 또는 감성 분석 sentiment analysis (예를 들면 영화 리뷰를 읽어서 영화에 대한 평가자의 느낌을 추 출하는 것 1 ) 같은 자연어 처리(NLP )에 매우 유용합니다. 또한 RNN의 예측 능력은 놀라운 창의력을 발휘합니다. 멜로디에서 가장 가능성 있는 다음 음 표를 예측하고, 그 음표 중 하나를 랜덤하게 선택해서 연주를 할 수 있습니다. 그런 다음 가장 가능성 있는 다음 음표를 골라 연주하고, 이 과정을 계속해서 반복합니다. 네트워크는 구글 마 젠타 프로젝트( https://magenta.tensorflow.org/ )에서 만든 것( http://goo.gl/IxIL1V ) 과 같은 멜로디를 순식간에 작곡할 것입니다.2 이와 비슷하게 RNN은 문장(http://goo.gl/ 1 옮긴이_ 사이킷런을 이용한 한국어와 영어로 된 영화 리뷰의 감성 분석 예제는 『파이썬 라이브러리를 활용한 머신러닝』(한빛미디어, 2017 )의 7장을 참고하세요. 2 옮긴이_ 2017년 6월에 마젠타 프로젝트에서 공개한 퍼포먼스 RNN (「Performance RNN : Generating Music with Expressive Timing and Dynamics」 , Magenta Blog , 2017, https://goo.gl/HeLqAH )의 놀라운 피아노 연주( https://goo.gl/ QSnG5v )도 감상해보세요.

14장 순환 신경망 481


onkPNd ), 이미지 캡션( http://goo.gl/Nwx7Kh ) 등 많은 것을 생성할 수 있습니다. 아직 생성

한 결과가 셰익스피어나 모차르트와 같지는 않지만 몇 년 후 어떤 일을 해낼지 누가 알겠어요. 이 장에서는 RNN의 핵심 개념, 당면한 주요 문제(말하자면 11장에서 언급한 그래디언트 소 실과 폭주)와 이를 해결하기 위한 방법인 LSTM과 GRU 셀을 살펴보겠습니다. 항상 그렇듯이 이 과정에서 텐서플로를 사용해 어떻게 RNN을 구축하는지 소개합니다. 마지막으로 기계 번역 시스템의 구조를 살펴보겠습니다.

14.1 순환 뉴런 지금까지는 활성화 신호가 입력층에서 출력층 한 방향으로만 흐르는 피드포워드 신경망을 살 펴봤습니다(부록 E에 있는 몇 개의 네트워크는 예외입니다). 순환 신경망은 피드포워드 신경 망과 매우 비슷하지만 뒤쪽으로 향하는 연결도 있다는 점이 다릅니다. [그림 14-1] 왼쪽의 그 림처럼 입력을 받아 출력을 만들고 자신에게도 출력을 보내는 뉴런 하나로 구성된 가장 간단 한 RNN을 살펴보겠습니다. 각 타임 스텝 time step t (또는 프레임 frame )마다 이 순환 뉴런 recurrent neuron

은 x (t ) 는 물론 이전 타임 스텝의 출력인 y (t -1 ) 을 입력으로 받습니다. 이 작은 네트워크를

[그림 14-1] 오른쪽처럼 시간을 축으로하여 표현할 수 있습니다. 이를 시간에 따라 네트워크를 펼쳤다고 말합니다. 그림 14-1 순환 뉴런(왼쪽)과 타임 스텝으로 펼친 뉴런(오른쪽)

시간

순환 뉴런으로 된 층은 쉽게 만들 수 있습니다. [그림 14-2]처럼 타임 스텝 t 마다 모든 뉴런은

482 2부 신경망과 딥러닝


입력 벡터 x (t ) 와 이전 타임 스텝의 출력 벡터 y (t -1 ) 을 받습니다. 이제 입력과 출력이 모두 벡터 가 됩니다(뉴런이 하나일 때는 출력이 스칼라입니다). 그림 14-2 순환 뉴런의 층(왼쪽)과 타임 스텝으로 펼쳐진 층(오른쪽)

시간

각 순환 뉴런은 두 벌의 가중치를 가집니다. 하나는 입력 x (t ) 를 위한 것이고 다른 하나는 이전 타임 스텝의 출력 y (t -1 ) 을 위한 것입니다. 이 가중치 벡터를 wx와 wy라고 하겠습니다. 하나의 순환 뉴런이 아니라 순환 층 전체를 생각하면 가중치 벡터를 가중치 행렬 Wx 와 Wy 로 바꿀 수 있습니다. 그러면 순환 층 전체의 출력은 익숙한 형태인 [식 14-1]과 같이 계산됩니다(b는 편 향이고 φ (·)는 ReLU 3와 같은 활성화 함수입니다). 식 14-1 하나의 샘플에 대한 순환 층의 출력

(

T

T

)

y(t ) = φ Wx ⋅ x (t ) + Wy ⋅ y (t −1) + b

피드포워드 신경망처럼 타임 스텝 t 에서의 모든 입력을 행렬 X (t )로 만들어 미니배치 전체에 대 해 순환 층의 출력을 한번에 계산할 수 있습니다(식 14-2 ). 식 14-2 미니배치에 있는 전체 샘플에 대한 순환 뉴런 층의 출력

Y( t ) = φ ( X ( t ) ⋅ Wx + Y( t −1) ⋅ Wy + b) = φ ([X ( t ) Y( t −1) ] ⋅ W + b)

여기서 W

 Wx  =   Wy 

3 많은 연구자들이 RNN에서 ReLU 활성화 함수보다 하이퍼볼릭 탄젠트( tanh ) 활성화 함수를 선호합니다. 「Dropout Improves Recurrent Neural Networks for Handwriting Recognition」, Vu Pham et al . (https://goo.gl/2WSnaj ) 논문을 참고하세 요. 그러나 「A Simple Way to Initialize Recurrent Networks of Rectified Linear Units」, Quoc V. Le et al . (https://goo. gl/NrKAP0 ) 논문에서 보여준 것처럼 ReLU 기반의 RNN도 가능합니다.

14장 순환 신경망 483


Y (t ) 는 타임 스텝 t 에서 미니배치에 있는 각 샘플에 대한 층의 출력을 담고 있는 m × n neurons 행렬입니다(m

은 미니배치에 있는 샘플 수이고 n neurons 는 뉴런 수입니다). X (t ) 는 모든 샘플의 입력값을 담고 있는 m × n inputs 행렬입니다(n inputs 는 입력 특성 수입니다).

W x 는 현재 타임 스텝의 입력에 대한 연결 가중치를 담고 있는 n inputs × n neurons 행렬입니다.

W y 는 이전 타임 스텝의 출력에 대한 연결 가중치를 담고 있는 n neurons × n neurons 행렬입니다.

b 는 각 뉴런의 편향을 담고 있는 n neurons 크기의 벡터입니다.

가중치 행렬 Wx 와 Wy 는 종종 (n inputs + n neurons ) × n neurons 크기의 가중치 행렬 W 하나로 연결합니다([식

14 -2]의 두 번째 줄을 참조하세요). [X (t ) Y (t -1 )] 표기는 행렬 X (t ) Y (t -1 )을 수평적으로 연결한다는 것을 나타냅니다.4

Y (t ) 는 X (t ) 와 Y (t - 1 )의 함수고, Y (t - 1 )은 X (t - 1 )과 Y (t - 2 )의 함수고, Y (t - 2 )는 X (t - 2 )와 Y (t - 3 )의 함수가 되는 식입니다. 결국 Y (t ) 는 시간 t = 0에서부터 모든 입력에 대한 함수가 됩니다(즉, X , X , ..., X ). 첫 번째 타임 스텝 t = 0에서는 이전 출력이 없으므로 보통 모두 0이라고 (0 )

(1 )

(t )

가정합니다.

14.1.1 메모리 셀 타임 스텝 t 에서 순환 뉴런의 출력은 이전 타임 스텝의 모든 입력에 대한 함수이기 때문에 이를 일종의 메모리 형태라고 말할 수 있습니다. 타임 스텝에 걸쳐서 어떤 상태를 보존하는 신경망 의 구성 요소를 메모리 셀 memory cell (혹은 간단히 셀)이라고 합니다. 하나의 순환 뉴런 또는 순 환 뉴런의 층은 매우 기본적인 셀입니다.5 하지만 이 장 뒷부분에서 더 복잡하고 강력한 종류 의 셀을 볼 것입니다. 일반적으로 타임 스텝 t 에서의 셀의 상태 h (t ) (h는 히든 hidden 을 의미)는 그 타임 스텝의 입력 과 이전 타임 스텝의 상태에 대한 함수입니다. 즉, h (t ) = f (h (t-1 ), x (t ) )입니다. 타임 스텝 t 에서 의 출력 y (t ) 도 이전 상태와 현재 입력에 대한 함수입니다. 지금까지 이야기한 기본 셀의 경우 출력은 셀의 상태와 동일하지만, [그림 14-3]처럼 더 복잡한 셀에서는 항상 그렇지 않습니다.6

4 옮긴이_ 이 행렬의 크기는 m × (n inputs + n neurons )가 됩니다. 5 옮긴이_ 보통 RNN에서 셀이라고 말할 때는 완전 연결 신경망에서 층(layer )을 의미합니다. 6 옮긴이_ [그림 14-2]는 히든 상태(h ) 대신 출력(y )이 다시 입력으로 주입됩니다. [그림 14-3]은 출력(y )과 히든 상태(h )가 구분되어 있어서 두 값이 동일하지 않을 수 있다는 것을 나타냅니다.

484 2부 신경망과 딥러닝


그림 14-3 셀의 히든 상태와 출력은 다를 수 있습니다.

시간

14.1.2 입력과 출력 시퀀스 RNN은 입력 시퀀스를 받아 출력 시퀀스 만들 수 있습니다([그림 14-4] 왼쪽 위의 네트워크). 이는 시퀀스-투-시퀀스 sequence-to-sequence 네트워크로, 예를 들어 주식가격 같은 시계열 데이터 를 예측하는 데 유용합니다. 최근 N 일치의 주식가격을 주입하면 네트워크는 하루 앞선 가격을 출력해야 합니다(즉, N − 1일 전부터 내일까지). 또는 입력 시퀀스를 네트워크에 주입하고, 마지막을 제외한 모든 출력을 무시할 수 있습니다 (오른쪽 위의 네트워크). 이는 시퀀스-투-벡터 sequence-to-vector 네트워크로, 예를 들어 영화 리 뷰에 있는 연속된 단어를 주입하면 네트워크는 감성 점수를 출력합니다(예를 들면 -1 (싫다) 에서부터 +1 (좋다)까지). 반대로 첫 번째 타임 스텝에서 단 하나의 입력만(다른 모든 타임 스텝에서는 0을) 네트워크 에 주입하고, 출력 시퀀스를 연결할 수 있습니다(왼쪽 아래 네트워크). 이는 벡터-투-시퀀스 vector-to-sequence

네트워크로, 예를 들어 이미지를 입력하여 이미지에 대한 캡션을 출력할 수 있습

니다. 또한 인코더 encoder 라 불리는 시퀀스-투-벡터 네트워크 뒤에 디코더 decoder 라 불리는 벡터-투시퀀스 네트워크를 연결할 수 있습니다(오른쪽 아래 네트워크). 이는 지연된 시퀀스-투-시퀀 스 delayed sequence-to-sequence 네트워크로, 예를 들어 한 언어의 문장을 다른 언어로 번역하는 데 사용할 수 있습니다. 한 언어의 문장을 네트워크에 주입하면 인코더는 이 문장을 하나의 벡터 표현으로 변환하고, 그다음에 디코더가 이 벡터를 다른 언어의 문장으로 디코딩합니다. 인코 더-디코더로 불리는 이런 이중 단계 모델은 하나의 시퀀스-투-시퀀스 RNN을 사용하여 한 단 14장 순환 신경망 485


어씩 번역하는 것보다 훨씬 더 잘 작동합니다. 문장의 마지막 단어가 번역의 첫 번째 단어에 영향 을 줄 수 있기 때문입니다. 그래서 번역하기 전에 전체 문장이 주입될 때까지 기다릴 필요가 있습 니다. 그림 14-4 시퀀스-투-시퀀스(왼쪽 위), 시퀀스-투-벡터(오른쪽 위), 벡터-투-시퀀스(왼쪽 아래), 지연된 시퀀스-투-시 퀀스(오른쪽 아래) 무시된 출력

인코더

디코더

기대가 되네요. 그럼 코딩을 시작해보죠!

14.2 텐서플로로 기본 RNN 구성하기 내부 구조를 잘 이해하기 위해 먼저 텐서플로의 RNN 연산을 전혀 사용하지 않고 매우 간단한

RNN 모델을 구현해보겠습니다. tanh 활성화 함수를 사용하는 ([그림 14-2]에 표현된 RNN 같은) 다섯 개의 순환 뉴런의 층으로 구성된 RNN을 만들겠습니다. 이 RNN은 타임 스텝마다 크기 3의 입력 벡터를 받고 단지 두 개의 타임 스텝에 대해서만 작동한다고 가정하겠습니다. 다음 코드는 두 개의 타임 스텝에 걸쳐 펼쳐진 이 RNN을 구성합니다.

486 2부 신경망과 딥러닝


CHAPTER

15

오토인코더

오토인코더 autoencoder 는 어떤 감독 없이도(즉, 레이블되어 있지 않은 훈련 데이터를 사용해서) 입력 데이터의 효율적인 표현인 코딩 coding 1을 학습할 수 있는 인공 신경망입니다. 이런 코딩은 일반적으로 입력보다 훨씬 낮은 차원을 가지므로 오토인코더가 차원 축소(8장 참조)에 유용 하게 사용됩니다. 더 중요한 점은 오토인코더가 강력한 특성 추출기처럼 작동하기 때문에 심층 신경망의 비지도 사전훈련에 사용될 수 있다는 것입니다(11장에서 언급한 것처럼). 또한 훈련 데이터와 매우 비슷한 새로운 데이터를 생성할 수 있습니다. 이를 생성 모델 generative model 이라 고 합니다. 예를 들어 얼굴 사진을 사용해 오토인코더를 훈련시키면 이 모델은 새로운 얼굴을 생성할 수 있을 것입니다. 놀랍게도 오토인코더가 학습하는 것은 단순히 입력을 출력으로 복사하는 것뿐입니다. 간단한 작 업처럼 보이지만 네트워크에 여러 방법으로 제약을 가해 오히려 어려운 작업으로 만듭니다. 예 를 들어 내부 표현의 크기를 제한하거나 2 입력에 잡음을 추가한 후 원본 입력을 복원할 수 있도 록 네트워크를 훈련시킵니다. 이런 제약은 오토인코더가 단순히 입력을 바로 출력으로 복사하 지 못하도록 막고, 데이터를 효율적으로 표현하는 방법을 배우도록 강제시킵니다. 간단히 말해 코딩은 어떤 제약 조건 하에서 항등 함수를 학습하려는 오토인코더의 노력으로 생겨난 부산물 입니다.

1 옮긴이_ 여기서 코딩은 컴퓨터 프로그래밍이 아닌 일반적인 부호화를 말합니다. 2 옮긴이_ 은닉층에 있는 뉴런 수를 입력층보다 적게 한다는 뜻입니다.

15장 오토인코더 521


이 장에서는 차원 축소, 특성 추출, 비지도 사전훈련, 생성 모델을 위한 오토인코더가 어떻게 작 동하는지, 어떤 종류의 제약조건을 가할 수 있는지, 텐서플로를 사용해 어떻게 구현할 수 있는지 자세히 살펴보겠습니다.

15.1 효율적인 데이터 표현 다음과 같은 일련의 숫자를 쉽게 기억할 수 있는 방법이 있을까요? 4 0, 27, 25, 36, 81, 57, 10, 73, 19, 68

5 0, 25, 76, 38, 19, 58, 29, 88, 44, 22, 11, 34, 17, 52, 26, 13, 40, 20

처음 봤을 땐 첫 번째 수열이 짧기 때문에 더 쉬워 보입니다. 하지만 두 번째 수열을 자세히 살 펴보면 간단한 두 개의 규칙을 따르고 있다는 것을 알 수 있습니다. 짝수는 절반으로 줄어들고, 홀수는 3을 곱하고 1이 더해집니다(이를 헤일스톤 수열 hailstone sequence 이라고 합니다 3 ). 일단 이 패턴을 알게 되면 두 개의 규칙과 시작 숫자와 수열의 길이만 기억하면 되기 때문에 두 번째 수열이 기억하기 훨씬 더 쉽습니다. 아주 긴 수열을 빠르고 쉽게 기억할 수 있다면 두 번째 수 열에 패턴이 있는지 신경 쓸 필요가 없습니다. 모든 숫자를 외우면 그만이기 때문입니다. 긴 수 열은 기억하기 어렵기 때문에 패턴을 찾는 것이 유용하며 이와 마찬가지 이유로 훈련하는 동안 오토인코더에 제약을 가해서 데이터에 있는 패턴을 찾아 활용하도록 만듭니다. 기억, 지각, 패턴 매칭 pattern matching 사이의 관계는 1970년대 초 윌리엄 체이스 William Chase 와 허 버트 사이먼 Herbert Simon 에 의해 많이 연구되었습니다.4 이들은 숙련된 체스 플레이어가 체스 판 을 5초 동안만 바라보고도 전체 말의 위치를 외울 수 있다는 것을 알아냈습니다. 대부분의 사 람에게는 불가능한 일입니다. 그러나 이는 체스 말들이 무작위로 놓여 있을 때가 아니라 (실제 게임처럼) 현실적인 위치에 있을 경우에만 그렇습니다. 체스 전문가라 하더라도 우리보다 더 뛰어난 기억력을 가지고 있지는 않습니다. 단지 그 게임에 대한 경험 덕분에 체스 패턴을 더 쉽 게 보는 것뿐입니다. 즉, 패턴을 찾게 되면 정보를 효율적으로 저장할 수 있습니다. 이런 기억 실험의 체스 플레이어처럼 오토인코더가 입력을 받아 효율적인 내부 표현으로 바꾸 3 옮긴이_ 이 수열을 제안한 로타르 콜라츠(Lothar Collatz )의 이름을 따서 콜라츠 추측이라고도 합니다. 4 Perception in chess」, W. Chase and H. Simon (1973 ), https://goo.gl/kSNcX0

522 2부 신경망과 딥러닝


고 입력과 (바라건대) 매우 가까워 보이는 어떤 것을 출력합니다. 오토인코더는 항상 두 부분으 로 구성되어 있습니다. 입력을 내부 표현으로 바꾸는 인코더 encoder (또는 인지 네트워크 recognition network

)와 내부 표현을 출력으로 바꾸는 디코더 decoder (또는 생성 네트워크 generative network )입니

다(그림 15-1 ). 그림에서 볼 수 있듯이 출력층의 뉴런 수가 입력 개수와 동일하다는 것을 제외하면, 일반적으 로 오토인코더는 다층 퍼셉트론( MLP, 10장 참조)과 동일한 구조를 가집니다. 이 예에서는 두 개의 뉴런으로 구성된 하나의 은닉층이 있습니다(인코더). 그리고 세 개의 뉴런으로 구성 된 출력층이 있습니다(디코더). 오토인코더가 입력을 재구성하기 때문에 출력을 종종 재구성 reconstruction

이라고 부릅니다. 비용 함수는 재구성이 입력과 다를 때 모델에 벌점을 부과하는 재

구성 손실을 포함하고 있습니다.5 그림 15-1 체스 기억 실험(왼쪽)과 간단한 오토인코더(오른쪽)

출력(≈입력)

인코더

내부 표현 디코더

입력

내부 표현이 입력 데이터보다 저차원이기 때문에(즉, 3차원 대신 2차원) 이런 오토인코더를 과소완전 undercomplete 6이라고 합니다. 과소완전 오토인코더는 입력을 코딩으로 간단히 복사할

5 옮긴이_ 즉, 오토인코더는 입력이 곧 타깃이 됩니다. 입력을 타깃으로 사용하는 이런 알고리즘을 일반적인 비지도 학습과 구분하여 자기 지도 학습(self-supervised learning )이라고 부르기도 합니다. 6 옮긴이_ undercomplete의 대수학적 정의를 보면 기저(basis )보다 적은 개수로 표현되는 것을 말하며 overcomplete는 그 반대의 경우입니다. 이 두 용어에 대한 적절한 번역 사례를 찾지 못했으나 underfitting/overfitting (과소적합/과대적합)의 경우를 참고하여 과 소완전, 과대완전이라고 옮겼습니다.

15장 오토인코더 523


수 없으며, 입력과 똑같은 것을 출력하기 위한 다른 방법을 찾아야 합니다. 이는 입력 데이터에 서 가장 중요한 특성을 학습하도록 만듭니다(그리고 중요하지 않은 것은 버립니다). 그럼 차원 축소를 위한 아주 간단한 과소완전 오토인코더를 어떻게 구현하는지 살펴보겠습니다.

15.2 과소완전 선형 오토인코더로 PCA 수행하기 오토인코더가 선형 활성화 함수만 사용하고 비용 함수가 평균 제곱 오차(MSE )라면, 이는 결국 주성분 분석(PCA, 8장 참조)을 수행하는 것으로 볼 수 있습니다.7 다음 코드는 3D 데이터셋에 PCA를 적용해 2D에 투영하는 간단한 선형 오토인코더를 만듭 니다. import tensorflow as tf n_inputs = 3 # 3D 입력 n_hidden = 2 # 2D 코딩 n_outputs = n_inputs learning_rate = 0.01 X = tf.placeholder(tf.float32, shape=[None, n_inputs]) hidden = tf.layers.dense(X, n_hidden) outputs = tf.layers.dense(hidden, n_outputs) reconstruction_loss = tf.reduce_mean(tf.square(outputs - X))

# MSE

optimizer = tf.train.AdamOptimizer(learning_rate) training_op = optimizer.minimize(reconstruction_loss) init = tf.global_variables_initializer()

7 옮긴이_ PCA는 분산이 가장 큰 방향(주성분)을 찾습니다. 즉, 원본 데이터와 투영 거리(유클리디안 거리)를 가장 작게 만드는 성분을 찾 는 것입니다. 따라서 이 거리는 MSE를 최소화하려는 오토인코더의 목적과 동일합니다. 하지만 PCA로 찾은 주성분과 오토인코더의 코 딩이 같지는 않습니다.

524 2부 신경망과 딥러닝


이 코드는 이전 장에서 만들었던 MLP와 정말로 많이 다르지 않습니다. 특별히 언급할 두 가지 는 다음과 같습니다. ●

출력의 개수가 입력의 개수와 동일합니다.

단순한 PCA를 수행하기 위해서는 활성화 함수를 사용하지 않으며(즉, 모든 뉴런이 선형입니다), 비용 함수 는 MSE입니다. 잠시 후에 조금 더 복잡한 오토인코더를 보게 될 것입니다.

이제 데이터셋을 로드해서 훈련 세트에 모델을 훈련시키고 테스트 세트를 인코딩해보겠습니다 (즉, 2D에 투영합니다). X_train, X_test = [...]

# 데이터셋을 로드합니다.

n_iterations = 1000 codings = hidden # 코딩을 만드는 은닉층을 출력합니다. with tf.Session() as sess: init.run() for iteration in range(n_iterations): training_op.run(feed_dict={X: X_train}) # 레이블이 없습니다(비지도 학습). codings_val = codings.eval(feed_dict={X: X_test})

[그림 15-2]는 원본 3D 데이터셋(왼쪽)과 오토인코더의 은닉층의 출력(즉, 코딩층, 오른쪽) 을 보여줍니다. 여기서 볼 수 있듯이 오토인코더는 (PCA처럼) 데이터에 있는 분산이 가능한 한 많이 보존되도록 데이터를 투영할 최상의 2D 평면을 찾습니다. 그림 15-2 과소완전 선형 오토인코더에 의해 수행된 PCA 원본 3D 데이터셋 원본 3D 데이터셋

분산이 가장 큰 2D 투영 분산이 가장 큰 2D 투영

15장 오토인코더 525


15.3 적층 오토인코더 앞서 살펴봤던 다른 신경망과 마찬가지로 오토인코더도 여러 개의 은닉층을 가질 수 있습니다. 이런 경우를 적층 오토인코더 stacked autoencoder (또는 심층 오토인코더 deep autoencoder )라고 합니 다.8 층을 더 추가하면 오토인코더가 더 복잡한 코딩을 학습할 수 있습니다. 그러나 오토인코 더가 너무 강력하게 되지 않도록 주의해야 합니다. 인코더가 너무 강력해서 각각의 입력 데이 터를 임의의 한 숫자로 매핑하도록 학습했다고(그리고 디코더는 역으로 매핑하는 걸 학습했다 고) 가정해보겠습니다. 당연히 이런 오토인코더는 훈련 데이터를 완벽하게 재구성하겠지만 이 과정에서 유용한 데이터 표현을 학습하지 못할 것입니다(그리고 새로운 샘플에 잘 일반화될 것 같지 않습니다). 적층 오토인코더의 구조는 전형적으로 가운데 은닉층(코딩층)을 기준으로 대칭입니다. 간단 히 말해 샌드위치 같은 모양입니다. 예를 들어 (3장에서 소개한) MNIST를 위한 오토인코더 라면 784개의 입력이 있고, 그다음에 300개의 뉴런으로 된 은닉층, 그다음에 150개 뉴런으로 된 가운데 은닉층, 그다음에 300개의 뉴런으로 된 또 다른 은닉층, 마지막으로 784개의 뉴런 으로 된 출력층을 가집니다. [그림 15-3]에 이 적층 오토인코더를 나타냈습니다. 그림 15-3 적층 오토인코더

784 유닛

300 유닛 150 유닛 300 유닛 784 유닛

재구성(≈입력)

출력 은닉층 3 은닉층 2

코딩

은닉층 1 입력

8 옮긴이_ 여러 개의 은닉층을 가졌으므로 다층(multi layer ) 오토인코더라고 표현할 수도 있지만, 쌓았다(stacked )는 의미를 강조하기 위해 ‘적층’이라고 번역했습니다.

526 2부 신경망과 딥러닝


CHAPTER

16

강화 학습

강화 학습 Reinforcement Learning (RL )은 요즘 머신러닝에서 가장 흥미진진한 분야고 또한 가장 오 래된 분야 중 하나입니다. 1950년대부터 시작해서 여러 해 동안 특히 게임(예를 들면 백개먼 Backgammon

플레이 프로그램인 TD-Gammon1 )과 기계 제어 분야에서 관심을 끄는 애플리케

이션들이 많이 나왔지만 2 좀처럼 뉴스의 헤드라인을 장식하지는 못했습니다. 하지만 2013년 영국의 한 스타트업인 딥마인드의 연구원들이 아타리 Atari 게임을 아무 정보 없이 그냥 플레이 하면서 학습하는 시스템을 시연하면서 혁명이 일어났습니다.3 화면 픽셀에 대한 데이터만 입 력으로 받고 게임 규칙에 대한 어떤 사전 정보도 없이 대부분 사람을 능가하는 4 성과를 냈습니 다.5 이는 놀라운 성과의 1막이었고, 2017년 5월 알파고가 바둑 세계챔피언 커제를 이기면서 절정에 다다랐습니다. 세계챔피언은 고사하고 이전에는 어느 프로그램도 이 게임의 고수와 견 줄만한 수준이 못 되었습니다. 오늘날 RL의 전 분야가 매우 다양한 애플리케이션에서 새로운 아 이디어로 들끓고 있습니다. 구글은 2014년에 딥마인드를 5억 달러에 인수했습니다. 1 옮긴이_ 백개먼은 아주 오래된 2인용 전략 보드 게임입니다. TD-Gammon은 1992년 IBM 왓슨 연구소의 제랄드 테사우로(Gerald Tesauro )가 개발한 컴퓨터 프로그램으로, 인공 신경망을 사용한 강화 학습으로 사람과 거의 비슷한 수준의 성능을 냈습니다. 2 조금 더 자세한 내용은 리차드 서튼(Richard Sutton )과 앤드류 바르토(Andrew Barto )의 강화 학습에 관한 책인 『Reinforcement Learning: An Introduction』(MIT Press, https://goo.gl/ipr4aZ )이나 데이비드 실버(David Silver )의 무료 온라인 강화 학 습 강좌(https://goo.gl/AWcMFW )를 참고하세요. 옮긴이_ 리차드 서튼의 강화 학습 책은 2판의 초고가 완성되어 온라인에서 무료로 읽을 수 있습니다(https://goo.gl/m8qviL ). 이 책의 16장에서 TD-Gammon과 알파고를 비롯해 여러 가지 애플리케이션에 대한 자세한 내용을 읽을 수 있습니다. 3 「Playing Atari with Deep Reinforcement Learning」, V. Mnih et al . (2013 ), https://goo.gl/hceDs5 4 「Human - level control through deep reinforcement learning」, V. Mnih et al . (2015 ), https://goo.gl/hgpvz7 5 스페이스 인베이더(Space Invaders ), 브레이크아웃(Breakout ) 등의 게임 플레이를 배우는 딥마인드 시스템의 학습 동영상을 확인해 보세요(https://goo.gl/yTsH6X ).

16장 강화 학습 551


그들은 어떻게 이렇게 한 걸까요? 알고 보면 매우 단순합니다. 강화 학습 분야에 강력한 딥러닝을 적용했더니 상상 이상의 성능을 낸 것입니다. 이 장에서는 먼저 강화 학습이 무엇인지와 어떤 일 을 잘할 수 있는지 설명하겠습니다. 그러고 나서 심층 강화 학습 deep Reinforcement Learning 에서 가장 중요한 두 가지 기술인 정책 그래디언트 policy gradient 와 심층 Q-네트워크 deep Q-networks (DQN ) 를 마르코프 결정 과정 Markov decision process (MDP )과 함께 소개하겠습니다. 이 기법을 사용해 움직이는 카트 cart 에서 막대가 넘어지지 않게 균형을 잡는 모델과 아타리 게임을 플레이하는 모 델을 훈련시키겠습니다. 동일한 기술이 보행 로봇에서부터 자율주행 자동차에 이르기까지 다 양한 종류의 작업에 사용됩니다.

16.1 보상을 최적화하기 위한 학습 강화 학습에서 소프트웨어 에이전트 agent 는 관측 observation 을 하고 주어진 환경 environment 에서 행 동 action 을 합니다. 그리고 그 결과로 보상 reward 을 받습니다. 에이전트의 목적은 보상의 장기간 기대치를 최대로 만드는 행동을 학습하는 것입니다. 양수 positive 보상은 기쁨으로, 음수 negative 보상은(이 경우에는 보상이란 말이 맞지 않지만) 아픔으로 생각할 수 있습니다. 간단히 말해 에이전트는 환경 안에서 행동하고 시행착오를 통해 기쁨이 최대가 되고 아픔이 최소가 되도록 학습합니다. 이는 다양한 종류의 작업에 적용할 수 있는 폭 넓은 정의입니다. 다음은 몇 가지 사례입니다(그 림 16-1 ). a 에이전트는 보행 로봇을 제어하는 프로그램일 수 있습니다. 이 경우 환경은 실제 세상이고, 에이전트는 카메라 나 터치 센서 같은 여러 센서를 통해 환경을 관찰합니다. 그리고 행동은 모터를 구동하기 위해 시그널을 전송 하는 것입니다. 에이전트는 목적지에 도착할 때 양수의 보상을 받고, 시간을 낭비하거나 잘못된 방향으로 향하 거나 넘어질 때 음수의 보상을 받도록 프로그램될 수 있습니다. 6 b 에이전트는 미스 팩맨 Ms. Pac-Man 을 제어하는 프로그램일 수 있습니다. 이 경우 환경은 아타리 게임 시뮬레이

션이고, 행동은 가능한 아홉 개의 조이스틱 위치(왼위, 아래, 가운데 등)입니다. 관측은 스크린샷이 되고 보상 은 게임의 점수입니다.

6 옮긴이_ 미스 팩맨은 오리지널 팩맨의 게임을 향상시킨 버전으로 1982년 초에 아케이드 캐비닛으로 출시되었고 가정용 게임기인 아타 리 2600을 위한 카트리지로도 출시되었습니다. 오리지널 팩맨과 달리 미스 팩맨은 미로의 벽이 색으로 채워져 있어서 강화 학습에 사용 하기 좋습니다.

552 2부 신경망과 딥러닝


c 에이전트는 바둑 같은 보드 게임을 플레이하는 프로그램일 수 있습니다. d 에이전트가 물리적으로(또는 가상으로) 무언가를 움직여야 하는 것은 아닙니다. 예를 들어 에이전트는 목표 온도를 맞추어 에너지를 절약하면 양수 보상을 받고, 사람이 온도를 조작할 필요가 생기면 음수 보상을 받는 스마트 온도조절기일 수 있습니다. 그러므로 에이전트는 사람의 요구를 예측하도록 학습되어야 합니다. e 에이전트는 주식시장의 가격을 관찰하고 매초 얼마나 사고팔아야 할지 결정할 수 있습니다. 당연히 보상은 금 전적 이익과 손실이 됩니다. 그림 16-1 강화 학습의 예: (a ) 보행 로봇, (b ) 미스 팩맨, (c ) 바둑 게임, (d ) 온도조절기, (e ) 자동 매매 프로그램 7

양수 보상이 전혀 없을 수도 있습니다. 예를 들어 에이전트가 미로 속을 움직인다면 매 타임 스 텝마다 음수 보상을 받기 때문에 가능한 한 빨리 탈출구를 찾는 것이 좋을 것입니다! 강화 학습 7 이미지 (a ), (c ), (d )는 위키피디아에서 가져왔습니다. (a )와 (d )는 퍼블릭 도메인이고 (c )는 Stevertigo 사용자가 만든 것으로 크리 에이티브 커먼즈 BY-SA 2.0 (https://creativecommons.org/licenses/by-sa/2.0/deed.ko )을 따릅니다. (b )는 미스 팩 맨 게임의 스크린샷으로 아타리에 저작권이 있습니다(이것은 공정 사용(fair use )에 해당한다고 믿습니다). (e )는 무료 이미지 저장소인

Pixabay에서 가져왔으며 크리에이티브 커먼즈 CC0 (https://creativecommons.org/publicdomain/zero/1.0/deed.ko ) 를 따릅니다.

16장 강화 학습 553


이 잘 들어맞는 작업의 사례가 많이 있습니다. 예를 들면 자율주행 자동차나 웹 페이지에 광고 를 배치하는 것 8 또는 이미지 분류 시스템이 주의를 집중할 곳을 제어하는 것 등입니다.

16.2 정책 탐색 소프트웨어 에이전트가 행동을 결정하기 위해 사용하는 알고리즘을 정책 policy 이라고 합니다. 예를 들어 관측을 입력으로 받고 수행할 행동을 출력하는 신경망이 정책이 될 수 있습니다(그 림 16-2 ). 그림 16-2 신경망 정책을 사용한 강화 학습 에이전트

환경 정책 행동

보상 + 관측

정책은 생각할 수 있는 어떤 알고리즘도 될 수 있으며 심지어 결정적일 필요도 없습니다. 예를 들어 30분 동안 수집한 먼지의 양을 보상으로 받는 로봇 진공청소기를 생각해보겠습니다. 이 청소기의 정책은 매 초마다 어떤 확률 p 만큼 전진하는 것일 수도 있고, 또는 (1 - p )의 확률로 왼쪽 또는 오른쪽으로 랜덤하게 회전하는 것일 수도 있습니다. 회전 각도는 - r 과 + r 사이의 랜 덤한 각도일 수 있습니다. 이 정책에는 무작위성이 포함되어 있기 때문에 확률적 정책 stochastic policy

이라고 합니다. 로봇이 도달할 수 있는 어떤 장소라도 모두 찾아서 먼지를 수집하려고 이

상한 궤적을 만들어낼 것입니다. 궁금한 것은 ‘30분 동안 얼마나 많은 먼지를 수집할 것인가’입 니다. 8 옮긴이_ 온라인 광고 시스템은 강화 학습의 주요 애플리케이션 중 하나입니다. 프로그래매틱( programmatic ) 광고 시스템에서 에이전 트는 광고 입찰을 하는 소프트웨어고, 행동은 광고 거래( Ad Exchange ) 시스템과 사용자를 관찰하여 입찰을 하는 것입니다. 보상은 광 고 클릭, 회원 가입 등이 될 수 있습니다.

554 2부 신경망과 딥러닝


이런 로봇을 어떻게 훈련시킬 수 있을까요? 여기에는 변경이 가능한 두 개의 정책 파라미터 policy parameter

가 있습니다. 확률 p 와 각도의 범위 r 입니다. 생각해볼 수 있는 학습 알고리즘은

이 파라미터에 많은 다른 값을 시도해보고, 가장 성능이 좋은 조합을 고르는 것입니다(그림

16-3 ). 이것은 정책 탐색 policy search 의 한 예인데 여기에서는 무식한 방법을 사용했습니다. 하 지만 정책 공간 policy space 이 매우 크면(일반적인 경우입니다), 이런 식으로 좋은 파라미터 조합 을 찾는 것은 모래사장에서 바늘을 찾는 격입니다. 정책 공간을 탐색하는 다른 방법으로 유전 알고리즘 genetic algorithm 이 있습니다. 예를 들어 1세대

100개의 정책을 랜덤하게 생성해서 시도해본 다음, 성능이 낮은 80개의 정책은 버리고 9 20개 를 살려 각각 4개의 자식 정책을 생산하도록 합니다. 이 자식 정책은 단순히 부모를 복사한 것 10 에 약간의 무작위성을 더한 것입니다. 살아남은 정책과 그 자식은 2세대를 구성합니다. 이런 식 으로 좋은 정책을 찾을 때까지 여러 세대에 걸쳐 반복합니다. 그림 16-3 정책 공간에서 4개의 지점과 이에 상응하는 에이전트의 행동 11 정책 공간

결과 행동

9 유전자풀(gene pool )에 다양성을 보존하기 위해 낮은 성능의 정책도 조금 살아남을 여지를 주는 것이 더 나을 때가 많습니다. 10 하나의 부모만 있는 경우를 무성 생식이라고 합니다. 두 개(혹은 그 이상)의 부모가 있는 경우를 유성 생식이라고 합니다. 자식의 게놈 (genome, 여기서는 일련의 정책 파라미터)은 부모의 게놈 일부분을 사용하여 랜덤하게 구성됩니다. 11 옮긴이_ a 정책은 직진할 가능성이 낮고 최대 회전각은 크므로 주변을 많이 맴도는 궤적을 만듭니다. b 정책은 직진성과 회전성이 모두 좋은 궤적을 보여줍니다. c 정책은 a처럼 직진할 가능성은 낮지만 최대 회전각도 작아서 비교적 부드러운 궤적을 만듭니다. d 정책은 회 전은 거의 없고 거의 직진만 하는 궤적을 그립니다.

16장 강화 학습 555


또 다른 방법은 정책 파라미터에 대한 보상의 그래디언트를 평가해서 높은 보상의 방향을 따르 는 그래디언트로(즉, 경사 상승법으로) 파라미터를 수정하는 최적화 기법을 사용하는 것입니 다. 이 방법을 정책 그래디언트 policy gradient (PG )라고 하며, 잠시 후 자세히 다룰 것입니다. 로 봇 진공청소기를 다시 생각해보면, p 를 조금 증가시키고 30분 동안 로봇이 수집한 먼지의 양 이 증가했는지 평가해볼 수 있습니다. 만약 그렇다면 p 를 조금 증가시키고 그렇지 않으면 p 를 감소시킵니다. 여기에서는 널리 알려진 PG 알고리즘을 텐서플로를 사용해 구현하겠습니다. 하지만 그전에 에이전트가 활동할 환경을 만들어야 합니다. 이제 OpenAI 짐 gym 을 소개할 시 간입니다.

16.3 OpenAI 짐 강화 학습의 도전과제 중 하나는 에이전트를 훈련시키기 위해 먼저 작업 환경을 마련해야 한 다는 것입니다. 아타리 게임 플레이를 학습할 에이전트를 프로그래밍하려면 아타리 게임 시뮬 레이터가 필요할 것입니다. 만약 보행 로봇을 프로그래밍한다면 실제 세상이 환경이므로 로봇 을 실제 세상에서 바로 훈련시킬 수 있습니다. 하지만 여기에는 제약사항이 따릅니다. 만약 로봇 이 절벽에서 떨어지면 이를 되돌릴 방법이 없습니다. 또한 훈련 속도도 높일 수 없습니다. 즉, 컴 퓨터의 성능을 높인다고 해도 로봇을 더 빠르게 움직이게 만들 수는 없습니다. 그렇다고 동시에

1,000대의 로봇을 훈련시키는 것은 너무 많은 비용이 듭니다. 간단히 말해 실제 세상에서 훈련 시키는 것은 어렵고 느립니다. 그래서 훈련을 위한 최소한의 시뮬레이션 환경이 필요합니다.

OpenAI 짐(https://gym.openai.com )12은 다양한 종류의 시뮬레이션 환경(아타리 게임, 보 드 게임, 2D와 3D 물리 시뮬레이션 등)을 제공하는 툴킷입니다. 이를 사용하여 에이전트를 훈련시키고 이들을 비교하거나 새로운 RL 알고리즘을 개발할 수 있습니다.

12 옮긴이_ OpenAI는 엘론 머스크(Elon Musk )가 투자한 비영리 인공지능 연구 회사입니다. 이 회사의 목적은 인류에게 도움 되는 AI 를 개발하고 모두가 그 혜택을 누릴 수 있도록 하는 것입니다.

556 2부 신경망과 딥러닝


INDEX 기 호

binary classifier 126

ε -그리디 정책 578

black box model 229

χ2 검정 234

blender 263 BN 360

A accuracy 34, 129 action 552 activation function 337 active constraint 634

Boltzmann machine 647 boosting 253 bottleneck layer 471

C

AdaBoost 253

CAE 547

AdaGrad 380

CART 비용 함수 230, 236

Adam 최적화 383

CART 알고리즘 230

adaptive learning rate 381

classification 39

adaptive moment estimation 383

Classification And Regression Tree algorithm 230

agent 552 AlexNet 468

cluster specification 415

ANN 327

CNN 451

annealing 169

CNN 구조 465

anomaly detection 43

coding 521

Approximate Q - Learning 579

coding space 542

area under the curve 138

complementary slackness condition 634

artificial neural networks 327

component 71

artificial neuron 331

computation graph 295

association rule learning 43

computational complexity 160

attribute 39

confusion matrix 129

AUC 138

contractive autoencoder 547

autoencoder 521

convex function 163

average pooling layer 465

convolution kernel 456 convolutional layer 454

B backpropagation 337 bagging 245 Batch Gradient Descent 166 batch learning 46 Batch Normalization 360 Bellman Optimality Equation 572 between - graph replication 440

convolutional neural network 451 cost function 52 critical point 633 cross-validation 63 CUDA 403 cuDNN 403

D

bias 156

data augmentation 395

bias neuron 333

data mining 37

찾아보기

655


INDEX data parallelism 444

exploring 561

data snooping bias 85

Extra -Trees 251

DBN 44, 650

Extremely Randomized Trees 251

decision function 133 Decision Tree 225 decoder 485, 523

F fan - in 355

deep autoencoder 526

fan - out 356

deep belief network 44, 650

feature 39

deep neural network 336

feature engineering 58

Deep Q - Learning 579

feature extraction 42, 59

Deep Q - Network 579

feature map 457

deep RNN 443, 504

feature scaling 107

degree of freedom 60

feature selection 59

depth concat layer 470

feature space 285

dimensionality reduction 42

feed forward neural network 339

distributed session 420

FIFO 423

DNN 336

filter 456

DQN 579

first - in first - out 423

dropconnect 393

fitness function 52

dropout 390

FNN 339

dual problem 218

fold 113

duality 633

forget gate 510

dying ReLU 357

forward - mode autodiff 641

dynamic placer 408

frame 482 F1 점수 132

E early stopping 186

G

Elastic Net 185

GAN 547

ELU 활성화 함수 359

gate controller 511

encoder 485, 523

Gated Recurrent Unit 512

Ensemble Learning 241

GBRT 258

environment 552

GD 161

epoch 170

generalization error 62

equality constraint 633

generative adversarial network 547

estimator 101

generative autoencoder 542

Euclidian norm 74

generative model 521

event file 313

generative network 523

exploiting 561

generative stochastic network 547

exploration policy 576

genetic algorithm 555

656 찾아보기


global average pooling 473

instance - based learning 49

global minimum 163

inter - op 스레드 풀 412

Glorot initialization 456

intercept 156

GoogLeNet 470

intra - op 스레드 풀 412

GPU RAM 관리 405

IPCA 283

Gradient Boosted Regression Tree 258

irreducible error 179

Gradient Boosting 253, 258

Isomap 291

Gradient Clipping 366 Gradient Descent 161 Gradient Tree Boosting 258

K K - fold cross - validation 113

GRU 512

k - Nearest Neighbors regression 54

GRU 셀 512

K -겹 교차 검증 113

GSN 547

k -최근접 이웃 회귀 54 keep probability 391

H

kernel PCA 285

hard margin classification 202

kernel trick 207

hard voting 242

KKT 조건 634

He initialization 356

KL 발산 540

He 초기화 356

kPCA 285

Heaviside step function 332

Kullback - Leibler divergence 539

Hebb’s rule 333 hidden layer 336 hierarchical clustering 42

L

1과 2 규제 388

hinge loss 223

label 39

Hopfield network 645

Lagrange multiplier method 633

hyperparameter 61

Lagrange function 633

hypothesis 73

Lagrangian 633

hypothesis boosting 253

large margin classification 202 Lasso 183

I

latent loss 543

impurity 228

latent space 542

in - graph replication 439

law of large numbers 243

inception module 470

LDA 291

incremental learning 48

LeakyReLU 358

Incremental PCA 283

learning rate 48

inequality constraint 634

learning schedule 169

inference 54

Least Absolute Shrinkage and Selection Operator

input gate 510 input neuron 333

183 LeNet - 5 467

찾아보기

657


INDEX Linear Discriminant Analysis 291

model selection 51

linear model 51

model zoo 374

LLE 289

model - based learning 50

local minimum 163

momentum 377

local response normalization 469

Momentum optimization 377

local session 420

momentum vector 377

localization 466

MSE 157

Locally Linear Embedding 289

Multi - Layer Perceptron 328, 335

location invariance 463

multiclass classifier 141

Logistic Regression 188

Multidimensional Scaling 291

Logit Regression 188

multilabel classification 149

long short - term memory 509

multinomial classifier 141

LRN 469

Multinomial Logistic Regression 194

LSTM 509

multioutput classification 150

LSTM 셀 509

multioutput - multiclass classification 150 multivariate regression 72

M Manhattan norm 74

N

Manifold Learning 275

NAG 378

MapReduce 72

name scope 316

margin violation 203

Nesterov Accelerated Gradient 378

Markov chain 570

Nesterov Momentum optimization 378

master service 417

NFL 64

max pooling layer 463

NLDR 289

max - norm regularization 393

No Free Lunch 64

MDS 291

nonlinear dimensionality reduction 289

Mean Absolute Error 74

nonparametric model 233

mean coding 542

nonresponse bias 58

Mean Square Error 157

norm 74

memory cell 484

Normal Equation 158

Mercer’s condition 221

normalization 107

Mercer’s theorem 221

normalized exponential 194

meta learner 263

null hypothesis 234

min - max 스케일링 107 mini - batch 47

O

Mini - batch Gradient Descent 171

object detection 466

MLP 328, 335

observation 552

MNIST 123

OCR 33

model parallelism 442

offline learning 46

658 찾아보기


one - hot encoding 103

predictor 39, 101

online DQN 580

preloading 429

online learning 47

primal problem 218

oob 평가 248

Principal Component Analysis 276

OpenAI 짐 556

probabilistic autoencoder 542

operation 303

projection 272

ops 303

pruning 234

Optical Character Recognition 33 optimizer 305 out - of - core learning 48

Q Q - Learning algorithm 576

out - of - sample error 62

Q - Value 573

output gate 510

Q - Value Iteration algorithm 574

output layer 336

Q -가치 573

overfitting 59

Q -가치 반복 574 Q -가치 반복 알고리즘 574

P

Q -러닝 알고리즘 576

p -값 234

QP 217

parameter server 414

Quadratic Programming 217

parameter space 165

quantizing 448

parametric model 233 partial derivative 165

R

pasting 245

Radial Basis Function 208

PCA 276, 524

Random Forest 241

peephole connection 512

random initialization 161

penalty 45

Random Patches method 250

Perceptron 332

Random Subspaces method 250

Perceptron convergence theorem 334

Randomized PCA 284

PG 556

RBF 208

pipeline 71

RBM 374, 649

placeholder 308

reader operation 430

policy 45, 554

recall 131

policy gradient 556

receiver operating characteristic 137

policy parameter 555

recognition network 523

policy space 555

reconstruction 523

Polynomial Regression 173

reconstruction error 282

pooling kernel 463

rectified linear unit 317

pooling layer 463

recurrent neural networks 481

pre - image 288

recurrent neuron 482

precision 130

regression 39

찾아보기

659


INDEX regularization 60

Singular Value Decomposition 278

Reinforcement Learning 45, 551

skip connection 396, 473

ReLU 317

slack variable 216

ReLU 함수 338

soft margin classification 203

residual learning 473

soft voting 245

Residual Network 473

softmax function 194

residual unit 474

Softmax Regression 194

resource container 420

SOM 652

Restricted Boltzmann Machine 374

source ops 303

reverse-mode autodiff 307, 643

spam filter 33

reward 45, 552

sparse features 211

RL 551

sparse matrix 104

RMSE 72, 157

sparsity loss 539

RMSProp 382

specificity 137

RNN 481

speech recognition 37

RNN 훈련 493

stacked autoencoder 526

ROC 곡선 137

stacked convolutional autoencoders 547

Root Mean Square Error 72, 157

stacking 263

RU 474

standard correlation coefficient 94 state value 572

S

state - action value 573

saddle point 633

stationary point 633

sampling bias 57

statistical mode 246

sampling noise 57

step function 332

segmentation 466

Stochastic Gradient Boosting 262

self-organizing map 652

Stochastic Gradient Descent 126

semisupervised learning 44

stochastic policy 554

sensitivity 131

strata 88

Seq2Seq 514

stratified sampling 88

sequence - to - sequence 485

stride 455

sequence - to - vector 485

strong learner 243

SGD 126

subgradient vector 185

shortcut connection 473

subsample 463

shrinkage 260

summary 313

sigmoid function 188

supervised learning 39

signal 70

support vector 202

similarity 49

Support Vector Machine 201

similarity function 208

SVD 278

simple placer 408

SVM 201

660 찾아보기


SVM 회귀 212

variational autoencoder 542 vector - to - sequence 485 visualization 42

T t - Distributed Stochastic Neighbor Embedding 291

W

t - SNE 291

weak learner 243

target DQN 580

white box model 229

TD 학습 576

winner - take - all autoencoder 547

Temporal Difference Learning 576

Word2Vec 514

tensor 303

worker service 417

TensorBoard 297

WTA 오토인코더 547

TensorFlow 295 TensorFlow Serving 439 TF - slim 297

X Xavier initialization 356

TF.Learn 297 time series 481 time step 482

Z zero padding 455

TPR 131 training 52 training data 34 training instance 34 training set 34 training set expansion 152 transfer learning 366 transformer 101 true positive rate 131

U undercomplete 523 underfitting 61 univariate regression 72 unsupervised learning 40 unsupervised pretraining 374 utility function 52

ㄱ 가설 73 가설 부스팅 253 가우시안 RBF 커널 209 가정 검사 74 가중치 묶기 528 가지치기 234 가치 반복 알고리즘 573 간접 배치 411 간접 투표 245 강한 학습기 243 강화 학습 45, 551 검증 세트 63 게이트 순환 유닛 셀 512 게이트 제어기 511 결정 경계 191 결정 임곗값 133

V

결정 트리 225

validation set 63

결정 함수 133, 214

Value Iteration algorithm 573

경사 하강법 161

variance 179

경사 하강법 구현 305

찾아보기

661


INDEX 계단 함수 332

노름 74

계산 그래프 295

뉴런 329

계산 복잡도 160, 211, 231 계층 88

계층 군집 42

다변량 회귀 72

계층적 샘플링 88

다중 레이블 분류 149

고수준 API 339

다중 분류 141

곡선 아래의 면적 138

다중 분류기 141

공개 데이터 저장소 68

다중 출력 다중 클래스 분류 150

공짜 점심 없음 64

다중 출력 분류 150

과대적합 59, 387

다차원 스케일링 291

과소완전 523

다층 퍼셉트론 328, 335

과소완전 선형 오토인코더 524

다항 로지스틱 회귀 194

과소적합 61

다항 분류기 141

관측 552

다항 회귀 173

광학 문자 판독기 33

다항식 커널 207, 220

교차 검증 63, 113, 128

단변량 회귀 72

군집 알고리즘 41

단순 배치 408

귀무가설 234

단순 배치자 408

규제 60, 179, 387

담금질 169

규제 매개변수 233

대역폭 포화 446

그래디언트 부스티드 회귀 트리 258

데이터 마이닝 37

그래디언트 부스팅 253, 258

데이터 병렬화 444

그래디언트 소실 354

데이터 스누핑 편향 85

그래디언트 자동 계산 307

데이터 정제 99

그래디언트 클리핑 366

데이터 증식 152, 395

그래디언트 트리 부스팅 258

동기 업데이트 444

그래디언트 폭주 354

동적 배치 함수 410

그래프 간 복제 440

동적 배치자 408

그래프 내 복제 439

드롭아웃 390, 506

그리드 탐색 116

드롭커넥트 393

근사 Q -러닝 579

등식 제약 633

글로럿 초기화 356

디코더 485, 523

기호 미분 638

딥러닝 라이브러리 298

깊이 연결 층 470

ㄹ ㄴ

라그랑주 승수법 633

네스테로프 가속 경사 378

라그랑주 함수 633

네스테로프 모멘텀 최적화 378

라쏘 회귀 183

662 찾아보기


라지 마진 분류 202

모델 해석 229

랜덤 PCA 284

모듈화 317

랜덤 서브스페이스 방식 250

모멘텀 377

랜덤 탐색 118

모멘텀 벡터 377

랜덤 패치 방식 250

모멘텀 최적화 377

랜덤 포레스트 241, 250

목적 함수 215

레이블 39, 72

무작위 초기화 161

로지스틱 함수 189

문제 정의 70

로지스틱 회귀 188

물체 감지 466

로짓 회귀 188

미니배치 47, 171

로컬 세션 420

미니배치 경사 하강법 171

론칭 121

민감도 131

리더 연산 430 리소스 컨테이너 420

릿지 회귀 180

방사 기저 함수 208 배깅 245

배치 경사 하강법 165, 166

마르코프 연쇄 570

배치 로깅 409

마스터 서비스 417

배치 정규화 360

마진 오류 203

배치 학습 46

매니폴드 학습 275

벌점 45

맥스-노름 규제 393

벡터-투-시퀀스 485

맨해튼 노름 74

벨만 최적 방정식 572

맵리듀스 72

변수 공유 320

머서의 정리 221

변이형 오토인코더 542

머서의 조건 221

변환 파이프라인 108

머신러닝 34

변환기 101

멀티스레드 리더 433

병렬 실행 411

메모리 셀 484

병목층 471

메타 학습기 263

보상 45, 552

모니터링 121

보존 확률 391

모델 기반 학습 50

복원 310

모델 병렬화 442

볼록 함수 163

모델 선택 51, 110

볼츠만 머신 647

모델 세부 튜닝 115

부등식 제약 634

모델 재사용 367, 370

부스팅 253

모델 저장 310

부표본 463

모델 저장소 374

분류 39

모델 파라미터 51

분류 시스템 123

찾아보기

663


INDEX 분산 179

선형 모델 51

분산 세션 420

선형 판별 분석 291

분산 텐서플로 401

선형 회귀 156

불순도 228

성능 측정 127

브로드캐스팅 343

성능 측정 지표 선택 72

블랙박스 모델 229

세션 열기 416

블렌더 263

세이비어 초기화 356

비동기 업데이트 445

소스 연산 303

비선형 SVM 분류 205

소프트 마진 분류 203

비선형 차원 축소 289

소프트맥스 함수 194

비용 함수 52, 157, 164, 180, 183, 186, 189, 195,

소프트맥스 회귀 194

222, 230, 236

속성 39

비응답 편향 58

숏컷 연결 473

비지도 사전훈련 374, 535

수동 미분 637

비지도 학습 40

수렴율 168

비파라미터 모델 233

수신기 조작 특성 곡선 137 수축 오토인코더 547

수치 미분 639

사례 기반 학습 49

순환 뉴런 482

사이킷런 101, 280

순환 신경망 481

사전훈련 374, 375

스킵 연결 473

삭제 게이트 510

스킵 커넥션 396

상관관계 조사 94

스태킹 263

상보적 여유성 조건 634

스트라이드 455

상태 가치 572

스팸 필터 33

상태 공유 420

슬랙 변수 216

상태-행동 가치 573

시각 피질 452

샘플 34

시각화 42, 90, 312

샘플링 잡음 57

시간차 학습 576

샘플링 편향 57

시계열 데이터 481

생성 네트워크 523

시그모이드 함수 188

생성 모델 521

시스템 유지 보수 121

생성 오토인코더 542

시스템 평가 120

서머리 313

시퀀스-투-벡터 485

서브그래디언트 벡터 185

시퀀스-투-시퀀스 485

서포트 벡터 202

신경망 병렬화 437

서포트 벡터 머신 201

신경망 정책 560

선입선출 423

신호 70

선형 SVM 분류 201

심층 Q -네트워크 579

664 찾아보기


심층 Q -러닝 579

온라인 학습 47

심층 RNN 504

옵티마이저 305, 308, 376

심층 RNN 분산 505

외부 메모리 학습 48

심층 순환 신경망 443

외부 샘플 오류 62

심층 신경망 336, 353

워드 임베딩 514

심층 신뢰 신경망 44, 650

워커 서비스 417

심층 오토인코더 526

원 문제 218

쌍곡 탄젠트 함수 338

원-핫 인코딩 103

쌍대 문제 218

위치 불변성 463

쌍대성 633

위치 추정 466 유사도 49

유사도 함수 208

아다부스트 253

유전 알고리즘 555

안장점 633

유클리디안 노름 74

앙상블 119

은닉층 336

앙상블 학습 114, 241

음성 인식 37

약한 학습기 243

이름 범위 316

양자화 448

이미지 분할 466

어널링 169

이벤트 파일 313

에러 분석 144

이상치 탐지 43

에이전트 552

이진 분류기 126

에포크 170

익스트림 랜덤 트리 251

엑스트라 트리 251

인공 뉴런 331

엔트로피 232

인공 신경망 327

엘라스틱넷 185

인셉션 모듈 470

역전파 337

인지 네트워크 523

연관 규칙 학습 43

인코더 485, 523

연산 303, 410

인코더-디코더 네트워크 516

연산 배치하기 408

일반화 49

연산 할당 418

일반화 오류 62

예측 50, 214

일반화된 라그랑주 함수 634

예측 변수 39

임계점 633

예측기 101

임베딩 515

오차 분석 119

입력 게이트 510

오차 행렬 129

입력 뉴런 333

오토인코더 521 오프라인 학습 46

온라인 DQN 580

자기 조직화 지도 652

온라인 SVM 222

자동 미분 306, 641, 643

찾아보기

665


INDEX 자연어 처리 514

정책 파라미터 555

자유도 60

정확도 34, 129

잔차 네트워크 473

제로 패딩 455

잔차 유닛 474

제어 의존성 413

잔차 학습 473

제한된 볼츠만 머신 44, 374, 649

잠재 변수 공간 542

조기 종료 186, 388

잠재 변수 손실 543

주성분 분석 276, 524

잡음제거 오토인코더 536

죽은 ReLU 357

장단기 메모리 셀 509

준지도 학습 44

재구성 523

줄일 수 없는 오차 179

재구성 손실 523

지니 불순도 232

재구성 시각화 532

지도 학습 39

재구성 오차 282

지리적 데이터 시각화 91

재구성 원상 288

지역 선형 임베딩 289

재현율 131

지역 최솟값 163

저수준 API 341

직접 투표 242

적대적 생성 네트워크 547

진짜 양성 비율 131

적응적 모멘트 추정 383 적응적 학습률 381

적층 오토인코더 526, 535

차원 축소 42, 272

적층 합성곱 오토인코더 547

차원의 저주 270

적합도 함수 52

초기화 매개변수 356

전역 최솟값 163

최대 풀링층 463

전역 평균 풀링 473

추론 54

전이 학습 366

추정기 101

전진 모드 자동 미분 641

축소 260

절편 156

출력 게이트 510

점진적 PCA 283

출력층 336

점진적 학습 48 정규방정식 158 정규화 107 정규화된 지수 함수 194 정류점 633 정밀도 130 정밀도/재현율 트레이드오프 133 정책 45, 554 정책 공간 555 정책 그래디언트 556, 564 정책 탐색 554

666 찾아보기

ㅋ 커널 220, 410 커널 PCA 285 커널 SVM 219 커널 선택 286 커널 트릭 207 컴포넌트 71 코딩 521 코딩 공간 542 콰드라틱 프로그래밍 문제 217


쿨백 라이블러 발산 539 큐 종료 426 크로스 엔트로피 195 큰 수의 법칙 243 클래스 확률 추정 229 클러스터 명세 415

ㅍ 파라미터 공간 165 파라미터 모델 233 파라미터 서버 414 파이프라인 71 팬아웃 356 팬인 355

퍼셉트론 332

타깃 DQN 580

퍼셉트론 수렴 이론 334

타깃 Q -가치 579

페이스팅 245

타임 스텝 482

편도함수 165

탐색 90

편향 156, 179

탐험 561

편향 뉴런 333

탐험 정책 576, 578

편향/분산 트레이드오프 179

테스트 세트 62

평균 절대 오차 73

텐서 303

평균 제곱 오차 157

텐서보드 297, 312

평균 제곱근 오차 72, 157

텐서플로 295

평균 코딩 542

텐서플로 서빙 439

평균 풀링층 465

텐서플로 큐 422

폴드 113

텐서플로 클러스터 415

표준 상관계수 94

텐서플로 합성곱 연산 477

표준화 107

통계적 최빈값 246

풀링 커널 463

투영 272, 279

풀링층 463

투표 기반 분류기 242

프레임 482

튜플 큐 425

프리로딩 429

특성 39

플레이스홀더 308

특성 공간 58, 285

피드포워드 신경망 339

특성 맵 456

필터 456

특성 벡터 157

핍홀 연결 512

특성 선택 59 특성 스케일링 107 특성 시각화 533 특성 중요도 252 특성 추출 42, 59 특이도 137 특잇값 분해 278 티호노프 규제 180

ㅎ 하드 마진 분류 202 하이퍼볼릭 탄젠트 함수 338 하이퍼파라미터 61 하이퍼파라미터 튜닝 286, 348 학습 곡선 175 학습 스케줄 169 학습률 48, 162

찾아보기

667


INDEX 학습률 스케줄링 385

활성화 함수 337

합성곱 신경망 451, 453

활용 561

합성곱 층 454

회귀 39, 234

합성곱 커널 456

효용 함수 52

행동 552

후진 모드 자동 미분 307, 643

행동 평가 563

훈련 52, 110

헤브의 규칙 333

훈련 데이터 34

헤비사이드 계단 함수 332

훈련 사례 34

홉필드 네트워크 645

훈련 세트 34, 62

화이트박스 모델 229

훈련 세트 확장 152

확률적 경사 하강법 126, 168

희소 모델 훈련 384

확률적 그래디언트 부스팅 262

희소 손실 539

확률적 생성 네트워크 547

희소 오토인코더 539

확률적 오토인코더 542

희소 특성 211

확률적 정책 554

희소 행렬 104

환경 552

힌지 손실 223

활성 제약 634

668 찾아보기


사 이 킷 런 A P

I

metrics.accuracy_score 244, 249, 340

BaggingClassifier 251

metrics.confusion_matrix 130

base.BaseEstimator 106, 129

metrics.f1_score 132

base.clone 128, 187

metrics.mean_squared_error 111, 176, 261,

base.TransformerMixin 106

288 metrics.precision_recall_curve 135

datasets.fetch_california_housing 304

metrics.precision_score 132

datasets.fetch_mldata 124

metrics.recall_score 132

datasets.load_iris 226, 252, 335

metrics.roc_auc_score 139

datasets.load_sample_images 460

metrics.roc_curve 137

datasets.make_moons 206

model_selection.cross_val_predict 130

decomposition.IncrementalPCA 284

model_selection.cross_val_score 113, 128

decomposition.KernelPCA 285

model_selection.GridSearchCV 116, 286

decomposition.PCA 280

model_selection.StratifiedKFold 128 model_selection.StratifiedShuffleSplit 89

ensemble.AdaBoostClassifier 257 ensemble.BaggingClassifier 247 ensemble.GradientBoostingRegressor 259

model_selection.train_test_split 87, 176,

261 multiclass.OneVsOneClassifier 143

ensemble.RandomForestClassifier 139, 244,

250

neighbors.KNeighborsClassifier 149

ensemble.RandomForestRegressor 114

neighbors.KNeighborsRegressor 54

ensemble.VotingClassifier 244

neural_networks.MLPClassifier 379

externals.joblib 115

neural_networks.MLPRegressor 379

ExtraTreesClassifier 251 ExtraTreesRegressor 251

pipeline.FeatureUnion 110 pipeline.Pipeline 108, 178. 204. 206, 286

feature_selection.chi2 234

preprocessing.CategoricalEncoder 104 preprocessing.Imputer 100

linear_model.ElasticNet 186

preprocessing.OneHotEncoder 103

linear_model.Lasso 185

preprocessing.PolynomialFeatures 174, 206

linear_model.LinearRegression 53, 111, 160

preprocessing.StandardScaler 108, 144, 204

linear_model.LogisticRegression 192, 244,

286 linear_model.Perceptron 335

svm.LinearSVC 204, 213 svm.SVC 207, 213, 244,

linear_model.Ridge 182 linear_model.SGDClassifier 127

tree.DecisionTreeClassifier 226, 247

linear_model.SGDRegressor 171

tree.DecisionTreeRegressor 112, 234, 258 tree.export_graphviz 22

manifold.LocallyLinearEmbedding 289

찾아보기

669


INDEX 텐 서 플 로 A P

I

errors.OutOfRangeError 432

abs 389 add 318

FIFOQueue 423, 425

add_n 318 add_to_collection 368

get_collection 365, 368

assign 306, 393

get_default_graph 301, 368 get_default_session 300

cast 345

get_variable 321, 389

clip_by_norm 393

global_variables_initializer 300

clip_by_value 366

glorot_uniform_initializer 343

ConfigProto 406, 441

gradients 307

constant 302

Graph 302

constant_initializer 321

GraphKeys.GLOBAL_VARIABLES 369

container 421

GraphKeys.TRAINABLE_VARIABLES 371

contrib.layers.fully_connected 343

GraphKeys.UPDATE_OPS 365

contrib.layers.l1_regularizer 389

group 585

contrib.layers.l2_regularizer 527 contrib.layers.variance_scaling_initializer

InteractiveSession 301

357, 527 contrib.learn.DNNClassifier 340

layer.dense 357

contrib.learn.infer_real_valued_columns_from_

layers.average_pooling2d 465

input 340

layers.conv1d 477

contrib.learn.SKCompat 340

layers.conv2d 461

contrib.legacy_seq2seq 519

layers.conv2d_transpose 477

contrib.rnn.BasicLSTMCell 509

layers.conv3d 477

contrib.rnn.BasicRNNCell 488, 502, 505, 507

layers.dense 343, 360, 389

contrib.rnn.DeviceWrapper 505

layers.max_pooling2d 465

contrib.rnn.GRUCell 514

layers.separable_conv2d 478

contrib.rnn.LSTMCell 512

log 540

contrib.rnn.MultiRNNCell 504 contrib.rnn.OutputProjectionWrapper 499

matmul 304

contrib.rnn.static_rnn 488

matrix_inverse 304

contrib.seq2seq 519

maximum 318

control_dependencies 414 convert_to_tensor 538

name_scope 316 nn.atrous_conv2d 477

decode_csv 431

nn.batch_normalization 363

device 409, 505

nn.conv2d 460 nn.convolution 477

errors.DeadlineExceededError 441

670 찾아보기

nn.depthwise_conv2d 478


nn.dropout 392

sigmoid 545

nn.dynamic_rnn 491, 502, 504

split 465

nn.elu 360, 363

square 306, 316

nn.embedding_lookup 516

stack 431

nn.in_top_k 345

stop_gradient 372

nn.leaky_relu 360

subtract 305

nn.local_response_normalization 469

summary.FileWriter 313

nn.max_pool 464

summary.scalar 313

nn.relu 317, 343 nn.sigmoid 541

tanh 487

nn.sigmoid_cross_entropy_with_logits 541

Tensor 300

nn.sparse_softmax_cross_entropy_with_logits

TextLineReader 430, 435

344, 389 nn.swish 360

to_float 565 train.AdamOptimizer 384, 499, 524 train.Coordinator 434

one_hot 585

train.exponential_decay 387

Operation 300

train.GradientDescentOptimizer 308, 344, 366 train.import_meta_graph 311, 368

PaddingFIFOQueue 429

train.MomentumOptimizer 308, 378, 586

placeholder 309

train.Optimizer 305

placeholder_with_default 363, 507

train.QueueRunner 434 train.replica_device_setter 419

RandomShuffleQueue 427, 431

train.RMSPropOptimizer 382

random_normal 318

train.Saver 310

random_uniform 305

train.start_queue_runner 437

reduce_max 465

transpose 304, 489

reduce_mean 306

truncated_normal 342

reduce_sum 389 reset_default_graph 302

unstack 489

reshape 503 RunOptions 441

Variable 299 variable_scope 321

Session 300, 416 Session.reset 421

zeros 342

shape 538

zeros_initializer 34

찾아보기

671


아마존 인공지능 분야 부동의 1위 도서

사이킷런과 텐서플로를 활용한 머신러닝, 딥러닝 실무

H a n d s- O n M a ch in e Le a r n in g w i t h S cik i t- Le a r n a n d Te n s o r Fl ow

래머도 데이터로부터 학습하는 프로그램을 어렵지 않게 작성할 수 있다. 이 책은 그 지름길이다. 구체적인 예, 핵심 이론, 검증된 두 프레임워크(사이킷런, 텐서플로)를 이용해 지능형 시스템을 구축하는 개념과 방법을 확 실하게 알려준다. 또한, 각 장의 연습문제는 익힌 것을 실전에 응용하는 데 큰 도움이 될 것이다.

핸즈온 머신러닝

1부. 사이킷런을 활용한 머신러닝 실무

2부. 텐서플로를 활용한 딥러닝 실무

•한눈에 보는 머신러닝

•텐서플로 시작하기

•머신러닝 프로젝트 처음부터 끝까지

•인공 신경망 소개

•분류

•심층 신경망 훈련

•모델 훈련

•다중 머신과 장치를 위한 분산 텐서플로

•서포트 벡터 머신(SVM)

•합성곱 신경망(CNN)

•결정 트리

•순환 신경망(RNN)

•앙상블 학습과 랜덤 포레스트

•오토인코더(autoencoder)

•차원 축소

•강화 학습

Hands-On Machine Learning with Scikit-Learn & TensorFlow

최근의 눈부신 혁신들로 딥러닝은 머신러닝 분야 전체를 뒤흔들고 있다. 이제 이 기술을 거의 모르는 프로그

Hands-On Machine Learning with Scikit-Learn & TensorFlow 핸즈온 머신러닝

신경망으로 문제를 해결하는 이론과 실전을 멋지게 소개한 책이다. 효율적인 애플리케이션을 구축하 는 핵심을 잘 짚어냈고, 하루가 다르게 쏟아지는 새로운 관련 연구를 이해할 수 있는 기초를 확실히 닦아준다. 실용적인 머신러닝을 공부하려는 모든 이에게 이 책을 추천한다. 피트 워든, 텐서플로 모바일 리드

박해선 옮김

파이썬 라이브러리를 활용한 머신러닝

골빈해커의 3분 딥러닝, 텐서플로맛

오렐리앙 제롱 지음

관련 도서

처음 배우는 딥러닝 수학 머신러닝 / 딥러닝

93000

예제 소스 https://github.com/rickiepark/handson-ml

9 791162 240731

ISBN 979-11-6224-073-1

정가 33,000원

오렐리앙 제롱 지음 박해선 옮김


Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.