표지 동물은 송골매다. 이 매는 세상에서 가장 흔한 맹금류 중 하나로 남극을 제외한 모든 대륙에 서식한다.
또한, 도시, 열대 지역, 사막, 툰드라 등 다양한 환경에서 생존할 수 있다. 일부는 겨울과 여름 서식지 간
의 머나먼 여행을 한다.
송골매는 세상에서 가장 빨리 나는 새로, 시속 약 320km로 급강하할 수 있다. 참새나 오리와
같은 다른 새와 박쥐를 먹이로 하는데, 공중에서도 먹이를 낚아챌 수 있다.
다 자란 송골매의 날개는 푸른 잿빛을, 등은 어두운 갈색을 띠며, 담황색 배에는 갈색
점이, 하얀 얼굴에는 검은색 눈물점이 있다. 그리고 갈고리 모양의 부리와 강
한 발톱도 있다. 송골매의 영어 이름인 peregrine falcon은 라틴어의
peregrinus에서 온 말인데, 그 뜻은 방랑자다. 송골매는 매조련사들
의 사랑을 받아왔으며, 여러 세기에 걸쳐 사냥에 동원되었다.
오라일리 책의 표지에 등장하는 동물 중 상당수는 멸종 위기에 처해 있다. 이들 모두가 우리 세상에 소중한 존재다. 이 동
물들을 돕고 싶다면 animals.oreilly.com으로 가보자.
표지 그림은 라이데커의 『Royal Natural History』에서 가져왔다.
9가지 사례로 익히는 고급 스파크 분석(2판)
현실 세계 빅데이터로 배우는 데이터 과학과 머신러닝
초판 1쇄 발행 2016년 7월 1일
2판   1쇄 발행 2018년 3월 5일
지은이 샌디 라이자, 유리 레이저슨, 션 오언, 조시 윌스 / 옮긴이 박상은, 권한철, 서양주 / 펴낸이 김태헌
펴낸곳 한빛미디어 (주) / 주소 서울시 서대문구 연희로2길 62 한빛미디어(주) IT출판부
전화 02 – 325 – 5544 / 팩스 02 – 336 – 7124
등록 1999년 6월 24일 제10 – 1779호 / ISBN 979 – 11 – 6224 – 052 – 6 93000
총괄 전태호 / 책임편집 김창수 / 기획·편집 이복연
디자인 표지 박정화, 내지 김연정, 조판 백지선
영업 김형진, 김진불, 조유미 / 마케팅 박상용, 송경석, 변지영 / 제작 박성우, 김정우
이 책에 대한 의견이나 오탈자 및 잘못된 내용에 대한 수정 정보는 한빛미디어(주)의 홈페이지나 아래 이메일로
알려주십시오. 잘못된 책은 구입하신 서점에서 교환해 드립니다. 책값은 뒤표지에 표시되어 있습니다.
한빛미디어 홈페이지 www.hanbit.co.kr / 이메일 ask@hanbit.co.kr
© 2018 Hanbit Media Inc.
Authorized Korean translation of the English edition of Advanced Analytics with Spark 2E ISBN
9781491972953 © 2017 Sanford Ryza, Uri Laserson, Sean Owen, and Joshua Wills
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 ) 로 보내주세요.
한빛미디어(주)는 여러분의 소중한 경험과 지식을 기다리고 있습니다.
| 표지 설명 |
9가지 사례로 익히는 고급 스파크 분석 2판
4
샌디 라이자 Sandy Ryza
리믹스에서 대중교통에 적용할 수 있는 알고리즘을 개발하고 있다. 이전에는 클라우데라와 클로버
헬스에서 선임 데이터 과학자로 근무했다. 아파치 스파크 커미터이자 아파치 하둡의 PMC 멤버이
며 스파크 시계열 데이터 처리 프로젝트의 창설자이다. 2012년 브라운 대학교 전산학과의 트와이
닝 어워즈에서 ‘Most Chill’ 부문을 수상했다.
유리 레이저슨 Uri Laserson
마운트 시나이 의과대학교 아이칸 스쿨의 유전학 조교수다. 하둡 생태계를 활용해 유전체학과 면역
학에 적용할 수 있는 확장 가능한 기술을 개발하고 있다.
션 오언 Sean Owen
클라우데라 데이터 과학팀의 디렉터다. 아파치 스파크 커미터와 PMC 멤버이며, 아파치 머하웃
Apache Mahout의 커미터였다.
조시 윌스 Josh Wills
슬랙Slack 데이터 엔지니어링팀의 리더이며 아파치 크런치Apache Crunch 프로젝트의 창설자이다. 데이
터 과학자들에 관한 트윗을 한 번 남긴 적이 있다.
지은이 소개
5
박상은 edberg.s@gmail.com
컴퓨터에 붙은 그림을 보고 애플이라는 단어의 뜻을 알게 된 이 땅의 흔한 개발자 중 한 사람이다.
포항공과대학교에서 전산학을, 한국과학기술원에서 인공지능을 공부했으며, 그 덕분에 알파고와
스카이넷을 구분할 줄 아는 지혜를 갖추게 되었다. 메일, 브라우저, CMS, 도서 관리 시스템 등 일
관성을 찾기 어려운 다양한 프로젝트에 참여했다. 이렇게 하여 물에 물 탄듯한 경력이 완성되는 듯
했으나, 최근 몇 년은 빅데이터 처리와 관련한 연구개발에 집중했다. 현재 에스코어에서 Elastic 스
택을 활용한 빅데이터 저장/검색 서비스 제공과 머신러닝 및 딥러닝 관련 업무를 수행하고 있다. 대
량의 데이터를 실시간으로 수집, 처리, 분석하여, 실시간으로 생산되는 데이터의 수집과 시각화 사
이의 시간 간격을 줄이는 데 각별한 관심이 있다.
권한철 ultradioc@gmail.com
에스코어의 데이터 분석가 및 플랫폼 개발자다. 보안 관제용 실시간 CEP 엔진 개발을 비롯해서 스
파크를 활용한 다수의 프로젝트에 참여했으며, 현재는 파이썬 라이브러리를 활용하여 콜센터 데이
터 분석 업무를 수행하고 있다. 특히 실시간 데이터 분석과 통계 및 머신러닝 알고리즘을 활용한 데
이터 분석에 관심이 많다.
서양주 yangsuh84@gmail.com
한국과학기술원 학부에서 수학을, 서울대학교에서 석사과정으로 통계학을 전공하였으며, 티맥스소
프트를 시작으로 개발자로서 일하게 되었다. 그 후 에스코어에서 2013년 하둡과 스파크를 접한 이
후로 빅데이터 분석을 주 업무로 수행하게 되었다. 현재는 카카오 추천팀에서 실시간 콘텐츠 추천
업무를 하고 있다.
옮긴이 소개
6
버클리에서 스파크 프로젝트를 시작한 이래로, 나는 단순히 빠른 병렬 시스템을 구축한다는 사
실보다는 점점 더 많은 사람이 대규모 컴퓨팅을 사용할 수 있게 돕는다는 점에 흥분해왔다. 데
이터 과학 전문가 네 명이 스파크 기반의 고급 분석에 대해서 쓴 이 책을 읽는 것이 즐거운 이
유가 바로 여기에 있다. 샌디, 유리, 션 그리고 조시는 오랫동안 스파크로 작업해왔으며, 그만
큼 충실한 설명과 예제를 이 책에 담아냈다.
이 책에서 가장 마음에 드는 부분은 실제 응용 사례와 현실 세계의 데이터셋을 가져와 예제 중
심으로 설명하는 점이다. 독자의 PC에서 직접 실행해볼 수 있는 아홉 개의 개별 빅데이터 예제
를 제공한 책은 흔치 않은데, 저자들은 이런 예제들을 모아서 스파크로 실습할 수 있도록 모든
것을 세팅해두었다. 게다가, 핵심 알고리즘만 다룬 것이 아니라, 정말로 좋은 결과를 얻는 데
필요한 데이터 준비와 모듈 튜닝의 복잡한 사항까지 다루고 있다. 독자는 이들 예제에서 터득
한 개념을 자신의 문제를 푸는 데 곧바로 적용할 수 있을 것이다.
오늘날 빅데이터 처리는 의심할 여지 없이 컴퓨터로 할 수 있는 가장 흥미로운 분야이며, 빠르
게 진화하고 새로운 아이디어들이 도입되는 분야이기도 하다. 나는 독자들이 이 흥미로운 새로
운 분야로 들어서는 데 이 책이 도움이 될 거라 기대한다.
마테이 자하리아
스파크 창시자, 『러닝 스파크』 저자
아파치 스파크는 빅데이터 영역에서 가장 핫한 기술로, 범용적이면서 빠른 대용량 분산 처리를
지원한다. 또한 기초 데이터 분석부터 머신러닝 등의 기능까지 지원하게 되면서 개발자만의 오
픈 소스에서 분석가를 위한 오픈 소스로 주목받고 있다. 이 책은 스파크로 빅데이터를 분석하
기 위한 가장 실용적인 데이터와 분석 방법을 설명하고 있다. 빅데이터에 관심 있거나 종사하
는 개발자와 분석가 모두에게 추천한다.
이상훈
한국 스파크 사용자 모임 운영자, 『실시간 분석의 모든 것』 역자
추천의 글
7
교통, 금융 분야 등의 실제 데이터로 데이터 획득, 전처리, 가중치 결정, 실행, 평가 그리고 시
각화까지 해볼 수 있는 스파크 활용서다. 스파크 입문을 넘어 실무에 적용하려 할 때 좋은 참고
서다. 자신의 관심 도메인에 맞는 부분만 찾아서 읽어도 좋을 것 같다.
최홍용
현대오토에버
8
학교를 졸업하고 몇 군데의 회사를 거쳐 2008년에 지금의 회사에 입사했다. 처음에는 콘텐츠
관리 시스템 개발로 시작했지만, 몇 번의 굴곡을 거쳐 회사는 이름이 바뀌었고 내가 하는 개발
업무도 바뀌게 되었다. 2011년, 데이터를 집계, 분석하여 실시간으로 시각화하는 과제를 수행
하게 되었다. 지금은 다른 회사에서 잘나가고 계신 배병우 씨와 함께 이를 위한 시스템을 설계
하면서 아파치 스톰Apache Storm을 알게 되었다. 그 후 몇 년간, 우리 회사의 개발팀은 스톰의 끝
을 보고 왔다. 그리고 스톰의 몇 가지 한계를 실감하게 되었다. 스톰은 스트림을 처리하는 훌륭
한 도구지만, 딱 거기까지였다(물론 이번에 릴리스된 스톰 1.0에서는 많은 부분이 개선되긴 했
다). 상태를 저장할 방법이 없는 탓에 완전한 분산 컴퓨팅 환경이라 말할 수 없다든지, 오류가
났을 시에 원래 상태를 복원할 수 없는 등 스톰이 할 수 없는 일이 꽤 있었다.
그러던 어느 날, 공역자인 권한철 씨와 서양주 씨가 아파치 스파크를 만났다. 당시 약간 모자라
보이던 스파크는, 맵리듀스MapReduce 로직을 인메모리로 처리하여 성능을 확장할 수 있다는 점
외에도, 일반적인 프로그래밍 환경에 데이터 분산 처리의 거의 모든 것을 가져올 수 있다는 특
징을 가지고 있었다. 여기에 분산 환경마저도 추상화하여 설치 이외에는 별다른 고민 없이 분
산 데이터 처리가 가능하다는 매력도 지녔다. 그리고 스톰의 강점인 스트림 처리마저도 스파크
스트리밍Spark Streaming이 마이크로 배치 형태로 처리할 수 있었다. 데이터 처리의 팔방미인이라
고 해도 과언이 아니었고, 우리는 그때부터 스파크에 집중하게 되었다. 그리고 약 2년이 흘렀
다. 스파크를 활용한 몇 개의 과제를 성공적으로 수행했으며, 새로운 도구를 받아들이는데 다
소 보수적인 분야의 현장에서도 스파크를 활용하여 얻을 수 있는 이점을 받아들이고 있다. 우
리는 스파크의 시대가 열리는 것을 목격한 운 좋은 증인이 되었고, 이 책을 읽을 독자분들도 아
직 늦지 않았다는 이야기를 해주고 싶다.
이 책은 단순한 스파크 참고서가 아니다. 스파크 참고서로는 더 좋은 책들이 여럿 있다. 부끄럽
지만 우리는 이 책도 그러한 참고서 중 하나인 줄 알고 번역을 시작했고, 그 착각 탓에 더 어려
운 길을 가야 했지만, 동시에 더 재미있는 길을 가볼 수 있었다. 이 책의 매력은 다양한 현장의
분석을 책에 담아낸 점에 있다. 스파크로 무엇을 해야 할지가 막막하다면 이 책을 펴면 도움이
옮긴이의 말
9
될 것이다. 굳이 스파크가 아닌 다른 도구를 사용하더라도 유용한 정보도 들어 있다. 이 책이
역자들에게 도움이 된 것처럼 독자들께도 도움이 될 것으로 생각한다.
이 책을 번역하느라 업무 부담을 조금씩 나눠주신 에스코어 엔터프라이즈 공통 플랫폼 그룹 김
세준 그룹장 이하 동료들에게 감사를 전한다. 동시에 몇 달 동안 아빠를 번역에 빼앗긴 건우에
게도 미안함을 전한다. 다른 역자들도 마찬가지의 미안함과 고마움을 가지고 있으리라 생각한
다. 번역이라는 것이 이렇게 어려운 작업인 줄은 상상도 못 했다. 책을 읽다가 책의 문장이 발
바닥에 꽂힌 가시 같다는 기분이 들면, 그 책임이 역자들에게도 있을 수 있음을 이해해주시기
바란다.
박상은
10
과거를 후회하는 걸 좋아하진 않지만, 잠시 태만했던 2011년 시절 믿기 어려운 일이 벌어졌다.
당시 나는 어려운 이산 최적화 문제를 클러스터에 효율적으로 분배하는 방법을 고민하고 있었
다. 내 지도교수는 스파크라는 것이 최신 유행이라며 설명해주었지만, 그 개념은 실현되기엔
너무 이상적이라 실패할 것으로 판단하고 바로 학부 졸업논문을 맵리듀스로 작성하였다. 그 후
스파크와 나 모두 성장하였지만, 스파크는 도저히 무시할 수 없는 거물이 되었다. 대략 2년 후,
스파크에 주목해야 함이 명백해졌다.
MPI부터 맵리듀스에 이르기까지, 스파크 이전의 프레임워크들은 분산 시스템의 어렵고 세세
한 핵심들을 추상화하여 대규모 자원을 활용한 프로그램을 작성할 수 있도록 해주었다. 이들
프레임워크는 늘어가는 데이터를 처리하기 위해 발전해온 만큼, 빅데이터가 진출할 수 있는 범
위는 이들 프레임워크의 능력 한계와 밀접하게 연관될 수밖에 없었다. 스파크는 분산 프로그램
도 일반 프로그램을 작성하듯 쉽게 짤 수 있게 하여 이 범위를 좀 더 넓혀주고 있다.
스파크를 사용하면 ETL 파이프라인의 성능이 엄청나게 향상될 것이며 매일 하둡의 신에게 절
망을 하소연하는 맵리듀스 프로그래머들의 고통을 덜어줄 것이다. 그러나 나에게 가장 흥미
로운 점은 항상 스파크가 개척해준 복잡한 분석 작업이었다. 스파크는 반복적 알고리즘 Iterative
Algorithm과 대화형 탐색Interactive Exploration을 지원하는 패러다임을 갖춰, 마침내 데이터 과학자가 대
규모 데이터셋을 생산적으로 다룰 수 있는 오픈 소스 프레임워크가 되었다.
나는 데이터 과학을 가르치는 가장 좋은 방법은 예제를 활용한 것이라고 생각한다. 이를 위해
나와 동료 저자들은 책에 여러 가지 응용 예를 담았으며, 가장 일반적인 알고리즘들과 데이터
셋들, 그리고 대규모 분석에서의 디자인 패턴들 간의 상호작용을 다루려고 노력하였다. 이 책
은 독자가 처음부터 끝까지 정독하라는 의도로 쓰이지 않았다. 여러분이 성취해봤으면 하는 주
제나 흥미를 자아내는 장을 펼쳐보자.
샌디 라이자
지은이의 말
11
이 책의 1장에서는 데이터 과학과 빅데이터 분석이라는 넓은 맥락에서 스파크의 가치를 소개
한다. 그다음부터 각 장은 스파크를 사용한 독립적인 분석으로 구성된다. 2장은 데이터를 정제
하는 간단한 예로 스파크와 스칼라를 사용한 데이터 분석의 기초를 소개한다. 그리고 그다음
몇 장은 가장 일반적으로 사용되는 알고리즘 몇 개를 전형적인 분야에 적용하면서, 핵심적인
머신러닝 문제를 스파크를 활용하여 푸는 방법을 살펴볼 것이다. 나머지 장들은 좀 더 특수한
분야를 다룬다. 위키백과의 텍스트 안에 숨겨진 의미 관계를 알아보거나 유전체학 데이터도 분
석해볼 것이다.
2판에 대하여
1판이 출간된 이후 스파크의 메이저 버전이 올라가면서 완전히 새로운 핵심 API가 도입되고
MLlib이나 Spark SQL과 같은 하위 컴포넌트들도 크게 바뀌었다. 2판에서는 이에 따른 사용
예를 전달하기 위해서 스파크의 예제 코드를 대폭 수정했고 관련 설명도 지금 시점에 맞게 새
로 썼다.
예제 내려받기
코드 예제와 데이터셋은 다음 주소에서 내려받을 수 있다.
https://github.com/sryza/aas
이 책의 구성
12
아파치 스파크와 MLlib이 없었다면 여러분이 이 책을 읽을 수 있었을 리 만무하다. 우리 모두
는 스파크와 MLlib을 개발하고 오픈 소스로 제공한 개발팀과 여기에 참여한 수백 명의 기여자
에게 감사를 전한다.
이 책을 검토하느라 시간을 내어준 모든 전문가에게도 감사를 전하고 싶다. 미카엘 베르니코,
아담 브레인델, 이안 부스, 파르비즈 데이힘, 제레미 프리먼, 크리스 프레글리, 드바시시 고시,
줄리엣 호글랜드, 조나단 키블러, 니샤 무크타버, 프랭크 나샤프트, 닉 펜트리스, 코스타스 사
켈리스, 톰 화이트, 마르셀로 반진, 그리고 줄리엣 호글랜드(한 번 더), 모두 고마워! 신세를
졌어. 덕분에 책의 구성과 품질 모두 크게 개선되었다.
또한, 나(샌디)는 어려운 주제의 배경 이론과 관련하여 조언해준 조단 핀쿠스와 리처드 왕에
게 감사를 표한다.
이 책이 출판되고 독자의 손에 들어가기까지 물심양면으로 지원해주고 이런 경험을 하게 해준
마리 보구로와 오라일리에도 감사를 표한다.
샌디 라이자
감사의 말
13
CONTENTS
	 지은이 소개 �����������������������������������������������������������������������������������������������������������������������������
4
	 옮긴이 소개 �����������������������������������������������������������������������������������������������������������������������������
5
	 추천의 글 ��������������������������������������������������������������������������������������������������������������������������������
6
	 옮긴이의 말 �����������������������������������������������������������������������������������������������������������������������������
8
	 지은이의 말 ��������������������������������������������������������������������������������������������������������������������������
10
	 이 책의 구성 �������������������������������������������������������������������������������������������������������������������������
11
	 감사의 말 �����������������������������������������������������������������������������������������������������������������������������
12
CHAPTER 1 빅데이터 분석하기
1.1 데이터 과학의 어려움......................................................................................................
21
1.2 아파치 스파크란.............................................................................................................
23
1.3 이 책에 관하여...............................................................................................................
26
1.4 2판에 관하여..................................................................................................................
26
CHAPTER 2 스칼라와 스파크를 활용한 데이터 분석
2.1 데이터 과학자를 위한 스칼라...........................................................................................
30
2.2 스파크 프로그래밍 모델..................................................................................................
32
2.3 레코드 링크....................................................................................................................
32
2.4 스파크 셸과 SparkContext 시작하기...............................................................................
34
2.5 클러스터에서 클라이언트로 데이터 가져오기....................................................................
41
2.6 클라이언트에서 클러스터로 코드 보내기...........................................................................
46
2.7 RDD에서 Data Frame으로.............................................................................................
47
2.8 DataFrame API로 데이터 분석하기.................................................................................
51
2.9 데이터프레임에 대한 빠른 요약 통계................................................................................
57
2.10 데이터프레임의 축 회전과 형태변환...............................................................................
59
14
CONTENTS
2.11 데이터프레임을 결합하고 특징 선택하기........................................................................
63
2.12 실제 환경을 위한 모델 준비하기....................................................................................
65
2.13 모델 평가.....................................................................................................................
67
2.14 한 걸음 더 나아가기.....................................................................................................
69
CHAPTER 3 음악 추천과 Audioscrobbler 데이터셋
3.1 데이터셋........................................................................................................................
72
3.2 교차 최소 제곱 추천 알고리즘..........................................................................................
73
3.3 데이터 준비하기.............................................................................................................
77
3.4 첫 번째 모델 만들기........................................................................................................
82
3.5 추천 결과 추출 검사하기.................................................................................................
86
3.6 추천 품질 평가하기.........................................................................................................
89
3.7 AUC 계산하기................................................................................................................
91
3.8 하이퍼파라미터 선택하기................................................................................................
93
3.9 추천 결과 만들기............................................................................................................
96
3.10 한 걸음 더 나아가기.....................................................................................................
98
CHAPTER 4 의사 결정 나무로 산림 식생 분포 예측하기
4.1 회귀로 돌아와서..........................................................................................................
102
4.2 벡터와 특징.................................................................................................................
102
4.3 학습 예제....................................................................................................................
104
4.4 의사 결정 나무와 랜덤 포레스트...................................................................................
104
4.5 Covtype 데이터셋.......................................................................................................
108
4.6 데이터 준비하기..........................................................................................................
109
4.7 첫 번째 의사 결정 나무................................................................................................
111
4.8 의사 결정 나무 하이퍼파라미터.....................................................................................
119
15
4.9 의사 결정 나무 튜닝하기..............................................................................................
121
4.10 범주형 특징 다시 살펴보기.........................................................................................
126
4.11 랜덤 포레스트...........................................................................................................
129
4.12 예측하기...................................................................................................................
132
4.13 한 걸음 더 나아가기..................................................................................................
133
CHAPTER 5 K-평균 군집화로 네트워크 이상 탐지하기
5.1 이상 탐지....................................................................................................................
136
5.2 K-평균 군집화............................................................................................................
137
5.3 네트워크 침입..............................................................................................................
138
5.4 KDD 컵 1999 데이터셋...............................................................................................
139
5.5 첫 번째 군집화하기......................................................................................................
140
5.6 k 선정하기..................................................................................................................
143
5.7 R에서 시각화하기........................................................................................................
146
5.8 특징 정규화.................................................................................................................
152
5.9 범주형 변수.................................................................................................................
154
5.10 엔트로피와 함께 레이블 활용하기...............................................................................
156
5.11 군집화하기................................................................................................................
157
5.12 한 걸음 더 나아가기..................................................................................................
160
CHAPTER 6 숨은 의미 분석으로 위키백과 이해하기
6.1 문서-단어 행렬...........................................................................................................
163
6.2 데이터 구하기..............................................................................................................
165
6.3 파싱하여 데이터 준비하기............................................................................................
166
6.4 표제어 추출.................................................................................................................
168
6.5 단어빈도-역문서빈도(TF-IDF) 계산하기.......................................................................
170
16
CONTENTS
6.6 특잇값 분해.................................................................................................................
172
6.7 중요한 의미 찾기.........................................................................................................
174
6.8 낮은 차원 표현에 대한 의문과 고찰...............................................................................
179
6.9 단어와 단어 사이의 연관도...........................................................................................
180
6.10 문서와 문서 사이의 연관도.........................................................................................
183
6.11 문서와 단어 사이의 연관도.........................................................................................
185
6.12 여러 개의 단어로 질의하기.........................................................................................
186
6.13 한 걸음 더 나아가기..................................................................................................
188
CHAPTER 7 그래프엑스로 동시발생 네트워크 분석하기
7.1 네트워크 분석 사례: MEDLINE의 인용 색인..................................................................
191
7.2 데이터 구하기..............................................................................................................
192
7.3 스칼라 XML 라이브러리로 XML 문서 파싱하기..............................................................
195
7.4 MeSH 주요 주제와 주제들의 동시발생 분석하기............................................................
198
7.5 그래프엑스로 동시발생 네트워크 구성하기....................................................................
201
7.6 네트워크의 구조 이해하기............................................................................................
206
7.6.1 연결 성분.............................................................................................................
206
7.6.2 차수의 분포..........................................................................................................
209
7.7 관련성 낮은 관계 필터링하기........................................................................................
212
7.7.1 EdgeTriplets 처리................................................................................................
213
7.7.2 필터링된 그래프 분석하기.......................................................................................
216
7.8 작은 세상 네트워크......................................................................................................
217
7.8.1 클릭과 군집계수....................................................................................................
218
7.8.2 프레겔을 사용하여 평균 경로 길이 계산하기...............................................................
220
7.9 한 걸음 더 나아가기 ...................................................................................................
226
17
CHAPTER 8 뉴욕 택시 운행 데이터로 위치 및 시간 데이터 분석하기
8.1 데이터 얻기.................................................................................................................
228
8.2 스파크에서 서드파티 라이브러리로 작업하기.................................................................
229
8.3 지리 데이터와 Esri Geometry API, 그리고 Spray..........................................................
230
8.3.1 Esri Geometry API 살펴보기.................................................................................
231
8.3.2 GeoJSON 소개...................................................................................................
233
8.4 뉴욕 택시 운행 데이터 준비하기...................................................................................
236
8.4.1 잘못된 레코드 대규모로 다루기................................................................................
239
8.4.2 지리 정보 분석하기................................................................................................
244
8.5 스파크에서 세션화 작업 수행하기.................................................................................
247
8.5.1 세션 구성하기: 스파크에서 보조 정렬하기..................................................................
249
8.6 한 걸음 더 나아가기.....................................................................................................
252
CHAPTER 9 몬테카를로 시뮬레이션으로 금융 리스크 추정하기
9.1 전문 용어....................................................................................................................
254
9.2 VaR 계산 방법.............................................................................................................
255
9.2.1 분산-공분산 ........................................................................................................
255
9.2.2 과거 기반 시뮬레이션.............................................................................................
256
9.2.3 몬테카를로 시뮬레이션...........................................................................................
256
9.3 우리의 모델.................................................................................................................
257
9.4 데이터 구하기..............................................................................................................
258
9.5 전처리하기..................................................................................................................
259
9.6 요인 가중치 결정하기...................................................................................................
263
9.7 표본추출.....................................................................................................................
265
9.7.1 다변량 정규분포....................................................................................................
268
9.8 실험 실행하기..............................................................................................................
270
18
CONTENTS
9.9 수익 분포 시각화하기...................................................................................................
274
9.10 결과 평가하기...........................................................................................................
275
9.11 한 걸음 더 나아가기..................................................................................................
278
CHAPTER 10 BDG 프로젝트와 유전체학 데이터 분석하기
10.1 모델링과 저장소를 분리하기.......................................................................................
283
10.2 ADAM CLI를 이용한 유전체학 데이터 처리................................................................
287
10.2.1 파케이 형식과 열 기반 저장소...............................................................................
294
10.3 ENCODE 데이터로부터 전사인자 결합 부위 예측하기.................................................
296
10.4 1000 지놈 프로젝트에서 유전자형 질의하기...............................................................
305
10.5 한 걸음 더 나아가기..................................................................................................
308
CHAPTER 11 파이스파크와 썬더로 신경 영상 데이터 분석하기
11.1 파이스파크 소개........................................................................................................
312
11.1.1 파이스파크 내부 구조...........................................................................................
314
11.2 썬더 라이브러리 개요와 설치.....................................................................................
316
11.3 썬더로 데이터 읽어 들이기.........................................................................................
317
11.3.1 썬더 핵심 자료형.................................................................................................
323
11.4 썬더로 신경 세포 유형 분류하기.................................................................................
324
11.5 한 걸음 더 나아가기..................................................................................................
329
찾아보기 ���������������������������������������������������������������������������������������������������������������������������������������������������
330
191장 빅데이터 분석하기
“데이터 애플리케이션은 소시지와 비슷하다. 어떻게 만드는지 모르는 편이 나으니까.”
-오토 폰 비스마르크1
●	‌‌셀 수 없이 많은 트랜잭션과 수천 가지 특징을 활용해 신용카드 부정 사용을 감지하는 모델 구축
●	‌‌수백만 사용자에게 수백만 가지의 제품 중 적절한 것을 지능적으로 추천
●	‌‌수백만의 요소를 고려한 포트폴리오 시뮬레이션을 통한 투자 위험도 추정
●	‌‌질환의 유전적 연관성을 파악하기 위한 대규모 인간 유전자 분석
몇 년 전만 하더라도 이와 같은 작업은 꽤 어려운 일이었다. 요즘을 빅데이터의 시대라고 말할 수
있는 이유는 기존에는 경험하지 못한 규모로 정보를 수집, 저장, 처리할 수 있는 도구가 준비되
었기 때문이다. 이 배경에는 오픈 소스 소프트웨어 생태계가 있는데, 그 덕분에 엄청난 양의 데
이터를 다룰 수 있는 컴퓨터 클러스터 환경을 저렴하게 사용할 수 있게 되었다. 하둡Apache Hadoop
과 같은 분산 시스템이 대세가 되었으며, 거의 모든 분야의 수많은 현장에서 활용하고 있다.
하지만 돌덩어리와 끌이 있다고 해서 조각상이 저절로 만들어지는 것이 아니듯, 빅데이터와 이
를 다룰 도구를 갖추었다는 것과 이를 활용하여 무언가 쓸모 있는 일을 한다는 것 사이에는 차
이가 있다. 데이터 과학이 필요한 이유가 바로 여기에 있다. 조각이 도구를 사용하여 원석을 다
른 사람들에게 의미 있는 무언가로 바꾸는 작업이듯, 데이터 과학도 도구를 사용하여 원본 데
1	 옮긴이_ 비스마르크는 원래 ‘데이터 애플리케이션’이 아니라 ‘법률’이 그러하다고 말했다.
빅데이터 분석하기
CHAPTER 1
샌디 라이자
20 9가지 사례로 익히는 고급 스파크 분석 (2판)
이터를 데이터 과학자가 아닌 사람들의 관심을 끌 만한 의미 있는 것으로 바꾸는 작업이다.
흔히 ‘쓸모 있는 일 하기’는 스키마Schema를 설계하고 SQL을 사용하여 “등록 과정의 세 번째 페
이지에 도달한 엄청난 수의 사용자 중 25세 이상은 몇 명인가?”와 같은 질문에 답하는 것을 의
미한다. 이런 질문에 쉽게 답할 수 있도록 데이터 웨어하우스Data Warehouse를 구성하고 정보를 체
계화하는 방법을 다루는 분야도 중요하지만, 이 책에서는 이런 복잡한 일은 되도록 다루지 않
으려 한다.
때로는 ‘쓸모 있는 일 하기’에는 노력이 더 필요할 수 있다. SQL은 여전히 주요한 수단이다. 하
지만 다루는 데이터가 매우 독특하거나 분석 작업이 복잡하다면 SQL보다 유연하고 근본적이
며 머신러닝과 통계 기능이 풍부한 새로운 프로그래밍 패러다임이 필요해진다. 이런 유형의 분
석이 이 책에서 이야기하려는 대상이다.
오랜 기간에 걸쳐 R, PyData 스택(파이썬 데이터 분석 도구 모음), 옥타브Octave와 같은 오픈
소스 프레임워크 덕에 작은 데이터셋Dataset을 빠르게 분석하고 모델을 수립할 수 있었다. 데이
터셋의 일부를 사용해서 머신러닝 모델을 학습시키고 나머지 데이터의 레이블을 예측하는 일
이 10줄 이내의 코드로도 가능하다. 여기서 조금만 더 나아가면 결측치Missing Data를 보정하고,
몇몇 모델을 실험해 최적의 모델을 찾고, 한 모델의 결과를 다른 모델을 적합Fit시키기 위한 입
력으로 사용할 수 있다. 대규모 데이터셋에서 같은 결과를 얻기 위해 컴퓨터 클러스터 환경을
활용한다면 이러한 과정이 어떻게 달라질까?
단순히 프레임워크를 여러 노드에서 동작하도록 확장하고 프로그래밍 모델은 그대로 유지한
채 분산 환경에서 잘 동작하게끔 내부를 수정하는 것이 옳을 수도 있다. 하지만 단일 노드에서
는 문제가 되지 않았지만 분산 컴퓨팅에서는 새롭게 고민해야 하는 것들이 있다. 예를 들어 네
트워크는 메모리보다 월등히 느리므로 데이터가 클러스터의 여러 노드에 나뉘어 있다면 많은
데이터를 참조하는 알고리즘은 성능이 매우 나빠진다. 분산 환경에서 동작하는 노드의 수가 늘
어날수록 오류가 발생할 가능성도 커진다. 이러한 사실들을 종합해볼 때 고도의 병렬 실행 코
드를 쉽게 작성할 수 있는, 분산 환경의 특징을 충실하게 활용하는 프로그래밍 패러다임이 필
요하다.
하나의 노드에서 동작하는 PyData나 R 같은 도구가 소프트웨어 커뮤니티에서 최근 주목받
고 있지만, 이들만이 데이터 분석을 위한 도구는 아니다. 대량의 데이터를 다루는 유전체학 같
은 과학 분야에서도 수십 년간 병렬 컴퓨팅 프레임워크를 발전시켜왔다. 이 분야에서 데이터를
211장 빅데이터 분석하기
다루는 사람 대부분은 HPCHigh-Performance Computing (고성능 컴퓨팅)라는 클러스터 컴퓨팅 환경
에 익숙하다. PyData나 R은 확장성이 부족해 문제라면, HPC에서는 추상화 수준이 지나치게
낮아서 발생하는 나쁜 사용성이 문제다. 예컨대 DNA 염기서열로 가득 찬 커다란 파일을 병렬
처리하려면 수작업으로 일일이 작은 파일로 나눈 후, 각각에 대한 처리 작업을 클러스터의 스
케줄러에 하나씩 등록해야 한다. 일부에서 오류가 발생하면 작업자는 그 오류를 직접 찾아내서
수동으로 재입력해야 한다. 분석하다 보면 전체 데이터셋의 정렬과 같은 데이터 전체를 사용하
는 작업을 수행해야 할 때가 있다. 이 경우에는 커다란 데이터 모두를 하나의 노드에 밀어 넣거
나 MPI와 같은 저수준 분산 프레임워크에 의존해야 하는데, 그러려면 C 언어와 분산 네트워크
환경을 잘 이해하고 있어야 한다.
또, HPC 환경에 맞게 제작된 도구들은 저수준 저장소 모델로부터 인메모리In-memory 데이터 모
델을 분리하기가 어려운 경우가 많다. 예를 들어 많은 도구가 POSIX 파일시스템의 단일 데이
터 스트림으로만 데이터를 읽을 수 있도록 만들어졌다. 이러한 도구는 병렬화하거나 데이터베
이스 같은 다른 종류의 백엔드 저장소를 사용하도록 변경하기가 쉽지 않다. 하둡 생태계의 요
즘 시스템들은 사용자가 클러스터 환경을 단일 컴퓨터 환경처럼 다룰 수 있도록 추상화해준다.
파일을 쪼개 여러 노드에 걸쳐 있는 저장소에 분산하고, 일을 작은 단위로 나눠 처리하고, 오류
를 복구하는 모든 작업을 자동으로 수행한다. 하둡 생태계는 큰 데이터 파일을 다루는 과정도
자동화할 수 있으며, HPC보다 훨씬 저렴하다.
1.1 데이터 과학의 어려움
데이터 과학을 실제로 적용하다 보면 종종 어려운 문제에 부딪히게 된다. 클라우데라Cloudera의
데이터 과학팀은 이러한 어려움을 널리 알리는 데 큰 역할을 해왔다. 대량의 데이터로부터 복
잡한 분석을 성공적으로 처리하는 시스템을 구축하려면 (설사 실제로 벌어지지 않더라도) 이
런 어려움에 관해서 알고 있어야 한다.
첫째, 성공적인 분석을 위한 작업 대부분은 데이터의 전처리 과정에서 이뤄진다. 데이터는 너
저분하다. 그래서 데이터를 활용하기 전에 정제, 개조, 합치기, 섞기 같은 여러 가지 전처리 과
정이 필요하다. 특히, 맨눈으로 검사하기 어려울 정도로 데이터가 많다면 어떠한 전처리 과정
이 필요한지를 파악하는 일조차 별도의 처리 과정을 거쳐야 한다. 심지어 모델의 성능을 최적
22 9가지 사례로 익히는 고급 스파크 분석 (2판)
화해야 할 때는 알고리즘을 선택해서 구현하는 일보다 특징을 추출하고 선택하는 데 일반적으
로 더 큰 노력이 들어간다.
예컨대 온라인 구매 데이터에서 사기 행위를 찾는 모델을 만들고자 한다면 데이터 과학자들은
사용자가 작성하는 주문서 상의 여러 정보, 즉 사용자 IP의 위치 정보, 로그인 시각, 웹 사이트
내비게이션 로그와 같은 활용 가능한 수많은 특징 중에서 무엇을 사용할지 선택해야 한다. 선
택한 각 특징을 머신러닝 알고리즘에 적합한 벡터로 변환해야 하며, 이를 위해서 더블형Double
숫자로 이뤄진 2차원 배열을 수학적 모델로 변환하는 일 정도는 해줄 수 있는 시스템이 있어야
한다.
둘째, 데이터 과학은 기본적으로 반복 Iteration 작업들로 구성된다. 보통은 모델을 만들고 분석하
는 과정에서 같은 데이터를 여러 번 반복해서 읽게 된다. 이는 머신러닝이나 통계적 절차의 특
징에 기인하는데, 값이 수렴할 때까지 입력 데이터를 반복해서 사용하는 확률적 구배법Stochastic
Gradient Descent (SGD)이나 기댓값 최대화법Expectation Maximization 같은 널리 사용되는 최적화 기법들
을 보면 알 수 있다. 반복 과정은 데이터 과학자 자신의 작업 흐름 안에서도 중요하다. 데이터
과학자가 처음 접하는 데이터셋을 파악하고자 할 때, 특정 질의의 결과를 바탕으로 다음에 수
행해야 할 질의를 결정하는 것이 일반적이다. 모델을 만들 때도 데이터 과학자는 단 한 번의 시
도로 모델이 완성되리라 기대하지 않는다. 실험을 통해서 알맞은 특징을 선택하고, 적절한 알
고리즘을 선택하고, 유의성 검정을 하고, 맞춤 하이퍼파라미터들을 찾아낸다. 어떤 프레임워크
가 같은 데이터를 매번 디스크에서 가져온다면 전체 과정의 속도가 디스크 입출력만큼 느려지
고, 그 결과 반복해서 시도해볼 수 있는 횟수가 줄어들게 된다.
셋째, 잘 돌아가는 모델이 완성되었다고 해서 일이 끝나는 것은 아니다. 데이터 과학의 핵심이
데이터를 직접 분석하지 않는 사람들에게 유용한 정보를 뽑아내는 것이라면, 데이터 과학자 컴
퓨터의 텍스트 파일에 회귀 가중치의 목록 형태로 (즉, 다른 사람이 이해하기 힘든 형태로) 저
장된 모델을 만드는 일은 진정한 목적이 될 수 없다. 데이터 애플리케이션이라면 추천 시스템
이나 실시간 사기 탐지 시스템처럼 의미 있게 활용할 수 있어야 한다. 이런 시스템에서는 모델
이 제품 서비스의 일부이므로 주기적으로 혹은 실시간으로 다시 생성해야 할 수도 있다.
이런 상황에서는 연구를 위한 분석과 현장을 위한 분석을 구분해야 한다. 연구를 위한 분석은 데
이터에 대한 탐사 분석Exploratory Analytics을 의미한다. 이 분석에서는 데이터의 특성을 이해하려 시
도한다. 그 결과를 시각화하고, 아직 적용하지 않은 이론들을 시험한다. 여러 종류의 특징과 현
231장 빅데이터 분석하기
재의 데이터를 보강할 수 있는 후보 데이터도 시험하게 된다. 한두 가지는 성공하기를 바라면
서 다양한 알고리즘을 시험하는 것이다. 반면 데이터 애플리케이션을 구축하는 현장에서는 운
영을 위한 분석Operational Analytics을 수행한다. 분석 모델을 실제 의사 결정에 영향을 주는 서비스에
적용하며, 일정 기간 모델의 성과를 추적하고, 정확도를 조금이라도 올리기 위한 미세 조정 방
안을 궁리한다. 그리고 서비스 수준 협약서Service Level Agreement (SLA)와 가동시간Uptime도 고민하
게 된다. 현재의 사례를 보면, R과 같은 언어로 탐사 분석을 수행한 이후에, 양산 단계에서는
데이터 처리 과정을 자바나 C++로 완전히 새롭게 구현하는 것이 일반적이다.
물론 처음에 만든 모델의 코드를 실무 애플리케이션에서도 사용할 수 있다면 좋겠지만, R과 같
은 언어는 성능도 좋지 않은 데다가 제품의 다른 구성요소들과 통합하기에는 적합하지 않다.
반대로 자바나 C++ 쪽은 탐사 분석에 쓸만한 도구를 찾아보기 어렵다. 자바나 C++에서는 데
이터와 상호작용할 수 있는 REPLRead-Evaluate-Print-Loop 환경이 부족하며, 간단한 변환식을 구현
하는 데도 많은 양의 코드가 필요하다. 그리하여 모델링 과정에서도 쉽게 쓸 수 있고 제품에도
적용할 수 있는 프레임워크가 필요한 상황이 되었다.
1.2 아파치 스파크란
아파치 스파크로 들어가 보자. 스파크는 세련된 방법으로 클러스터의 여러 노드로 프로그램
을 분배하고, 그 위에서 동작하는 프로그램을 개발할 수 있도록 개발된 오픈 소스 프레임워
크다. UC 버클리의 AMPLab에서 탄생해, 지금은 아파치 소프트웨어 재단에서 관리하는 스
파크는 데이터 과학자가 분산 프로그래밍을 할 수 있게 해주는 아마도 최초의 오픈 소스 소
프트웨어일 것이다.
스파크를 쉽게 이해하기 위하여 스파크의 선배라 할 수 있는 맵리듀스MapReduce와 비교해보자.
맵리듀스는 수십만 개의 노드를 활용하는 병렬 처리를 간단히 구현할 수 있는 모델로, 대량의
데이터 연산 분야에 일대 혁신을 가져왔다. 맵리듀스는 거의 선형에 가까운 확장성을 보여준
다. 데이터가 많아지면 컴퓨팅 노드도 그만큼 추가하여 같은 시간에 일을 마무리 지을 수 있음
을 의미한다. 그리고 “하나의 노드에서는 잘 발생하지 않는 오류라도 규모가 큰 클러스터 환경
에서는 일상적으로 발생한다”는 상식으로부터도 자유롭다. 맵리듀스는 일을 작은 단위 작업으로
쪼개고, 단위 작업에서 오류가 나더라도 전체에 영향을 주지 않도록 우아한 방식으로 오류를
24 9가지 사례로 익히는 고급 스파크 분석 (2판)
처리한다.
스파크는 맵리듀스의 선형 확장성과 결함 포용Fault Tolerance성을 유지하면서, 세 가지 중요한 개
선을 이뤄냈다. 먼저, ‘맵 단계 후 리듀스 단계’를 지키지 않아도 되며, 훨씬 일반적인 방향성 비
순환 그래프Directed Acyclic Graph (DAG) 형태로 정의한 연산들을 실행할 수 있다. 맵리듀스라면 중
간 결과를 분산 파일시스템에 반드시 저장해야 하는 상황에서, 스파크는 파이프라인의 다음 단
계로 중간 결과를 바로 넘길 수 있다는 뜻이다. 이는 맵리듀스의 후손이자 마이크로소프트 연
구소에서 시작된 Dryad(https://goo.gl/Or3T8P)와 유사한 방식이다. 두 번째, 사용자가 연
산을 더욱 자연스럽게 표현할 수 있도록 풍부한 변환 방식을 제공하여 처리 능력을 확장하고
있다. 개발자 중심의 기능을 제공하여 몇 줄의 코드만으로 복잡한 파이프라인을 구현할 수 있
는 간소화된 API를 제공한다.
마지막 개선은 인메모리 처리 방식이다. 스파크의 데이터셋Dataset과 데이터프레임DataFrame을 통
한 추상화는 개발자가 데이터 처리 파이프라인의 어느 지점에서라도 데이터를 클러스터의 메
모리로 저장할 수 있도록 해준다. 이후 단계에서 같은 데이터를 사용해야 한다면 데이터를 다
시 연산하거나 디스크로부터 다시 읽을 필요가 없다는 뜻이다. 이 능력 덕분에 과거의 분산 처
리 엔진들이 하지 못하던 용도로도 사용할 수 있게 되었다. 예를 들어 데이터셋을 여러 번 훑어
야 하는 알고리즘이나 사용자 요청에 빠르게 응답하기 위해 커다란 인메모리 데이터셋을 스캔
해야 하는 반응형 애플리케이션Reactive Application에 아주 적합하다.
데이터 분석에서 가장 큰 병목이 CPU, 디스크, 네트워크 같은 컴퓨팅 환경이 아니라 분석가의
생산성에 달려 있음을 이해한다면, 앞 절에서 이야기한 ‘데이터 과학의 어려움’을 해결하는 데
스파크가 좋은 해답이라는 사실이 아마도 가장 중요할 것이다. 전처리부터 모델 평가까지의 전
체 과정을 단일 프로그래밍 환경에서 수행하는 것이 개발 속도 면에서 얼마나 큰 이점인지는
아무리 과장해도 지나치지 않을 것이다. REPL 환경의 분석 라이브러리들을 가지고 많은 것을
표현할 수 있는 프로그래밍 모델로 묶어낼 수 있는 스파크에서는 맵리듀스와 같은 특정 프레임
워크를 사용하느라 여러 IDE를 오갈 필요도 없고, R과 같은 프레임워크를 사용하느라 하둡 분
산 파일시스템Hadoop Distributed File System (HDFS)으로부터 데이터를 샘플링하거나 이리저리 이동
시킬 필요도 없다. 분석가가 데이터를 조사하는 시간이 절약될수록 뭔가 쓸만한 일을 할 가능
성은 더 커진다.
데이터 조작 또는 ETL에 적용할 수 있다는 관점에서는 스파크는 빅데이터를 다루는 매트랩
251장 빅데이터 분석하기
Matlab이라기보다는 빅데이터를 다루는 파이썬에 가까워 보인다. 범용 연산 엔진으로서 스파크
의 핵심 API는 통계, 머신러닝, 행렬 연산의 어떤 기능과도 독립적인, 데이터 변환을 위한 강
력한 토대를 제공한다. 스파크의 스칼라 API와 파이썬 API 덕분에 범용 언어에서 쉽게 불러
쓸 수 있고, 기존의 다른 라이브러리와 함께 사용할 수도 있다.
스파크의 인메모리 캐시 기능은 반복적으로 이뤄지는 크고 작은 모든 데이터 처리에 이상적이
다. 이 기능을 활용하면 학습 데이터를 반복해서 읽어야 하는 머신러닝 알고리즘에서는 학습
데이터를 메모리에 캐싱할 수 있다. 데이터 과학자가 데이터를 파악하려 할 때도 데이터를 디
스크에서 매번 읽어 들이는 대신, 메모리에 올려둔 채 다양한 질의를 테스트해보고, 또 그 결과
를 메모리에 쉽게 저장할 수도 있다.
마지막으로, 스파크는 탐사 분석 시스템과 운영 분석 시스템 사이의 간격을 좁힐 수 있다. 세간
에서 데이터 과학자는 통계학자보다는 엔지니어링을 잘하고 엔지니어보다는 통계 활용에 능하
다고 이야기하는데, 적어도 스파크는 대부분의 다른 탐사 분석 시스템보다는 운영 시스템에 적
용하기 좋고, 운영 시스템에서 일반적으로 사용하는 기술들에 비해 데이터 탐사 분석에도 적합
하다. 스파크는 근본적으로 성능과 신뢰성 모두를 위해서 만들어졌다. 자바 가상 머신Java Virtual
Machine (JVM)에서 돌아가기 때문에 자바 스택에서 돌아가는 수많은 운영 및 디버깅 도구도 활
용할 수 있다.
스파크는 하둡 생태계의 다양한 도구와 통합하기에도 좋다. 스파크는 맵리듀스가 지원하는 모
든 데이터 포맷을 읽고 쓸 수 있어서, 에이브로Apache Avro, 파케이Apache Parquet와 같은 하둡의 일
반적인 데이터 저장 파일 포맷도 사용할 수 있다. 물론 하둡 이전부터 사용된 쉼표로 분리된 텍
스트 형식(CSV)도 지원한다. 그리고 HBase와 카산드라Apache Cassandra 같은 NoSQL 데이터베
이스로부터 데이터를 읽고 쓸 수도 있다. 스파크의 스트림 처리 라이브러리인 스파크 스트리밍
Spark Streaming을 사용하면 플룸Apache Flume이나 카프카Apache Kafka로부터 연속적으로 데이터를 입력
받을 수도 있다. SQL 라이브러리인 Spark SQL로는 하이브 메타스토어Apache Hive Metastore와 상
호작용이 가능하며, 하이브 온 스파크Hive on Spark를 사용하여 맵리듀스 대신 스파크를 하이브의
기본 실행 엔진으로 사용할 수 있다. 하둡의 스케줄링과 자원 관리를 담당하는 YARNYet Another
Resource Negotiator 내부에서도 동작한다. 이를 통해서 클러스터 사이에서 자원을 동적으로 공유할
수 있으며, 맵리듀스나 임팔라Apache Impala 같은 다른 처리 엔진과 동일한 정책으로 관리할 수 있
게 되었다.
26 9가지 사례로 익히는 고급 스파크 분석 (2판)
1.3 이 책에 관하여
이 책의 나머지 부분에서는 스파크의 장점이나 단점은 다루지 않는다. 기본적인 스파크 프
로그래밍 모델과 스칼라 언어의 기초는 소개하지만, 스파크의 레퍼런스에 해당하는 내용이
나 모든 것에 대한 포괄적인 지침 같은 것은 제공하지 않으려 한다. 머신러닝, 통계학, 선형
대수의 튜토리얼로 만들 생각도 없다. 물론, 필요하다면 기본적인 배경은 설명할 것이다.
그 대신, 대량의 데이터셋을 다루는 복잡한 분석을 스파크로 실행해보며, 그 생생한 느낌을
여러분께 전달하고자 한다. 단순히 모델을 구축하고 평가하는 데 그치지 않고, 전체 파이프
라인을 돌아보며 데이터 정제, 전처리, 탐사 분석, 실제 제품으로 만들기까지를 보여주고자
한다. 아마도 실제 예제를 통해 보여주는 방법이 최선일 것이다. 그래서 우선 스파크와 그
생태계를 간단히 설명한 후, 그다음 장부터는 각 분야의 데이터를 스파크로 분석하는 독립
적인 설명들로 채울 것이다.
가능하다면 단순히 ‘정답’을 제공하기보다는 데이터 과학의 절차 전체, 즉 모든 반복, 막다른
길, 재시도 등을 설명할 것이다. 이 책은 스칼라, 스파크, 머신러닝, 데이터 분석에 더 친숙
해지는 계기가 될 것이다. 그리고 이 모두는 더 큰 목적을 향한 과정이다. 우리는 이번 장의
처음에 언급한 여러 업무에 어떻게 접근하는지를 보여주려는 것이다. 약 30쪽 내외로 구성
된 각 장을 통해 데이터 애플리케이션의 일부를 만들어내는 방법을 가능한 한 실제처럼 설
명할 것이다.
1.4 2판에 관하여
2015년과 2016년에 스파크는 많은 변화를 겪었으며, 그 결과로 2016년 7월에 스파크 2.0
이 출시되었다. 가장 큰 변화는 스파크의 핵심 API에서 이뤄졌다. 1.x 버전의 스파크 API는
여러 컴퓨터 클러스터에 걸쳐 느슨하게 인스턴스화된 객체의 모음인 탄력적 분산 데이터셋Resilient
Distributed Dataset (RDD)을 중심으로 구성되어 있었다.
RDD를 기반으로 강력하고 표현력 높은 API를 구성할 수 있었지만, 중요한 문제가 두 가지 생
겼다. 첫째, 성능과 안정성의 측면에서 적합하지 않았다. 자바나 파이썬 객체를 기반으로 했기
때문에 메모리 사용 면에서 비효율적이었고, 가비지 컬렉션 때문에 스파크 프로그램이 대기해
271장 빅데이터 분석하기
야 하는 시간이 길어졌다. 또한, 실행 계획이 API에 묶여 있어, 사용자가 프로그램의 실행을
최적화하는 부담이 커지게 되었다. 예를 들어, 전통적인 RDBMS를 사용하면 조인할 테이블의
크기에 따라 최선의 조인 전략이 알아서 선택되는 반면, 스파크를 사용할 때는 사용자가 이를
직접 선택해야 했다. 둘째, 스파크 API는 일반적으로 데이터가 구조화된 관계형 모델에 잘 들
어맞는다는 사실을 무시했다. 튜플 내에서의 순서 대신 열의 이름을 사용한다든지의 방법으로
데이터를 훨씬 더 쉽게 조작할 수 있는 기본 자료형을 제공할 수 없었다.
스파크 2.0은 RDD를 Dataset과 DataFrame으로 대체하여 이러한 문제점을 해결했다.
Dataset은 RDD와 비슷하지만 객체를 인코더에 매핑하여 인메모리 표현에 훨씬 효율적이다.
이를 통해서 스파크 프로그램을 더 빠르고, 더 작은 메모리로, 더 예측 가능하게 실행할 수 있
다. 또, 데이터셋과 실행 계획 사이에 최적화 기능을 배치하여 실행 방법에 대해서 더 지능적인
결정을 내릴 수 있다. DataFrame은 관계형 데이터, 즉 고정된 열의 데이터가 행 단위로 이뤄
진 데이터를 모델링하는 데 특화된 Dataset의 하위클래스다. 열 개념을 도입하여 더 깨끗하고
표현력이 풍부한 API를 사용할 수 있으며, 거기에 다양한 성능 최적화가 가능해졌다. 예를 들
어, 결과를 만들어내는 데 열의 일부만 필요하다는 사실을 알고 있다면, 열 전체를 메모리에 올
리지 않아도 된다. 그리고 이전에는 사용자 정의 함수로 정의해야 했던 많은 변환을 이제 API
에서 직접 표현할 수 있다. 이 기능은 파이썬을 사용할 때 특히 유용한데, 스파크 내부 동작이
파이썬에서 정의된 함수보다 변환을 훨씬 빠르게 수행할 수 있기 때문이다. 또한 DataFrame
은 Spark SQL과 상호운용성을 제공하므로, 사용자가 SQL 질의를 작성해서 DataFrame을
반환받고, 그 DataFrame을 스파크가 지원하는 프로그래밍 언어에서 사용할 수 있다. 새 API
는 기존 API와 매우 유사해 보이지만, 세부적인 변화 때문에 거의 모든 스파크 프로그램이 수
정되어야 한다.
스파크 2.0은 이러한 변화 외에도, 머신러닝과 통계 분석에 사용하는 API도 크게 변경되었다.
이전 버전에서는 머신러닝 알고리즘별로 고유한 API가 있어서, 알고리즘에 적용할 데이터를
준비하거나 특정 알고리즘의 결과를 다른 알고리즘에 적용하고자 할 때는 각각을 조합하는 코
드를 만들어야 했다. 스파크 2.0에 포함된 Spark ML API는 머신러닝 알고리즘과 특징Feature
의 변환 단계의 파이프라인을 구성할 수 있는 프레임워크를 제공한다. 인기 있는 파이썬 도구
인 사이킷런Scikit-Learn의 API에서 영감을 받아서, 데이터의 파라미터를 학습하고, 이 파라미터
를 데이터를 변환시키는 데 사용하는 객체인 추정자Estimator와 변환자Transformer를 중심으로 돌아간
다. Spark ML API는 DataFrame API와 많은 부분이 결합되어 있어, 관계형 데이터로도 머
28 9가지 사례로 익히는 고급 스파크 분석 (2판)
신러닝을 쉽게 수행할 수 있다. 예를 들어서 사용자는 특징 벡터의 순서 값 대신 이름으로 특징
을 참조할 수 있다.
이러한 변화들이 반영되다 보니, 이 책 초판의 많은 부분이 의미가 없게 되었다. 이번 2판은 새
로운 스파크 API를 사용하기 위해서 모든 장을 수정하였다. 추가로, 더 이상 관련이 없는 부분
은 제외했다. 예를 들어 몇몇 복잡한 API를 다루던 전체 부록을 삭제했는데, 이 부분을 지금은
사용자 개입 없이 스파크가 알아서 처리해주기 때문이다. 안정적으로 성숙한 스파크의 시대가
된 터라, 스파크를 사용한 분석에 있어서 수년간은 이 책이 유용한 자료로 남아있기를 희망한다.
292장 스칼라와 스파크를 활용한 데이터 분석
“흥미를 잃지 않는다면 못할 일은 아무 것도 없다.”
-데이비드 포스터 월리스
데이터 정제는 모든 데이터 과학 프로젝트의 시작이자, 매우 중요한 일이다. 분석에 사용하는
데이터의 품질이나 다른 내재적 원인에 의하여 분석 결과가 왜곡되거나 실제와 다른 결론
이 도출된다면 아무리 뛰어난 분석 방법이라 할지라도 도움이 되지 않을 것이다.
이러한 중요성에도 불구하고 데이터 과학 서적이나 강의에서는 데이터 정제 과정에 관해서
다루지 않거나 그냥 언급만 하고 지나치곤 한다. 사실 데이터 정제는 꽤 지루한 과정이다.
우리가 새 문제에 써보고 싶은 멋진 머신러닝 알고리즘을 적용하기 전에 거쳐야 하는 아주
따분한 일이다. 많은 풋내기 데이터 과학자는 조악한 품질의 데이터로 분석을 시작하고, 복
잡한 알고리즘을 적용한 후 말도 안 되는 답을 얻고 나서야 비로소 데이터 품질에 심각한 문
제가 있음을 깨닫기도 한다.
“쓰레기를 넣으면 쓰레기가 나온다Garbage in, garbage out”라는 말도 있지만, 현실은 이보다 훨씬 심
각하다. 어떤 데이터에 쉽게 파악되지 않는 심각한 품질 문제가 있어서 그럴싸한 데이터로 오
인된다면 도출된 결과도 그럴싸해 보일 수 있다. 이런 식의 심각한 오답을 제시하는 것은 데이
터 과학자에게 치명적인 실수다.
데이터 과학자로서 갖춰야 할 중요한 소질 하나는 데이터 분석의 모든 단계에서 흥미롭고 가치
있는 문제를 찾아내는 능력이다. 분석의 초기 단계에 기술과 통찰을 더하면 최종 결과물의 신
스칼라와 스파크를 활용한 데이터 분석
CHAPTER 2
조시 윌스
30 9가지 사례로 익히는 고급 스파크 분석 (2판)
뢰도는 더 커지게 된다.
데이터 과학자에게 데이터 품질 관리에 신경 쓰라고 하다니, 물론 말은 쉽다. 아이들에게 채소
를 먹으라고 이야기하는 것처럼 말이다. 하지만 스파크와 같은 새로운 도구를 써보는 일이 훨
씬 재미있다. 스파크로는 멋진 머신러닝 알고리즘을 만들어보거나, 스트리밍 데이터를 처리하
는 엔진을 개발한다거나 복잡하게 연결된 그래프를 분석하는 등의 일을 해볼 수 있으니 말이
다. 그래서 스파크와 스칼라를 활용하여 데이터를 정제하는 예를 직접 보여주는 것으로부터 시
작하려고 한다.
2.1 데이터 과학자를 위한 스칼라
데이터 과학자 대부분은 데이터를 조작하고 분석할 때 R이나 파이썬과 같은, 자신에게 가장
능숙한 특정 도구를 선호한다. 어쩔 수 없이 다른 환경에서 일하게 되더라도 선호하는 도구
에 집착하며 그 도구를 사용할 수 있는 방법을 찾아 헤매곤 한다. 새로운 문법과 새로운 패
턴을 습득해야 하는 새로운 도구를 도입하는 것은 최선의 상황에서도 꽤 힘든 도전적인 일
이다.
스파크에는 R이나 파이썬으로 코드를 작성할 수 있는 라이브러리와 래퍼Wrapper가 있다. 그중
파이스파크PySpark라는 훌륭한 파이썬 래퍼는 이 책의 11장에서도 일부 다루고 있다. 하지만 대
부분의 예제는 스칼라로 제공할 것이다. 스파크 자체가 스칼라 언어로 구현되어 있어서, 스칼
라를 직접 사용하면 다음과 같은 효과를 기대할 수 있다.
성능 면에서 유리하다.
스칼라처럼 JVM에서 동작하는 언어 위에서 R이나 파이썬으로 만들어진 알고리즘을 실행하
려면 코드와 데이터를 변환하거나 다른 환경으로 옮기는 작업이 추가로 필요하며, 때에 따
라서는 이 추가 과정에서 오류가 생길 수도 있다. 반면, 스파크가 제공하는 스칼라 API를 사
용한다면 의도한 대로 동작할 가능성이 매우 커진다.
312장 스칼라와 스파크를 활용한 데이터 분석
최신 기능을 활용할 수 있다.
스파크의 머신러닝, 스트림 처리, 그래프 분석 등의 라이브러리는 모두 스칼라로 작성했기
때문에 새로운 기능이 파이썬이나 R 환경까지 지원하는 데 시일이 걸리는 편이다. 그러므로
스파크가 제공하는 모든 최신 기능을 곧바로 사용하려 한다면 최소한 스칼라에 대해서 조금
은 알아야 하며, 그 기능들을 확장하여 새로운 문제에 적용하려면 스칼라를 어느 정도 능숙
하게 다룰 수 있어야 한다.
스파크의 철학을 이해하기 쉽다.
파이썬이나 R로 스파크를 사용한다 할지라도, 스파크의 API에는 이를 구현한 언어인 스칼
라로부터 시작된 철학이 녹아 있다. 여러분이 다른 언어를 사용하더라도 스칼라로 스파크를
다루는 방법을 알고 있다면 스파크 체계를 이해하고 문제를 ‘스파크답게’ 해결하는 데 도움
이 된다.
다른 데이터 분석 도구들과는 많이 다르기 때문에 설명하기 힘든, 스칼라의 또 다른 장점이
있다. 만약 R이나 파이썬으로 데이터베이스에 있는 데이터를 분석해왔다면 필요한 데이터를
SQL로 가져온 후, 작업 환경을 R이나 파이썬으로 바꿔서 그 데이터를 다루고 시각화하는 절차
에 익숙할 것이다. 누군가는 클러스터에 저장된 데이터에 접근하여 작업하는 일(SQL)과 PC
에 저장된 데이터를 다루고 시각화하는 일(파이썬/R)에 각각 다른 언어를 사용해왔을 수도 있
다. 그리고 SQL 사용자 정의 함수를 이용해 데이터를 처리하는 위치를 데이터베이스 엔진으로
옮기고 싶다면 C++나 자바 같은 또 다른 프로그래밍 환경으로 바꿔 작업해야 할 수도 있다.
오랫동안 사용해 익숙해졌다면 이런 방식의 불편함을 자각하지 못할지도 모른다.
스칼라와 스파크를 사용한다면 이야기가 달라진다. 어떤 경우에도 같은 언어를 사용할 수 있기
때문이다. 스파크를 통해 클러스터에서 데이터를 가져오고, 그 데이터를 로컬 환경에서 다루는
일 모두를 스칼라 코드를 작성하여 처리할 수 있다. 무엇보다 좋은 점은 로컬에서 작성한 스칼
라 코드를 클러스터로 보내서, 클러스터에 저장된 데이터를 로컬에서 다룬 결과와 완전히 똑같
이 처리할 수 있다는 것이다. 심지어 Spark SQL과 같은 고수준 언어로 작업할 때도 자신만의
사용자 정의 함수를 만들어 Spark SQL 엔진에 등록하여 그대로 사용하면 되며, 이 과정에서
작업 환경을 바꿀 필요가 없다.
32 9가지 사례로 익히는 고급 스파크 분석 (2판)
데이터의 저장 위치나 처리 위치와 상관없이, 데이터를 조작하고 분석하는 모든 일을 하나의
환경에서 할 수 있다는 것이 얼마나 혁신적인지 설명하기는 쉽지 않지만, 일단 경험해보면 알
것이다. 필자들은 스파크를 처음 접했을 때 느꼈던 신비한 힘을 예제에 담아내려고 노력했다.
2.2 스파크 프로그래밍 모델
스파크 프로그래밍을 위해서 데이터와 이를 담은 저장소가 필요하다. 데이터는 보통 HDFS와
같은 분산 저장소에 저장한다. 일반적으로 스파크 프로그램은 다음과 같은 몇 개의 연이은 단
계로 구성된다.
1.	‌‌입력 데이터에 적용할 변환을 정의한다.
2.	‌‌변환된 데이터를 저장소로 보내거나 구동자Driver의 로컬 메모리로 반환하는 액션을 수행한다.
3.	‌‌분산 처리 방식으로 계산된 결과를 바탕으로 로컬 계산을 수행한다. 이 작업은 다음에 수행할 변환과 액션을
결정하는 기준이 될 수도 있다.
스파크 버전이 1.2에서 2.1로 진화함에 따라 각 단계를 수행할 때 사용할 수 있는 도구들이 양
적, 질적으로 발전했다. 분석을 수행하는 과정의 복잡한 SQL 질의, 머신러닝 라이브러리 및 사
용자 작성 코드들을 섞어 쓰거나 골라 쓸 수 있고, 더 짧은 시간에 더 많은 응답을 제공하기 위
해서 수년간 스파크 커뮤니티가 개발해온 모든 상위 수준의 추상화를 활용할 수 있다. 동시에,
이 모든 상위 수준 추상화가 ‘저장소와 실행 사이의 상호작용’이라는 스파크의 가장 근원적인
철학을 지켜나가고 있다는 점을 기억해둬야 한다. 스파크는 데이터 처리 파이프라인상의 어떤
중간 단계에서도 이후에 사용하기 위해서 메모리에 데이터를 캐시할 수 있도록 하여 이러한 추
상화를 훌륭하게 결합한다. 이 원칙을 이해한다면 데이터 분석에 스파크를 더 효율적으로 활용
할 수 있다.
2.3 레코드 링크
이 장에서 논의할 문제는 문헌과 실무 현장에서 엔티티 해소Entity Resolution, 레코드 중복 제거Record
Deduplication, 병합 및 제거Merge-and-purge, 목록 정리List Washing 등 다양한 이름으로 불리고 있다. 모
332장 스칼라와 스파크를 활용한 데이터 분석
순되게도 이 문제가 다양한 이름으로 불리기 때문에 문제 해결을 위한 기술들을 훑어보고자 해
도 관련 논문조차 다 찾아내기 어렵다. 오히려 이 데이터 정제 문제에 대한 참고 문헌들에서 중
복 제거를 수행할 데이터 과학자가 필요한 처지다! 이 장의 목적을 원만히 이루기 위해 이제부
터 ‘같은 실체를 가리키는 레코드들을 연결 짓는’ 이 문제를 레코드 링크Record Linkage라 하겠다.
이 문제의 일반적인 형태는 다음과 같다. 하나 또는 그 이상의 데이터 출처로부터 데이터를 수
집하여 취합하면 그 속의 레코드 일부가 실제로는 같은 고객, 같은 환자, 같은 위치, 같은 행사
등 동일한 실체를 가리킬 수 있다. 각 실체는 이름, 주소, 생일과 같은 여러 속성을 가지고 있어
서 동일한 실체를 가리키는 레코드들을 찾아내려면 이 속성값을 이용해야 한다. 안타깝게도 이
속성값들은 불완전하다. 형식이 다르거나 오타가 있거나 값이 누락되었을 수 있다. 그러므로
단순하게 속성의 값이 같은지만을 검사한다면 상당수의 중복 레코드를 놓치게 될 것이다. [표
2-1]을 살펴보자.
표 2-1 레코드 링크의 어려움
이름 주소 도시 주 전화번호
조시의 커피숍 선셋 대로 1234 서 할리우드 CA (213)-555-1212
조시 커피 선셋 대로 1234, 서 할리우드 CA 555-1212
커피숍 체인 #1234 선셋 가 1400, 2 할리우드 CA 206-555-1212
커피숍 체인 지역 사무소 선셋 가 1400, 2호실 할리우드 캘리포니아 206-555-1212
이 표에서 위의 두 줄은 각각 ‘서 할리우드’와 ‘할리우드’라는 도시에 있는 서로 다른 작은 커피
숍처럼 보인다. 하지만 이는 입력상의 실수로, 사실은 같은 커피숍을 가리킨다. 그다음의 두 줄
은 주소가 같지만 2개의 서로 다른 사업장을 가리키고 있는데, 하나는 실제 커피숍이며 다른
하나는 지역의 체인점 사무소다. 둘 다 시애틀에 있는 본사의 대표 전화번호가 기록되어 있다.
이 예제는 레코드 링크가 얼마나 어려운지를 보여준다. 각각의 묶음이 서로 유사하게 보이더라
도 중복이 있는지를 결정하기 위해 사용하는 기준은 묶음마다 다르다. 사람은 직관으로 쉽게
구분할 수 있겠지만 컴퓨터가 그 구분법을 학습하기에는 어려운 형태다.
34 9가지 사례로 익히는 고급 스파크 분석 (2판)
2.4 스파크 셸과 SparkContext 시작하기
여기에서는 UC 어바인의 머신러닝 데이터 저장소UC Irvine Machine Learning Repository에서 구할 수 있는
표본 데이터를 사용한다. 이 저장소에서 연구와 교육을 위한 흥미로운 (더구나 무료인) 데이
터셋들을 구할 수 있다. 우리가 분석할 데이터셋은 2010년에 독일의 한 병원에서 실시한 레코
드 링크 연구에서 나온 것으로, 환자의 성과 이름, 주소, 생일 등 몇 가지 기준에 따라 묶은 수
백만 건의 환자 기록 묶음이 들어 있다. 각 묶음에는 문자열 유사도에 따라 0.0부터 1.0까지 점
수를 매겼고, 그 후 같은 사람을 표현한 묶음과 그렇지 않은 묶음을 분류해 일일이 표시하였다.
데이터셋을 만드는 데 사용한 필드 자체의 원래 값은 환자의 개인 정보를 보호하기 위해 제거
되었으며 식별번호, 필드별 유사도 점수, 묶음별 실제 분류값(같은 사람인지 여부)이 레코드
링크 연구 용도로 발행되었다.
다음과 같이 셸shell 명령어로 저장소로부터 데이터를 가져오자.
$ mkdir linkage
$ cd linkage/
$ curl -L -o donation.zip http://bit.ly/1Aoywaq
$ unzip donation.zip
$ unzip 'block_*.zip'
사용할 수 있는 하둡 클러스터가 있으면, HDFS에 블록 데이터용 디렉터리를 생성하고 데이터
파일을 그 디렉터리에 복사한다.
$ hadoop fs -mkdir linkage
$ hadoop fs -put block_*.csv linkage
이 책의 예제 코드는 2.1.0 버전의 스파크를 사용한다. 필요한 릴리스는 스파크 프로젝트 사이
트에서 내려받을 수 있다(http://spark.apache.org/downloads.html). 클러스터 환경을 사용
하든 로컬 PC 환경을 사용하든, 스파크 참조 문서를 보고 환경을 설정하면 된다(http://spark.
apache.org/docs/latest/).
이제 spark-shell을 실행할 준비가 되었다. spark-shell은 스파크 확장 API를 제공하는 스
칼라 REPL이다. REPL이라는 용어가 생소하다면 R 환경과 유사한 것으로 생각하면 된다.
spark-shell은 스칼라 프로그래밍 언어를 사용하여 함수를 정의하고 데이터를 다룰 수 있는
713장 음악 추천과 Audioscrobbler 데이터셋
“De gustibus non est disputandum.”
(취향에 이유를 따지지 마라.)
-작자 미상
누군가 나에게 무슨 일을 하냐고 물을 때 ‘데이터 과학’ 또는 ‘머신러닝’이라고 직접적으로 대답
하면, 들리기야 멋있게 들리지만 반응은 싸한 편이다. 실제 데이터 과학자들조차도 이 용어의
뜻을 명확하게 정의하지 못하고 있으니(많은 데이터를 저장하고, 계산하고, 무언가 예측하는
일?) 당연히 그럴 만하다. 대신 예를 들어 대답해보자.
“아마존에서 고객이 과거에 구매한 책들과 유사한 책을 추천해주는 걸 알고 계신가요? 정말요?
네. 바로 그게 제가 하는 일입니다.”
추천 엔진은 적어도 내 주변 사람은 모두 알고 있으며, 또 많은 사람이 아마존을 통해 경험한
대규모 머신러닝의 사례일 것이다. 소셜 네트워크에서 동영상 사이트, 그리고 온라인 쇼핑몰까
지 추천 엔진은 모든 영역에 적용되는 공통분모에 해당하며, 실제로 동작하는 모습을 직접 관
찰할 수도 있다. Gmail이 우리가 신경 쓰지 않아도 스팸을 골라내는 것과 흡사한 방법으로, 스
포티파이Spotify 역시 재생할 음악을 컴퓨터가 골라주고 있다는 사실을 알고 있다.
추천 알고리즘의 결과는 다른 머신러닝 알고리즘보다 훨씬 직관적이다. 게다가 흥미롭기까지
하다. 우리가 개인의 음악 취향이 너무 사적이어서 설명할 수 없다고 생각한다는 점을 고려해
음악 추천과 Audioscrobbler 데이터셋
CHAPTER 3
션 오언
72 9가지 사례로 익히는 고급 스파크 분석 (2판)
보면, 추천 엔진은 우리가 좋아하리라 생각하지도 못한 음악을 찾아내는 놀라운 일을 해낸다.
추천 엔진이 널리 사용되는 음악과 영화 분야에서는 추천된 목록이 누군가 과거에 접해본 콘텐
츠와 왜 잘 들어맞는지를 추리해내기가 상대적으로 쉽다. 하지만 모든 군집화Clustering1
나 분류
Classification 알고리즘이 설명하기 쉬운 건 아니다. 예컨대 서포트 벡터 머신Support Vector Machine 분류
기는 계수들의 집합으로 구성되는데, 예측은 하더라도 그 계수들의 의미를 설명하기란 전문가
조차도 쉽지 않다.
그래서 앞으로 3개 장에 걸쳐서 스파크의 핵심 머신러닝 알고리즘을 다뤄보려 한다. 그중 처음
인 이번 장은 음악에 특화된 추천 엔진을 들여다보겠다. 이는 스파크와 MLlib을 실제 세상의
문제에 적용하는 방식을 소개하고, 이어지는 장에서 더 깊게 파헤칠 머신러닝 알고리즘의 기본
을 소개하는 적절한 방법일 것이다.
3.1 데이터셋
이 장의 예제에서는 오디오스크로블러Audioscrobbler에서 공개한 데이터셋을 사용한다. 오디오스
크로블러는 2002년에 초기 인터넷 스트리밍 라디오 서비스를 제공한 last.fm(http://www.
last.fm)을 위해서 만들어진 첫 번째 음악 추천 시스템이다. 오디오스크로블러는 ‘스크로블링’2
용 오픈 API를 제공했고, 청취자의 음악 재생 내역을 기록했다. 서드파티 앱과 사이트들이 추
천 엔진에 음악 감상 관련 데이터를 돌려준 덕에, 이 시스템의 사용자는 수백만 명에 이르렀다.
당시의 추천 엔진 관련 연구는 대부분 평점 데이터를 학습하는 데 그쳤다. 즉, “개똥이가 소녀
시대에게 별점 3개 반을 주었군”과 같은 입력에 기초해 동작하는 도구처럼 보이곤 했다.
오디오스크로블버의 데이터셋이 재미있는 점은 “개똥이가 소녀시대 음악을 들었어”와 같은 단
순 재생 정보만 기록한다는 것이다. 단순 재생 여부는 평점보다 정보가 적다. 개똥이가 듣는다는
사실만으로 개똥이가 실제로 좋아하는지 혹은 싫어하는지를 판단할 수 없기 때문이다. 종종 별
관심 없는 아티스트의 음악을 틀어놓을 때도 있고, 또 음악을 틀어놓고 외출해버릴 수도 있다.
1	 옮긴이_ 흔히 영어를 그대로 읽어 클러스터링이라 부르지만, 이 책에서는 분산 처리 분야의 용어인 클러스터와 명확히 구분하기 위해 우
리말 용어인 군집화로 옮긴다.
2	 옮긴이_음악을 들을 때 아티스트, 제목, 앨범 등의 정보를 last.fm 서버에 보내는 작업이다.
733장 음악 추천과 Audioscrobbler 데이터셋
하지만 감상한 음악에 평점을 매기는 횟수는 음악을 듣는 일에 비해서 훨씬 드물다. 그래서 음
악 감상 데이터 하나의 정보량은 음악 평점 데이터 하나의 정보량보다 적지만, 음악 감상 데이
터셋은 크기도 훨씬 크고, 더 많은 사용자와 아티스트를 포함하며, 정보의 총량도 훨씬 많다.
사용자와 아티스트 사이의 관계가 명시적 평점이나 ‘좋아요’ 버튼으로 직접 주어지지 않고 다
른 행위들로부터 의도치 않게 은연중에 드러나기 때문에 이런 종류의 데이터를 암묵적 피드백
Implicit Feedback이라고 부르기도 한다.
2005년에 last.fm에서 배포한 데이터셋의 스냅샷을 인터넷에서 압축된 파일 형태로 구할 수
있다. https://goo.gl/yoWRAl 에서 압축 파일을 내려받은 후, 그 안의 몇몇 파일을 찾아보자.
중심이 되는 데이터셋은 user_artist_data.txt 파일에 들어 있다. 이 안에는 141,000명의 사
용자와 160만 명의 아티스트 정보가 담겨 있으며 약 2,420만 건의 음악 재생 정보가 재생 횟
수와 함께 기록되어 있다.
또한, 이 데이터셋의 artist_data.txt 파일에는 각각의 아티스트에 ID를 부여하고 있다. 음악
이 재생되면 클라이언트 프로그램이 재생되는 아티스트의 이름을 전송하는데, 그 이름은 잘못
기록되었거나 공식 명칭이 아닐 수 있으며, 이러한 오류가 뒤늦게 발견될 수도 있다. 예를 들어
“The Smiths”, “Smiths, The”, “the smiths”는 데이터셋 안에서는 별도의 아티스트 ID를 가
질지도 모르지만, 이 모두가 단 한 사람에게 붙여진 것일 수 있다. 그래서 데이터셋의 artist_
alias.txt 파일은 아티스트 명칭의 흔한 오기 패턴과 다양한 변형 표기법으로 기록된 아티스트
ID를 해당 아티스트의 대표 ID와 연결짓고 있다.
3.2 교차 최소 제곱 추천 알고리즘
우리는 암묵적 피드백 데이터에 적합한 추천 알고리즘을 선택해야 한다. 우리의 데이터셋은 전
적으로 사용자와 아티스트의 음악 사이의 상호작용으로만 구성되며, 아티스트 이름 외에 사용
자와 아티스트에 대한 어떤 정보도 포함하고 있지 않다. 우리는 사용자와 아티스트의 속성에
대해 아는 바가 없어도 학습이 가능한 알고리즘이 필요하다. 이런 알고리즘을 일반적으로 협업
필터링Collaborative Filtering (https://goo.gl/eK7KYG)이라고 한다. 예를 들어 두 사용자가 단지 동
년배라서 취향이 비슷하다고 이야기하는 것은 협업 필터링이 아니다. 두 사람이 들은 노래 중
같은 것이 많기 때문에 같은 노래를 좋아할 수도 있다고 예측하는 것이 협업 필터링의 예라고
74 9가지 사례로 익히는 고급 스파크 분석 (2판)
할 수 있다.
수천만 건의 재생 기록을 담은 이 데이터는 얼핏 방대해 보이지만, 다른 관점에서 보면 밀도가
낮기 때문에 꼭 그렇지도 않다. 한 사용자가 160만 명의 아티스트 중 평균 171명의 노래만 재
생했다. 어떤 사용자는 딱 한 아티스트의 노래만 듣기도 했다. 이런 사용자들에게도 괜찮은 추
천이 가능한 알고리즘이 필요하다. 어찌 되었든 음악을 듣는 누구라도 처음에는 딱 한 곡의 청
취 기록만 있었을 것이다!
결국 대규모 모델을 만들 수 있고 동시에 빠르게 추천해주는, 확장 가능한 알고리즘이 필요하
다. 일반적으로 추천 결과가 내일 나온다면 너무 늦다. 1초 이내의 준 실시간으로 나와야 한다.
이 예제에서는 잠재요인Latent-factor (https://goo.gl/w0isfF) 모델로 분류할 수 있는 많은 알고리
즘 중 하나를 사용하고자 한다. 잠재요인 모델은 다수의 사용자와 아이템 사이에서 관측된 상
호작용Observed Interaction을 상대적으로 적은 수의 관측되지 않은 숨은 원인Unobserved Underlying Reason
으로 설명하려 할 때 사용한다. 이는 수백만의 사람이 수천 개의 음반 중 특정 음반을 구입한
이유를 (직접 관측할 수 없고 데이터도 주어지지 않은) 수십 개 음악 장르에 대한 개인 취향으
로 설명하는 것과 유사하다.
예를 들어 메탈 밴드인 메가데스와 판테라의 음반뿐 아니라 클래식 작곡가 모차르트의 음반을
구매한 사람을 생각해보자. 왜 이런 음반만 구매하고 다른 음반은 구매하지 않았는지에 대한
정확한 이유를 설명하는 것은 어렵다. 그렇지만 이 음반들은 더 큰 음악 취향에서의 매우 작은
부분일 수 있다. 이 사람은 아마도 메탈 음악부터 프로그레시브 록, 클래식에 이르는 음악을 좋
아할 것이다. 이렇게 설명하는 것은 더 간단할 뿐 아니라 이 설명을 바탕으로 흥미를 유발할 수
있는 다른 많은 앨범을 제안할 수도 있다. 여기서 메탈, 프로그레시브 록, 클래식을 좋아한다는
것이 수만 개의 앨범 각각에 대한 선호도를 설명할 수 있는 세 개의 숨은 원인이다.
더 구체적으로는 행렬 분해Matrix Factorization (https://goo.gl/w0isfF) 모델을 사용할 것이다. 수학
적으로 이들 알고리즘에서는 사용자와 제품 데이터를 큰 행렬 A로 간주해 다루는데, A는 사용
자 i가 아티스트 j의 음악을 들었다면 A의 i행 j열에 값이 존재하는 행렬이다. A는 희소 행렬
Sparse Matrix이다. 사용자-아티스트의 가능한 모든 조합 중 오직 극소수만이 실제 데이터로 등장
하기 때문에, 이 행렬의 원소 대부분은 0이 된다. 이들 행렬 분해 알고리즘은 A를 더 작은 행렬
X와 Y의 행렬 곱으로 분해하는데, 이 X와 Y는 매우 길쭉하다. A가 다수의 행과 열을 가지기
때문에 X와 Y는 매우 많은 행을 가지게 되는 데 반해, 열은 몇 개(k) 되지 않는다. k개의 열은
753장 음악 추천과 Audioscrobbler 데이터셋
상호작용하는 데이터를 설명하는 데 사용하는 잠재요인에 해당한다.
[그림 3-1]에서 볼 수 있듯, k가 작기 때문에 이 분해는 근사치일 수밖에 없다.
그림 3-1 행렬 분해
원래의 행렬 A는 매우 희소한 데 비해 행렬 곱 XYT
는 밀도가 매우 높아서 이 알고리즘을 행렬
채우기Matrix Completion 알고리즘이라고 부를 때도 있다. 설사 값이 0인 원소가 있다 할지라도 매
우 드물게 나타나므로, 이 모델은 A의 근삿값일 뿐이다. 원래의 행렬 A에서 결측된(즉, 값이 0
인) 많은 원소에 대한 값조차도 생성한다는(채워준다는) 점에서 행렬 분해는 하나의 모델이라
할 수 있다.
다행히도 선형대수학이 직관과 아주 잘 들어맞는다. 이 두 행렬은 각 사용자와 각 아티스트를
하나씩의 행으로 담고 있다. 이 행들은 매우 작은 수(k개)의 값만을 가진다. 그리고 각 값은 모
델에서 잠재특징Latent Feature에 대응한다. 그래서 행들은 사용자와 아티스트가, 아마도 취향이나
장르에 대응하리라 추측되는 이들 잠재 특징과 얼마나 밀접하게 관련되는지를 표시하게 된다.
그리고 간단히 사용자-특징 행렬과 특징-아티스트 행렬을 곱하는 것으로 사용자-아티스트
상호작용 밀집 행렬 전체의 근사치를 얻을 수 있다. 이 행렬 곱은 아이템을 아이템 속성들에 대
응시킨 뒤 사용자 속성들을 가중치로 준 것으로 생각할 수 있다.
안타까운 점은 A를 완벽하게 표현하기에는 X와 Y가 충분히 크지 않아(선형대수학에서는 계수
Rank가 너무 작다고 기술한다. https://goo.gl/49ymAa) 일반적으로 정확하게 A = XYT
를 만족
하는 해를 구할 수 없다는 것이다. 하지만 알고 보면 나쁘지 않다. A는 발생할 수 있는 모든 상
76 9가지 사례로 익히는 고급 스파크 분석 (2판)
호작용 중 아주 작은 표본일 뿐이다. 우리는 A 행렬의 정보가 매우 드문드문 존재해서 (단지
몇 가지 작은 k개의 요인으로 잘 설명되는) 훨씬 간단한 감춰진 진실의 모습을 설명하기 힘든
것으로 생각한다. 고양이 그림의 직소 퍼즐을 생각해보자. 완성된 퍼즐을 보고 고양이라고 설
명하기는 아주 쉬워도, 조각 몇 개만 쥐고 있다면 이것이 어떤 그림이라고 설명하기란 매우 어
렵다.
XYT
은 여전히 A에 가능한 한 가까워야 한다. 어쨌든 이것이 우리가 해야 할 일이다. 정확하게
구하지는 못할 것이고 또 구할 수도 없다. 설상가상으로, X와 Y의 가장 좋은 답을 동시에 직접
적으로 구할 수조차 없다. 그나마 나은 소식은 Y를 알고 있을 때는 X의 정답을 구할 수 있음이
자명하고, 그 반대도 마찬가지라는 것이다. 뭐, 아직은 둘 다 모르는 상태지만!
다행히 이런 딜레마를 극복하고 제대로 된 해를 찾아주는 알고리즘이 있다. 더 구체적으로 설
명하면, 이 장의 예제에서는 X와 Y를 계산하기 위해 교차 최소 제곱Alternating Least Squares (ALS,
https://goo.gl/hPoZq5) 알고리즘을 사용할 것이다. 이런 종류의 접근법은 넷플릭스 프라이즈
Netflix Prize (https://goo.gl/EtIzYO)가 열리던 시절에 발표된 「암묵적 피드백 데이터셋에 대한 협
업 필터링Collaborative Filtering for Implicit Feedback Datasets」 (https://goo.gl/8WZqmk)과 「넷플릭스 프라이
즈를 위한 대규모의 병렬 협업 필터링Large-scale Parallel Collaborative Filtering for the Netflix Prize」(https://goo.
gl/tG99s9) 같은 논문 덕에 유명해졌다. 사실 스파크의 MLlib이 제공하는 ALS 알고리즘도 이
논문들에서 아이디어를 가져와 구현한 것이다.
Y의 값을 모르지만, 무작위로 값이 선택된 행 벡터로 초기화할 수는 있다. 그런 다음 간단한 선
형대수를 통해 주어진 A와 Y에 대한 최적 X를 구할 수 있다. 사실, X의 각 행 i는 Y와 A의 한
행의 함수로 독립적으로 쉽게 계산할 수 있다. 독립적으로 수행할 수 있으니 병렬 처리가 가능
하며, 이는 대규모로 계산할 때 매우 훌륭한 장점이다.
AiY(YT
Y )-1 = Xi
이 수식의 양 변을 똑같이 만들기란 불가능하므로, 우리의 목표는 양 변의 차이인
|AiY (YT
Y )-1
- Xi|, 즉 두 행렬에서 대응되는 원소 간 차의 제곱의 합을 최소화하는 것이다.
여기서 최소 제곱Least Squares이라는 이름이 유래되었다. 실전에서는 역행렬을 구하는 방법으로
계산하지 않고 QR 분해QR Decomposition (https://goo.gl/OvtPVU)와 같은 방법으로 더 빠르게 바
로 계산할 수 있다. 앞의 식은 단순히 행 벡터가 어떻게 계산되는지의 이론을 설명하기 위한 것
1014장 의사 결정 나무로 산림 식생 분포 예측하기
“예측은 매우 어려우며, 미래에 대해서는 특히 그렇다.”
-닐스 보어
19세기 후반 영국의 우생학자 프랜시스 골턴 경Sir Francis Galton은 완두콩과 사람 등을 대상으로 그
키를 측정하는 데 집중했다. 그는 키가 큰 완두콩과 사람의 다음 세대 역시 평균보다 크다는 사
실을 발견했다. 놀라운 발견이라고 할 수는 없다. 하지만 자식 세대는 평균적으로 부모보다 조
금 작았다. 키가 2미터에 달하는 야구 선수의 자식은 물론 평균보다는 크겠지만, 그렇다고 2미
터까지 크지는 않는다는 뜻이다.
이 연구의 뜻하지 않은 결과 덕분에 골턴 경은 부모 세대의 키와 비교하여 자식 세대의 키를 정
리해보았고 둘 사이에 대략적인 선형 관계가 있음을 알아냈다. 큰 부모 완두콩은 큰 자식 완두
콩으로 이어졌지만, 부모보다는 조금 작았다. 작은 부모 완두콩도 작은 자식 완두콩으로 이어
지지만, 역시 부모보다는 조금 컸다. 이 선형 관계에서 직선의 기울기는 1보다 작은 양수였고,
골턴 경은 이 현상을 평균으로의 회귀Regression to the Mean라고 표현했다. 오늘날 우리도 이 표현을 사
용한다.
당시에는 인지하지 못했을지언정, 이 선형 관계는 예측 모델의 오래된 예로 보인다. 두 값을 연
결한 선이 있다는 것은 하나의 값이 다른 값에 대해 많은 것을 시사할 수 있음을 의미한다. 어
떤 완두콩의 자식의 크기는 그 완두콩과 비슷하리라고 가정하는 것보다 이 관계를 이용하여 그
크기를 계산하는 쪽이 훨씬 정확할 것이다.
의사 결정 나무로
산림 식생 분포 예측하기
CHAPTER 4
션 오언
102 9가지 사례로 익히는 고급 스파크 분석 (2판)
4.1 회귀로 돌아와서
통계학이 체계를 갖춘 지 한 세기 이상이 지나고 머신러닝과 데이터 과학이 등장한 오늘날에
도, 주어진 값들로부터 새로운 값을 예측하는 방법으로 ‘회귀(https://goo.gl/yFA7xy)’를 꼽는
다. 심지어 값이 평균에 가까워지거나 실제로 가까워지려는 움직임조차 없을지라도 말이다. 또
한, 회귀 기법은 분류 기법과 연관이 있다(https://goo.gl/Tq7xfG). 일반적으로 회귀는 크기,
수입, 온도와 같은 숫자를 예측하며, 분류는 ‘스팸 메일’, ‘고양이 사진’과 같은 레이블이나 범주
를 예측하는 데 사용한다.
회귀와 분류는 모두 하나 이상의 값이 주어졌을 때 하나 이상의 값을 예측해낸다. 이를 위해서
학습을 위한 입출력 체계가 구성되어 있어야 하며, 질문과 이에 대한 답변도 제공되어야 한다.
이러한 탓에 회귀와 분류는 지도 학습Supervised Learning (https://goo.gl/ktFn24) 유형에 들어간다.
분류와 회귀는 가장 오래되고 가장 잘 연구된 유형의 예측 분석이다. 서포트 벡터 머신Support
Vector Machine, 로지스틱 회귀Logistic Regression, 나이브 베이즈 분류Naïve Bayes, 신경망Neural Network, 딥러
닝Deep Learning과 같은 분석 패키지나 라이브러리에서 자주 접하는 대부분의 알고리즘은 분류와
회귀 기법이다. 3장의 주제인 추천 엔진도 더 직관적이라는 이유로 앞 장의 주제로 사용했지
만, 역시 비교적 최근에 따로 떨어져나온 머신러닝의 하위 주제일 뿐이다.
이번 장에서는 분류와 회귀 모두에 적용할 수 있는 대중적이고 유연한 알고리즘인 의사 결정
나무(https://goo.gl/CT9gWE), 그리고 이 알고리즘의 확장판인 랜덤 포레스트(https://goo.
gl/fC83b1)를 다루고자 한다. 이 알고리즘과 관련한 흥미로운 사실은 닐스 보어가 미래 예측
에 대해서 말한 것과 달리 미래 예측에 사용할 수 있으며, 적어도 아직은 우리가 명확히 알지
못하는 것을 예측할 수 있다는 것이다. 예를 들어 온라인에서의 행동 양식으로부터 자동차를
살 가능성을 예측한다든지, 이메일 본문의 어떤 단어로부터 그 이메일이 스팸인지 여부를 찾아
낸다든지, 위치와 토양의 화학성분비가 주어졌을 때 어느 부분의 땅이 작물을 가장 잘 키워낼
지와 같은 것이다.
4.2 벡터와 특징
특정 데이터셋과 알고리즘을 선택하는 방법, 그리고 회귀와 분류가 동작하는 방법을 설명하려
1034장 의사 결정 나무로 산림 식생 분포 예측하기
면 우선 입력과 출력을 나타내는 용어들을 간단하게 정의해둬야 한다.
오늘의 날씨를 전제로 내일 최고 기온을 예측하는 문제를 생각해보자. 별문제 없어 보이지만,
그저 ‘오늘의 날씨’라고 하면 너무 광범위한 개념이라 학습 데이터로 사용하려면 구조화해야
한다.
오늘 날씨의 다음과 같은 특징Feature으로부터 내일 기온을 예측할 수 있다.
●	‌‌‌오늘의 최고 기온
●	‌‌‌오늘의 최저 기온
●	‌‌‌오늘의 습도
●	‌‌‌흐림(cloudy), 비(rainy), 맑음(clear)과 같은 날씨 유형
●	‌‌‌내일 일시적 한파를 예상한 기상 예보관의 수
이 특징들은 종종 차원Dimension, 예측 변수Predictor 또는 단순히 변수Variable로 불린다. 각각의 특징
은 정량화될 수 있다. 예를 들어 최고 기온과 최저 기온은 섭씨온도로 측정하고, 습도는 0과 1
사이의 소수로 계량하고, 날씨 유형은 ‘cloudy’, ‘rainy’, ‘clear’로 표시할 수 있다. 물론 예보관
의 수는 정수다. 이에 따라 오늘의 날씨는 ‘13.1, 19.0, 0.73, cloudy, 1’과 같은 하나의 리스
트로 축약할 수 있다.
이 다섯 특징을 순서대로 묶어 특징 벡터Feature Vector라 하고, 어떤 날의 날씨를 표현할 수 있다. 이
벡터에 숫자형이 아닌 값이 포함될 수 있고, 또 어떤 값은 생략될 수도 있다는 점만 제외하면
선형대수에서의 벡터 사용법과 비슷하다.
이들 특징은 모두 형식이 제각각이다. 앞의 둘은 섭씨온도로 측정한 값이지만, 세 번째는 단위
가 없는 비율이다. 네 번째는 아예 수가 아니고, 다섯 번째는 음이 아닌 정수다.
논하는 바의 목적에 맞춰 이 책에서는 범주형 특징Categorical Feature과 수치형 특징Numeric Feature 두 종류
의 특징에 대해서만 다룰 것이다. 여기서 수치형 특징은 수를 사용해 정량화할 수 있고 순서가
의미가 있다. 예를 들어 오늘의 최고 기온인 23도가 어제 최고 기온인 22도보다 높다고 이야기
하는 것은 유효하다. 날씨 유형을 제외한 모든 특징은 수다. ‘clear’와 같은 용어는 수도 아니고
순서도 없다. 그래서 ‘cloudy’가 ‘clear’보다 크다고 말하는 것은 의미가 없다. 이는 범주형 특
징에 해당하며, 여러 불연속Discrete 값 중 하나를 취하게 된다.
104 9가지 사례로 익히는 고급 스파크 분석 (2판)
4.3 학습 예제
예측을 수행하려면 먼저 학습 알고리즘을 데이터로 학습시켜야 한다. 이를 위해 과거 데이터
로부터 얻은 많은 수의 입력 데이터와 그 각각에 대응하는 정확한 출력 데이터가 필요하다. 다
시 오늘의 날씨를 예로 들자면, 어느 날 기온은 최저 12도, 최고 16도이며, 습도는 10%에 날씨
는 맑고, 아무도 한파를 예상하지 않았다는 그 날의 날씨 정보가 입력 데이터가 되고, 다음 날
의 최고 기온인 17.2도가 출력 데이터가 된다. 이 둘을 동시에 학습 알고리즘에 제공하는 형태
로 학습이 이뤄진다. 이러한 예제 데이터가 충분히 많이 있어야 다음 날의 최고 기온을 예측하
는 학습 알고리즘을 제대로 학습시킬 수 있다.
특징 벡터는 학습 알고리즘용 입력을 표현하는 체계적인 방법을 제공한다. 여기에서는 {12.5,
15.5, 0.10, clear, 0}이 된다. 예측의 출력이나 목표Target 또한 특징으로 간주할 수 있는데, 예
를 들어 내일 최고 기온 17.2는 수치형 특징이다. 입력용 특징 벡터에 목표를 하나의 특징으로
포함시키는 것은 드문 일이 아니다. 학습을 위한 완전한 예는 목표인 다음 날의 최고 기온까지
포함한 {12.5, 15.5, 0.10, clear, 0, 17.2}로 봐야 하며, 이 예들의 집합을 학습 데이터셋Training
Set이라고 한다.
회귀에서는 수를, 분류에서는 범주를 대상으로 삼는다는 점을 기억하자. 모든 회귀나 분류 알
고리즘이 범주형 특징을 다루거나 범주를 목적으로 할 수 있는 것은 아니다. 일부는 수치형 특
징으로만 제한된다.
4.4 의사 결정 나무와 랜덤 포레스트
의사 결정 나무Decision Tree에 속하는 알고리즘은 범주형 특징과 수치형 특징 모두를 자연스럽게 다
룰 수 있다. 단일 트리와 다중 트리 모두 병렬로 바로 구축할 수도 있다. 의사 결정 나무는 데이
터 내의 이상치Outlier에 잘 휘둘리지 않는다는 특성이 있는데, 몇몇 극단적인 오류를 내포한 값
들이 예측치에 영향을 줄 수 없음을 뜻한다. 그리고 전처리나 정규화 과정을 거치지 않고도 다
른 유형과 다른 척도의 데이터를 다룰 수 있다(이 내용은 5장에서 다시 소개할 것이다).
의사 결정 나무를 더 강력하게 일반화한 알고리즘이 랜덤 포레스트Random Decision Forest다. 이 장에서
는 스파크 MLlib이 제공하는 DecisionTree와 RandomForest를 데이터셋에 적용해서 이들
1054장 의사 결정 나무로 산림 식생 분포 예측하기
알고리즘의 유연함을 살펴볼 것이다.
의사 결정 나무 기반의 알고리즘은 직관적으로 이해할 수 있고 추론할 수 있다는 게 장점이다.
실제로 누구나 의사 결정 나무에 내재된 방식과 똑같은 추론을 일상에서 사용하리라 생각한다.
예를 들어 나는 모닝커피에 우유를 섞어 마시는데, 우유를 붓기 전에 ‘우유가 상했는지’를 예측
해보고 싶다. 확신이 없다면 유통기한이 지났는지를 확인한다. 유통기한이 지나지 않았다면 상
하지 않은 것으로 예측한다. 유통기한이 지났더라도 사흘이 넘지 않았다면 상하지 않은 것으로
예측하고, 사흘이 넘었다면 냄새를 맡아봐서 그 냄새가 이상하면 상한 것, 그렇지 않다면 상하
지 않은 것으로 예측한다.
예측으로 이어지는 일련의 예/아니오 선택이 의사 결정 나무에 내재된 추론 방식이다. 각각의
결정으로 두 결과 중 하나로 넘어가는데, [그림 4-1]에서 볼 수 있듯, 최종 결과일 수도 있고
또 다른 결정의 순간일 수도 있다. 이런 의미에서 이 프로세스는 각각의 결정을 내부 노드로,
최종 해답을 말단 노드로 가지는 트리 구조로 간주할 수 있다.
그림 4-1 의사 결정 나무 : 우유가 상했나?
이런 규칙은 어린 시절 수년에 걸쳐 직관적으로 습득해 적용해온 것으로, 상한 우유와 상하지
않은 우유를 구분하는 간단하면서도 쓸만한 규칙이자, 의사 결정 나무의 성격을 보여주는 좋은
106 9가지 사례로 익히는 고급 스파크 분석 (2판)
예다.
이것은 단순화한 의사 결정 나무로, 정밀하게 만들어지지는 않았다. 더 자세히 알아보기 위해
다른 예를 생각해보자. 로봇이 이색 애완동물 가게에서 일하고 있다. 로봇은 가게 문을 열기 전
에 어떤 동물이 아이에게 적절한지를 배우고 싶어 한다. 가게 주인은 서둘러 애완동물 아홉 마
리 각각이 아이에게 적절한지를 기록한 목록인 [표 4-1]을 작성한다. 이제 로봇은 애완동물을
조사하면서 [표 4-1]의 정보와 조합한다.
표 4-1 이색 애완동물 상점 ‘특징 벡터’
이름 무게(Kg) 다리의 수 색 아이에게 적절한가?
초코 20.5 4 갈색 적절
콩이 3.1 0 녹색 부적절
호야 0.2 0 구릿빛 적절
치즈 1390.8 4 회색 부적절
나비 12.1 4 회색 적절
다롱이 150.9 2 구릿빛 부적절
은띵이 0.1 100 갈색 부적절
꾸꾸 1.0 2 회색 부적절
루비 10.0 4 갈색 적절
이름은 특징에 포함되지 않는다. ‘루비’라는 이름은 고양이한테도, 독거미한테도 붙일 수 있으
니 이름만으로 무엇인가를 예측할 수 있으리라 생각할만한 근거가 없기 때문이다. 그렇다면 수
치형 특징 두 개(무게와 다리의 수)와 범주형 특징 하나(색)가 남는다.
그리고 이 특징들로 예측할 범주인 “아이에게 적절한가?”가 있다. 처음에는 [그림 4-2]처럼 무
게를 유일한 판단 기준으로 삼는 간단한 의사 결정 나무를 이 데이터셋에 적합시켜보자.
1355장 K-평균 군집화로 네트워크 이상 탐지하기
“알고 있음이 알려진 것들이 있다. 즉, 우리가 알고 있음을 우리가 아는 것들이 있다.
또, 모르고 있음이 알려진 것들이 있다.
다시 말해서, 우리가 모르는 어떤 것들이 있음을 우리는 알고 있다.
그러나 역시 모르고 있음이 알려지지 않은 것들, 즉 우리가 모르고 있는지도 모르는 것들도 있다.”
-도널드 럼즈펠드
분류와 회귀는 강력하고 깊이 연구된 머신러닝 기술이다. 4장에서는 모르는 값들을 예측하
는 데 쓰이는 분류기를 다루었다. 그러나 문제가 하나 있었다. 새로운 데이터에 대한 모르는
값들을 예측하려면 사전에 관측한 많은 사례의 목푯값들을 알고 있어야 했다. 분류기는 우
리 데이터 과학자가 찾고 있는 것이 무엇인지 이미 알고 있고, 입력과 그에 따른 결과가 알
려진 사례가 확보되었을 때만 도움이 될 수 있다. 학습 과정에서 사례별 정확한 결괏값을 입
력으로 받아들이기 때문에 이런 종류의 방법을 지도 학습이라 한다.
하지만 일부 또는 전체 사례의 정확한 결괏값을 알 수 없을 때도 종종 있다. 전자상거래 사이트
고객들을 쇼핑 습관이나 취향별로 분류하는 문제를 생각해보자. 입력 특징에는 구매 이력, 클
릭 정보, 인구통계학적 정보 등이 있다. 출력은 고객들을 나눈 집단들일 것이다. 아마도 어떤
집단은 유행에 민감한 구매자들을 나타낼 것이고, 또 다른 집단은 가격에 민감하며 싸고 질 좋
은 물건을 사려는 고객으로 밝혀질 것이고, 기타 등등의 집단이 있을 것이다.
K-평균 군집화로
네트워크 이상 탐지하기
CHAPTER 5
션 오언
136 9가지 사례로 익히는 고급 스파크 분석 (2판)
새로운 고객이 가입할 때마다 그 고객이 어떤 목표 레이블Target Label에 해당하는지 결정해야 한
다면 분류기와 같은 지도 학습 기술은 곧 문제에 봉착하게 될 것이다. 누가 유행에 민감하다고
여겨야 할지에 대한 선험적 지식이 없기 때문이다. 사실 맨 처음에는 ‘유행에 민감함’이란 기준
이 사이트 고객을 의미 있게 군집화하는지조차 확신할 수 없을 것이다.
다행히도 비지도 학습Unsupervised Learning (https://goo.gl/U7mBF4) 방법이 도움이 될 수 있다. 비
지도 학습에서는 이용할 수 있는 목푯값이 하나도 없기 때문에 목푯값을 예측하기 위한 학습을
하지 않는다. 그러나 이 방법은 데이터의 구조를 학습할 수 있고, 비슷한 입력들의 집단을 찾을
수 있고, 발생 가능성이 높은 입력과 그렇지 않은 입력의 종류를 학습할 수 있다. 이번 장에서
는 MLlib의 군집화 구현을 사용하여 비지도 학습을 소개할 것이다.
5.1 이상 탐지
이상 탐지Anomaly Detection는 그 이름이 암시하듯 특이한 것들을 찾아내는 문제다. 특정 데이터셋
에서 ‘이상한’이 뜻하는 바를 이미 알고 있다면 지도 학습 방법으로도 이상한 부분을 쉽게 찾아
낼 수 있을 것이다. 지도 학습 알고리즘은 ‘정상Normal’이나 ‘이상Anomaly’ 레이블이 붙은 입력을 받
아서 그 둘을 구분하도록 학습될 것이다. 하지만 이상한 것들의 본질은 ‘모르고 있음이 알려지
지 않은 것’이라는 데 있다. 다시 말해, 관측하고 이해할 수 있게 된 ‘이상’은 더 이상 ‘이상’이 아
닌 것이다.
이상 탐지는 사기Fraud를 찾거나 네트워크 공격을 탐지하거나 서버의 문제점 또는 센서를 갖춘
설비의 문제점을 발견하는 데 주로 사용한다. 이런 경우에는 새로운 형태의 사기, 새로운 침입,
새로운 서버 장애 유형 등 지금까지 겪어보지 못한 새로운 종류의 이상을 찾아내는 능력이 중
요하다.
비지도 학습 기법은 이럴 때 유용하다. 왜냐하면, 비지도 학습 기법은 입력 데이터의 정상적인
형태를 학습해가며 새로운 데이터가 과거 데이터와 비슷하지 않을 때 이를 감지할 수 있기 때
문이다. 과거와 다른 새로움이 반드시 공격이나 사기인 것은 아니다. 하지만 단지 특이하다는
이유만으로도 더 조사해볼 가치가 있다.
1375장 K-평균 군집화로 네트워크 이상 탐지하기
5.2 K-평균 군집화
군집화는 가장 잘 알려진 비지도 학습 방법이다. 군집화 알고리즘은 데이터를 자연스럽게 군집
(집단)으로 묶는 것을 목적으로 한다. 데이터 포인트들 중 서로 비슷하지만 그 외의 것들과는
차이가 나는 것들이 의미 있는 군집일 가능성이 높으므로, 군집화 알고리즘은 이런 데이터끼리
같은 군집으로 묶기 위해 노력한다.
K-평균 군집화K-means Clustering (https://goo.gl/AGqJ4n)는 가장 널리 사용되는 군집화 알고리
즘일 것이다. 이 알고리즘은 데이터셋에서 k개의 군집을 찾으려 시도하며, 여기서 k는 데이터
과학자가 정한다. k는 해당 모델의 하이퍼파라미터이고, 적절한 값은 데이터셋에 따라 다를 것
이다. 사실 좋은 k 값을 선정하는 것이 이번 장의 핵심이다.
고객의 행위와 같은 정보를 포함한 데이터셋에서 ‘비슷하다’는 말은 무슨 의미일까? 또 트랜
잭션과 같은 데이터셋에서는 어떠한가? 이 의미를 측량하기 위해 데이터 포인트 간 거리라는
개념이 필요한데, K-평균 알고리즘에서는 이 거리를 측정할 때 간단한 유클리드 거리Euclidean
Distance를 가장 널리 사용하며, 이 책을 쓰는 시점에 MLlib이 유일하게 지원하는 거리 함수이기
도 하다. 유클리드 거리는 특징들이 모두 숫자인 데이터에서 사용할 수 있다. 데이터 포인트들
이 ‘비슷하다’는 것은 둘 사이의 유클리드 거리가 가깝다는 뜻이다.
K-평균 알고리즘에서 군집은 그 군집을 이루는 모든 요소 점들의 중심을 나타내는 하나의 점
에 지나지 않는다. 사실 요소 점들은 모두 숫자로 이뤄진 특징 벡터일 뿐이며, 간단히 벡터라고
부를 수 있다. 하지만 여기서는 점으로 생각하는 게 더 직관적일 수 있다. 이들은 유클리드 공
간Euclidean Space에서는 점으로 취급하기 때문이다.
군집의 한가운데를 군집 중심Centroid이라 하며, 군집 내의 점들의 산술 평균에 해당한다. 그래서
K-평균이라고 부르는 것이다. 이 알고리즘은 우선 일부 데이터 포인트들을 초기 군집 중심으
로 선택한다. 그런 후에 모든 각각의 데이터 포인트는 가장 가까운 중심으로 할당된다. 그런 다
음에 군집별로 군집에 할당된 모든 데이터 포인트의 산술 평균을 구해서 새로운 군집 중심을
구한다. 이 과정이 반복된다.
이 알고리즘에 대해서는 당장은 이 정도면 충분하다. 더 흥미롭고 자세한 내용은 다음 활용 사
례에서 보게 될 것이다.
138 9가지 사례로 익히는 고급 스파크 분석 (2판)
5.3 네트워크 침입
뉴스를 보면 소위 사이버 공격이 점점 늘어나고 있다. 어떤 공격은 정상적인 네트워크 접근을
방해할 목적으로 대량의 네트워크 트래픽을 쏟아붓는다. 또 다른 공격은 네트워크 소프트웨어
의 취약점을 공격하여 승인되지 않은 권한을 확보하려고 시도한다. 트래픽을 이용한 공격은 매
우 명확한 상황인 데 비해, 익스플로잇Exploit이라고도 하는 취약점 공격을 감지하기란 네트워크
요청들의 거대한 건초 더미에서 바늘 찾기와 같을 수 있다.
몇몇 취약점 공격의 행동 패턴은 알려져 있다. 예를 들어 지속적으로 빠르게 모든 포트에 접근
해보는 일은 정상적인 소프트웨어가 할 만한 행동은 아니지만, 침입자라면 컴퓨터에서 악용할
만한 서비스를 찾기 위해서 맨 처음 하는 일반적인 행위다.
만약 짧은 시간에 원격 호스트가 서로 다른 포트에 접근한 횟수를 집계할 수 있다면 포트 스캐
닝 공격을 꽤 잘 예측할 수 있는 특징을 가진 것이다. 몇 건 정도는 아마도 정상이겠지만, 수백
건이 되면 공격일 것이다. 전송하고 수신한 바이트의 수, TCP 오류 등 네트워크 연결과 관련한
다른 특징도 동일한 방식을 활용해서 다른 종류의 침입을 탐지할 수도 있다.
하지만 알려지지 않은 미지의 패턴이라면 어떨까? 지금까지 한 번도 알려진 적이 없어서 분류
된 적도 없는 그런 공격이 가장 큰 위협일 수 있다. 잠재적 네트워크 침입을 찾아내는 일은 이
상 탐지에 해당한다. 이런 경우는 침입 행위로 알려져 있지는 않지만, 과거에 관측된 네트워크
연결들과는 양상이 다르다.
이상한 네트워크 연결을 찾아내는 데 K-평균과 같은 비지도 학습 기법을 사용할 수 있다. K-
평균 방법은 연결 각각에 대한 통계에 기반을 두어 연결들을 군집화할 수 있다. 결과로 나온 군
집들 자체에는 의미가 없다. 하지만 군집들은 전체적으로 과거의 연결들과 유사한 연결 유형들
을 정의하고 있다. 어떤 군집에도 속하지 않은 연결은 이상한 연결일 수 있다. 군집들이 정상
연결들의 영역을 정의할 때 그 군집들은 의미를 가진다. 그 범위 밖의 모든 연결은 특이하며 잠
재적으로 이상한 연결이다.
1395장 K-평균 군집화로 네트워크 이상 탐지하기
5.4 KDD 컵 1999 데이터셋
KDD 컵KDD Cup (http://www.kdd.org/)은 국제컴퓨터학회(ACM)의 특화 분야 분과에서 매
년 주최하던 데이터 마이닝 대회다. 해마다 하나의 머신러닝 문제가 데이터셋과 함께 출제되
며, 연구자들은 그 문제를 푸는 최선의 답을 상세히 기술한 논문을 제출한다. 캐글Kaggle (http://
www.kaggle.com/)이 열리기 전 시절, KDD 컵은 캐글과 비슷한 것이었다. 네트워크 침입을
주제로 한 1999년 대회의 데이터셋은 지금도 사용할 수 있다(http://bit.ly/1ALCuZN). 이번
장의 나머지 부분에서는 이 데이터를 학습하여 스파크를 사용한 이상 네트워크 트래픽 탐지 시
스템을 구축하는 방법을 보여주려 한다.
NOTE_ 이 데이터셋을 실제 네트워크 침입 탐지 시스템을 구축하는 데 이용하지는 마라! 이 데이터가 그 당
시의 실제 네트워크 트래픽을 반영하는 것도 아니며, 혹 반영했더라도 17년도 더 전의 트래픽 패턴일 뿐이다.
다행히도 주최 측은 네트워크 패킷 원본을 개별 네트워크 연결에 관한 요약 정보 형태로 처리
해두었다. 데이터셋의 크기는 약 708MB이며 490만 개의 연결을 담고 있다. 방대하다고 말하
기는 그렇지만 제법 큰 데이터인데, 이 장에서 필요한 만큼은 된다. 데이터셋은 각 연결의 전송
된 바이트 수, 로그인 시도 횟수, TCP 에러 개수 등과 같은 정보를 담고 있다. 데이터의 한 줄이
연결 하나에 대응하며 다음과 같이 38개의 수치형 특징을 포함한 CSV 형식으로 만들어졌다.1
0,tcp,http,SF,215,45076,
0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,1,
0.00,0.00,0.00,0.00,1.00,0.00,0.00,0,0,0.00,
0.00,0.00,0.00,0.00,0.00,0.00,0.00,normal.
이 연결은 HTTP 서비스에 대한 TCP 연결로, 215바이트를 송신하고 45,706바이트를 수신했
다. 사용자는 로그인되어 있으며, 기타 다른 내용도 포함하고 있다. 많은 특징이 17번째 특징
인 num_file_creations와 같은 횟수 정보다.2
또 많은 특징이 15번째 특징인 su_attempted처럼 어떤 행위가 있음 혹은 없음을 나타내는 0
또는 1을 취한다. 4장에서 소개한 원-핫 인코딩을 사용해 범주형 특징을 수치형으로 다시 표
1	 옮긴이_ 총 42개의 값 중 범주형 특징 3개와 레이블 1개를 빼서 38개다.
2	 옮긴이_ 각 특징의 이름과 형태는 공개된 데이터셋의 kddcup.names 파일에 기록돼 있다. http://goo.gl/CBEZv5
140 9가지 사례로 익히는 고급 스파크 분석 (2판)
현한 것과 비슷해 보이지만, 사실 동일한 방법으로 묶거나 관련지은 것은 아니다. 이들은 예/
아니오 특징 같은 것이고, 따라서 범주형 특징임에는 거의 틀림없다. 범주형 특징을 숫자로 바
꾸어 마치 순서가 있는 것처럼 취급하는 것이 항상 적절한 것은 아니지만, 이진Binary 범주형 특
징과 같이 특별한 경우에는 0과 1을 취하는 수치형 특징에 대응하더라도 대부분의 머신러닝 알
고리즘에서 잘 동작할 것이다.
끝에서 두 번째인 dst_host_srv_rerror_rate와 같이 나머지는 모두 비율을 나타내고 0.0~1.0
의 값을 가진다.
흥미롭게도 레이블은 마지막 필드로 제공된다. 대부분의 연결은 정상(normal.)이지만, 일부
는 다양한 유형의 네트워크 공격 사례로 기록되어 있다. 이를 이용하여 알려진 공격을 정상 연
결과 구분하도록 학습할 수 있다. 하지만 여기서 하려는 일은 이상을 탐지하여, 궁극적으로는
알려지지 않은 새로운 공격을 찾아내는 것이다. 레이블은 이런 목적과 맞지 않기 때문에 대부
분의 예제에서 사용하지 않는다.
5.5 첫 번째 군집화하기
kddcup.data.gz 파일의 압축을 풀고 HDFS로 복사하자. 다른 장과 마찬가지로 이 예제에
서도 파일이 /user/ds/ 디렉터리에 있다고 가정한다. spark-shell을 실행하고 다음과 같
이 CSV 데이터를 데이터프레임으로 읽어 들인다. CSV 파일이지만 헤더 정보가 없으므로
kddcup.names 파일에서 제공한 열 이름을 사용해야 한다.
val dataWithoutHeader = spark.read.
option(inferSchema, true).
option(header, false).
csv(hdfs:///user/ds/kddcup.data)
val data = dataWithoutHeader.toDF(
duration, protocol_type, service, flag,
src_bytes, dst_bytes, land, wrong_fragment, urgent,
hot, num_failed_logins, logged_in, num_compromised,
root_shell, su_attempted, num_root, num_file_creations,
num_shells, num_access_files, num_outbound_cmds,
is_host_login, is_guest_login, count, srv_count,
1616장 숨은 의미 분석으로 위키백과 이해하기
“스노든의 무리는 작년에 어디 있었나?”1
-요사리안 대위
데이터 엔지니어링 과정의 대부분은 수집한 데이터를 질의가 가능한 형태로 가공하는 일이다.
테이블 형태로 구조화되어 있으면 SQL을 사용할 수 있듯, 데이터가 구조화되어 있으면 형식
언어로 질의할 수 있다. 높은 수준으로 구조화하는 일이 결코 쉬운 일은 아니지만, 데이터를 테
이블 형태로 만드는 일 자체는 간단할 수도 있다. 다양한 데이터 출처로부터 데이터를 가져다
가 테이블 하나에 쑤셔 넣은 다음, 정해진 방법에 따라 데이터를 정제하고 잘 합쳐내면 되는 일
이다. 구조화되지 않은 텍스트 데이터를 다루는 것은 완전히 다른 일이다. 사람이 가져다 쓸 수
있는 형태로 데이터를 준비하는 작업은 ‘조립Assembly’이라기 보다는 ‘색인 작업Indexing’에 가까운
데, 그나마도 ‘억지Coercion’스러운 작업이 되어버리곤 한다. 일반적으로 색인을 사용하면 주어진
단어들을 포함한 문서 집합을 빠르게 찾을 수 있다. 하지만 종종 정확한 문자열이 주어지지 않
더라도 특정 단어의 의미와 관련된 문서를 찾고자 할 때도 있는데, 표준적인 검색 색인에서는
주어진 텍스트의 ‘주제’와 관련한 숨어 있는 구조를 찾아내지 못할 때가 많다.
숨은 의미 분석Latent Semantic Analysis (LSA)은 문서 뭉치corpus의 이해를 돕고, 뭉치에 속한 문서 속 단
어들 사이의 관계를 찾는 자연어 처리Natural Language Processing (NLP) 및 정보 검색 기술이다. LSA
1	 옮긴이_ 소설 『캐치-22』의 주인공인 요사리안 대위가 소설 중에서 던진, 답이 없는 질문이다.
숨은 의미 분석으로 위키백과 이해하기
CHAPTER 6
샌디 라이자
162 9가지 사례로 익히는 고급 스파크 분석 (2판)
는 뭉치들로부터 적절한 의미들의 집합을 뽑아낸다. 각각의 의미는 다양하게 변형되어 문서에
나타나는데, 그중에 해당 문서 뭉치가 다루는 주제에 부합되는 것이 있다. 수학적으로 접근하
기는 아직 이르지만, 모든 의미는 세 가지 속성을 갖는다. 첫째는 뭉치에 속한 각 문서가 가지
는 관련성의 정도, 둘째는 뭉치 내의 각 단어가 가지는 관련성의 정도, 셋째는 어떤 의미가 데
이터셋 내의 변형을 설명하는 데 얼마나 유용한가를 나타내는 중요도 점수다. 예를 들어 ‘아시
모프Asimov’와 ‘로봇Robot’이라는 단어 사이의 강한 연관성, 그리고 ​『파운데이션』 연작2
문서들과
과학 소설 문서들 사이의 강한 연관성에 LSA를 적용하면 (연관성이 지니는) 의미를 찾아낼 수
있을 것이다. LSA를 시행하면서 매우 중요한 의미들만 선택하면 관련성이 낮은 노이즈를 제거
하고 겹치는 부분을 합칠 수 있으며, 이를 통해서 데이터를 더 간단하게 표현할 수 있다.
이렇게 만들어진 간단한 표현을 다양한 작업에 적용할 수 있다. LSA로부터 단어와 단어 사이,
문서와 문서 사이, 그리고 단어와 문서 사이의 유사성 점수를 얻을 수 있다. 뭉치 안의 다양한
패턴을 잘 묶어내면, 단순히 특정 단어가 몇 번 나왔는지나 어떤 단어 조합이 함께 나온 게 몇
번인지를 세는 것보다 유사성 점수가 그 문서를 이해하는 데 더 도움이 될 것이다. 이러한 유사
성 척도는 특정 단어와 연관된 문서 찾기, 주제가 같은 문서끼리 묶기, 그리고 관련 단어 찾기
등과 같은 작업에 알맞은 방법이다.
LSA는 특잇값 분해(SVD)라는 선형대수 기법을 활용하여 이러한 더 낮은 차원의 표현 방법을
찾아낸다. 특잇값 분해는 3장에서 본 ALS 분해의 더 강력한 버전으로 생각하면 된다. 먼저, 각
문서에 특정 단어가 나온 횟수를 세어 문서-단어 행렬Document-term Matrix을 만든다. 이 행렬에서 문
서는 각각의 행에, 단어는 각각의 열에 대응하며, 행렬의 원소는 특정 문서에 있어서 특정 단
어의 중요도를 나타낸다. 그런 다음 특잇값 분해를 적용하여 이 행렬을 세 개의 행렬로 분해한
다. 하나는 문서들과 관련된 의미들을 표현한 행렬, 다른 하나는 단어들과 관련된 의미들을 표
현한 행렬, 마지막 하나는 각 의미의 중요도를 담고 있는 행렬이다. 이런 구조를 가진 3개의
행렬에서 중요도가 낮은 의미에 대응하는 행과 열을 제거하여 원 행렬의 낮은 계수 근사Low-rank
Approximation를 만들 수 있다. 각각의 행렬에서 행과 열을 제거한 후 다시 곱하면 원래 행렬의 근
사 행렬이 만들어지는데, 의미가 하나씩 제거될 때마다 근사의 정확성은 점점 떨어지게 된다.
이 장에서는 숨은 의미의 관계에 근거하여 인간 지식의 전 범위를 아우르는 질의를 가능하게
2	 옮긴이_ 아이작 아시모프는 ‘로봇 3원칙’으로 유명한, 작고한 SF 소설가이며 ‘파운데이션(Foundation)’은 그의 연작 과학 소설의 제목
이다.
1636장 숨은 의미 분석으로 위키백과 이해하기
하는 소소한 작업에 착수하려 한다. 구체적으로 말하자면, 원문 텍스트 기준으로 약 46GB3
에
달하는 위키백과에 포함된 모든 문서로 구성된 문서 뭉치에 LSA를 적용할 것이다. 이 데이터
를 읽고, 정제하고, 수치 형태로 개조하는 데이터 전처리 과정에 스파크를 활용하는 방법을 다
루려 한다. 또, 특잇값 분해를 계산하는 방법과 이것을 어떻게 해석하고 활용해야 하는지를 보
여줄 것이다.
특잇값 분해는 LSA 외에도 폭넓게 활용되고 있다. 기후 변화 추세 파악(마이클 만의 유명한
하키 스틱 그래프 참고, https://goo.gl/MzbT56), 얼굴 인식, 이미지 압축과 같은 다양한 곳에
사용된다. 스파크는 엄청나게 커다란 데이터셋도 행렬분해할 수 있어서 또 다른 새로운 분야에
도 기술의 이기를 전파할 수 있을 것이다.
6.1 문서-단어 행렬
분석에 들어가기 전에, 문서 뭉치 내의 원문에서 LSA에 사용할 문서-단어 행렬을 만들어야 한
다. 이 행렬의 각 열은 문서 뭉치에서 등장하는 하나의 단어를 나타내고, 각 행은 하나의 문서
를 나타낸다. 대략, 행과 열이 만나는 지점의 값은 어떤 문서에 있어서 어떤 단어의 중요도에
대응되어야 한다. 중요도를 계산하는 방법이 몇 가지 있지만, 가장 널리 쓰이는 것은 단어 빈도
Term Frequency (TF)와 역문서 빈도Inverse Document Frequency (IDF)를 곱하는 방법이고, 줄여서 TF-IDF
라고 한다. 다음은 이를 구하는 스칼라 코드다. 하지만 스파크에서는 이를 계산하는 기능을 별
도로 제공하므로 이 코드를 사용하지는 않을 것이다.
def termDocWeight(termFrequencyInDoc: Int, totalTermsInDoc: Int,
termFreqInCorpus: Int, totalDocs: Int): Double = {
val tf = termFrequencyInDoc.toDouble / totalTermsInDoc
val docFreq = totalDocs.toDouble / termFreqInCorpus
val idf = math.log(docFreq)
tf * idf
}
TF-IDF는 문서를 적절하게 설명할 수 있는 단어에 대한 두 가지 직관을 담아내고 있다. 첫 번
3	 옮긴이_ 이 책의 1판이 집필되던 때의 크기다.
164 9가지 사례로 익히는 고급 스파크 분석 (2판)
째 직관은 특정 문서에 어떤 단어가 많이 나올수록 그 문서에서 그 단어는 더욱 중요하다는 것
이다. 두 번째 직관은 전역적으로 볼 때 모든 단어의 가치가 똑같지는 않다는 것이다. 약방의
감초같이 항상 등장하는 단어보다 문서 뭉치의 다른 문서에는 잘 쓰이지 않는 단어가 등장하는
쪽이 더 의미가 있다. 그래서 뭉치의 전체 문서에서 단어가 출현하는 빈도의 역Inverse을 사용하
자는 것이다.
문서 뭉치에서 단어들의 출현 빈도는 기하급수적인 차이를 보인다. 흔히 쓰이는 단어들은 덜
흔한 단어들보다 수십 배 더 자주 등장하지만, 이러한 덜 흔한 단어들조차 드문드문 사용되는
단어들에 비하면 수십, 수천 배 더 자주 등장한다. 이 때문에 단순히 역문서 빈도를 그대로 사
용하면 드문드문 사용되는 단어들에 어마어마하게 큰 가중치를 부여해서 다른 모든 단어의 영
향력이 무시되는 문제가 생긴다. 그래서 실전에서는 역문서 빈도의 로그 값을 사용한다. 로그
값을 사용하면 곱의 차를 합의 차로 바꾸어서, 빈도로부터 오는 격차를 완화한다.
모델을 만들려면 몇 가지 가정이 필요하다. 문서를 ‘단어들의 가방’으로 생각하자. 이는 어순이
나 문장 구조, 또는 부정을 나타내는 꾸밈말 같은 것은 무시하겠다는 것이다. 또 각각의 단어는
한 가지 의미만을 가지며, 다의어多義語는 다루지 않는다. 예를 들어 이 모델에서는 “라디오헤드
는 역대 최고의 밴드다”에서의 밴드와 “고무 밴드가 끊어졌어”에서의 밴드의 차이를 구분하지
않겠다는 뜻이다. 만약 두 문장이 한 문서 뭉치에서 자주 등장하면 고무와 라디오헤드가 연결
된다.
우리가 사용할 문서 뭉치에는 천만 개의 문서가 포함되어 있다. 잘 알려지지 않은 기술 용어까
지 포함하면 영어 단어는 약 백만 개에 달하는데, 이 중 일부인 수만 개 정도면 문서 뭉치를 이
해하는 데 유용하지 않을까 한다. 단어의 수에 비해서 문서의 수가 훨씬 많으니, 문서-단어 행
렬을 각각이 하나의 문서에 대응하는 희소 벡터Sparse Vector들의 집합인 행 행렬Row Matrix 형태로 만
드는 것이 타당하다.
위키백과를 덤프한 원문은 하나의 커다란 XML 파일로, 그 안에 각 문서가 page 태그로 구
분되어 있다. 이를 문서-단어 행렬 형태로 바꾸는 전처리 과정은 다음과 같다. 먼저 이 XML
파일을 문서 단위로 쪼개고, 각 문서에서 위키 특화 태그를 제거해 플레인 텍스트 파일로 바
꿔야 한다. 그 다음, 이 플레인 텍스트 파일을 토큰으로 나눈다. 이때 여러 가지 형태4
로 표기
된 단어를 기본형으로 바꾸어 전체 토큰의 가짓수를 줄이는 과정을 거친다. 이 과정을 표제
4	 옮긴이_ 복수형이나 과거 분사 등
1656장 숨은 의미 분석으로 위키백과 이해하기
어 추출이라고 한다. 그러고 나면 이 토큰을 대상으로 문서 빈도와 단어 빈도를 계산하여, 최
종적으로 실제 벡터 객체를 만들게 된다. 이 책에서 제공하는 깃허브 저장소에는 이 내용이
AssembleDocumentTermMatrix 클래스에 추상화되어 있다.
이 과정의 앞부분은 각각의 문서를 완전히 병렬로 처리할 수 있지만(스파크에서는 처리 과정
이 맵 함수들로 구성된다는 의미다), 역문서 빈도를 계산할 때는 모든 문서를 대상으로 집계해
야 한다. 몇몇 유용한 범용 자연어 처리 도구와 위키백과에 특화된 추출 도구들을 사용하면 도
움이 된다.
6.2 데이터 구하기
위키백과는 문서를 덤프하는 기능을 제공한다. 다음과 같이 http://dumps.wikimedia.org/
enwiki에 들어 있는 문서들을 하나의 커다란 XML 파일 형태로 덤프하여 HDFS에 저장한다.5
$ curl -s -L https://dumps.wikimedia.org/enwiki/latest/
$ enwiki-latest-pages-articles-multistream.xml.bz2 
$ | bzip2 -cd 
$ | hadoop fs -put - wikidump.xml
이와 같이 많은 양의 데이터를 처리하는 데는 복수 개의 노드를 가진 클러스터로 작업하는 것
이 바람직하다. 이 장의 코드를 로컬 PC에서 실행하려면 위키백과 내보내기 페이지(https://
en.wikipedia.org/wiki/Special:Export)를 통해서 작은 덤프 파일을 만들어 사용하는 것이
좋다. ‘Megafauna’(대형 동물군)나 ‘Geometry’(기하학)와 같이 페이지 수는 많은데 하위
카테고리는 적은 카테고리를 덤프해 사용해보자. 이렇게 만든 덤프 파일을 이후에 이어지는 코
드에 사용하려면, 파일을 디렉터리에 복사하고 파일 이름을 wikidump.xml로 바꾸면 된다.6
5	 옮긴이_ 코드의 위키백과 덤프 주소는 위키 덤프 상황에 따라 유효하지 않는 시점이 종종 있다. 이 경우 https://dumps.wikimedia.org/
enwiki/latest/ 에서 적당한 파일을 선택해서 저장하면 된다.
6	 옮긴이_ Geometry 카테고리를 선택하였다면 이어지는 예제에서 단어와 관련된 질의어로 ‘minkowski’(민코프스키)를 사용해보자. 러
시아의 수학자인데, 민코프스키 공간 등 그와 관련된 다양한 주제가 Geometry 카테고리 내의 문서에 녹아 있다. 문서 관련 질의는 민코
프스키와 관련해서 나오는 문서 중 하나를 골라서 질의해보자.
166 9가지 사례로 익히는 고급 스파크 분석 (2판)
6.3 파싱하여 데이터 준비하기
덤프 파일의 앞부분은 다음과 같은 모양이다.
page
titleAnarchism/title
ns0/ns
id12/id
revision
id584215651/id
parentid584213644/parentid
timestamp2013-12-02T15:14:01Z/timestamp
contributor
usernameAnomieBOT/username
id7611264/id
/contributor
commentRescuing orphaned refs (quot;autogenerated1quot; from rev
584155010; quot;bbcquot; from rev 584155010)/comment
text xml:space=preserve{{Redirect|Anarchist|the fictional character|
Anarchist (comics)}}
{{Redirect|Anarchists}}
{{pp-move-indef}}
{{Anarchism sidebar}}
'''Anarchism''' is a [[political philosophy]] that advocates [[stateless society|
stateless societies]] often defined as [[self-governance|self-governed]]
voluntary institutions,lt;refgt;quot;ANARCHISM, a social philosophy that
rejects authoritarian government and maintains that voluntary institutions are
best suited to express man's natural social tendencies.quot; George Woodcock.
quot;Anarchismquot; at The Encyclopedia of Philosophylt;/refgt;lt;refgt;
quot;In a society developed on these lines, the voluntary associations which
already now begin to cover all the fields of human activity would take a still
greater extension so as to substitute
...
스파크 셸을 시작해보자. 이 장에서는 작업을 좀 더 쉽게 만들어주는 몇몇 라이브러리를 활용
할 것이다. 의존하는 라이브러리들을 모두 포함한 JAR 파일을 빌드해주는 메이븐 프로젝트를
깃허브 저장소에 올려두었다.
$ cd ch06-lsa/
$ mvn package
1897장 그래프엑스로 동시발생 네트워크 분석하기
“세상은 참 좁다. 계속해서 교차하고 있다.”
-데이비드 미첼
데이터 과학자들은 다양한 분야, 다양한 깊이의 학문적 배경을 지니고 있다. 그중 다수는 컴퓨
터 과학, 수학, 물리학이 전공이겠지만, 신경과학, 사회학, 정치학 등을 전공한 사람도 있다. 후
자의 분야는 뇌, 사람, 정치기구 등 컴퓨터와 관련 없는 분야를 연구하고 학과생에게 프로그래
밍을 가르치진 않지만, 데이터 과학자로 성장하는 데 발판이 되는 중요한 특징 두 가지를 지니
고 있다.
첫째, 이들 분야는 대상들(신경세포든 개인이든 국가든 상관없이) 사이의 ‘관계’를 이해하고
그 관계가 대상의 행동에 어떻게 영향을 주는지를 이해하는 데 초점을 맞추고 있다. 둘째, 지난
10년간의 폭발적인 디지털 데이터의 증가로 대상들의 관계와 관련한 거대한 규모의 정보에 접
근할 수 있게 되었고, 이 데이터셋을 구하고 관리하기 위한 새로운 기술을 개발해야 했다.
각 영역의 과학자들이 서로, 그리고 컴퓨터 전문가들과 협업하기 시작하면서 대상들의 관계를
분석할 때 사용하던 많은 기술을 다른 분야에도 적용할 수 있음을 깨달았다. 그리하여 네트워크
과학 분야가 탄생했다. 네트워크 과학에는 대상(꼭짓점Vertex, Node ) 사이의 관계(변Edge, Link, Line )를
연구하는 수학 분야인 그래프 이론Graph Theory에서 탄생한 도구들이 사용된다. 또한, 그래프 이론
은 자료구조부터 컴퓨터 구조나 인터넷과 같은 네트워크 설계까지 컴퓨터 분야에서 폭넓게 활
용되고 있다.
그래프엑스로
동시발생 네트워크 분석하기
CHAPTER 7
조시 윌스
190 9가지 사례로 익히는 고급 스파크 분석 (2판)
그래프 이론과 네트워크 과학은 비즈니스 분야에도 큰 영향을 주었다. 대부분의 인터넷 회사가
영향력 있는 관계 네트워크를 구축하고 분석하는 데 경쟁자들보다 우위를 점하는 식으로 회사
의 가치를 높여 왔다. 아마존과 넷플릭스는 각 회사가 만들고 통제해온 사용자-제품구매(아마
존), 사용자-감상평(넷플릭스) 네트워크를 기반으로 추천 알고리즘을 만들었다. 페이스북과
링크드인은 콘텐트의 피드를 구성하고, 광고를 삽입하고, 새로운 관계를 맺어주기 위해서 사용
자를 분석하여 사람 사이의 관계 그래프를 만든다. 이 중에서도 가장 유명한 사례로는 웹 검색
을 근본적으로 개선하기 위해 창업자가 개발한 구글의 페이지랭크PageRank 알고리즘을 꼽을 수
있을 것이다.
이들 네트워크 중심 회사에 필요했던 엄청난 양의 계산과 분석 수요는 맵리듀스와 같은 분산
처리 프레임워크가 만들어지는 계기가 되었을 뿐 아니라, 계속해서 늘어만 가는 데이터를 분
석하여 가치를 만들어내는 도구를 사용할 줄 아는 데이터 과학자들을 고용하는 계기가 되었다.
맵리듀스의 초기 활용사례 중 하나가 페이지랭크의 핵심 공식을 풀어내는 확장 가능하고 신뢰
성 있는 방법을 구축하는 것이었다. 시간이 지나면서 그래프가 점점 커지자 데이터 과학자들
은 분석 속도를 더 높여야 한다는 압박에 시달렸다. 그 결과 구글의 프레겔Pregel, 야후의 지라프
Giraph, 카네기 멜런 대학교의 그래프랩GraphLab과 같이 그래프를 병렬로 처리하는 새로운 프레임
워크가 개발되었다. 이 프레임워크들은 결함 허용, 인메모리, 반복 가능, 그래프 중심의 분석을
지원했고, 특정 유형의 그래프 연산에서는 데이터 중심의 병렬 처리 프레임워크인 맵리듀스보
다 자릿수가 다를 정도로 더 빠른 모습을 보여주었다.
이 장에서는 그래프엑스GraphX라는 스파크 라이브러리를 소개하려 한다. 이 라이브러리는 프레
겔, 지라프, 그래프랩에서 처리하던 그래프 중심 병렬 작업의 많은 부분을 스파크가 처리할 수
있도록 확장한다. 비록 모든 연산을 전용 그래프 프레임워크만큼 빠르게 수행할 수는 없겠지
만, 그래프엑스가 스파크 라이브러리라는 사실은 일반적인 데이터 분석 워크플로에서 언제든
지 그래프(혹은 네트워크) 중심 데이터셋도 분석할 수 있음을 뜻한다. 즉, 지금까지 사용해온
익숙한 스파크 추상화에 병렬 그래프 처리 프로그래밍을 더할 수 있다.
그래프엑스와 그래프프레임
그래프엑스는 데이터프레임이 도입되기 전인 스파크 1.3 때 만들어졌기 때문에 그래프엑스
의 API는 RDD를 통해서 동작하도록 설계되었다. 최근에는 그래프엑스를 데이터프레임 기
1917장 그래프엑스로 동시발생 네트워크 분석하기
반인 그래프프레임GraphFrames이라는 새로운 API로 포팅하려는 노력이 진행되고 있다. 그래프
프레임은 데이터프레임 API와 그래프 질의를 통해서 직렬화된 데이터를 읽고 쓰는 기능을
폭넓게 지원하는 등 다양한 이점을 제공한다.
이 책의 2판을 집필하는 시점에는 스파크 2.1의 그래프프레임 API로는 이번 장에서 수행하
는 분석 일부를 진행할 수 없기 때문에 여기서는 그래프엑스 API를 사용하기로 하였다. 하
지만 그래프프레임은 그래프엑스로부터 많은 영감을 받고 있기 때문에 이 장에서 소개하는
모든 메서드와 개념은 그래프프레임에 일대일로 대응된다. 아직은 미정이지만, 이 책의 다
음 판에서는 그래프프레임으로 옮겨갈 수 있기를 기대하고 있다. 프로젝트의 진행 상황은 그
래프프레임의 프로젝트 페이지(http://graphframes.github.io/)에서 살펴볼 수 있다.
7.1 네트워크 분석 사례: MEDLINE의 인용 색인
온라인 의학 문헌 분석 및 검색 시스템인 MEDLINEMedical Literature Analysis and Retrieval System Online
은 생명과학과 의학 저널들에서 발행한 학술 논문의 데이터베이스로, 미국 국립 보건원National
Institute of Health (NIH)의 한 부서인 미국 국립 의학도서관US National Library of Medicine (NLM)에서 관리
한다. 수천 개의 저널에 실린 기사들을 기록하는 인용 색인은 1879년부터 만들어지기 시작했
고, 1971년부터 의과 대학에 온라인으로 제공했으며, 1996년부터는 웹을 통해서 일반에 제공
하고 있다. 주 데이터베이스는 1950년대 초반 이후의 2천만 건이 넘는 기사를 담고 있으며, 공
휴일을 제외한 매일 갱신되고 있다.
엄청난 인용 데이터의 크기와 빈번한 갱신 주기 때문에 연구 커뮤니티에서는 MeSHMedical subject
Headings (의학 주제 제목)라는 포괄적인 의미 태그를 개발하여 색인에 포함된 모든 인용에 적용
했다. 이들 태그는 문헌 검토를 위해서 문서 사이의 관계를 조사할 때 사용할 수 있는 중요한
프레임워크를 제공하며, 데이터 기반 제품을 만드는 기초 자료로 사용할 수도 있다. 2001년에
PubGene사는 생의학 텍스트 마이닝을 활용한 첫 번째 상용 제품을 선보였다. 이 제품은 사
용자가 관련 문서들을 연결하는 MeSH 키워드의 그래프를 탐색하게 해주는 검색 엔진이었다.
이 장에서는 스칼라, 스파크, 그래프엑스를 사용하여 MEDLINE 데이터 중 최근에 발행된 인
용 데이터 일부에 대한 MeSH 네트워크를 만들고 변환하고 분석해볼 것이다. 여기서 수행할
192 9가지 사례로 익히는 고급 스파크 분석 (2판)
네트워크 분석은 2014년 카스트린Kastrin 등이 쓴 「함께 사용된 MeSH 키워드 네트워크의 거대
한 구조: 거시적 특징들의 정적 분석Large-Scale Structure of a Network of Co-Occurring MeSH Terms: Statistical Analysis
of Macroscopic Properties」(https://goo.gl/7hR1dc)에서 아이디어를 가져온 것이다. 다만, 이 논문에
서 사용한 인용 데이터와는 다른 부분집합을 사용할 것이며, 이 논문에서는 R과 C++를 사용
했지만 여기서는 그래프엑스로 분석할 것이다.
우리의 목적은 인용 그래프의 모양과 특성에 대한 감을 잡는 것이다. 우리는 데이터셋의 완전
한 조망을 얻기 위해서 여러 각도에서 공략할 것이다. 먼저 핵심 주제들, 그리고 이 주제들이
동시에 발생하는 정도를 살펴보는, 즉 그래프엑스를 사용할 필요가 없는 간단한 분석부터 시작
할 것이다. 그 다음으로는 연결 성분Connected Component을 찾을 것이다. 이를 통해서 “특정 주제에
서 다른 주제로 색인 경로를 따라갈 수 있을 것인가?” 또는 “데이터가 어떤 분리된 작은 그래프
들의 집합인가?”와 같은 질문에 대답할 수 있다. 그 후에, 그래프의 차수 분포Degree Distribution를 살
펴 특정 주제의 관련성이 얼마나 넓게 걸쳐 있는지에 대한 감을 잡고, 다른 주제들과 가장 많이
연결된 주제를 찾아볼 것이다. 마지막으로 군집계수Clustering Coefficient와 평균 경로 길이Average Path Length
를 구하는, 두 가지의 조금 전문적인 그래프 통계량을 계산할 것이다. 이들 통계량은 여러모로
사용되겠지만, 여기서는 인용 그래프가 웹이나 페이스북의 사회 관계망 같은 우리 주변의 현실
세상 그래프와 얼마나 비슷한가를 이해하게끔 해줄 것이다.
7.2 데이터 구하기
미국 국립 보건원의 FTP 서버에서 인용 색인 데이터의 표본을 얻을 수 있다.
$ mkdir medline_data
$ cd medline_data
$ wget ftp://ftp.nlm.nih.gov/nlmdata/sample/medline/*.gz
HDFS에 올리기 전에 인용 데이터의 압축을 풀고 검사를 하자.
$ gunzip *.gz
$ ls -ltr
...
total 1814128
1937장 그래프엑스로 동시발생 네트워크 분석하기
-rw-r--r-- 1 jwills staff 145188012 Dec 3 2015 medsamp2016h.xml
-rw-r--r-- 1 jwills staff 133663105 Dec 3 2015 medsamp2016g.xml
-rw-r--r-- 1 jwills staff 131298588 Dec 3 2015 medsamp2016f.xml
-rw-r--r-- 1 jwills staff 156910066 Dec 3 2015 medsamp2016e.xml
-rw-r--r-- 1 jwills staff 112711106 Dec 3 2015 medsamp2016d.xml
-rw-r--r-- 1 jwills staff 105189622 Dec 3 2015 medsamp2016c.xml
-rw-r--r-- 1 jwills staff 72705330 Dec 3 2015 medsamp2016b.xml
-rw-r--r-- 1 jwills staff 71147066 Dec 3 2015 medsamp2016a.xml
옮긴이_ 이 책의 1판에서는 책에서 사용한 데이터와 실제 얻을 수 있는 데이터에 차이가 있었다. 책에서는 이
름에 2014년을 의미하는 ‘2014’라는 숫자가 붙은 데이터를 사용하여 설명했지만, 번역하는 시점이 다소 늦
은 탓에 ‘2016’이 붙은 최신 데이터가 위 FTP 서버의 디렉터리에 들어 있었다. 그 탓에 이 책이 보여주는 예
제와 독자가 실습하면서 접하는 결과가 다소 다른, 난감한 상황을 겪었다.
다행히도, 2판을 번역하는 지금(2017년)은 앞의 파일 목록과 동일한 데이터를 저 위치에서 찾을 수 있다. 하
지만 독자가 읽는 시점에 다시 최근의 표본으로 바뀌어 있을지도 모른다. 이로 인하여 책에 실린 결과와 독자
의 실습 결과가 또다시 달라질 수 있겠지만, 그 결과가 다르다고 해서 대세에 큰 영향을 주지는 않음을 밝혀
둔다. 실제로 2014년 데이터로 결과를 보여준 1판과 2016년 데이터로 결과를 보여준 2판의 일부 숫자와 결
과는 차이가 있지만, 책의 논지와 대세에는 아무 영향이 없다.
아울러 이어지는 예제를 클러스터가 아닌 PC 환경에서 분석하고자 할 때는 유의할 사항이 있다. 가장 일반적
이라 추측하는 리눅스 환경에서는 시스템이 동시에 열 수 있는 파일의 수가 기본적으로 1,024개로 설정되어
있다. 만약 테스트 도중에 “열린 파일이 너무 많음” 또는 “Too Many Open Files”나 이와 유사한 오류 메
시지를 접하게 된다면 OS의 옵션을 조정해야 한다. 리눅스에서 ulimit -a 명령으로 동시에 열 수 있는 파일
의 수를 확인할 수 있으며(open files 값), ulimit -n 2048과 같이 이 수를 원하는 값으로 조정할 수 있다. 하
지만 이 방법은 일시적이며 OS의 제약으로 인해서 이와 같이 변경하는 일도 쉽지 않다. 대신 /etc/security/
limits.conf 파일에서 값을 변경하는 방법을 추천한다. 값을 4096으로 설정하고 테스트를 수행하면 아마도
앞의 오류 메시지를 피할 수 있을 것이다. 대부분의 시스템에서는 더 큰 값으로 변경하면 변경 설정이 적용되
지 않을 수 있다. 그리고 2장과 3장에서 소개한 몇 가지 프로세서와 메모리에 관한 설정도 사용하는 것이 좋
다. 하지만 가능하다면 PC 환경보다는 클러스터링 환경에서 테스트해보기를 권한다. 이 장의 후반부 예제,
특히 프레겔을 사용한 예제들은 일반 PC 환경에서는 수 시간씩이 소요될지도 모른다.
압축을 풀면 총 600MB의 XML 파일들이 나온다. 표본 파일의 각 엔트리는 MedlineCitation
레코드로, 저널 이름, 권호Issue, 출간일, 저자명, 초록Abstract, 해당 기사와 관련된 MeSH 키
워드 등, 생의학 저널의 기사와 관련된 정보가 들어 있다. 각 MeSH 키워드에는 그 키워
드가 나타내는 개념이 그 기사의 핵심 주제인지를 알려주는 속성도 포함되어 있다. 그러면
medsamp2016a.xml에 포함된 첫 번째 인용 레코드를 살펴보자.
194 9가지 사례로 익히는 고급 스파크 분석 (2판)
MedlineCitation Owner=PIP Status=MEDLINE
PMID Version=112255379/PMID
DateCreated
Year1980/Year
Month01/Month
Day03/Day
/DateCreated
...
MeshHeadingList
...
MeshHeading
DescriptorName MajorTopicYN=NHumans/DescriptorName
/MeshHeading
MeshHeading
DescriptorName MajorTopicYN=YIntelligence/DescriptorName
/MeshHeading
MeshHeading
DescriptorName MajorTopicYN=YRorschach Test/DescriptorName
/MeshHeading
...
/MeshHeadingList
...
/MedlineCitation
6장에서 다룬 위키백과 문서 관련 숨은 의미 분석(LSA)에서는 주로 XML의 각 레코드에 담
긴 구조화되지 않은 텍스트에 관심을 두었다. 하지만 이번 장의 동시발생 분석에서는 XML의
구조를 직접 파싱하여 DesciptorName 태그에 담긴 값을 꺼내려 한다. 마침, 스칼라에는
XML 문서를 파싱하고 질의하기 위한 scala-xml이라는 훌륭한 라이브러리가 있어서 이 작업
을 쉽게 처리할 수 있다.
인용 데이터를 HDFS에 올리는 것부터 시작해보자.
$ hadoop fs -mkdir medline
$ hadoop fs -put *.xml medline
이제 스파크 셸을 시작할 준비가 되었다. 6장에서 언급한 XML 데이터 파싱 코드(XMLInput
Format 클래스)를 이 장에서도 사용한다. 이 코드를 컴파일하고 JAR 파일로 만들어 사용할
것이다. 다음과 같이 깃 저장소의 ch07-graph/ 디렉터리로 이동한 다음, 메이븐을 사용해 빌
드하자.
2278장 뉴욕 택시 운행 데이터로 위치 및 시간 데이터 분석하기
“시간과 공간만큼 내게 혼란을 주는 것은 없다.
그러나 시간과 공간만큼 나를 괴롭히지 않는 대상도 없다.
왜냐하면 나는 그 주제를 한 번도 생각해본 적이 없기 때문이다.”
-찰스 램
뉴욕은 노란 택시로 유명하다. 노점상에서 핫도그를 사 먹거나 엘리베이터를 타고 엠파이어 스
테이트 빌딩 꼭대기까지 올라가 보는 일과 마찬가지로 노란 택시 타보기는 뉴욕 관광의 필수
코스가 되었다.
뉴욕 주민들은 러시아워나 궂은 날씨에 택시를 잡을 때, 언제 혹은 어디가 좋은지와 같은 수많
은 (입증되지 않은 경험에 근거한) 정보를 알고 있다. 하지만 모든 사람이 매일 오후 4~5시
사이의 교대시간만큼은 그냥 지하철을 타라고 이구동성으로 이야기한다. 이 시간에 노란 택시
들은 (주로 퀸스에 위치한) 교대 장소로 돌아가 택시 기사를 교대하는데, 늦게 돌아오는 택시
기사에게는 벌금이 부과된다.
2014년 3월, 뉴욕 택시 리무진 위원회는 영업 중인 택시의 수와 승객을 태운 택시의 비율을 시
간대별로 정리한 인포그래픽을 트위터 계정 @nyctaxi(https://twitter.com/nyctaxi)로 공유
했다. 당연하게도, 오후 4~6시 사이에 영업 중인 택시의 수는 눈에 띌 만큼 적었고, 그중 2/3
정도가 승객을 태우고 있었다.
뉴욕 택시 운행 데이터로
위치 및 시간 데이터 분석하기
CHAPTER 8
조시 윌스
228 9가지 사례로 익히는 고급 스파크 분석 (2판)
이 트윗을 자칭 도시 계획 전문가이자 지도 제작자이자 데이터 광인 크리스 홍Chris Whong이 주목
했다. 그는 인포그래픽 제작에 이용된 데이터를 공개적으로 사용할 수 있는지를 알아보기 위해
@nyctaxi 계정으로 트윗을 보냈고, 택시 위원회는 정보공개법에 따른 공식 요청서와 데이터
를 담아 갈 하드디스크를 제출하면 데이터를 건네주겠다고 답했다. 크리스는 요청서를 작성하
고 500GB의 하드디스크 2개를 구입해 보냈고, 영업일 기준으로 이틀 후에 2013년 전체의 모
든 택시 운행 정보를 손에 쥐었다. 여기서 그치지 않고, 그는 모든 택시 요금 데이터를 인터넷
에 올렸고, 지금까지 이 정보는 뉴욕의 교통수단과 관련한 멋진 시각화 자료들의 기초 데이터
로 사용되고 있다.
택시의 경제학을 이해하는 데 중요한 통계 하나는 영업시간과 승객을 태운 시간의 비율인 이용
률Utilization이다. 승객의 목적지는 이용률에 영향을 주는 요소다. 예를 들어서 한낮에 유니언 광
장 근처에서 승객을 내린 택시는 단 1~2분 안에 다음 승객을 태울 가능성이 매우 높은 반면,
새벽 2시에 스태튼섬에서 승객을 내린 택시는 다음 승객을 찾으려면 맨해튼까지 돌아와야만
할 수도 있다. 우리는 이러한 영향을 수치화하고 택시에 다음 승객이 탈 때까지의 평균 시간을
승객이 내린 자치구의 함수로 만들어내고자 한다. 함수의 입력값으로는 맨해튼, 브루클린, 퀸
스, 브롱크스, 스태튼섬, 기타(뉴어크Newark 국제공항과 같은 뉴욕 바깥 지역)가 있다.
이 분석을 수행하려면 항시 마주하게 되는 두 종류의 데이터를 다뤄야 한다. 하나는 날짜와 시
각 같은 시간 데이터고, 다른 하나는 경도와 위도 및 지역 경계와 같은 위치 데이터다. 이 책 초판
이 출간된 이후로 스파크에서 시간 데이터를 다루는 방법에 몇 가지 개선이 있었다. 자바 8에
서 java.time이라는 신규 패키지가 소개되었고, Spark SQL에는 아파치 하이브 프로젝트의
사용자 정의 함수(UDF)들이 포함되었다. 이 사용자 정의 함수들에는 date_add와 from_
timestamp 같이 시간을 다루는 함수들이 다수 포함되어, 스파크 1 때보다 작업을 훨씬 수월
하게 해준다. 반면, 위치 데이터는 여전히 다소 특별한 종류의 분석이라서 이를 효과적으로 분
석하려면 서드파티 라이브러리들을 사용하고 필요한 사용자 정의 함수들을 우리가 직접 작성
해야 한다.
8.1 데이터 얻기
이번 분석에서 2013년 1월의 요금 데이터만 다룰 것인데, 압축을 풀면 2.5GB 정도 된다.
2298장 뉴욕 택시 운행 데이터로 위치 및 시간 데이터 분석하기
2013년의 월별 데이터는 http://www.andresmh.com/nyctaxitrips/에서 내려받을 수 있다. 사
용할 수 있는 스파크 클러스터가 충분히 크다면, 이제부터 수행할 분석을 2013년 전체 데이터
로도 해볼 수 있을 것이다. 먼저 클라이언트 노드에 작업 디렉터리를 만들고 요금 데이터의 구
조를 살펴보도록 하자.
$ mkdir taxidata
$ cd taxidata
$ curl -O https://nyctaxitrips.blob.core.windows.net/data/trip_data_1.csv.zip
$ unzip trip_data_1.csv.zip
$ head -n 10 trip_data_1.csv
이 파일은 머릿줄을 제외하면 한 줄에 택시 운행 한 건씩 CSV 형식으로 기록되어 있다. 각 운
행 정보는 택시 정보(해시된 메달리온 번호1
)와 운전자 정보(해시된 핵 라이선스Hack License, 택시
면허), 운행 시작 시각과 종료 시각과 같은 시간 정보, 승객의 탑승 지점과 하차 지점의 경도·위
도 좌표 등의 속성으로 이뤄진다.
8.2 스파크에서 서드파티 라이브러리로 작업하기
자바 플랫폼의 최고 장점 하나는 이 플랫폼만을 위해서 수년간 개발되어온 코드의 양 그 자체
다. 어떤 자료형이나 알고리즘도 이미 다른 누군가가 자바 라이브러리로 개발해두었을 가능성
이 크며, 나아가 그 라이브러리의 오픈 소스 버전이 존재하여 무료로 사용할 수 있을 가능성이
크다.
물론, 단지 무료 라이브러리가 있다는 사실이 반드시 그 라이브러리를 사용해야 할 이유는 되
지 못한다. 오픈 소스 프로젝트는 품질, (버그 수정 및 신규 기능에 대한) 개발 진행 상황,
(API 설계와 잘 작성된 문서와 튜토리얼의 유무에 따른) 사용 편의성 측면에서 편차가 매우
크다.
우리가 라이브러리를 선정하는 과정은 애플리케이션 개발자가 라이브러리를 선정하는 과정
과 약간 다르다. 우리는 대화형 데이터 분석에 사용하기 좋고, 분산 애플리케이션에서 쉽게 사
1	 옮긴이_ 메달리온은 뉴욕 노란 택시의 전면에 장착하는 휘장을 말하고, 메달리온에는 번호가 부여되어 있다.
230 9가지 사례로 익히는 고급 스파크 분석 (2판)
용할 수 있는 라이브러리를 원한다. 특히 RDD 내에서 다룰 주요 자료형들은 Serializable 인
터페이스를 구현했거나 Kryo 같은 라이브러리를 통해 쉽게 직렬화된다는 점을 반드시 만족하
길 원한다.
거기다가 대화형 분석에 사용하는 라이브러리는 가능한 한 다른 외부 라이브러리에 대한 의존
성이 없는 것을 선호한다. 메이븐이나 SBT와 같은 도구는 개발자가 애플리케이션을 빌드할 때
복잡한 의존성 문제를 처리해주지만, 대화형 데이터 분석의 경우에는 단순히 필요한 모든 코드
를 JAR 파일에 다 담아버리고, 스파크 셸에서 읽어 들여 그대로 분석을 시작하는 편이 훨씬 좋
다. 게다가 라이브러리가 의존성을 다수 갖게 되면 스파크가 사용하는 다른 라이브러리와 버전
충돌이 발생할 수도 있다. 이 상황이 심해지면 개발자 사이에서 소위 ‘JAR 지옥’이라 불리는 진
단하기 어려운 오류 상황에 빠지게 된다.
마지막으로 추상 팩토리 패턴이나 방문자 패턴과 같은 자바 위주의 디자인 패턴을 많이 사용하
지 않는, 비교적 간단하고 풍부한 API를 선호한다. 디자인 패턴이 애플리케이션 개발자에게는
매우 유용하겠지만, 분석과 관련 없는 부분에서 코드를 훨씬 복잡하게 만드는 경향이 있다. 그
나마 나은 것은 많은 자바 라이브러리에 스칼라 래퍼가 있어, 라이브러리를 사용하는 데 필요
한 자질구레한 코드를 줄이고 스칼라의 장점을 살려주고 있다.
8.3 지리 데이터와 Esri Geometry API, 그리고 Spray
JVM에서 시간 데이터를 다루는 일은 자바 8의 java.time 패키지 덕에 매우 쉬워졌다. 이 패키
지는 널리 사용되는 JodaTime 라이브리리를 기초로 설계되었다. 한편, 지리 데이터 쪽은 그
리 녹록지 않다. 관련 라이브러리와 도구가 다양하나, 기능, 개발 진행 상황, 성숙도에서 차이
를 보여 모든 상황에 압도적으로 널리 사용되는 라이브러리는 없다.
라이브러리를 선택할 때 첫째로 반드시 생각해봐야 하는 건 어떤 유형의 지리 데이터를 다루느
냐다. 주요한 두 유형으로 벡터Vector와 래스터Raster가 있으며, 각각은 지원하는 도구도 다르다.
우리 예제인 택시 운행 기록에는 경도와 위도라는 위치 값이 있고 뉴욕의 여러 자치구 경계를
표현하는 벡터 데이터도 있는데, 여기서 벡터 데이터는 GeoJSON 포맷으로 저장되어 있다.
그러므로 우리는 GeoJSON 데이터를 파싱할 수 있고, 주어진 경도, 위도 쌍이 (특정 자치구
경계를 표현하는) 다각형 내부에 있는지 알아내는 것과 같은 위치 관계를 다룰 수 있는 라이브
2318장 뉴욕 택시 운행 데이터로 위치 및 시간 데이터 분석하기
러리가 필요하다.
안타깝지만, 우리의 바람에 정확히 들어맞는 오픈 소스 라이브러리는 없다. GeoJSON 레코드
들을 자바 객체들로 변환하는 GeoJSON 파서 라이브러리가 있으나, 결과로 생성된 객체의 공
간 관계를 분석해줄 관련 지리 라이브러리가 없다. GeoTools 프로젝트라는 것도 있지만 다
른 컴포넌트에 대한 의존성이 크다. 따라서 스파크 셸에서 사용할 라이브러리를 고른다면 피해
야 할 대상에 해당된다. 마지막으로 자바용 Esri Geometry API가 있는데, 의존성이 거의 없
고 공간 관계도 분석할 수 있다. 하지만 GeoJSON 표준 중 일부 형태만 파싱할 수 있기 때문
에 몇 가지 데이터 전처리 없이는 우리가 내려받은 GeoJSON 데이터를 파싱할 수 없다.
적합한 분석 도구가 없다는 것은 데이터 분석가에게는 큰 난관이다. 그러나 우리는 데이터 과
학자다. 만약 도구의 한계로 문제를 해결하지 못한다면 새로운 도구를 만들면 된다. 이번 장
에서는 JSON 파싱을 지원하는 수많은 스칼라 프로젝트 중 하나를 이용하여, Esri Geometry
API에서 처리할 수 없는 사례까지 포함한 모든 GeoJSON 데이터를 파싱할 수 있도록 스칼라
기능을 추가할 것이다. 이어지는 절들에서 다룰 코드는 이 책의 깃허브 저장소는 물론, 독립 라
이브러리로 형태로도 깃허브(https://github.com/jwills/geojson)에 따로 공개해뒀으니, 다른
스칼라 지리 분석 프로젝트에도 사용할 수 있다.
8.3.1 Esri Geometry API 살펴보기
Esri 라이브러리의 핵심 자료형은 Geometry다. Geometry는 기하학 형태와 그 기하학 형태
가 점유하는 지리적 위치 정보를 함께 기술한다. Esri는 기하학 구조물과 그들 사이의 관계를
분석하는 일련의 위치 연산 기능을 제공한다. 이러한 연산 기능들로 기하학 구조물의 영역을
계산하거나, 두 기하학 구조물이 겹치는지 알아내거나, 두 기하학 구조물을 합쳐 하나의 구조
물로 변환하는 등의 일을 할 수 있다.
우리의 분석 문제에서는 택시 승객의 하차 지점(경도와 위도)을 나타내는 Geometry 객체들
과 뉴욕 내 자치구 경계를 나타내는 Geometry 객체들을 가지게 될 것이다. 여러 위치 관계 중
우리의 관심사는 “주어진 지점이 맨해튼 자치구에 관련된 여러 다각형 중 하나의 내부에 위치
하는가?”와 같은 ‘포함 관계’다.
Esri가 제공하는 GeometryEngine라는 편의 클래스는 contains 연산은 물론 모든 종류의
232 9가지 사례로 익히는 고급 스파크 분석 (2판)
위치 관계 연산을 수행하는 정적 메서드들을 가진다. contains 메서드는 3개의 인수를 받는
데, 2개는 Geometry 객체고 다른 1개는 SpatialReference 클래스의 인스턴스다. 여기서
SpatialReference 클래스는 지리공간 계산에 이용되는 좌표계Coordinate System를 나타낸다. 최대
한 정확하게 계산하기 위해서 우리는 일그러진 3차원 구체인 지구의 각 지점을 2차원 좌표계로
매핑하는 ‘좌표면에 관한 공간적 관계들’을 분석해야 한다. 지리공간 정보를 다루는 엔지니어들
은 좌표계를 표시할 때 흔히 사용하는 통용식별자Well-known Identifier (WKID)라는 표준을 사용한
다. 이 책의 예제에서는 GPS용 표준 좌표 시스템인 WKID 4326을 사용할 것이다.
스칼라 개발자로서 우리는 항상 스파크 셸로 수행하는 대화형 분석 작업 시의 타이핑 양을 줄
여주는 방법을 찾는다. 이클립스Eclipse나 인텔리제이IntelliJ 같은 IDE가 제공하는 메서드 이름 자
동 완성과 특정 연산을 더 읽기 편하게 하는 일부 편의 문법을 스파크 셸에서는 사용할 수 없는
상황이다. 그래서 우리는 Esri의 Geometry 클래스에 유용한 도우미 메서드를 몇 개 추가해
확장한 RichGeometry 클래스를 정의할 것이다. 여기서 명명규칙은 NScalaTime 라이브러
리가 래퍼 클래스 이름(RichDateTime, RichDuration 등)에 적용한 형태를 참고했다.
import com.esri.core.geometry.Geometry
import com.esri.core.geometry.GeometryEngine
import com.esri.core.geometry.SpatialReference
class RichGeometry(val geometry: Geometry,
val spatialReference: SpatialReference =
SpatialReference.create(4326)) {
def area2D() = geometry.calculateArea2D()
def contains(other: Geometry): Boolean = {
GeometryEngine.contains(geometry, other, spatialReference)
}
def distance(other: Geometry): Double = {
GeometryEngine.distance(geometry, other, spatialReference)
}
}
또 RichGeometry의 동반 객체를 선언하여 Geometry 클래스의 인스턴스를 RichGeometry
인스턴스로 변환하는 암묵적 형변환을 제공할 것이다.
object RichGeometry {
2539장 몬테카를로 시뮬레이션으로 금융 리스크 추정하기
“지질학을 이해하고 싶다면 지진을 공부하라.
경제학을 이해하고 싶다면 경기 침체를 공부하라.”
-벤 버냉키
합리적인 상황에서 여러분은 얼마만큼의 손실을 예상할 수 있는가? 이것이 최대손실예상액Value at
Risk (VaR)이라는 금융 통계량이 측정하고자 하는 양이다. VaR은 1987년 주식 시장 붕괴 직후
개발되어 모든 금융 서비스 조직에서 널리 사용하고 있다. 이 통계량은 금융 기관들이 추구하
는 신용 등급을 만족하기 위해 보유해야 하는 현금의 양을 정하는 데 도움이 되기 때문에 자산
관리에서 필수적인 역할을 한다. 일부 기관은 대규모 포트폴리오들의 리스크 특성을 더 광범위
하게 이해하기 위해 사용하고, 또 다른 일부는 거래 실행 전에 이 값을 계산하여 즉각적인 결정
을 내리는 데 도움을 얻는다.
VaR 통계량을 추정하는 여러 정교한 방법들 대부분은 계산량이 매우 많은 방법인 임의 상황
에서의 시장 시뮬레이션에 의존한다. 그리고 이런 방법 뒤에는 몬테카를로 시뮬레이션Monte Carlo
Simulation이라는 기술이 있다. 이 기술은 수천에서 수백만의 임의 시장 시나리오를 제기하고, 그
상황이 포트폴리오에 어떤 영향을 주는지 관찰한다. 몬테카를로 시뮬레이션은 자연스럽게 대
규모로 병렬화되기 때문에 스파크는 이를 위한 최적의 도구다. 스파크는 수천의 코어를 활용하
여 임의 실험들을 수행하고 실험 결과들을 집계할 수 있다. 또한 범용 데이터 변환 엔진인 스파
크는 시뮬레이션 관련 전처리와 후처리에도 능숙하다. 스파크는 원시 금융 데이터를 여러 시뮬
몬테카를로 시뮬레이션으로
금융 리스크 추정하기
CHAPTER 9
샌디 라이자
254 9가지 사례로 익히는 고급 스파크 분석 (2판)
레이션 수행에 필요한 모델 파라미터들로 변환하는 일뿐만 아니라 시뮬레이션 결과들에 대한
애드혹Ad-hoc 분석도 지원한다. 스파크의 간단한 프로그래밍 모델은 HPC 환경을 이용하는 전
통적인 방법보다 개발 기간을 현저히 줄일 수 있다.
‘예상할 수 있는 손실의 양’을 좀 더 엄격하게 정의해보자. VaR은 간단한 투자 리스크 척도로,
투자 포트폴리오가 특정 기간에 입을 수 있는 최대 손실에 대한 합리적인 추정치를 제공하는
것이 목적이다. VaR 통계량은 포트폴리오, 보유 기간, 확률이라는 세 파라미터에 따라 값이 달
라진다. “5%의 확률로 보유 기간은 2주일 때의 VaR 통계량이 1백만 달러다”라는 말은 “해당
포트폴리오가 2주 동안 1백만 달러 ‘이상’의 손실을 볼 확률이 단 5%다”라는 의미다.
VaR과 관련된 조건부 최대손실예상액Conditional Value at Risk (CVaR)이라는 통계량 계산 방법도 논의
할 것이다(기대 손실Expected Shortfall이라고도 한다). CVaR은 바젤 은행 감독 위원회가 VaR보다
나은 리스크 척도로써 최근 제안했다. CVaR 통계량은 VaR 통계량이 가지고 있는 세 파라미터
를 똑같이 가지나, 컷오프 값 대신 기대 손실 관점을 다룬다. “5%의 확률로 보유 기간은 2주일
때 CVaR 통계량이 5백만 달러다”라는 말은 “전체 시나리오 중 최악의 결과를 내는 5%의 시나
리오들에서의 ‘평균’ 손실이 5백만 달러다”라는 의미다.
이번 장에서는 VaR 모델링을 다루며 몇 가지 개념, 방법, 패키지를 소개할 것이다. 구체적으로
는 커널 밀도 추정, breeze-viz 패키지를 활용한 시각화, 다변량 정규분포를 활용한 표본추출
그리고 아파치 커먼즈 수학Apache Commons Math 패키지를 활용하여 통계 함수들을 다룰 것이다.
9.1 전문 용어
이 장에서는 금융 도메인에 특화된 용어들을 사용한다. 먼저 이들 용어를 간단히 정의해보자.
금융상품Instrument
거래 가능한 자산으로 채권, 대출, 옵션, 주식이 있다. 어떤 시점이든 금융상품은 판매 가
격을 가진다고 간주한다.
포트폴리오Portfolio
금융 기관이 소유한 금융상품들의 모음
2559장 몬테카를로 시뮬레이션으로 금융 리스크 추정하기
수익Return
금융상품 또는 포트폴리오의 일정 기간의 가격 변화
손실Loss
마이너스 수익
지수Index
가상의 금융상품 포트폴리오. 예를 들어서 나스닥 지수는 약 3,000개의 미국 혹은 국제 기
업들의 주식과 유사 금융상품을 포함한다.
시장 요인Market Factor
특정 시간에 재정 상황의 거시적 측면을 나타내는 지표로 사용될 수 있는 값. 예를 들어서
미국의 국내 총생산(GDP) 또는 달러-유로 환율과 같은 인덱스 값이 있다. 이 책에서는 종
종 시장 요인을 그냥 요인이라고 언급할 것이다.
9.2 VaR 계산 방법
지금까지 우리가 내린 VaR의 정의에는 정하지 않은 부분이 상당히 있다. 이 통계량을 추정하
려면 어떻게 포트폴리오가 동작하는지에 대한 모델을 제안하고 이 포트폴리오의 수익이 따를
법한 확률 분포를 선택해야 한다. 기관들은 VaR을 계산하기 위해 다양한 방법을 쓰고 있지만,
이 모든 방법은 몇 가지 일반적인 방법의 범주에 속하는 경향이 있다.
9.2.1 분산-공분산
분산-공분산Variance-Covariance은 단연코 가장 간단하고 가장 계산량이 적은 방법이다. 분산-공분
산 모델은 각 금융상품의 수익이 정규분포를 따른다고 가정하여 VaR 통계량을 해석적으로 유
도할 수 있게 한다.
256 9가지 사례로 익히는 고급 스파크 분석 (2판)
9.2.2 과거 기반 시뮬레이션
과거 기반 시뮬레이션Historical Simulation은 요약 통계에 의존하는 대신 과거 데이터의 분포를 직접
이용하여 리스크를 추정한다. 예를 들어서 포트폴리오의 5% VaR을 알아내기 위해 그 포트폴
리오의 지난 100일간의 성과를 보고 그중 5번째로 나쁜 날의 값으로 VaR 통계량 값을 추정할
수도 있다. 이 방법의 문제는 과거 데이터가 그만큼 많이 쌓여 있지 않을 수 있고, 지금 가정하
는 시나리오들을 포함하지 못할 수 있다는 것이다. 예를 들어, 시장붕괴를 겪어본 적 없는 금
융상품들로 구성된 포트폴리오를 가지고 시장붕괴가 일어났을 때 무슨 일이 일어날지를 모델
링하려 한다면 어떻게 해야 하느냐는 말이다. 역사적 시뮬레이션을 이러한 상황에 덜 민감하게
만들어주는 기술로 데이터 속에 쇼크Shock를 넣는 등의 기법이 있지만 여기서는 다루지 않기로
한다.
9.2.3 몬테카를로 시뮬레이션
이 장의 나머지에서 중점적으로 다룰 몬테카를로 시뮬레이션은 포트폴리오를 임의 상황에서
시뮬레이션함으로써 앞에서 소개한 방법이 취해야 했던 가정을 약화시키려 노력한다. 확률 분
포의 닫힌 형태Closed-form를 해석적으로 유도할 수 없다면, 보통 이 분포에 영향을 주는 더 간단
한 확률 변수Random Variable를 반복해서 표본추출한 다음, 이 변수들이 전체에 어떤 영향을 주는
지 관찰하여 확률 밀도 함수Probability Density Function (PDF)를 추정할 수 있다. 가장 일반적인 형태
에서 이 방법은 다음과 같다.
●	‌‌시장 상황들과 각 금융상품의 수익 사이의 관계를 정의한다. 이 관계는 과거 데이터에 적합된Fitted 모델의 형태
를 가진다.
●	‌‌시장 상황들이 따르는 분포들을 정의한다. 이 분포들은 과거 데이터에 적합된다.
●	‌‌임의 시장 상황들로 구성된 실험Trial들을 제기한다.
●	‌‌각 실험에서 전체 포트폴리오 손실을 계산하고, 이 손실값들을 이용하여 손실에 대한 경험적 분포Empirical
Distribution를 정의한다. 이는 만약 실험을 100번 실행하고 5% VaR을 추정하길 원한다면, 손실이 5번째로 큰
실험으로부터 얻어진 손실값을 추정치로 선택할 것임을 뜻한다. 5% CVaR을 계산하려면 최악의 결과를 내
는 실험 5개의 평균 손실을 구할 것이다.
물론, 몬테카를로 방법 역시 완벽한 건 아니다. 몬테카를로 방법은 실험 상황들을 생성하는 모
델과 금융상품 성과를 추정하는 모델에 의존적이며, 여기서 이 모델들은 반드시 단순화한 가정
들을 하게 된다. 만약 이 단순화한 가정들이 현실을 반영하지 못한다면, 결과로 얻게 될 최종
2579장 몬테카를로 시뮬레이션으로 금융 리스크 추정하기
확률 분포 역시 현실을 반영하지 못할 것이다.
9.3 우리의 모델
몬테카를로 리스크 모델은 일반적으로 각 금융상품의 수익을 ‘시장 요인’ 항Term들로 표현한다.
공통적인 시장 요인은 SP 500, 미국 GDP, 환율 같은 지수값일 것이다. 그 후에 이런 시장
상황에서 각 금융상품 수익을 예측하는 모델이 필요하다. 우리 시뮬레이션에서는 간단한 선형
모델을 사용할 것이다. 앞에서 내린 수익의 정의에 따라, 요인 수익Factor Return은 특정 기간의 시장
요인 값의 변화다. 예를 들어서 특정 기간에 SP 500 지수가 2,000에서 2,100으로 움직였다
면 요인 수익은 100이다. 우리는 요인 수익들의 간단한 변형으로부터 일련의 특징들을 얻을 것
이다. 즉, 어떤 함수 Φ를 적용해서 실험 t용 시장 요인 벡터 mt를 변형하여 길이가 다를 수 있
는 특징 벡터 ft를 만들려는 것이다.
ft = Φ(mt )
금융상품별로 각 특징에 가중치를 부여하는 모델을 학습할 것이다. 실험 t에서 금융상품 i의 수
익인 rit를 계산하기 위해 우리는 금융상품에 대한 절편Intercept Term인 ci, 특징 j의 금융상품 i에
대한 회귀 비중Regression Weight인 wij, 그리고 실험 t에서 무작위로 생성된 특징 j의 값인 ftj를 사용
할 것이다.
rit = ci +
|wi|
j=1
wij ∗ ftj
이 수식은 각 금융상품 수익이 시장 요인 특징들의 수익에 해당 금융상품에 대한 특징들의 가
중치를 곱한 값의 합으로 계산됨을 뜻한다. 우리는 과거 데이터를 활용하여 금융상품별 선형
모형을 적합시킬 수 있다(선형 회귀분석을 한다고도 한다). 만약 VaR 계산에서 보유 기간이 2
주라면, 회귀분석은 과거 이력에서의 모든 (겹쳐지는) 2주 간격을 레이블된 포인트로 취급한다.
또한, 우리가 더 복잡한 모델을 선택할 수도 있다는 점을 언급해두고자 한다. 예를 들어서 모델
이 꼭 선형일 필요는 없다. 모델은 회귀 트리여도 되고 명시적으로 특정 도메인 지식을 포함할
258 9가지 사례로 익히는 고급 스파크 분석 (2판)
수 있다.
시장 요인들로부터 금융상품 손실을 계산할 수 있는 모델이 생겼으니, 이제 시장 요인들의 움
직임을 시뮬레이션하는 절차가 필요하다. 간단히 각 시장 요인 수익은 정규분포를 따른다고 가
정할 수 있다. 시장 요인들은 흔히 서로 연관되어 있다는 사실(나스닥 지수가 내려가면 다우
지수도 악화될 가능성이 높다)을 반영하기 위해 우리는 비대각 공분산 행렬Non-diagonal Covariance
Matrix을 가지는 다변량 정규분포를 사용할 수 있다.
mt
( , )µ
여기서 μ는 요인들의 수익에 대한 경험적 평균Empirical Mean 벡터이고, Σ는 요인들의 수익에 대한
경험적 공분산 행렬Empirical Covariance Matrix이다.
이전과 마찬가지로, 더 복잡한 시장 시뮬레이션 방법을 선택하거나 시장 요인별로 다른 유형의
분포(꼬리 쪽이 두터운 분포라든지)를 가정해도 된다.
9.4 데이터 구하기
대규모로 잘 형식화된 과거의 가격 데이터를 찾기는 어려울 수 있으나, 야후!에서 다양한 주식
데이터를 CSV 형식으로 내려받을 수는 있다. 예제 깃허브 저장소 risk/data 디렉터리의 다음
스크립트는 일련의 REST 요청을 날려 나스닥에 등록된 모든 주식의 과거 데이터를 내려받아
stocks 디렉터리에 저장한다.1
$ ./download-all-symbols.sh
리스크 요인들에 대한 과거 데이터도 필요하다. 우리는 시장 요인으로 SP 500과 나스닥 지수
의 값들뿐만 아니라 미국 재무부가 발행한 5년, 30년 만기 국채 가격들을 사용할 것이다. 이들
역시 야후!에서 내려받을 수 있다.
1	 옮긴이_ 이 책에서 사용한 야후!로부터 주식 데이터를 내려받는 API 서비스는 2017년 5월 17일 종료되었다. 이후 2017년 8월 4일에
예제 깃허브 소스에서 데이터 소스를 구글로 변경해두었으나, 역시 제대로 작동하지 않는 것으로 보인다. 그래서 작동하는 버전을 옮긴이
깃허브(https://goo.gl/VxPQTb)에 올려두었다. 단, 데이터 정렬 결과와 품질이 책의 내용과 살짝 달라질 수 있으니 참고하기 바란다.
Σ
28110장 BDG 프로젝트와 유전체학 데이터 분석하기
“그래서 우리는 유전자의 구성 물질을 우주로 쏴 보내야 한다.”1
-조지 처치
차세대 염기서열 분석Next-generation DNA Sequencing (NGS) 기술의 출현으로 생명과학도 데이터
가 주도하는 분야로 급변하고 있다. 하지만 DRMAADistributed Resource Management Application API2
나
MPIMessage Passing Interface3
와 같은 사용하기 어려운 저수준의 개발 환경과 정형화 수준이 낮은 텍
스트 기반 파일 포맷이 난립하는 상황에서 개발된 전통적인 컴퓨팅 생태계 탓에, 이 데이터를
효율적으로 이용하기까지 많은 난관에 부딪히고 있다.
이 장의 주요 목적은 세 가지다. 먼저, 일반적인 스파크 사용자에게 하둡과 함께 사용하기 좋은
새로운 직렬화 방법과 파일 형식(에이브로Apache Avro와 파케이Apache Parquet )을 소개한다. 이 형식
들은 데이터를 관리할 때 마주치는 수많은 문제를 매우 단순하게 만들어준다. 압축된 바이너리
형태, 서비스 지향 아키텍처(SOA), 언어 간 상호 호환성을 위해서 보통은 이런 직렬화 방법
을 사용하도록 권장한다. 다음으로는, 숙련된 생물정보학자가 일반적인 유전체학 작업을 어떻
게 수행하는지를 스파크의 맥락에서 보여준다.
1	 옮긴이_ 조지 처치는 그의 저서 『Regenesis: How Synthetic Biology Will Reinvent Nature and Ourselves』에서 인류의 역사
를 보존하기 위한 방법으로 인간의 유전체 정보를 담은 전파를 우주로 보내자고 제안한다.
2	 옮긴이_ 그리드, 클라우드 컴퓨팅 등에서 사용할 수 있도록 정의된 분산 컴퓨팅 API다. 자세한 내용은 DRMAA 워킹 그룹 홈페이지를
참조하기 바란다. https://www.drmaa.org/
3	 옮긴이_ 분산 및 병렬 처리에서 정보 교환과 관련된 추상화 수준의 상위 표준이다.
BDG 프로젝트와
유전체학 데이터 분석하기
CHAPTER 10
유리 레이저슨
282 9가지 사례로 익히는 고급 스파크 분석 (2판)
구체적으로 말하면, 처리 대상인 많은 양의 유전체4
데이터와 필터 데이터를 다루고, 전사인자
Transcription Factor (TF) 결합 부위 예측 모델을 세우고, 1000 지놈 프로젝트1000 Genome Project의 변이
체에 대해서 ENCODEEncyclopedia of DNA Elements 유전체 주석 데이터를 결합하는 일에 스파크를 사
용할 것이다.5
마지막으로, ADAM아담 프로젝트의 튜토리얼을 제공한다. 이 프로젝트는 대규모
유전체 분석을 위한 유전체 특화 에이브로 스키마와, 스파크 기반의 API, 명령줄 도구의 모음
이다. ADAM은 하둡과 스파크를 이용한 유전체 분석 툴킷Genome Analysis Toolkit (GATK) 모범 사
례를 분산 형태로 구현하여 제공한다.
이 장에서 유전체학 관련 부분은 일반적인 문제들에 익숙한 숙련된 생물정보학자를 대상으로
하지만, 데이터 직렬화 부분은 대량의 데이터를 다루는 모든 이에게 유용할 것이다. 이번 장에
서 다루는 분야를 처음 접하면서도 흥미가 생긴다면 에릭 랜더Eric S. Lander 등이 강의하는 edX 코
스(https://goo.gl/afZ6qk)를 추천한다. 생물정보학에 대한 소개는 옥스퍼드 대학교 출판부에
서 나온 아서 레스크Arthur Lesk의 『Introduction to Bioinformatics』(2014)를 참고하면 된다.
첨언하자면, 유전체는 1차원 좌표계라 할 수 있으므로 유전체 조작은 본질적으로 공간과 관련
된 작업이다. ADAM 프로젝트가 제공하는 유전체 맞춤 API는 예전의 RDD 인터페이스를 사
용하여 공간상의 조인을 분산으로 처리하도록 구현되어 있다. 그러므로 이 장에서는 현재 버전
스파크에서 제공하는 데이터셋이나 데이터프레임 인터페이스 대신 원래의 인터페이스를 그대
로 사용하기로 한다.
RDD를 사용하는 것에 관하여
이 책의 많은 부분과 달리, 이 장과 다음 장에서는 스파크의 구식 탄력적 분산 데이터셋, 즉
RDD API를 사용한다. 가장 큰 이유는 유전체 처리에서 흔히 사용되는 1차원 기하학 연산
에 특화된 다수의 조인 연산을 ADAM 프로젝트에서 만들었기 때문이다. 이들 연산은 이식
4	 옮긴이_ 게놈 또는 유전체는 한 개체의 유전자의 총 염기서열로, 한 생물종의 거의 완전한 유전 정보의 총합이다. 참고로, 일반적으로 쓰
이고 이 책의 원문에서도 사용한 genome이라는 단어는 영어식으로 지놈이라고 읽히는데, 유전체에 처음 이름을 붙인 독일인 한스 윙
클러Hans Winkler가 붙인 이름인 genom의 독일어식 발음인 게놈을 읽는 것이 바람직하다. 다만 1000 Genome Project는 이것 자체가
하나의 고유명칭으로 1000 지놈 프로젝트로 번역하는 것이 옳다. 이 책에서는 Genome은 유전체로 번역하며, 1000 지놈 프로젝트라
는 번역명이 Genome을 지놈으로 번역하는 것이 옳음을 의미하지는 않는다.
5	 옮긴이_ 전사(transcription)는 DNA의 유전 정보를 RNA에 복사하는 과정이다. 이를 통해서 DNA 복제 과정에 필요한 단백질을
RNA가 형성하는 등의 대사가 이루어진다. 전사인자는 이 전사 과정에 개입하는 단백질을 뜻한다. 유전자의 발현은 이들 전사인자의 결
합 부위의 결합에 의해 조절되므로 이를 예측하는 것은 유전체학의 중요한 이슈 중 하나다. ENCODE와 1000 지놈 프로젝트는 각각
https://www.encodeproject.org/ 와 http://www.1000genomes.org/ 를 참조하기 바란다.
28310장 BDG 프로젝트와 유전체학 데이터 분석하기
계획은 있지만 아직 데이터셋 API로 이식되지 않았다. 게다가 데이터프레임 API는 분산 처
리와 관련된 상세한 부분을 지정할 수 없기 때문에 ADAM의 조인 연산을 포팅하려면 스파
크의 질의 플래너를 직접 사용해야 한다. 한편, 이 장은 독자가 여타 스파크 기반 라이브러리
나 다른 오래된 코드를 통해 RDD API를 사용해야 할 때 도움이 될 수 있을 것이다.
10.1 모델링과 저장소를 분리하기
많은 과학자가 자신이 사용하는 도구에 맞는 고유한 파일 포맷을 필수로 여기는 것처럼, 생
물정보학자도 파일 포맷에 대하여 고민하며 많은 시간을 보낸다. 파일 포맷의 예로는 .fasta,
.fastq, .sam, .bam, .vcg, .gvcf, .bcf, .bed, .gff, .gtf, .narrowPeak, .wig, .bigWig,
.bigBed, .ped, .tped 등이 있다. 이 중 많은 포맷의 명세가 불완전하고 모호하며(이러한 이
유로 일관되게 구현되리라 확신하기 어렵다) 데이터를 ASCII로 인코딩하도록 규정하고 있다.
ASCII를 사용한 데이터는 생물정보학에서 매우 흔하지만, 효율이 떨어지고 상대적으로 압축
률도 낮다. 그래서 https://github.com/samtools/hts-specs처럼 명세를 개선해보자는 커뮤니
티도 생겨났다. 거기에다 데이터를 항상 파싱해야 하기에 추가 연산도 수행해야 한다. 이들 파
일 포맷 모두 서열 정렬 판독Aligned Sequence Read, 유전자형 명칭Called Genotype, 염기서열 특징Sequence
Feature, 표현형Phenotype과 같은 몇 가지 공통 객체 타입만을 필수로 저장하기 때문에 문제가 두드
러진다. (‘염기서열 특징’이라는 용어는 유전체학에서 조금씩 다른 의미로 사용되는데, 이 장
에서는 UCSC 유전체 브라우저의 기록 요소라는 의미로 사용한다.) 유명한 라이브러리인 바
이오파이썬Biopython (http://biopython.org/)은 모든 파일 포맷을 소수의 공통된 인메모리 모델
(Bio.Seq, Bio.SeqRecord, Bio.SeqFeature 등)로 읽어 들이는 파서들(Bio.SeqlO 등)로
가득 차 있다.
이러한 모든 문제를 에이브로와 같은 직렬화 프레임워크를 사용하여 단번에 해결할 수 있다.
내부의 저장소 파일 포맷으로부터 데이터 모델(즉, 명시적인 스키마)을 분리할 수 있으며, 인
메모리 표현이 가능하다는 에이브로의 특징이 해결의 열쇠다. 에이브로는 특정 유형의 데이터
를 프로세스 사이에 전달하는 방법이나 데이터를 특정한 파일 포맷으로 기록하는 프로세스를
지정한다. 이때 프로세스들이 인터넷을 사이에 두고 멀리 떨어져 있더라도 상관없다. 예를 들
284 9가지 사례로 익히는 고급 스파크 분석 (2판)
어 에이브로를 사용하는 자바 프로그램은 에이브로의 데이터 모델과 완전히 호환되는 여러 기
본 파일 포맷으로 데이터를 기록할 수 있다. 각각의 프로세스가 여러 파일 포맷들과 모두 호환
되는지는 걱정할 필요가 없다. 프로세스는 에이브로 데이터를 해석할 수 있고, 파일시스템에서
에이브로로 데이터를 읽어올 수만 있으면 된다.
예제로 염기서열 특징을 들여다보자. 우선 에이브로의 인터페이스 정의 언어Interface Definition
Language (IDL)를 사용하여 객체에 적합한 스키마를 지정한다.
enum Strand {
Forward,
Reverse,
Independent
}
record SequenceFeature {
string featureId;
string featureType; ➊
string chromosome;
long startCoord;
long endCoord;
Strand strand;
double value;
mapstring attributes;
}
➊ ‘conservation(보존)’, ‘centipede(지네)’, ‘gene(유전자)’ 등의 유형이 올 수 있다.
이 자료형은 유전체 특정 위치의 보존 수준, 프로모터Promoter 또는 리보솜Ribosome 결합 부위의 존
재, 전사인자 결합 부위 등을 인코딩하는 데 사용할 수 있다. 인코딩할 때 고려할 수 있는 방법
의 하나로, 제약은 많지만 성능은 훨씬 좋은 이진 버전의 JSON이 있다. 특정한 데이터 스키마
가 주어지면 에이브로는 객체에 맞는 정확한 이진 인코딩을 정하여 네트워크를 통하거나 디스
크에 저장된 상태로 프로세스끼리 쉽게 데이터를 주고받을 수 있다. 각각의 프로세스가 다른
프로그래밍 언어로 만들어져도 상관없다. 에이브로 프로젝트는 자바, C/C++, 파이썬, 펄Perl을
포함한 많은 언어에서 에이브로로 인코딩된 데이터를 처리할 수 있는 모듈을 제공한다. 그렇
게 통신이 이뤄지고 나면, 메모리상의 객체를 프로그래밍 언어에 가장 알맞다고 생각되는 방법
으로 자유롭게 저장하면 된다. 저장 포맷과 데이터 모델을 분리하여 한 차원 높은 유연성과 추
28510장 BDG 프로젝트와 유전체학 데이터 분석하기
상화를 제공하는 것이다. 에이브로 데이터는 열 기반 파일 포맷(파케이 파일) 속의 에이브로-
직렬화 이진 객체Avro-serialized Binary Object (에이브로 컨테이너 파일)의 형태나 텍스트 JSON 형태
로 저장할 수 있다. 전자는 빠른 질의를 위한 것이고, 후자는 유연성을 극대화하기 위한 것이다
(효율은 가장 낮다). 마지막으로 에이브로는 필요에 따라 사용자가 새로운 필드를 추가할 수
있는 스키마 개정Schema Evolution 기능을 지원한다. 그 덕분에 스키마를 추가해도 모든 소프트웨어
가 구 버전과 새 버전의 스키마를 문제없이 처리할 수 있다.
요약하자면, 에이브로는 개정될 수 있는 데이터 스키마를 쉽게 명시하고, 많은 프로그래밍 언
어가 같은 데이터를 처리하고 여러 가지 포맷을 사용하여 데이터를 저장할 수 있게 해주는 효
율적인 이진 인코딩 수단이다. 에이브로 스키마를 사용해서 데이터를 저장하기로 하면 계산 성
능을 높이는 동시에 점점 더 많은 특수 데이터 포맷을 다뤄야 하는 고통에서 벗어날 수 있다.
6
직렬화/RPC 프레임워크들
개발 현장에는 수많은 직렬화 프레임워크가 쓰인다. 빅데이터 커뮤니티에서 가장 널
리 사용하는 프레임워크로 에이브로, 쓰리프트Apache Thrift, 구글의 프로토콜 버퍼Protocol
Buffers(protobuf)가 있다. 셋 모두 객체나 메시지의 스키마를 명시할 때 사용하는 인터페이
스 정의 언어(IDL)를 제공하며 다양한 프로그래밍 언어로 컴파일할 수 있다는 점이 핵심이
다. 쓰리프트는 IDL 외에도 RPC를 명시하는 방법도 제공한다(프로토콜 버퍼를 위한 구글의
RPC 프레임워크는 gRPC라는 이름으로 오픈 소스화 되어 있다). 그리고 에이브로는 IDL과
RPC 외에도 데이터를 디스크에 저장하기 위한 파일 포맷을 지정하는 기능도 제공한다. 구
글이 최근에 발표한 ‘직렬화’ 프레임워크는 통신상이건 메모리상이건 같은 크기의 같은 메시
지를 사용하기 때문에 직렬화 과정에 들어가는 비용을 효과적으로 줄여준다.6
이들 모두는 다른 언어를 지원하고 언어별로 성능이 다르므로 어떤 상황에 어떤 프레임워크
가 적당하다고 일반화해 말하기는 어렵다.
앞의 예제에서 본 SequenceFeature 모델은 실데이터에 사용하기에는 조금 단순했다. 하지만
빅데이터 유전체학 프로젝트BDG Project (http://bdgenomics.org/)를 보면 다음 예를 포함한 다양
6	 옮긴이_ 2016년 7월자 프로토콜 버퍼 3.0.0 베타4 버전에 추가된 Deterministic Serialization 기능을 말한다. 유용한 기능이지만
현재는 C++ API만 제공하고 있다.
286 9가지 사례로 익히는 고급 스파크 분석 (2판)
한 객체를 표현하는 데 사용할 수 있는 에이브로 스키마를 이미 정의해두었다.
●	‌‌리드Read7
를 표현하기 위한 AlignmentRecord
●	‌‌알려진 유전체 변이와 메타데이터를 표현하기 위한 Variant
●	‌‌특정한 유전자좌위Locus8
에서 지정된 유전자형을 표현하기 위한 Genotype
●	‌‌염기서열 특징(유전체 세그먼트에 대한 주석)을 표현하기 위한 Feature
실제 스키마는 깃허브에서 bdg-formats(https://goo.gl/8t2yDn)를 보면 찾을 수 있다.
BDG 형식은 BAM이나 VCF와 같은 흔한 ‘구닥다리’ 형식을 대체하는 것이기도 하지만, 일반
적으로는 고성능의 ‘중재자’ 형식의 역할을 한다(BDG 형식의 원래 목적은 BAM과 VCF의 사
용을 대체하는 것이었지만 기존 방식 사용자들의 완강한 저항으로 목표 달성이 험난할 것으로
보인다). 세계 유전체학 보건연대Global Alliance for Genomics and Health에서도 프로토콜 버퍼를 사용한
자체 스키마들을 개발해왔다(https://goo.gl/1NfS7q). 이것이 다음 풍자 그림과 같은 스키마
경쟁의 확산으로 변하지 않기를 바란다. 그렇기는 해도 에이브로는 현재의 사용자 정의 ASCII
보다 성능과 데이터 모델링 면에서 이점이 많다. 이 장의 나머지에서는 BDG 스키마 일부를
사용하여 몇몇 일반적인 유전체학 작업을 수행할 것이다.
(출처: http://xkcd.com/927/)
7	 옮긴이_ 유전자를 판독할 때 전체 유전자를 한 번에 죽 읽어내지 못하므로, 여러 조각을 내서 읽은 후 이를 병합하여 판독하는 방식을 사
용한다. 이때 조각의 판독된 정보를 흔히 리드(read)라 한다.
8	 옮긴이_ 염색체 지도에서 특정 유전자의 위치를 말한다.
표준이 급증하는 원리
(대표적인 예: A/C 충전기, 문자 인코딩, 모바일 메신저 등)
상황:
총 14개의 표준이
서로 경쟁한다.
상황:
총 15개의 표준이
서로 경쟁한다.
14개? 말도 안 돼!
모든 용도에 적합한
하나의 범용 표준을
만들어야겠어.
좋아!
잠시 후:
31111장 파이스파크와 썬더로 신경 영상 데이터 분석하기
“우리는 뇌가 차가운 오트밀과 농도가 같다는 사실에는 관심이 없다.”
-앨런 튜링
영상 장비와 자동화 분야의 발전으로 뇌 기능과 관련된 데이터가 넘쳐나게 되었다. 과거의 실
험은 몇 개의 전극으로부터 시계열Time Series 데이터를 만들거나 뇌 단면의 정지 영상 몇 장을 얻
는 데 그쳤지만, 오늘날의 기술은 유기체가 활발히 활동하는 동안 넓은 영역의 수많은 신경 세
포Neuron에서 뇌 활동을 샘플링할 수 있다. 실제로, 브레인 이니셔티브BRAIN Initiative1
는 예를 들어
장기간에 걸쳐 쥐의 뇌에서 모든 신경 세포의 전기적 활동을 동시에 기록하는 일과 같은 매우
높은 수준의 기술 개발을 목표로 하고 있다. 측정 기술의 혁신도 분명히 필요하겠지만, 엄청난
양의 데이터가 새로 생성되어 생물학 분야에 완전히 새로운 패러다임이 열릴 것이다.
이번 장에서는 파이썬으로 스파크를 구동하는 파이스파크PySpark
API(https://goo.gl/JXhKDg)
를 소개한다. 더불어 일반적인 대량의 시계열 데이터, 특히 신경 영상Neuroimaging 데이터를 처리
하기 위해서 파이스파크 위에서 개발된 썬더Thunder 프로젝트(http://thunder-project.org/)도
소개할 것이다. 파이스파크는 시각화를 위한 맷플롯립Matplotlib이나 ‘실행 가능한 문서’를 만들기
위한 아이파이썬 노트북IPython Notebook (주피터Jupyter 프로젝트)까지 포함한 파이데이터PyData 생태
계와 잘 통합되어 있기 때문에 탐색적 빅데이터 분석에 특히 잘 맞는 도구다.
1	 옮긴이_ 버락 오바마 미국 대통령은 2013년 4월 ‘브레인 이니셔티브’를 발표하였다. 이 프로젝트의 목표는 인간 두뇌 활동의 모든 경로
와 지도를 완성하여 뇌 속 신경 세포가 어떻게 상호작용하는지를 규명하는 것이다. https://www.braininitiative.nih.gov/
파이스파크와 썬더로
신경 영상 데이터 분석하기
CHAPTER 11
유리 레이저슨
312 9가지 사례로 익히는 고급 스파크 분석 (2판)
이번 장에서는 제브라피쉬Zebrafish2
의 뇌 구조 일부를 이해하는 작업에 이들 도구를 사용할 것이
다. 썬더를 사용해서 시간의 흐름에 따른 제브라피쉬의 활동 패턴을 파악하기 위해 뇌의 서로
다른 영역(신경 세포의 그룹)을 군집화할 것이다. 썬더는 파이스파크 RDD API로 빌드되어
있어서 이번 장에서는 RDD API를 사용한다.
11.1 파이스파크 소개
파이썬은 고수준 문법과 광범위한 라이브러리 패키지 덕분에 다양한 도구 중에서도 수많은 데
이터 과학자가 선호하는 도구다(http://bit.ly/186ShId). 스파크 생태계는 데이터 분석 환경에
서 파이썬의 중요성을 인식해왔으며, 파이썬과 JVM을 통합해보려는 과거의 시도가 큰 성과를
거두지 못했음에도 불구하고 스파크용 파이썬 API에 투자하고 있다.
3
전문가용 계산과 데이터 과학을 위한 파이썬
파이썬은 전문가용 계산과 데이터 과학에서 널리 사용되는 도구다. 예전에는 매트랩MATLAB,
R, 매스매티카Mathematica를 사용했을 애플리케이션에서 지금은 파이썬을 사용하고 있다. 그
이유는 다음과 같다.
●	‌‌파이썬은 사용하고 배우기 쉬운 고급 언어다.
●	‌‌수치 계산부터 웹 스크랩 유틸리티와 시각화 도구에 이르기까지 폭넓은 라이브러리가 있다.
●	‌‌C/C++ 코드와 쉽게 결합할 수 있어, BLAS/LAPACK/ATLAS를 포함한 고성능 라이브러리
를 활용하기에도 좋다.3
기억해두면 좋을 라이브러리를 몇 개 소개하자면 다음과 같다.
2	 옮긴이_ 성체의 크기가 3~4cm 정도인 열대 민물고기로 인간의 유전자 구성과 상당 부분 비슷하여 다양한 질병 연구에 활용되고 있다.
3	 옮긴이_ BLAS(Basic Linear Algebra Subprograms)는 벡터 곱, 행렬 곱과 같은 저수준 행렬과 벡터의 수치 연산을 위한 포트란 라
이브러리이며, LAPACK(Linear Algebra PACKage)은 이 책의 앞에서 등장한 특잇값 분해(SVD)와 같은 고수준 연산을 지원하는 포
트란 라이브러리다. ATLAS(Automatically Tuned Linear Algebra Software)는 BLAS와 LAPACK의 일부를 포트란 77과 C 언
어용으로 이식한 라이브러리다.
31311장 파이스파크와 썬더로 신경 영상 데이터 분석하기
numpy/scipy/matplotlib
고속 배열 연산, 전문가용 함수, 매트랩에서 아이디어를 가져온 플로팅 라이브러리를 포
함한 일반적인 매트랩의 기능을 재현한다.
pandas
R의 data.frame과 비슷한 기능을 제공한다. 보통은 성능도 더 뛰어나다.
scikit-learn/statsmodels
분류, 회귀, 군집화, 행렬 분해와 같은 머신러닝과 통계 모델을 고품질로 구현하여 제공한
다.
nltk
자연어 처리에 널리 사용되는 라이브러리다.
awesome-python 깃허브 저장소(https://github.com/vinta/awesome-python)에서 다른
많은 라이브러리의 목록을 찾을 수 있다.
스파크처럼 파이스파크를 시작해보자.
export PYSPARK_DRIVER_PYTHON=ipython # 파이스파크는 IPython 셸을 사용할 수 있다.
export PYSPARK_PYTHON=path/to/desired/python # 작업자 노드를 위한 설정이다.
pyspark --master ... --num-executors ... ➊
➊ pyspark도 spark-shell과 spark-submit에서와 같이 동일한 스파크 인수를 받는다.
spark-submit을 사용하면 우리 스크립트 중 확장자가 .py인 파일을 찾아 서브밋Submit해줄 것
이다. 작업자 노드와 드라이버(예, IPython)에서 사용할 파이썬 버전을 명시할 수 있으며 버
전이 일치해야 한다. 파이썬 셸을 시작하면 클러스터와 상호작용하는 (sc로 선언된) 파이썬
SparkContext 객체를 생성한다. SparkContext를 사용할 수 있게 되면 파이스파크 API는 스
파크 API와 매우 유사하게 동작한다. 예를 들어 다음은 CSV 데이터를 읽어 들이는 모습이다.
raw_data = sc.textFile('path/to/csv/data') # RDD[string]
# 필터링하고, 쉼표를 기준으로 나누고, 실수(float)를 파싱하여 RDD[list[float]]를 얻는다.
data = (raw_data
314 9가지 사례로 익히는 고급 스파크 분석 (2판)
.filter(lambda x: x.startswith(#))
.map(lambda x: map(float, x.split(','))))
data.take(5)
스칼라 RDD API를 사용할 때와 비슷하게 텍스트 파일을 읽어 #으로 시작하는 줄을 제거한
후, CSV 데이터를 float 값 목록으로 파싱한다. 인수로 전달된 (예를 들어 filter나 map에 전
달된) 파이썬 함수들은 매우 유연하다. 파이썬 객체를 인수로 받아 파이썬 객체를 반환해야 한
다(filter의 반환값은 불리언으로 해석된다). 제약이 없는 것은 아니다. 먼저, 파이썬 함수 객
체는 클라우드피클Cloudpickle로 직렬화할 수 있어야 한다. 익명(람다) 함수도 마찬가지다. 그리고
클로저에서 참조하는 모든 모듈은 실행자 파이썬 프로세스가 실행되는 환경의 PYTHONPATH
환경변수에서 지정한 위치에 설치되어 있어야 한다. 참조 모듈을 사용하려면 그 모듈을 클러스
터 전체에 설치하고 모듈의 위치를 실행자 프로세스 구동 환경의 PYTHONPATH에 명시한다.
혹은 해당 모듈의 ZIP/EGG 파일을 스파크로 명시적으로 배포하면 PYTHONPATH에 추가
된다. 후자의 방식은 sc.addPyFile( )을 호출하여 수행할 수 있다.
파이스파크 RDD는 단지 파이썬 객체들의 RDD일 뿐이다. 파이썬 리스트처럼 이 RDD에는
혼합된 자료형의 객체도 저장할 수 있다(모든 객체가 PyObject의 인스턴스인 덕분이다).
11.1.1 파이스파크 내부 구조
디버깅을 간소화하고 잠재적인 성능 저하의 원인을 알고 대처하려면 파이스파크의 구현 원리
를 어느 정도 이해해두는 것이 좋다. [그림 11-1]을 보자.
그림 11-1 파이스파크 내부 구조
31511장 파이스파크와 썬더로 신경 영상 데이터 분석하기
파이스파크의 파이썬 인터프리터가 시작될 때 JVM도 함께 실행되며, 둘은 소켓을 통해 통신하
게 된다. 이 통신에는 Py4J 프로젝트가 사용된다. JVM은 실제 스파크 구동자로서의 역할을 하
며, 클러스터 노드의 스파크 실행자들과 통신하는 JavaSparkContext를 로드한다. 그 후에는
SparkContext 객체가 호출한 파이썬 API는 JavaSparkContext에서 호출하는 자바 API로
변환된다. 예를 들어 파이스파크의 sc.textFile( )은 JavaSparkContext의 .textFile 메서드
를 호출하며, 마지막에는 HDFS에서 데이터를 읽어 들이기 위해서 스파크 실행자의 JVM들과
통신한다.4
클러스터의 스파크 실행자들은 파이썬 인터프리터를 코어마다 실행하는데, 사용자 코드를 실
행해야 할 때는 데이터 통신에 유닉스 파이프Unix Pipe (stdin, stdout)를 이용한다. 로컬 파이스
파크 클라이언트의 파이썬 RDD는 로컬 JVM의 PythonRDD 객체에 대응한다. RDD와 관
련한 데이터는 실제로는 스파크를 구동하는 JVM의 자바 객체로 되어 있다. 예를 들어 파이
썬 인터프리터에서 sc.textFile( )을 실행하면 JavaSparkContext의 textFile 메서드를 호출
하고 이 메서드가 데이터를 클러스터상의 자바 String 객체로 읽어 들인다. 비슷한 방식으로
newAPIHadoopFile을 사용하여 파케이/에이브로 파일을 읽으면 자바 에이브로 객체로 읽
어 들인다.
파이썬 RDD에서 API가 호출되면 파이썬 람다 함수 같은 모든 연관 코드는 클라우드피클 모
듈을 통해서 직렬화되어 실행자들에 배포된다. 그런 다음, 데이터는 자바 객체에서 파이썬에서
사용할 수 있는 형태(예를 들어 피클Pickle 객체)로 변환되고 파이프를 통해 실행자와 관련된 파
이썬 인터프리터로 흘러 들어간다. 필요한 모든 파이썬 처리는 인터프리터에서 실행되며, 결과
(기본 설정으로는 피클 객체)는 다시 JVM에 있는 RDD로 저장된다.
파이썬의 실행 코드 직렬화 기능은 스칼라의 직렬화만큼 강력하지는 않다. 파이스파크 개발자
들이 지금은 없어진 파이클라우드PiCloud에서 만든 클라우드피클이라는 별도 모듈을 사용해야
했던 이유다.
4	 옮긴이_ Py4J는 파이썬 인터프리터에서 파이썬 프로그램이 JVM의 자바 객체에 동적으로 접근할 수 있도록 처리해준다.
316 9가지 사례로 익히는 고급 스파크 분석 (2판)
11.2 썬더 라이브러리 개요와 설치
썬더 라이브러리의 예제와 문서
썬더 패키지는 훌륭한 문서와 튜토리얼을 제공한다. 이어지는 예제는 썬더 문서의 데이터셋
과 튜토리얼을 참조했다.
썬더는 스파크에서 대용량의 공간과 시계열 데이터셋(즉, 커다란 다차원 행렬)을 처리하기 위
한 파이썬 도구 모음이다. 행렬 계산에는 넘파이NumPy 모듈을, 몇몇 통계 기법을 분산 처리하는
데에는 MLlib 라이브러리를 적극적으로 사용한다. 파이썬으로 만들어져서 매우 유연하고, 또
수많은 개발자가 이용할 수 있다. 다음 절에서는 썬더 API를 소개하고 썬더와 파이스파크로 감
싸진 MLlib의 K-평균 군집화 구현을 사용하여 몇몇 신경 활동을 추적해 패턴을 분류해볼 것
이다. 썬더를 설치하려면 pip install thunder-python을 호출하기만 하면 되지만, 모든 작
업자 노드에 설치해야 한다.
설치를 끝내고 SPARK_HOME 환경변수를 설정하면 다음과 같이 파이스파크 셸을 실행할 수
있다.
$ export PYSPARK_DRIVER_PYTHON=ipython # 일반적으로 추천하는 설정이다.
$ pyspark --master ... --num-executors ...
[...some logging output...]
Welcome to
____ __
/ __/__ ___ _____/ /__
_ / _ / _ `/ __/ '_/
/__ / .__/_,_/_/ /_/_ version 2.0.2
/_/
Using Python version 2.7.6 (default, Apr 9 2014 11:54:50)
SparkContext available as sc.
Running thunder version 0.5.0_dev
A thunder context is available as tsc
In [1]:
31711장 파이스파크와 썬더로 신경 영상 데이터 분석하기
11.3 썬더로 데이터 읽어 들이기
썬더는 특별히 신경 영상 데이터셋을 염두에 두고 설계되었다. 그래서 시간별로 여러 번 촬영
한 대량의 영상 데이터를 분석하는 데 특화되었다.
먼저, S35
안의 썬더 저장소(s3://thunder-sample-data/images/fish/)에서 제공하는 예
제 데이터셋 중 제브라피쉬 뇌 영상 몇 장을 읽어보자. 동작 방식을 설명하는 것이 목적이므로
이 예제는 엄청나게 다운샘플링된 데이터로 수행한다. 데이터를 추가하거나 더 큰 데이터셋을
사용하고자 한다면 썬더 문서를 참조하자. 제브라피쉬는 생물학 연구에서 널리 사용하는 모델
생물Model Organism이다. 크기가 작고 짧은 주기로 번식하여 척추동물 발생의 모델로 사용한다. 또
한, 재생이 특출나게 빠르다는 점도 흥미롭다. 제브라피쉬가 신경과학 연구에 훌륭한 모델인
이유는 몸이 투명하고 뇌가 작아서 개별 신경을 구분할 수 있고, 그 전체를 고해상도 영상으로
녹화할 수 있기 때문이다. 다음은 데이터를 읽어 들이는 코드다.
import thunder as td
data = td.images.fromtif('/user/ds/neuro/fish', engine=sc) ➊
print data
print type(data.values)
print data.values._rdd
...
Images
mode: spark ➋
dtype: uint8
shape: (20, 2, 76, 87)
class 'bolt.spark.array.BoltArraySpark' ➌
PythonRDD[2] at RDD at PythonRDD.scala:48 ➍
➊ ‌SparkContext 객체를 전달하는 방법에 주목하자. 썬더는 동일한 API를 사용하여 로컬 모드 동작을 지원
한다.
➋ ‌스파크에서 지원하는 Images 객체를 볼 수 있다.
➌ ‌BoltArray는 기저의 데이터 컨테이너를 추상화한 것으로, 이 프로젝트에서는 로컬 데이터 표현과 스파크
RDD 표현을 추상화한다.
➍ ‌PythonRDD가 기저의 RDD 객체다.
5	 옮긴이_ S3는 아마존의 클라우드 저장소 서비스다.
330 찾아보기
INDEX
숫 자
3D화소 319
1000 지놈 프로젝트 282
ㄱ
가우시안 혼합 모델 160
거짓 양성 67
거짓 음성 67
경로 206
고계함수 43
고윳값 분해 269
곡선 아래 면적 90
과거 기반 시뮬레이션 256
과적합 93, 108, 126
교차 검증 데이터셋 90
교차 최소 제곱 73, 76
구동자 82
군집계수 192
군집 중심 137
군집화 72, 137
그래프엑스 190
그래프 이론 189
그래프프레임 190
꼭짓점 189
꼭짓점 속성 203
ㄴ
낮은 계수 근사 162
네트워크 평균 군집계수 220
ㄷ
다변량 정규분포 268
단어 빈도 163
단어빈도-역문서빈도 170
데이터 정제 29
데이터프레임 50, 51
동시발생 그래프 202
동시발생 네트워크 201
ㄹ
람다 93
랜덤 포레스트 104, 129
레코드 링크 33
ㅁ
마할라노비스 거리 160
메르센 트위스터 272
몬테카를로 시뮬레이션 253
문서-단어 행렬 162, 163
밀도 기반 공간 군집화 160
ㅂ
범주형 변수 154
범주형 특징 103
변 189
변 속성 203
복원추출 275
부분 적용 함수 93
부트스트래핑 275
분류 72, 102
분산-공분산 255
불용어 168
브레인 이니셔티브 311
브로드캐스트 변수 83
브로드캐스트 해시 조인 83
비지도 학습 136
비편향 추정 123
빅데이터 유전체학 프로젝트 285
ㅅ
세션화 248
수신자 조작 특성 90
수치형 특징 103
숨은 의미 분석 161
스크로블링 72
스파크R 146
스파크 셸 34
스파크 스트리밍 25, 159
실루엣 계수 160
썬더 316
ㅇ
암묵적 자료형 60
액션 42
어간 추출 168
엔트로피 120
역문서 빈도 163
연결 성분 192, 206
연구를 위한 분석 22
예측 함수 91
온전성 검사 153
완전 그래프 218
운영을 위한 분석 23
원-핫 인코딩 110
유클리드 거리 137, 143
의사 결정 나무 104
이상 탐지 136
ㅈ
자연어 처리 161
작은 세상 네트워크 217
잠재특징 75
정규직교 기저 172
지니 불순도 120
지도 학습 102
집계 함수 55
331찾아보기
INDEX
ㅊ
차수 210
차수 분포 192
차원 감소 150
최대 깊이 119
축 회전 59
ㅋ
카이제곱 검정 212
카이제곱 분포 213
카이제곱 통계량 213
캐시 52
커널 밀도 추정 265
케이스 클래스 65
코사인 유사도 179
콘틱 292
콜모고로프-스미르노프 검정 278
클로저 83
클릭 218
ㅌ
탄력적 분산 데이터셋 26, 37
테스트 데이터셋 90
통 119
특잇값 분해 172
특징 64, 103
특징 벡터 85, 103
특징 선택 63
특징 정규화 152
ㅍ
파이스파크 312
파이프라인 API 113
파케이 형식 294
파티션 37
평균 경로 길이 192
표제어 추출 164, 168
표준점수 152
품질 평가 89
프레겔 190, 220
ㅎ
하이브 56
하이퍼파라미터 86, 94
학습 데이터셋 90, 104
함수형 프로그래밍 43
행렬 분해 74
행렬 채우기 75
협업 필터링 73
형태변환 59
혼합 정규분포 278
화소 319
확률 밀도 함수 256
회귀 102
A ~    C
Action 42
ADAM CLI 287
ADAM 프로젝트 287
ALS 76
Anomaly Detection 136
AUC 90
AUC 계산 91
Average Path Length 192
BDG Project 285
Bin 119
Bootstrapping 275
BRAIN Initiative 311
Broadcast Hash Join 83
Case Class 65
Categorical Feature 103
Centroid 137
ChIP-seq 296
Chi-squared Distribution 213
Chi-squared Statistic 213
Chi-squared Test 212
Classification 72
Clique 218
Closure 83
Clustering 72
Clustering Coefficient 192
Collaborative Filtering 73
Complete Graph 218
Connected Component 192
Contig 292
Co-occurrence Graph 202
Co-occurrence Network 201
Cosine Similarity 179
Covtype 데이터셋 108
D ~    F
DataFrame 27
Dataset 27
DBSCAN 160
Decision Tree 104
Degree 210
Degree Distribution 192
Dimension Reduction 150
Document-term Matrix 162
Driver 82
Edge Attribute 203
EdgeRDD 203
Eigendecomposition 269
Entropy 120
Esri Geometry API 231
Euclidean Distance 137
False-negative 67
332 찾아보기
INDEX
False-positive 67
Feature 103
Feature Vector 85, 103
G ~    K
Gaussian Mixture Model 160
GeoJSON 233
Gini Impurity 120
GraphX 190
Higher-order Function 43
Historical Simulation 256
Hyperparameter 86
IDF 163
Implicit Type 60
Kernel Density Estimation 265
k-fold Cross-validation 92
K-means Clustering 137
Kolmogorov-Smirnoff Test 278
k-겹 교차 검증 92
K-평균++ 145
K-평균‖ 145
K-평균 군집화 137
L ~    N
Lambda 93
Latent Feature 75
Lemmatization 168
Low-rank Approximation 162
LSA 161
Mahalanobis Distance 160
Matrix Completion 75
Matrix Factorization 74
Mersenne Twister 272
Monte Carlo Simulation 253
Multivariate Normal Distribution
268
Network Average Clustering
Coefficient 220
NLP 161
Numeric Feature 103
O ~    Q
One-hot Encoding 110
Orthonormal Basis 172
Overfitting 93
Partition 37
Path 206
PDF 256
Pixel 319
QR Decomposition 76
QR 분해 76
R ~    S
R 146
Random Decision Forest 104
RDD 26, 37
Record Linkage 33
REPL 40
ROC 90
Sampling with Replacement
275
Sanity Check 153
Sessionization 248
Silhouette Coefficient 160
SparkContext 34
SparkR 146
Spark SQL 56
spray-json 234
Standard Score 152
Stemming 168
Stop Word 168
Supervised Learning 102
T ~    Z
TF 163
TF-IDF 170
Training Set 104
Unbiased Estimate 123
Unsupervised Learning 136
Variance-Covariance 255
Vertex Attribute 203
VertexRDD 203
Voxel 319
z-스택 319
​『9가지 사례로 익히는 고급 스파크 분석(2판) 』 맛보기

​『9가지 사례로 익히는 고급 스파크 분석(2판) 』 맛보기

  • 2.
    표지 동물은 송골매다.이 매는 세상에서 가장 흔한 맹금류 중 하나로 남극을 제외한 모든 대륙에 서식한다. 또한, 도시, 열대 지역, 사막, 툰드라 등 다양한 환경에서 생존할 수 있다. 일부는 겨울과 여름 서식지 간 의 머나먼 여행을 한다. 송골매는 세상에서 가장 빨리 나는 새로, 시속 약 320km로 급강하할 수 있다. 참새나 오리와 같은 다른 새와 박쥐를 먹이로 하는데, 공중에서도 먹이를 낚아챌 수 있다. 다 자란 송골매의 날개는 푸른 잿빛을, 등은 어두운 갈색을 띠며, 담황색 배에는 갈색 점이, 하얀 얼굴에는 검은색 눈물점이 있다. 그리고 갈고리 모양의 부리와 강 한 발톱도 있다. 송골매의 영어 이름인 peregrine falcon은 라틴어의 peregrinus에서 온 말인데, 그 뜻은 방랑자다. 송골매는 매조련사들 의 사랑을 받아왔으며, 여러 세기에 걸쳐 사냥에 동원되었다. 오라일리 책의 표지에 등장하는 동물 중 상당수는 멸종 위기에 처해 있다. 이들 모두가 우리 세상에 소중한 존재다. 이 동 물들을 돕고 싶다면 animals.oreilly.com으로 가보자. 표지 그림은 라이데커의 『Royal Natural History』에서 가져왔다. 9가지 사례로 익히는 고급 스파크 분석(2판) 현실 세계 빅데이터로 배우는 데이터 과학과 머신러닝 초판 1쇄 발행 2016년 7월 1일 2판   1쇄 발행 2018년 3월 5일 지은이 샌디 라이자, 유리 레이저슨, 션 오언, 조시 윌스 / 옮긴이 박상은, 권한철, 서양주 / 펴낸이 김태헌 펴낸곳 한빛미디어 (주) / 주소 서울시 서대문구 연희로2길 62 한빛미디어(주) IT출판부 전화 02 – 325 – 5544 / 팩스 02 – 336 – 7124 등록 1999년 6월 24일 제10 – 1779호 / ISBN 979 – 11 – 6224 – 052 – 6 93000 총괄 전태호 / 책임편집 김창수 / 기획·편집 이복연 디자인 표지 박정화, 내지 김연정, 조판 백지선 영업 김형진, 김진불, 조유미 / 마케팅 박상용, 송경석, 변지영 / 제작 박성우, 김정우 이 책에 대한 의견이나 오탈자 및 잘못된 내용에 대한 수정 정보는 한빛미디어(주)의 홈페이지나 아래 이메일로 알려주십시오. 잘못된 책은 구입하신 서점에서 교환해 드립니다. 책값은 뒤표지에 표시되어 있습니다. 한빛미디어 홈페이지 www.hanbit.co.kr / 이메일 ask@hanbit.co.kr © 2018 Hanbit Media Inc. Authorized Korean translation of the English edition of Advanced Analytics with Spark 2E ISBN 9781491972953 © 2017 Sanford Ryza, Uri Laserson, Sean Owen, and Joshua Wills 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 ) 로 보내주세요. 한빛미디어(주)는 여러분의 소중한 경험과 지식을 기다리고 있습니다. | 표지 설명 |
  • 3.
    9가지 사례로 익히는고급 스파크 분석 2판
  • 4.
    4 샌디 라이자 SandyRyza 리믹스에서 대중교통에 적용할 수 있는 알고리즘을 개발하고 있다. 이전에는 클라우데라와 클로버 헬스에서 선임 데이터 과학자로 근무했다. 아파치 스파크 커미터이자 아파치 하둡의 PMC 멤버이 며 스파크 시계열 데이터 처리 프로젝트의 창설자이다. 2012년 브라운 대학교 전산학과의 트와이 닝 어워즈에서 ‘Most Chill’ 부문을 수상했다. 유리 레이저슨 Uri Laserson 마운트 시나이 의과대학교 아이칸 스쿨의 유전학 조교수다. 하둡 생태계를 활용해 유전체학과 면역 학에 적용할 수 있는 확장 가능한 기술을 개발하고 있다. 션 오언 Sean Owen 클라우데라 데이터 과학팀의 디렉터다. 아파치 스파크 커미터와 PMC 멤버이며, 아파치 머하웃 Apache Mahout의 커미터였다. 조시 윌스 Josh Wills 슬랙Slack 데이터 엔지니어링팀의 리더이며 아파치 크런치Apache Crunch 프로젝트의 창설자이다. 데이 터 과학자들에 관한 트윗을 한 번 남긴 적이 있다. 지은이 소개
  • 5.
    5 박상은 edberg.s@gmail.com 컴퓨터에 붙은그림을 보고 애플이라는 단어의 뜻을 알게 된 이 땅의 흔한 개발자 중 한 사람이다. 포항공과대학교에서 전산학을, 한국과학기술원에서 인공지능을 공부했으며, 그 덕분에 알파고와 스카이넷을 구분할 줄 아는 지혜를 갖추게 되었다. 메일, 브라우저, CMS, 도서 관리 시스템 등 일 관성을 찾기 어려운 다양한 프로젝트에 참여했다. 이렇게 하여 물에 물 탄듯한 경력이 완성되는 듯 했으나, 최근 몇 년은 빅데이터 처리와 관련한 연구개발에 집중했다. 현재 에스코어에서 Elastic 스 택을 활용한 빅데이터 저장/검색 서비스 제공과 머신러닝 및 딥러닝 관련 업무를 수행하고 있다. 대 량의 데이터를 실시간으로 수집, 처리, 분석하여, 실시간으로 생산되는 데이터의 수집과 시각화 사 이의 시간 간격을 줄이는 데 각별한 관심이 있다. 권한철 ultradioc@gmail.com 에스코어의 데이터 분석가 및 플랫폼 개발자다. 보안 관제용 실시간 CEP 엔진 개발을 비롯해서 스 파크를 활용한 다수의 프로젝트에 참여했으며, 현재는 파이썬 라이브러리를 활용하여 콜센터 데이 터 분석 업무를 수행하고 있다. 특히 실시간 데이터 분석과 통계 및 머신러닝 알고리즘을 활용한 데 이터 분석에 관심이 많다. 서양주 yangsuh84@gmail.com 한국과학기술원 학부에서 수학을, 서울대학교에서 석사과정으로 통계학을 전공하였으며, 티맥스소 프트를 시작으로 개발자로서 일하게 되었다. 그 후 에스코어에서 2013년 하둡과 스파크를 접한 이 후로 빅데이터 분석을 주 업무로 수행하게 되었다. 현재는 카카오 추천팀에서 실시간 콘텐츠 추천 업무를 하고 있다. 옮긴이 소개
  • 6.
    6 버클리에서 스파크 프로젝트를시작한 이래로, 나는 단순히 빠른 병렬 시스템을 구축한다는 사 실보다는 점점 더 많은 사람이 대규모 컴퓨팅을 사용할 수 있게 돕는다는 점에 흥분해왔다. 데 이터 과학 전문가 네 명이 스파크 기반의 고급 분석에 대해서 쓴 이 책을 읽는 것이 즐거운 이 유가 바로 여기에 있다. 샌디, 유리, 션 그리고 조시는 오랫동안 스파크로 작업해왔으며, 그만 큼 충실한 설명과 예제를 이 책에 담아냈다. 이 책에서 가장 마음에 드는 부분은 실제 응용 사례와 현실 세계의 데이터셋을 가져와 예제 중 심으로 설명하는 점이다. 독자의 PC에서 직접 실행해볼 수 있는 아홉 개의 개별 빅데이터 예제 를 제공한 책은 흔치 않은데, 저자들은 이런 예제들을 모아서 스파크로 실습할 수 있도록 모든 것을 세팅해두었다. 게다가, 핵심 알고리즘만 다룬 것이 아니라, 정말로 좋은 결과를 얻는 데 필요한 데이터 준비와 모듈 튜닝의 복잡한 사항까지 다루고 있다. 독자는 이들 예제에서 터득 한 개념을 자신의 문제를 푸는 데 곧바로 적용할 수 있을 것이다. 오늘날 빅데이터 처리는 의심할 여지 없이 컴퓨터로 할 수 있는 가장 흥미로운 분야이며, 빠르 게 진화하고 새로운 아이디어들이 도입되는 분야이기도 하다. 나는 독자들이 이 흥미로운 새로 운 분야로 들어서는 데 이 책이 도움이 될 거라 기대한다. 마테이 자하리아 스파크 창시자, 『러닝 스파크』 저자 아파치 스파크는 빅데이터 영역에서 가장 핫한 기술로, 범용적이면서 빠른 대용량 분산 처리를 지원한다. 또한 기초 데이터 분석부터 머신러닝 등의 기능까지 지원하게 되면서 개발자만의 오 픈 소스에서 분석가를 위한 오픈 소스로 주목받고 있다. 이 책은 스파크로 빅데이터를 분석하 기 위한 가장 실용적인 데이터와 분석 방법을 설명하고 있다. 빅데이터에 관심 있거나 종사하 는 개발자와 분석가 모두에게 추천한다. 이상훈 한국 스파크 사용자 모임 운영자, 『실시간 분석의 모든 것』 역자 추천의 글
  • 7.
    7 교통, 금융 분야등의 실제 데이터로 데이터 획득, 전처리, 가중치 결정, 실행, 평가 그리고 시 각화까지 해볼 수 있는 스파크 활용서다. 스파크 입문을 넘어 실무에 적용하려 할 때 좋은 참고 서다. 자신의 관심 도메인에 맞는 부분만 찾아서 읽어도 좋을 것 같다. 최홍용 현대오토에버
  • 8.
    8 학교를 졸업하고 몇군데의 회사를 거쳐 2008년에 지금의 회사에 입사했다. 처음에는 콘텐츠 관리 시스템 개발로 시작했지만, 몇 번의 굴곡을 거쳐 회사는 이름이 바뀌었고 내가 하는 개발 업무도 바뀌게 되었다. 2011년, 데이터를 집계, 분석하여 실시간으로 시각화하는 과제를 수행 하게 되었다. 지금은 다른 회사에서 잘나가고 계신 배병우 씨와 함께 이를 위한 시스템을 설계 하면서 아파치 스톰Apache Storm을 알게 되었다. 그 후 몇 년간, 우리 회사의 개발팀은 스톰의 끝 을 보고 왔다. 그리고 스톰의 몇 가지 한계를 실감하게 되었다. 스톰은 스트림을 처리하는 훌륭 한 도구지만, 딱 거기까지였다(물론 이번에 릴리스된 스톰 1.0에서는 많은 부분이 개선되긴 했 다). 상태를 저장할 방법이 없는 탓에 완전한 분산 컴퓨팅 환경이라 말할 수 없다든지, 오류가 났을 시에 원래 상태를 복원할 수 없는 등 스톰이 할 수 없는 일이 꽤 있었다. 그러던 어느 날, 공역자인 권한철 씨와 서양주 씨가 아파치 스파크를 만났다. 당시 약간 모자라 보이던 스파크는, 맵리듀스MapReduce 로직을 인메모리로 처리하여 성능을 확장할 수 있다는 점 외에도, 일반적인 프로그래밍 환경에 데이터 분산 처리의 거의 모든 것을 가져올 수 있다는 특 징을 가지고 있었다. 여기에 분산 환경마저도 추상화하여 설치 이외에는 별다른 고민 없이 분 산 데이터 처리가 가능하다는 매력도 지녔다. 그리고 스톰의 강점인 스트림 처리마저도 스파크 스트리밍Spark Streaming이 마이크로 배치 형태로 처리할 수 있었다. 데이터 처리의 팔방미인이라 고 해도 과언이 아니었고, 우리는 그때부터 스파크에 집중하게 되었다. 그리고 약 2년이 흘렀 다. 스파크를 활용한 몇 개의 과제를 성공적으로 수행했으며, 새로운 도구를 받아들이는데 다 소 보수적인 분야의 현장에서도 스파크를 활용하여 얻을 수 있는 이점을 받아들이고 있다. 우 리는 스파크의 시대가 열리는 것을 목격한 운 좋은 증인이 되었고, 이 책을 읽을 독자분들도 아 직 늦지 않았다는 이야기를 해주고 싶다. 이 책은 단순한 스파크 참고서가 아니다. 스파크 참고서로는 더 좋은 책들이 여럿 있다. 부끄럽 지만 우리는 이 책도 그러한 참고서 중 하나인 줄 알고 번역을 시작했고, 그 착각 탓에 더 어려 운 길을 가야 했지만, 동시에 더 재미있는 길을 가볼 수 있었다. 이 책의 매력은 다양한 현장의 분석을 책에 담아낸 점에 있다. 스파크로 무엇을 해야 할지가 막막하다면 이 책을 펴면 도움이 옮긴이의 말
  • 9.
    9 될 것이다. 굳이스파크가 아닌 다른 도구를 사용하더라도 유용한 정보도 들어 있다. 이 책이 역자들에게 도움이 된 것처럼 독자들께도 도움이 될 것으로 생각한다. 이 책을 번역하느라 업무 부담을 조금씩 나눠주신 에스코어 엔터프라이즈 공통 플랫폼 그룹 김 세준 그룹장 이하 동료들에게 감사를 전한다. 동시에 몇 달 동안 아빠를 번역에 빼앗긴 건우에 게도 미안함을 전한다. 다른 역자들도 마찬가지의 미안함과 고마움을 가지고 있으리라 생각한 다. 번역이라는 것이 이렇게 어려운 작업인 줄은 상상도 못 했다. 책을 읽다가 책의 문장이 발 바닥에 꽂힌 가시 같다는 기분이 들면, 그 책임이 역자들에게도 있을 수 있음을 이해해주시기 바란다. 박상은
  • 10.
    10 과거를 후회하는 걸좋아하진 않지만, 잠시 태만했던 2011년 시절 믿기 어려운 일이 벌어졌다. 당시 나는 어려운 이산 최적화 문제를 클러스터에 효율적으로 분배하는 방법을 고민하고 있었 다. 내 지도교수는 스파크라는 것이 최신 유행이라며 설명해주었지만, 그 개념은 실현되기엔 너무 이상적이라 실패할 것으로 판단하고 바로 학부 졸업논문을 맵리듀스로 작성하였다. 그 후 스파크와 나 모두 성장하였지만, 스파크는 도저히 무시할 수 없는 거물이 되었다. 대략 2년 후, 스파크에 주목해야 함이 명백해졌다. MPI부터 맵리듀스에 이르기까지, 스파크 이전의 프레임워크들은 분산 시스템의 어렵고 세세 한 핵심들을 추상화하여 대규모 자원을 활용한 프로그램을 작성할 수 있도록 해주었다. 이들 프레임워크는 늘어가는 데이터를 처리하기 위해 발전해온 만큼, 빅데이터가 진출할 수 있는 범 위는 이들 프레임워크의 능력 한계와 밀접하게 연관될 수밖에 없었다. 스파크는 분산 프로그램 도 일반 프로그램을 작성하듯 쉽게 짤 수 있게 하여 이 범위를 좀 더 넓혀주고 있다. 스파크를 사용하면 ETL 파이프라인의 성능이 엄청나게 향상될 것이며 매일 하둡의 신에게 절 망을 하소연하는 맵리듀스 프로그래머들의 고통을 덜어줄 것이다. 그러나 나에게 가장 흥미 로운 점은 항상 스파크가 개척해준 복잡한 분석 작업이었다. 스파크는 반복적 알고리즘 Iterative Algorithm과 대화형 탐색Interactive Exploration을 지원하는 패러다임을 갖춰, 마침내 데이터 과학자가 대 규모 데이터셋을 생산적으로 다룰 수 있는 오픈 소스 프레임워크가 되었다. 나는 데이터 과학을 가르치는 가장 좋은 방법은 예제를 활용한 것이라고 생각한다. 이를 위해 나와 동료 저자들은 책에 여러 가지 응용 예를 담았으며, 가장 일반적인 알고리즘들과 데이터 셋들, 그리고 대규모 분석에서의 디자인 패턴들 간의 상호작용을 다루려고 노력하였다. 이 책 은 독자가 처음부터 끝까지 정독하라는 의도로 쓰이지 않았다. 여러분이 성취해봤으면 하는 주 제나 흥미를 자아내는 장을 펼쳐보자. 샌디 라이자 지은이의 말
  • 11.
    11 이 책의 1장에서는데이터 과학과 빅데이터 분석이라는 넓은 맥락에서 스파크의 가치를 소개 한다. 그다음부터 각 장은 스파크를 사용한 독립적인 분석으로 구성된다. 2장은 데이터를 정제 하는 간단한 예로 스파크와 스칼라를 사용한 데이터 분석의 기초를 소개한다. 그리고 그다음 몇 장은 가장 일반적으로 사용되는 알고리즘 몇 개를 전형적인 분야에 적용하면서, 핵심적인 머신러닝 문제를 스파크를 활용하여 푸는 방법을 살펴볼 것이다. 나머지 장들은 좀 더 특수한 분야를 다룬다. 위키백과의 텍스트 안에 숨겨진 의미 관계를 알아보거나 유전체학 데이터도 분 석해볼 것이다. 2판에 대하여 1판이 출간된 이후 스파크의 메이저 버전이 올라가면서 완전히 새로운 핵심 API가 도입되고 MLlib이나 Spark SQL과 같은 하위 컴포넌트들도 크게 바뀌었다. 2판에서는 이에 따른 사용 예를 전달하기 위해서 스파크의 예제 코드를 대폭 수정했고 관련 설명도 지금 시점에 맞게 새 로 썼다. 예제 내려받기 코드 예제와 데이터셋은 다음 주소에서 내려받을 수 있다. https://github.com/sryza/aas 이 책의 구성
  • 12.
    12 아파치 스파크와 MLlib이없었다면 여러분이 이 책을 읽을 수 있었을 리 만무하다. 우리 모두 는 스파크와 MLlib을 개발하고 오픈 소스로 제공한 개발팀과 여기에 참여한 수백 명의 기여자 에게 감사를 전한다. 이 책을 검토하느라 시간을 내어준 모든 전문가에게도 감사를 전하고 싶다. 미카엘 베르니코, 아담 브레인델, 이안 부스, 파르비즈 데이힘, 제레미 프리먼, 크리스 프레글리, 드바시시 고시, 줄리엣 호글랜드, 조나단 키블러, 니샤 무크타버, 프랭크 나샤프트, 닉 펜트리스, 코스타스 사 켈리스, 톰 화이트, 마르셀로 반진, 그리고 줄리엣 호글랜드(한 번 더), 모두 고마워! 신세를 졌어. 덕분에 책의 구성과 품질 모두 크게 개선되었다. 또한, 나(샌디)는 어려운 주제의 배경 이론과 관련하여 조언해준 조단 핀쿠스와 리처드 왕에 게 감사를 표한다. 이 책이 출판되고 독자의 손에 들어가기까지 물심양면으로 지원해주고 이런 경험을 하게 해준 마리 보구로와 오라일리에도 감사를 표한다. 샌디 라이자 감사의 말
  • 13.
    13 CONTENTS 지은이 소개����������������������������������������������������������������������������������������������������������������������������� 4 옮긴이 소개 ����������������������������������������������������������������������������������������������������������������������������� 5 추천의 글 �������������������������������������������������������������������������������������������������������������������������������� 6 옮긴이의 말 ����������������������������������������������������������������������������������������������������������������������������� 8 지은이의 말 �������������������������������������������������������������������������������������������������������������������������� 10 이 책의 구성 ������������������������������������������������������������������������������������������������������������������������� 11 감사의 말 ����������������������������������������������������������������������������������������������������������������������������� 12 CHAPTER 1 빅데이터 분석하기 1.1 데이터 과학의 어려움...................................................................................................... 21 1.2 아파치 스파크란............................................................................................................. 23 1.3 이 책에 관하여............................................................................................................... 26 1.4 2판에 관하여.................................................................................................................. 26 CHAPTER 2 스칼라와 스파크를 활용한 데이터 분석 2.1 데이터 과학자를 위한 스칼라........................................................................................... 30 2.2 스파크 프로그래밍 모델.................................................................................................. 32 2.3 레코드 링크.................................................................................................................... 32 2.4 스파크 셸과 SparkContext 시작하기............................................................................... 34 2.5 클러스터에서 클라이언트로 데이터 가져오기.................................................................... 41 2.6 클라이언트에서 클러스터로 코드 보내기........................................................................... 46 2.7 RDD에서 Data Frame으로............................................................................................. 47 2.8 DataFrame API로 데이터 분석하기................................................................................. 51 2.9 데이터프레임에 대한 빠른 요약 통계................................................................................ 57 2.10 데이터프레임의 축 회전과 형태변환............................................................................... 59
  • 14.
    14 CONTENTS 2.11 데이터프레임을 결합하고특징 선택하기........................................................................ 63 2.12 실제 환경을 위한 모델 준비하기.................................................................................... 65 2.13 모델 평가..................................................................................................................... 67 2.14 한 걸음 더 나아가기..................................................................................................... 69 CHAPTER 3 음악 추천과 Audioscrobbler 데이터셋 3.1 데이터셋........................................................................................................................ 72 3.2 교차 최소 제곱 추천 알고리즘.......................................................................................... 73 3.3 데이터 준비하기............................................................................................................. 77 3.4 첫 번째 모델 만들기........................................................................................................ 82 3.5 추천 결과 추출 검사하기................................................................................................. 86 3.6 추천 품질 평가하기......................................................................................................... 89 3.7 AUC 계산하기................................................................................................................ 91 3.8 하이퍼파라미터 선택하기................................................................................................ 93 3.9 추천 결과 만들기............................................................................................................ 96 3.10 한 걸음 더 나아가기..................................................................................................... 98 CHAPTER 4 의사 결정 나무로 산림 식생 분포 예측하기 4.1 회귀로 돌아와서.......................................................................................................... 102 4.2 벡터와 특징................................................................................................................. 102 4.3 학습 예제.................................................................................................................... 104 4.4 의사 결정 나무와 랜덤 포레스트................................................................................... 104 4.5 Covtype 데이터셋....................................................................................................... 108 4.6 데이터 준비하기.......................................................................................................... 109 4.7 첫 번째 의사 결정 나무................................................................................................ 111 4.8 의사 결정 나무 하이퍼파라미터..................................................................................... 119
  • 15.
    15 4.9 의사 결정나무 튜닝하기.............................................................................................. 121 4.10 범주형 특징 다시 살펴보기......................................................................................... 126 4.11 랜덤 포레스트........................................................................................................... 129 4.12 예측하기................................................................................................................... 132 4.13 한 걸음 더 나아가기.................................................................................................. 133 CHAPTER 5 K-평균 군집화로 네트워크 이상 탐지하기 5.1 이상 탐지.................................................................................................................... 136 5.2 K-평균 군집화............................................................................................................ 137 5.3 네트워크 침입.............................................................................................................. 138 5.4 KDD 컵 1999 데이터셋............................................................................................... 139 5.5 첫 번째 군집화하기...................................................................................................... 140 5.6 k 선정하기.................................................................................................................. 143 5.7 R에서 시각화하기........................................................................................................ 146 5.8 특징 정규화................................................................................................................. 152 5.9 범주형 변수................................................................................................................. 154 5.10 엔트로피와 함께 레이블 활용하기............................................................................... 156 5.11 군집화하기................................................................................................................ 157 5.12 한 걸음 더 나아가기.................................................................................................. 160 CHAPTER 6 숨은 의미 분석으로 위키백과 이해하기 6.1 문서-단어 행렬........................................................................................................... 163 6.2 데이터 구하기.............................................................................................................. 165 6.3 파싱하여 데이터 준비하기............................................................................................ 166 6.4 표제어 추출................................................................................................................. 168 6.5 단어빈도-역문서빈도(TF-IDF) 계산하기....................................................................... 170
  • 16.
    16 CONTENTS 6.6 특잇값 분해................................................................................................................. 172 6.7중요한 의미 찾기......................................................................................................... 174 6.8 낮은 차원 표현에 대한 의문과 고찰............................................................................... 179 6.9 단어와 단어 사이의 연관도........................................................................................... 180 6.10 문서와 문서 사이의 연관도......................................................................................... 183 6.11 문서와 단어 사이의 연관도......................................................................................... 185 6.12 여러 개의 단어로 질의하기......................................................................................... 186 6.13 한 걸음 더 나아가기.................................................................................................. 188 CHAPTER 7 그래프엑스로 동시발생 네트워크 분석하기 7.1 네트워크 분석 사례: MEDLINE의 인용 색인.................................................................. 191 7.2 데이터 구하기.............................................................................................................. 192 7.3 스칼라 XML 라이브러리로 XML 문서 파싱하기.............................................................. 195 7.4 MeSH 주요 주제와 주제들의 동시발생 분석하기............................................................ 198 7.5 그래프엑스로 동시발생 네트워크 구성하기.................................................................... 201 7.6 네트워크의 구조 이해하기............................................................................................ 206 7.6.1 연결 성분............................................................................................................. 206 7.6.2 차수의 분포.......................................................................................................... 209 7.7 관련성 낮은 관계 필터링하기........................................................................................ 212 7.7.1 EdgeTriplets 처리................................................................................................ 213 7.7.2 필터링된 그래프 분석하기....................................................................................... 216 7.8 작은 세상 네트워크...................................................................................................... 217 7.8.1 클릭과 군집계수.................................................................................................... 218 7.8.2 프레겔을 사용하여 평균 경로 길이 계산하기............................................................... 220 7.9 한 걸음 더 나아가기 ................................................................................................... 226
  • 17.
    17 CHAPTER 8 뉴욕택시 운행 데이터로 위치 및 시간 데이터 분석하기 8.1 데이터 얻기................................................................................................................. 228 8.2 스파크에서 서드파티 라이브러리로 작업하기................................................................. 229 8.3 지리 데이터와 Esri Geometry API, 그리고 Spray.......................................................... 230 8.3.1 Esri Geometry API 살펴보기................................................................................. 231 8.3.2 GeoJSON 소개................................................................................................... 233 8.4 뉴욕 택시 운행 데이터 준비하기................................................................................... 236 8.4.1 잘못된 레코드 대규모로 다루기................................................................................ 239 8.4.2 지리 정보 분석하기................................................................................................ 244 8.5 스파크에서 세션화 작업 수행하기................................................................................. 247 8.5.1 세션 구성하기: 스파크에서 보조 정렬하기.................................................................. 249 8.6 한 걸음 더 나아가기..................................................................................................... 252 CHAPTER 9 몬테카를로 시뮬레이션으로 금융 리스크 추정하기 9.1 전문 용어.................................................................................................................... 254 9.2 VaR 계산 방법............................................................................................................. 255 9.2.1 분산-공분산 ........................................................................................................ 255 9.2.2 과거 기반 시뮬레이션............................................................................................. 256 9.2.3 몬테카를로 시뮬레이션........................................................................................... 256 9.3 우리의 모델................................................................................................................. 257 9.4 데이터 구하기.............................................................................................................. 258 9.5 전처리하기.................................................................................................................. 259 9.6 요인 가중치 결정하기................................................................................................... 263 9.7 표본추출..................................................................................................................... 265 9.7.1 다변량 정규분포.................................................................................................... 268 9.8 실험 실행하기.............................................................................................................. 270
  • 18.
    18 CONTENTS 9.9 수익 분포시각화하기................................................................................................... 274 9.10 결과 평가하기........................................................................................................... 275 9.11 한 걸음 더 나아가기.................................................................................................. 278 CHAPTER 10 BDG 프로젝트와 유전체학 데이터 분석하기 10.1 모델링과 저장소를 분리하기....................................................................................... 283 10.2 ADAM CLI를 이용한 유전체학 데이터 처리................................................................ 287 10.2.1 파케이 형식과 열 기반 저장소............................................................................... 294 10.3 ENCODE 데이터로부터 전사인자 결합 부위 예측하기................................................. 296 10.4 1000 지놈 프로젝트에서 유전자형 질의하기............................................................... 305 10.5 한 걸음 더 나아가기.................................................................................................. 308 CHAPTER 11 파이스파크와 썬더로 신경 영상 데이터 분석하기 11.1 파이스파크 소개........................................................................................................ 312 11.1.1 파이스파크 내부 구조........................................................................................... 314 11.2 썬더 라이브러리 개요와 설치..................................................................................... 316 11.3 썬더로 데이터 읽어 들이기......................................................................................... 317 11.3.1 썬더 핵심 자료형................................................................................................. 323 11.4 썬더로 신경 세포 유형 분류하기................................................................................. 324 11.5 한 걸음 더 나아가기.................................................................................................. 329 찾아보기 ��������������������������������������������������������������������������������������������������������������������������������������������������� 330
  • 19.
    191장 빅데이터 분석하기 “데이터애플리케이션은 소시지와 비슷하다. 어떻게 만드는지 모르는 편이 나으니까.” -오토 폰 비스마르크1 ● ‌‌셀 수 없이 많은 트랜잭션과 수천 가지 특징을 활용해 신용카드 부정 사용을 감지하는 모델 구축 ● ‌‌수백만 사용자에게 수백만 가지의 제품 중 적절한 것을 지능적으로 추천 ● ‌‌수백만의 요소를 고려한 포트폴리오 시뮬레이션을 통한 투자 위험도 추정 ● ‌‌질환의 유전적 연관성을 파악하기 위한 대규모 인간 유전자 분석 몇 년 전만 하더라도 이와 같은 작업은 꽤 어려운 일이었다. 요즘을 빅데이터의 시대라고 말할 수 있는 이유는 기존에는 경험하지 못한 규모로 정보를 수집, 저장, 처리할 수 있는 도구가 준비되 었기 때문이다. 이 배경에는 오픈 소스 소프트웨어 생태계가 있는데, 그 덕분에 엄청난 양의 데 이터를 다룰 수 있는 컴퓨터 클러스터 환경을 저렴하게 사용할 수 있게 되었다. 하둡Apache Hadoop 과 같은 분산 시스템이 대세가 되었으며, 거의 모든 분야의 수많은 현장에서 활용하고 있다. 하지만 돌덩어리와 끌이 있다고 해서 조각상이 저절로 만들어지는 것이 아니듯, 빅데이터와 이 를 다룰 도구를 갖추었다는 것과 이를 활용하여 무언가 쓸모 있는 일을 한다는 것 사이에는 차 이가 있다. 데이터 과학이 필요한 이유가 바로 여기에 있다. 조각이 도구를 사용하여 원석을 다 른 사람들에게 의미 있는 무언가로 바꾸는 작업이듯, 데이터 과학도 도구를 사용하여 원본 데 1 옮긴이_ 비스마르크는 원래 ‘데이터 애플리케이션’이 아니라 ‘법률’이 그러하다고 말했다. 빅데이터 분석하기 CHAPTER 1 샌디 라이자
  • 20.
    20 9가지 사례로익히는 고급 스파크 분석 (2판) 이터를 데이터 과학자가 아닌 사람들의 관심을 끌 만한 의미 있는 것으로 바꾸는 작업이다. 흔히 ‘쓸모 있는 일 하기’는 스키마Schema를 설계하고 SQL을 사용하여 “등록 과정의 세 번째 페 이지에 도달한 엄청난 수의 사용자 중 25세 이상은 몇 명인가?”와 같은 질문에 답하는 것을 의 미한다. 이런 질문에 쉽게 답할 수 있도록 데이터 웨어하우스Data Warehouse를 구성하고 정보를 체 계화하는 방법을 다루는 분야도 중요하지만, 이 책에서는 이런 복잡한 일은 되도록 다루지 않 으려 한다. 때로는 ‘쓸모 있는 일 하기’에는 노력이 더 필요할 수 있다. SQL은 여전히 주요한 수단이다. 하 지만 다루는 데이터가 매우 독특하거나 분석 작업이 복잡하다면 SQL보다 유연하고 근본적이 며 머신러닝과 통계 기능이 풍부한 새로운 프로그래밍 패러다임이 필요해진다. 이런 유형의 분 석이 이 책에서 이야기하려는 대상이다. 오랜 기간에 걸쳐 R, PyData 스택(파이썬 데이터 분석 도구 모음), 옥타브Octave와 같은 오픈 소스 프레임워크 덕에 작은 데이터셋Dataset을 빠르게 분석하고 모델을 수립할 수 있었다. 데이 터셋의 일부를 사용해서 머신러닝 모델을 학습시키고 나머지 데이터의 레이블을 예측하는 일 이 10줄 이내의 코드로도 가능하다. 여기서 조금만 더 나아가면 결측치Missing Data를 보정하고, 몇몇 모델을 실험해 최적의 모델을 찾고, 한 모델의 결과를 다른 모델을 적합Fit시키기 위한 입 력으로 사용할 수 있다. 대규모 데이터셋에서 같은 결과를 얻기 위해 컴퓨터 클러스터 환경을 활용한다면 이러한 과정이 어떻게 달라질까? 단순히 프레임워크를 여러 노드에서 동작하도록 확장하고 프로그래밍 모델은 그대로 유지한 채 분산 환경에서 잘 동작하게끔 내부를 수정하는 것이 옳을 수도 있다. 하지만 단일 노드에서 는 문제가 되지 않았지만 분산 컴퓨팅에서는 새롭게 고민해야 하는 것들이 있다. 예를 들어 네 트워크는 메모리보다 월등히 느리므로 데이터가 클러스터의 여러 노드에 나뉘어 있다면 많은 데이터를 참조하는 알고리즘은 성능이 매우 나빠진다. 분산 환경에서 동작하는 노드의 수가 늘 어날수록 오류가 발생할 가능성도 커진다. 이러한 사실들을 종합해볼 때 고도의 병렬 실행 코 드를 쉽게 작성할 수 있는, 분산 환경의 특징을 충실하게 활용하는 프로그래밍 패러다임이 필 요하다. 하나의 노드에서 동작하는 PyData나 R 같은 도구가 소프트웨어 커뮤니티에서 최근 주목받 고 있지만, 이들만이 데이터 분석을 위한 도구는 아니다. 대량의 데이터를 다루는 유전체학 같 은 과학 분야에서도 수십 년간 병렬 컴퓨팅 프레임워크를 발전시켜왔다. 이 분야에서 데이터를
  • 21.
    211장 빅데이터 분석하기 다루는사람 대부분은 HPCHigh-Performance Computing (고성능 컴퓨팅)라는 클러스터 컴퓨팅 환경 에 익숙하다. PyData나 R은 확장성이 부족해 문제라면, HPC에서는 추상화 수준이 지나치게 낮아서 발생하는 나쁜 사용성이 문제다. 예컨대 DNA 염기서열로 가득 찬 커다란 파일을 병렬 처리하려면 수작업으로 일일이 작은 파일로 나눈 후, 각각에 대한 처리 작업을 클러스터의 스 케줄러에 하나씩 등록해야 한다. 일부에서 오류가 발생하면 작업자는 그 오류를 직접 찾아내서 수동으로 재입력해야 한다. 분석하다 보면 전체 데이터셋의 정렬과 같은 데이터 전체를 사용하 는 작업을 수행해야 할 때가 있다. 이 경우에는 커다란 데이터 모두를 하나의 노드에 밀어 넣거 나 MPI와 같은 저수준 분산 프레임워크에 의존해야 하는데, 그러려면 C 언어와 분산 네트워크 환경을 잘 이해하고 있어야 한다. 또, HPC 환경에 맞게 제작된 도구들은 저수준 저장소 모델로부터 인메모리In-memory 데이터 모 델을 분리하기가 어려운 경우가 많다. 예를 들어 많은 도구가 POSIX 파일시스템의 단일 데이 터 스트림으로만 데이터를 읽을 수 있도록 만들어졌다. 이러한 도구는 병렬화하거나 데이터베 이스 같은 다른 종류의 백엔드 저장소를 사용하도록 변경하기가 쉽지 않다. 하둡 생태계의 요 즘 시스템들은 사용자가 클러스터 환경을 단일 컴퓨터 환경처럼 다룰 수 있도록 추상화해준다. 파일을 쪼개 여러 노드에 걸쳐 있는 저장소에 분산하고, 일을 작은 단위로 나눠 처리하고, 오류 를 복구하는 모든 작업을 자동으로 수행한다. 하둡 생태계는 큰 데이터 파일을 다루는 과정도 자동화할 수 있으며, HPC보다 훨씬 저렴하다. 1.1 데이터 과학의 어려움 데이터 과학을 실제로 적용하다 보면 종종 어려운 문제에 부딪히게 된다. 클라우데라Cloudera의 데이터 과학팀은 이러한 어려움을 널리 알리는 데 큰 역할을 해왔다. 대량의 데이터로부터 복 잡한 분석을 성공적으로 처리하는 시스템을 구축하려면 (설사 실제로 벌어지지 않더라도) 이 런 어려움에 관해서 알고 있어야 한다. 첫째, 성공적인 분석을 위한 작업 대부분은 데이터의 전처리 과정에서 이뤄진다. 데이터는 너 저분하다. 그래서 데이터를 활용하기 전에 정제, 개조, 합치기, 섞기 같은 여러 가지 전처리 과 정이 필요하다. 특히, 맨눈으로 검사하기 어려울 정도로 데이터가 많다면 어떠한 전처리 과정 이 필요한지를 파악하는 일조차 별도의 처리 과정을 거쳐야 한다. 심지어 모델의 성능을 최적
  • 22.
    22 9가지 사례로익히는 고급 스파크 분석 (2판) 화해야 할 때는 알고리즘을 선택해서 구현하는 일보다 특징을 추출하고 선택하는 데 일반적으 로 더 큰 노력이 들어간다. 예컨대 온라인 구매 데이터에서 사기 행위를 찾는 모델을 만들고자 한다면 데이터 과학자들은 사용자가 작성하는 주문서 상의 여러 정보, 즉 사용자 IP의 위치 정보, 로그인 시각, 웹 사이트 내비게이션 로그와 같은 활용 가능한 수많은 특징 중에서 무엇을 사용할지 선택해야 한다. 선 택한 각 특징을 머신러닝 알고리즘에 적합한 벡터로 변환해야 하며, 이를 위해서 더블형Double 숫자로 이뤄진 2차원 배열을 수학적 모델로 변환하는 일 정도는 해줄 수 있는 시스템이 있어야 한다. 둘째, 데이터 과학은 기본적으로 반복 Iteration 작업들로 구성된다. 보통은 모델을 만들고 분석하 는 과정에서 같은 데이터를 여러 번 반복해서 읽게 된다. 이는 머신러닝이나 통계적 절차의 특 징에 기인하는데, 값이 수렴할 때까지 입력 데이터를 반복해서 사용하는 확률적 구배법Stochastic Gradient Descent (SGD)이나 기댓값 최대화법Expectation Maximization 같은 널리 사용되는 최적화 기법들 을 보면 알 수 있다. 반복 과정은 데이터 과학자 자신의 작업 흐름 안에서도 중요하다. 데이터 과학자가 처음 접하는 데이터셋을 파악하고자 할 때, 특정 질의의 결과를 바탕으로 다음에 수 행해야 할 질의를 결정하는 것이 일반적이다. 모델을 만들 때도 데이터 과학자는 단 한 번의 시 도로 모델이 완성되리라 기대하지 않는다. 실험을 통해서 알맞은 특징을 선택하고, 적절한 알 고리즘을 선택하고, 유의성 검정을 하고, 맞춤 하이퍼파라미터들을 찾아낸다. 어떤 프레임워크 가 같은 데이터를 매번 디스크에서 가져온다면 전체 과정의 속도가 디스크 입출력만큼 느려지 고, 그 결과 반복해서 시도해볼 수 있는 횟수가 줄어들게 된다. 셋째, 잘 돌아가는 모델이 완성되었다고 해서 일이 끝나는 것은 아니다. 데이터 과학의 핵심이 데이터를 직접 분석하지 않는 사람들에게 유용한 정보를 뽑아내는 것이라면, 데이터 과학자 컴 퓨터의 텍스트 파일에 회귀 가중치의 목록 형태로 (즉, 다른 사람이 이해하기 힘든 형태로) 저 장된 모델을 만드는 일은 진정한 목적이 될 수 없다. 데이터 애플리케이션이라면 추천 시스템 이나 실시간 사기 탐지 시스템처럼 의미 있게 활용할 수 있어야 한다. 이런 시스템에서는 모델 이 제품 서비스의 일부이므로 주기적으로 혹은 실시간으로 다시 생성해야 할 수도 있다. 이런 상황에서는 연구를 위한 분석과 현장을 위한 분석을 구분해야 한다. 연구를 위한 분석은 데 이터에 대한 탐사 분석Exploratory Analytics을 의미한다. 이 분석에서는 데이터의 특성을 이해하려 시 도한다. 그 결과를 시각화하고, 아직 적용하지 않은 이론들을 시험한다. 여러 종류의 특징과 현
  • 23.
    231장 빅데이터 분석하기 재의데이터를 보강할 수 있는 후보 데이터도 시험하게 된다. 한두 가지는 성공하기를 바라면 서 다양한 알고리즘을 시험하는 것이다. 반면 데이터 애플리케이션을 구축하는 현장에서는 운 영을 위한 분석Operational Analytics을 수행한다. 분석 모델을 실제 의사 결정에 영향을 주는 서비스에 적용하며, 일정 기간 모델의 성과를 추적하고, 정확도를 조금이라도 올리기 위한 미세 조정 방 안을 궁리한다. 그리고 서비스 수준 협약서Service Level Agreement (SLA)와 가동시간Uptime도 고민하 게 된다. 현재의 사례를 보면, R과 같은 언어로 탐사 분석을 수행한 이후에, 양산 단계에서는 데이터 처리 과정을 자바나 C++로 완전히 새롭게 구현하는 것이 일반적이다. 물론 처음에 만든 모델의 코드를 실무 애플리케이션에서도 사용할 수 있다면 좋겠지만, R과 같 은 언어는 성능도 좋지 않은 데다가 제품의 다른 구성요소들과 통합하기에는 적합하지 않다. 반대로 자바나 C++ 쪽은 탐사 분석에 쓸만한 도구를 찾아보기 어렵다. 자바나 C++에서는 데 이터와 상호작용할 수 있는 REPLRead-Evaluate-Print-Loop 환경이 부족하며, 간단한 변환식을 구현 하는 데도 많은 양의 코드가 필요하다. 그리하여 모델링 과정에서도 쉽게 쓸 수 있고 제품에도 적용할 수 있는 프레임워크가 필요한 상황이 되었다. 1.2 아파치 스파크란 아파치 스파크로 들어가 보자. 스파크는 세련된 방법으로 클러스터의 여러 노드로 프로그램 을 분배하고, 그 위에서 동작하는 프로그램을 개발할 수 있도록 개발된 오픈 소스 프레임워 크다. UC 버클리의 AMPLab에서 탄생해, 지금은 아파치 소프트웨어 재단에서 관리하는 스 파크는 데이터 과학자가 분산 프로그래밍을 할 수 있게 해주는 아마도 최초의 오픈 소스 소 프트웨어일 것이다. 스파크를 쉽게 이해하기 위하여 스파크의 선배라 할 수 있는 맵리듀스MapReduce와 비교해보자. 맵리듀스는 수십만 개의 노드를 활용하는 병렬 처리를 간단히 구현할 수 있는 모델로, 대량의 데이터 연산 분야에 일대 혁신을 가져왔다. 맵리듀스는 거의 선형에 가까운 확장성을 보여준 다. 데이터가 많아지면 컴퓨팅 노드도 그만큼 추가하여 같은 시간에 일을 마무리 지을 수 있음 을 의미한다. 그리고 “하나의 노드에서는 잘 발생하지 않는 오류라도 규모가 큰 클러스터 환경 에서는 일상적으로 발생한다”는 상식으로부터도 자유롭다. 맵리듀스는 일을 작은 단위 작업으로 쪼개고, 단위 작업에서 오류가 나더라도 전체에 영향을 주지 않도록 우아한 방식으로 오류를
  • 24.
    24 9가지 사례로익히는 고급 스파크 분석 (2판) 처리한다. 스파크는 맵리듀스의 선형 확장성과 결함 포용Fault Tolerance성을 유지하면서, 세 가지 중요한 개 선을 이뤄냈다. 먼저, ‘맵 단계 후 리듀스 단계’를 지키지 않아도 되며, 훨씬 일반적인 방향성 비 순환 그래프Directed Acyclic Graph (DAG) 형태로 정의한 연산들을 실행할 수 있다. 맵리듀스라면 중 간 결과를 분산 파일시스템에 반드시 저장해야 하는 상황에서, 스파크는 파이프라인의 다음 단 계로 중간 결과를 바로 넘길 수 있다는 뜻이다. 이는 맵리듀스의 후손이자 마이크로소프트 연 구소에서 시작된 Dryad(https://goo.gl/Or3T8P)와 유사한 방식이다. 두 번째, 사용자가 연 산을 더욱 자연스럽게 표현할 수 있도록 풍부한 변환 방식을 제공하여 처리 능력을 확장하고 있다. 개발자 중심의 기능을 제공하여 몇 줄의 코드만으로 복잡한 파이프라인을 구현할 수 있 는 간소화된 API를 제공한다. 마지막 개선은 인메모리 처리 방식이다. 스파크의 데이터셋Dataset과 데이터프레임DataFrame을 통 한 추상화는 개발자가 데이터 처리 파이프라인의 어느 지점에서라도 데이터를 클러스터의 메 모리로 저장할 수 있도록 해준다. 이후 단계에서 같은 데이터를 사용해야 한다면 데이터를 다 시 연산하거나 디스크로부터 다시 읽을 필요가 없다는 뜻이다. 이 능력 덕분에 과거의 분산 처 리 엔진들이 하지 못하던 용도로도 사용할 수 있게 되었다. 예를 들어 데이터셋을 여러 번 훑어 야 하는 알고리즘이나 사용자 요청에 빠르게 응답하기 위해 커다란 인메모리 데이터셋을 스캔 해야 하는 반응형 애플리케이션Reactive Application에 아주 적합하다. 데이터 분석에서 가장 큰 병목이 CPU, 디스크, 네트워크 같은 컴퓨팅 환경이 아니라 분석가의 생산성에 달려 있음을 이해한다면, 앞 절에서 이야기한 ‘데이터 과학의 어려움’을 해결하는 데 스파크가 좋은 해답이라는 사실이 아마도 가장 중요할 것이다. 전처리부터 모델 평가까지의 전 체 과정을 단일 프로그래밍 환경에서 수행하는 것이 개발 속도 면에서 얼마나 큰 이점인지는 아무리 과장해도 지나치지 않을 것이다. REPL 환경의 분석 라이브러리들을 가지고 많은 것을 표현할 수 있는 프로그래밍 모델로 묶어낼 수 있는 스파크에서는 맵리듀스와 같은 특정 프레임 워크를 사용하느라 여러 IDE를 오갈 필요도 없고, R과 같은 프레임워크를 사용하느라 하둡 분 산 파일시스템Hadoop Distributed File System (HDFS)으로부터 데이터를 샘플링하거나 이리저리 이동 시킬 필요도 없다. 분석가가 데이터를 조사하는 시간이 절약될수록 뭔가 쓸만한 일을 할 가능 성은 더 커진다. 데이터 조작 또는 ETL에 적용할 수 있다는 관점에서는 스파크는 빅데이터를 다루는 매트랩
  • 25.
    251장 빅데이터 분석하기 Matlab이라기보다는빅데이터를 다루는 파이썬에 가까워 보인다. 범용 연산 엔진으로서 스파크 의 핵심 API는 통계, 머신러닝, 행렬 연산의 어떤 기능과도 독립적인, 데이터 변환을 위한 강 력한 토대를 제공한다. 스파크의 스칼라 API와 파이썬 API 덕분에 범용 언어에서 쉽게 불러 쓸 수 있고, 기존의 다른 라이브러리와 함께 사용할 수도 있다. 스파크의 인메모리 캐시 기능은 반복적으로 이뤄지는 크고 작은 모든 데이터 처리에 이상적이 다. 이 기능을 활용하면 학습 데이터를 반복해서 읽어야 하는 머신러닝 알고리즘에서는 학습 데이터를 메모리에 캐싱할 수 있다. 데이터 과학자가 데이터를 파악하려 할 때도 데이터를 디 스크에서 매번 읽어 들이는 대신, 메모리에 올려둔 채 다양한 질의를 테스트해보고, 또 그 결과 를 메모리에 쉽게 저장할 수도 있다. 마지막으로, 스파크는 탐사 분석 시스템과 운영 분석 시스템 사이의 간격을 좁힐 수 있다. 세간 에서 데이터 과학자는 통계학자보다는 엔지니어링을 잘하고 엔지니어보다는 통계 활용에 능하 다고 이야기하는데, 적어도 스파크는 대부분의 다른 탐사 분석 시스템보다는 운영 시스템에 적 용하기 좋고, 운영 시스템에서 일반적으로 사용하는 기술들에 비해 데이터 탐사 분석에도 적합 하다. 스파크는 근본적으로 성능과 신뢰성 모두를 위해서 만들어졌다. 자바 가상 머신Java Virtual Machine (JVM)에서 돌아가기 때문에 자바 스택에서 돌아가는 수많은 운영 및 디버깅 도구도 활 용할 수 있다. 스파크는 하둡 생태계의 다양한 도구와 통합하기에도 좋다. 스파크는 맵리듀스가 지원하는 모 든 데이터 포맷을 읽고 쓸 수 있어서, 에이브로Apache Avro, 파케이Apache Parquet와 같은 하둡의 일 반적인 데이터 저장 파일 포맷도 사용할 수 있다. 물론 하둡 이전부터 사용된 쉼표로 분리된 텍 스트 형식(CSV)도 지원한다. 그리고 HBase와 카산드라Apache Cassandra 같은 NoSQL 데이터베 이스로부터 데이터를 읽고 쓸 수도 있다. 스파크의 스트림 처리 라이브러리인 스파크 스트리밍 Spark Streaming을 사용하면 플룸Apache Flume이나 카프카Apache Kafka로부터 연속적으로 데이터를 입력 받을 수도 있다. SQL 라이브러리인 Spark SQL로는 하이브 메타스토어Apache Hive Metastore와 상 호작용이 가능하며, 하이브 온 스파크Hive on Spark를 사용하여 맵리듀스 대신 스파크를 하이브의 기본 실행 엔진으로 사용할 수 있다. 하둡의 스케줄링과 자원 관리를 담당하는 YARNYet Another Resource Negotiator 내부에서도 동작한다. 이를 통해서 클러스터 사이에서 자원을 동적으로 공유할 수 있으며, 맵리듀스나 임팔라Apache Impala 같은 다른 처리 엔진과 동일한 정책으로 관리할 수 있 게 되었다.
  • 26.
    26 9가지 사례로익히는 고급 스파크 분석 (2판) 1.3 이 책에 관하여 이 책의 나머지 부분에서는 스파크의 장점이나 단점은 다루지 않는다. 기본적인 스파크 프 로그래밍 모델과 스칼라 언어의 기초는 소개하지만, 스파크의 레퍼런스에 해당하는 내용이 나 모든 것에 대한 포괄적인 지침 같은 것은 제공하지 않으려 한다. 머신러닝, 통계학, 선형 대수의 튜토리얼로 만들 생각도 없다. 물론, 필요하다면 기본적인 배경은 설명할 것이다. 그 대신, 대량의 데이터셋을 다루는 복잡한 분석을 스파크로 실행해보며, 그 생생한 느낌을 여러분께 전달하고자 한다. 단순히 모델을 구축하고 평가하는 데 그치지 않고, 전체 파이프 라인을 돌아보며 데이터 정제, 전처리, 탐사 분석, 실제 제품으로 만들기까지를 보여주고자 한다. 아마도 실제 예제를 통해 보여주는 방법이 최선일 것이다. 그래서 우선 스파크와 그 생태계를 간단히 설명한 후, 그다음 장부터는 각 분야의 데이터를 스파크로 분석하는 독립 적인 설명들로 채울 것이다. 가능하다면 단순히 ‘정답’을 제공하기보다는 데이터 과학의 절차 전체, 즉 모든 반복, 막다른 길, 재시도 등을 설명할 것이다. 이 책은 스칼라, 스파크, 머신러닝, 데이터 분석에 더 친숙 해지는 계기가 될 것이다. 그리고 이 모두는 더 큰 목적을 향한 과정이다. 우리는 이번 장의 처음에 언급한 여러 업무에 어떻게 접근하는지를 보여주려는 것이다. 약 30쪽 내외로 구성 된 각 장을 통해 데이터 애플리케이션의 일부를 만들어내는 방법을 가능한 한 실제처럼 설 명할 것이다. 1.4 2판에 관하여 2015년과 2016년에 스파크는 많은 변화를 겪었으며, 그 결과로 2016년 7월에 스파크 2.0 이 출시되었다. 가장 큰 변화는 스파크의 핵심 API에서 이뤄졌다. 1.x 버전의 스파크 API는 여러 컴퓨터 클러스터에 걸쳐 느슨하게 인스턴스화된 객체의 모음인 탄력적 분산 데이터셋Resilient Distributed Dataset (RDD)을 중심으로 구성되어 있었다. RDD를 기반으로 강력하고 표현력 높은 API를 구성할 수 있었지만, 중요한 문제가 두 가지 생 겼다. 첫째, 성능과 안정성의 측면에서 적합하지 않았다. 자바나 파이썬 객체를 기반으로 했기 때문에 메모리 사용 면에서 비효율적이었고, 가비지 컬렉션 때문에 스파크 프로그램이 대기해
  • 27.
    271장 빅데이터 분석하기 야하는 시간이 길어졌다. 또한, 실행 계획이 API에 묶여 있어, 사용자가 프로그램의 실행을 최적화하는 부담이 커지게 되었다. 예를 들어, 전통적인 RDBMS를 사용하면 조인할 테이블의 크기에 따라 최선의 조인 전략이 알아서 선택되는 반면, 스파크를 사용할 때는 사용자가 이를 직접 선택해야 했다. 둘째, 스파크 API는 일반적으로 데이터가 구조화된 관계형 모델에 잘 들 어맞는다는 사실을 무시했다. 튜플 내에서의 순서 대신 열의 이름을 사용한다든지의 방법으로 데이터를 훨씬 더 쉽게 조작할 수 있는 기본 자료형을 제공할 수 없었다. 스파크 2.0은 RDD를 Dataset과 DataFrame으로 대체하여 이러한 문제점을 해결했다. Dataset은 RDD와 비슷하지만 객체를 인코더에 매핑하여 인메모리 표현에 훨씬 효율적이다. 이를 통해서 스파크 프로그램을 더 빠르고, 더 작은 메모리로, 더 예측 가능하게 실행할 수 있 다. 또, 데이터셋과 실행 계획 사이에 최적화 기능을 배치하여 실행 방법에 대해서 더 지능적인 결정을 내릴 수 있다. DataFrame은 관계형 데이터, 즉 고정된 열의 데이터가 행 단위로 이뤄 진 데이터를 모델링하는 데 특화된 Dataset의 하위클래스다. 열 개념을 도입하여 더 깨끗하고 표현력이 풍부한 API를 사용할 수 있으며, 거기에 다양한 성능 최적화가 가능해졌다. 예를 들 어, 결과를 만들어내는 데 열의 일부만 필요하다는 사실을 알고 있다면, 열 전체를 메모리에 올 리지 않아도 된다. 그리고 이전에는 사용자 정의 함수로 정의해야 했던 많은 변환을 이제 API 에서 직접 표현할 수 있다. 이 기능은 파이썬을 사용할 때 특히 유용한데, 스파크 내부 동작이 파이썬에서 정의된 함수보다 변환을 훨씬 빠르게 수행할 수 있기 때문이다. 또한 DataFrame 은 Spark SQL과 상호운용성을 제공하므로, 사용자가 SQL 질의를 작성해서 DataFrame을 반환받고, 그 DataFrame을 스파크가 지원하는 프로그래밍 언어에서 사용할 수 있다. 새 API 는 기존 API와 매우 유사해 보이지만, 세부적인 변화 때문에 거의 모든 스파크 프로그램이 수 정되어야 한다. 스파크 2.0은 이러한 변화 외에도, 머신러닝과 통계 분석에 사용하는 API도 크게 변경되었다. 이전 버전에서는 머신러닝 알고리즘별로 고유한 API가 있어서, 알고리즘에 적용할 데이터를 준비하거나 특정 알고리즘의 결과를 다른 알고리즘에 적용하고자 할 때는 각각을 조합하는 코 드를 만들어야 했다. 스파크 2.0에 포함된 Spark ML API는 머신러닝 알고리즘과 특징Feature 의 변환 단계의 파이프라인을 구성할 수 있는 프레임워크를 제공한다. 인기 있는 파이썬 도구 인 사이킷런Scikit-Learn의 API에서 영감을 받아서, 데이터의 파라미터를 학습하고, 이 파라미터 를 데이터를 변환시키는 데 사용하는 객체인 추정자Estimator와 변환자Transformer를 중심으로 돌아간 다. Spark ML API는 DataFrame API와 많은 부분이 결합되어 있어, 관계형 데이터로도 머
  • 28.
    28 9가지 사례로익히는 고급 스파크 분석 (2판) 신러닝을 쉽게 수행할 수 있다. 예를 들어서 사용자는 특징 벡터의 순서 값 대신 이름으로 특징 을 참조할 수 있다. 이러한 변화들이 반영되다 보니, 이 책 초판의 많은 부분이 의미가 없게 되었다. 이번 2판은 새 로운 스파크 API를 사용하기 위해서 모든 장을 수정하였다. 추가로, 더 이상 관련이 없는 부분 은 제외했다. 예를 들어 몇몇 복잡한 API를 다루던 전체 부록을 삭제했는데, 이 부분을 지금은 사용자 개입 없이 스파크가 알아서 처리해주기 때문이다. 안정적으로 성숙한 스파크의 시대가 된 터라, 스파크를 사용한 분석에 있어서 수년간은 이 책이 유용한 자료로 남아있기를 희망한다.
  • 29.
    292장 스칼라와 스파크를활용한 데이터 분석 “흥미를 잃지 않는다면 못할 일은 아무 것도 없다.” -데이비드 포스터 월리스 데이터 정제는 모든 데이터 과학 프로젝트의 시작이자, 매우 중요한 일이다. 분석에 사용하는 데이터의 품질이나 다른 내재적 원인에 의하여 분석 결과가 왜곡되거나 실제와 다른 결론 이 도출된다면 아무리 뛰어난 분석 방법이라 할지라도 도움이 되지 않을 것이다. 이러한 중요성에도 불구하고 데이터 과학 서적이나 강의에서는 데이터 정제 과정에 관해서 다루지 않거나 그냥 언급만 하고 지나치곤 한다. 사실 데이터 정제는 꽤 지루한 과정이다. 우리가 새 문제에 써보고 싶은 멋진 머신러닝 알고리즘을 적용하기 전에 거쳐야 하는 아주 따분한 일이다. 많은 풋내기 데이터 과학자는 조악한 품질의 데이터로 분석을 시작하고, 복 잡한 알고리즘을 적용한 후 말도 안 되는 답을 얻고 나서야 비로소 데이터 품질에 심각한 문 제가 있음을 깨닫기도 한다. “쓰레기를 넣으면 쓰레기가 나온다Garbage in, garbage out”라는 말도 있지만, 현실은 이보다 훨씬 심 각하다. 어떤 데이터에 쉽게 파악되지 않는 심각한 품질 문제가 있어서 그럴싸한 데이터로 오 인된다면 도출된 결과도 그럴싸해 보일 수 있다. 이런 식의 심각한 오답을 제시하는 것은 데이 터 과학자에게 치명적인 실수다. 데이터 과학자로서 갖춰야 할 중요한 소질 하나는 데이터 분석의 모든 단계에서 흥미롭고 가치 있는 문제를 찾아내는 능력이다. 분석의 초기 단계에 기술과 통찰을 더하면 최종 결과물의 신 스칼라와 스파크를 활용한 데이터 분석 CHAPTER 2 조시 윌스
  • 30.
    30 9가지 사례로익히는 고급 스파크 분석 (2판) 뢰도는 더 커지게 된다. 데이터 과학자에게 데이터 품질 관리에 신경 쓰라고 하다니, 물론 말은 쉽다. 아이들에게 채소 를 먹으라고 이야기하는 것처럼 말이다. 하지만 스파크와 같은 새로운 도구를 써보는 일이 훨 씬 재미있다. 스파크로는 멋진 머신러닝 알고리즘을 만들어보거나, 스트리밍 데이터를 처리하 는 엔진을 개발한다거나 복잡하게 연결된 그래프를 분석하는 등의 일을 해볼 수 있으니 말이 다. 그래서 스파크와 스칼라를 활용하여 데이터를 정제하는 예를 직접 보여주는 것으로부터 시 작하려고 한다. 2.1 데이터 과학자를 위한 스칼라 데이터 과학자 대부분은 데이터를 조작하고 분석할 때 R이나 파이썬과 같은, 자신에게 가장 능숙한 특정 도구를 선호한다. 어쩔 수 없이 다른 환경에서 일하게 되더라도 선호하는 도구 에 집착하며 그 도구를 사용할 수 있는 방법을 찾아 헤매곤 한다. 새로운 문법과 새로운 패 턴을 습득해야 하는 새로운 도구를 도입하는 것은 최선의 상황에서도 꽤 힘든 도전적인 일 이다. 스파크에는 R이나 파이썬으로 코드를 작성할 수 있는 라이브러리와 래퍼Wrapper가 있다. 그중 파이스파크PySpark라는 훌륭한 파이썬 래퍼는 이 책의 11장에서도 일부 다루고 있다. 하지만 대 부분의 예제는 스칼라로 제공할 것이다. 스파크 자체가 스칼라 언어로 구현되어 있어서, 스칼 라를 직접 사용하면 다음과 같은 효과를 기대할 수 있다. 성능 면에서 유리하다. 스칼라처럼 JVM에서 동작하는 언어 위에서 R이나 파이썬으로 만들어진 알고리즘을 실행하 려면 코드와 데이터를 변환하거나 다른 환경으로 옮기는 작업이 추가로 필요하며, 때에 따 라서는 이 추가 과정에서 오류가 생길 수도 있다. 반면, 스파크가 제공하는 스칼라 API를 사 용한다면 의도한 대로 동작할 가능성이 매우 커진다.
  • 31.
    312장 스칼라와 스파크를활용한 데이터 분석 최신 기능을 활용할 수 있다. 스파크의 머신러닝, 스트림 처리, 그래프 분석 등의 라이브러리는 모두 스칼라로 작성했기 때문에 새로운 기능이 파이썬이나 R 환경까지 지원하는 데 시일이 걸리는 편이다. 그러므로 스파크가 제공하는 모든 최신 기능을 곧바로 사용하려 한다면 최소한 스칼라에 대해서 조금 은 알아야 하며, 그 기능들을 확장하여 새로운 문제에 적용하려면 스칼라를 어느 정도 능숙 하게 다룰 수 있어야 한다. 스파크의 철학을 이해하기 쉽다. 파이썬이나 R로 스파크를 사용한다 할지라도, 스파크의 API에는 이를 구현한 언어인 스칼 라로부터 시작된 철학이 녹아 있다. 여러분이 다른 언어를 사용하더라도 스칼라로 스파크를 다루는 방법을 알고 있다면 스파크 체계를 이해하고 문제를 ‘스파크답게’ 해결하는 데 도움 이 된다. 다른 데이터 분석 도구들과는 많이 다르기 때문에 설명하기 힘든, 스칼라의 또 다른 장점이 있다. 만약 R이나 파이썬으로 데이터베이스에 있는 데이터를 분석해왔다면 필요한 데이터를 SQL로 가져온 후, 작업 환경을 R이나 파이썬으로 바꿔서 그 데이터를 다루고 시각화하는 절차 에 익숙할 것이다. 누군가는 클러스터에 저장된 데이터에 접근하여 작업하는 일(SQL)과 PC 에 저장된 데이터를 다루고 시각화하는 일(파이썬/R)에 각각 다른 언어를 사용해왔을 수도 있 다. 그리고 SQL 사용자 정의 함수를 이용해 데이터를 처리하는 위치를 데이터베이스 엔진으로 옮기고 싶다면 C++나 자바 같은 또 다른 프로그래밍 환경으로 바꿔 작업해야 할 수도 있다. 오랫동안 사용해 익숙해졌다면 이런 방식의 불편함을 자각하지 못할지도 모른다. 스칼라와 스파크를 사용한다면 이야기가 달라진다. 어떤 경우에도 같은 언어를 사용할 수 있기 때문이다. 스파크를 통해 클러스터에서 데이터를 가져오고, 그 데이터를 로컬 환경에서 다루는 일 모두를 스칼라 코드를 작성하여 처리할 수 있다. 무엇보다 좋은 점은 로컬에서 작성한 스칼 라 코드를 클러스터로 보내서, 클러스터에 저장된 데이터를 로컬에서 다룬 결과와 완전히 똑같 이 처리할 수 있다는 것이다. 심지어 Spark SQL과 같은 고수준 언어로 작업할 때도 자신만의 사용자 정의 함수를 만들어 Spark SQL 엔진에 등록하여 그대로 사용하면 되며, 이 과정에서 작업 환경을 바꿀 필요가 없다.
  • 32.
    32 9가지 사례로익히는 고급 스파크 분석 (2판) 데이터의 저장 위치나 처리 위치와 상관없이, 데이터를 조작하고 분석하는 모든 일을 하나의 환경에서 할 수 있다는 것이 얼마나 혁신적인지 설명하기는 쉽지 않지만, 일단 경험해보면 알 것이다. 필자들은 스파크를 처음 접했을 때 느꼈던 신비한 힘을 예제에 담아내려고 노력했다. 2.2 스파크 프로그래밍 모델 스파크 프로그래밍을 위해서 데이터와 이를 담은 저장소가 필요하다. 데이터는 보통 HDFS와 같은 분산 저장소에 저장한다. 일반적으로 스파크 프로그램은 다음과 같은 몇 개의 연이은 단 계로 구성된다. 1. ‌‌입력 데이터에 적용할 변환을 정의한다. 2. ‌‌변환된 데이터를 저장소로 보내거나 구동자Driver의 로컬 메모리로 반환하는 액션을 수행한다. 3. ‌‌분산 처리 방식으로 계산된 결과를 바탕으로 로컬 계산을 수행한다. 이 작업은 다음에 수행할 변환과 액션을 결정하는 기준이 될 수도 있다. 스파크 버전이 1.2에서 2.1로 진화함에 따라 각 단계를 수행할 때 사용할 수 있는 도구들이 양 적, 질적으로 발전했다. 분석을 수행하는 과정의 복잡한 SQL 질의, 머신러닝 라이브러리 및 사 용자 작성 코드들을 섞어 쓰거나 골라 쓸 수 있고, 더 짧은 시간에 더 많은 응답을 제공하기 위 해서 수년간 스파크 커뮤니티가 개발해온 모든 상위 수준의 추상화를 활용할 수 있다. 동시에, 이 모든 상위 수준 추상화가 ‘저장소와 실행 사이의 상호작용’이라는 스파크의 가장 근원적인 철학을 지켜나가고 있다는 점을 기억해둬야 한다. 스파크는 데이터 처리 파이프라인상의 어떤 중간 단계에서도 이후에 사용하기 위해서 메모리에 데이터를 캐시할 수 있도록 하여 이러한 추 상화를 훌륭하게 결합한다. 이 원칙을 이해한다면 데이터 분석에 스파크를 더 효율적으로 활용 할 수 있다. 2.3 레코드 링크 이 장에서 논의할 문제는 문헌과 실무 현장에서 엔티티 해소Entity Resolution, 레코드 중복 제거Record Deduplication, 병합 및 제거Merge-and-purge, 목록 정리List Washing 등 다양한 이름으로 불리고 있다. 모
  • 33.
    332장 스칼라와 스파크를활용한 데이터 분석 순되게도 이 문제가 다양한 이름으로 불리기 때문에 문제 해결을 위한 기술들을 훑어보고자 해 도 관련 논문조차 다 찾아내기 어렵다. 오히려 이 데이터 정제 문제에 대한 참고 문헌들에서 중 복 제거를 수행할 데이터 과학자가 필요한 처지다! 이 장의 목적을 원만히 이루기 위해 이제부 터 ‘같은 실체를 가리키는 레코드들을 연결 짓는’ 이 문제를 레코드 링크Record Linkage라 하겠다. 이 문제의 일반적인 형태는 다음과 같다. 하나 또는 그 이상의 데이터 출처로부터 데이터를 수 집하여 취합하면 그 속의 레코드 일부가 실제로는 같은 고객, 같은 환자, 같은 위치, 같은 행사 등 동일한 실체를 가리킬 수 있다. 각 실체는 이름, 주소, 생일과 같은 여러 속성을 가지고 있어 서 동일한 실체를 가리키는 레코드들을 찾아내려면 이 속성값을 이용해야 한다. 안타깝게도 이 속성값들은 불완전하다. 형식이 다르거나 오타가 있거나 값이 누락되었을 수 있다. 그러므로 단순하게 속성의 값이 같은지만을 검사한다면 상당수의 중복 레코드를 놓치게 될 것이다. [표 2-1]을 살펴보자. 표 2-1 레코드 링크의 어려움 이름 주소 도시 주 전화번호 조시의 커피숍 선셋 대로 1234 서 할리우드 CA (213)-555-1212 조시 커피 선셋 대로 1234, 서 할리우드 CA 555-1212 커피숍 체인 #1234 선셋 가 1400, 2 할리우드 CA 206-555-1212 커피숍 체인 지역 사무소 선셋 가 1400, 2호실 할리우드 캘리포니아 206-555-1212 이 표에서 위의 두 줄은 각각 ‘서 할리우드’와 ‘할리우드’라는 도시에 있는 서로 다른 작은 커피 숍처럼 보인다. 하지만 이는 입력상의 실수로, 사실은 같은 커피숍을 가리킨다. 그다음의 두 줄 은 주소가 같지만 2개의 서로 다른 사업장을 가리키고 있는데, 하나는 실제 커피숍이며 다른 하나는 지역의 체인점 사무소다. 둘 다 시애틀에 있는 본사의 대표 전화번호가 기록되어 있다. 이 예제는 레코드 링크가 얼마나 어려운지를 보여준다. 각각의 묶음이 서로 유사하게 보이더라 도 중복이 있는지를 결정하기 위해 사용하는 기준은 묶음마다 다르다. 사람은 직관으로 쉽게 구분할 수 있겠지만 컴퓨터가 그 구분법을 학습하기에는 어려운 형태다.
  • 34.
    34 9가지 사례로익히는 고급 스파크 분석 (2판) 2.4 스파크 셸과 SparkContext 시작하기 여기에서는 UC 어바인의 머신러닝 데이터 저장소UC Irvine Machine Learning Repository에서 구할 수 있는 표본 데이터를 사용한다. 이 저장소에서 연구와 교육을 위한 흥미로운 (더구나 무료인) 데이 터셋들을 구할 수 있다. 우리가 분석할 데이터셋은 2010년에 독일의 한 병원에서 실시한 레코 드 링크 연구에서 나온 것으로, 환자의 성과 이름, 주소, 생일 등 몇 가지 기준에 따라 묶은 수 백만 건의 환자 기록 묶음이 들어 있다. 각 묶음에는 문자열 유사도에 따라 0.0부터 1.0까지 점 수를 매겼고, 그 후 같은 사람을 표현한 묶음과 그렇지 않은 묶음을 분류해 일일이 표시하였다. 데이터셋을 만드는 데 사용한 필드 자체의 원래 값은 환자의 개인 정보를 보호하기 위해 제거 되었으며 식별번호, 필드별 유사도 점수, 묶음별 실제 분류값(같은 사람인지 여부)이 레코드 링크 연구 용도로 발행되었다. 다음과 같이 셸shell 명령어로 저장소로부터 데이터를 가져오자. $ mkdir linkage $ cd linkage/ $ curl -L -o donation.zip http://bit.ly/1Aoywaq $ unzip donation.zip $ unzip 'block_*.zip' 사용할 수 있는 하둡 클러스터가 있으면, HDFS에 블록 데이터용 디렉터리를 생성하고 데이터 파일을 그 디렉터리에 복사한다. $ hadoop fs -mkdir linkage $ hadoop fs -put block_*.csv linkage 이 책의 예제 코드는 2.1.0 버전의 스파크를 사용한다. 필요한 릴리스는 스파크 프로젝트 사이 트에서 내려받을 수 있다(http://spark.apache.org/downloads.html). 클러스터 환경을 사용 하든 로컬 PC 환경을 사용하든, 스파크 참조 문서를 보고 환경을 설정하면 된다(http://spark. apache.org/docs/latest/). 이제 spark-shell을 실행할 준비가 되었다. spark-shell은 스파크 확장 API를 제공하는 스 칼라 REPL이다. REPL이라는 용어가 생소하다면 R 환경과 유사한 것으로 생각하면 된다. spark-shell은 스칼라 프로그래밍 언어를 사용하여 함수를 정의하고 데이터를 다룰 수 있는
  • 35.
    713장 음악 추천과Audioscrobbler 데이터셋 “De gustibus non est disputandum.” (취향에 이유를 따지지 마라.) -작자 미상 누군가 나에게 무슨 일을 하냐고 물을 때 ‘데이터 과학’ 또는 ‘머신러닝’이라고 직접적으로 대답 하면, 들리기야 멋있게 들리지만 반응은 싸한 편이다. 실제 데이터 과학자들조차도 이 용어의 뜻을 명확하게 정의하지 못하고 있으니(많은 데이터를 저장하고, 계산하고, 무언가 예측하는 일?) 당연히 그럴 만하다. 대신 예를 들어 대답해보자. “아마존에서 고객이 과거에 구매한 책들과 유사한 책을 추천해주는 걸 알고 계신가요? 정말요? 네. 바로 그게 제가 하는 일입니다.” 추천 엔진은 적어도 내 주변 사람은 모두 알고 있으며, 또 많은 사람이 아마존을 통해 경험한 대규모 머신러닝의 사례일 것이다. 소셜 네트워크에서 동영상 사이트, 그리고 온라인 쇼핑몰까 지 추천 엔진은 모든 영역에 적용되는 공통분모에 해당하며, 실제로 동작하는 모습을 직접 관 찰할 수도 있다. Gmail이 우리가 신경 쓰지 않아도 스팸을 골라내는 것과 흡사한 방법으로, 스 포티파이Spotify 역시 재생할 음악을 컴퓨터가 골라주고 있다는 사실을 알고 있다. 추천 알고리즘의 결과는 다른 머신러닝 알고리즘보다 훨씬 직관적이다. 게다가 흥미롭기까지 하다. 우리가 개인의 음악 취향이 너무 사적이어서 설명할 수 없다고 생각한다는 점을 고려해 음악 추천과 Audioscrobbler 데이터셋 CHAPTER 3 션 오언
  • 36.
    72 9가지 사례로익히는 고급 스파크 분석 (2판) 보면, 추천 엔진은 우리가 좋아하리라 생각하지도 못한 음악을 찾아내는 놀라운 일을 해낸다. 추천 엔진이 널리 사용되는 음악과 영화 분야에서는 추천된 목록이 누군가 과거에 접해본 콘텐 츠와 왜 잘 들어맞는지를 추리해내기가 상대적으로 쉽다. 하지만 모든 군집화Clustering1 나 분류 Classification 알고리즘이 설명하기 쉬운 건 아니다. 예컨대 서포트 벡터 머신Support Vector Machine 분류 기는 계수들의 집합으로 구성되는데, 예측은 하더라도 그 계수들의 의미를 설명하기란 전문가 조차도 쉽지 않다. 그래서 앞으로 3개 장에 걸쳐서 스파크의 핵심 머신러닝 알고리즘을 다뤄보려 한다. 그중 처음 인 이번 장은 음악에 특화된 추천 엔진을 들여다보겠다. 이는 스파크와 MLlib을 실제 세상의 문제에 적용하는 방식을 소개하고, 이어지는 장에서 더 깊게 파헤칠 머신러닝 알고리즘의 기본 을 소개하는 적절한 방법일 것이다. 3.1 데이터셋 이 장의 예제에서는 오디오스크로블러Audioscrobbler에서 공개한 데이터셋을 사용한다. 오디오스 크로블러는 2002년에 초기 인터넷 스트리밍 라디오 서비스를 제공한 last.fm(http://www. last.fm)을 위해서 만들어진 첫 번째 음악 추천 시스템이다. 오디오스크로블러는 ‘스크로블링’2 용 오픈 API를 제공했고, 청취자의 음악 재생 내역을 기록했다. 서드파티 앱과 사이트들이 추 천 엔진에 음악 감상 관련 데이터를 돌려준 덕에, 이 시스템의 사용자는 수백만 명에 이르렀다. 당시의 추천 엔진 관련 연구는 대부분 평점 데이터를 학습하는 데 그쳤다. 즉, “개똥이가 소녀 시대에게 별점 3개 반을 주었군”과 같은 입력에 기초해 동작하는 도구처럼 보이곤 했다. 오디오스크로블버의 데이터셋이 재미있는 점은 “개똥이가 소녀시대 음악을 들었어”와 같은 단 순 재생 정보만 기록한다는 것이다. 단순 재생 여부는 평점보다 정보가 적다. 개똥이가 듣는다는 사실만으로 개똥이가 실제로 좋아하는지 혹은 싫어하는지를 판단할 수 없기 때문이다. 종종 별 관심 없는 아티스트의 음악을 틀어놓을 때도 있고, 또 음악을 틀어놓고 외출해버릴 수도 있다. 1 옮긴이_ 흔히 영어를 그대로 읽어 클러스터링이라 부르지만, 이 책에서는 분산 처리 분야의 용어인 클러스터와 명확히 구분하기 위해 우 리말 용어인 군집화로 옮긴다. 2 옮긴이_음악을 들을 때 아티스트, 제목, 앨범 등의 정보를 last.fm 서버에 보내는 작업이다.
  • 37.
    733장 음악 추천과Audioscrobbler 데이터셋 하지만 감상한 음악에 평점을 매기는 횟수는 음악을 듣는 일에 비해서 훨씬 드물다. 그래서 음 악 감상 데이터 하나의 정보량은 음악 평점 데이터 하나의 정보량보다 적지만, 음악 감상 데이 터셋은 크기도 훨씬 크고, 더 많은 사용자와 아티스트를 포함하며, 정보의 총량도 훨씬 많다. 사용자와 아티스트 사이의 관계가 명시적 평점이나 ‘좋아요’ 버튼으로 직접 주어지지 않고 다 른 행위들로부터 의도치 않게 은연중에 드러나기 때문에 이런 종류의 데이터를 암묵적 피드백 Implicit Feedback이라고 부르기도 한다. 2005년에 last.fm에서 배포한 데이터셋의 스냅샷을 인터넷에서 압축된 파일 형태로 구할 수 있다. https://goo.gl/yoWRAl 에서 압축 파일을 내려받은 후, 그 안의 몇몇 파일을 찾아보자. 중심이 되는 데이터셋은 user_artist_data.txt 파일에 들어 있다. 이 안에는 141,000명의 사 용자와 160만 명의 아티스트 정보가 담겨 있으며 약 2,420만 건의 음악 재생 정보가 재생 횟 수와 함께 기록되어 있다. 또한, 이 데이터셋의 artist_data.txt 파일에는 각각의 아티스트에 ID를 부여하고 있다. 음악 이 재생되면 클라이언트 프로그램이 재생되는 아티스트의 이름을 전송하는데, 그 이름은 잘못 기록되었거나 공식 명칭이 아닐 수 있으며, 이러한 오류가 뒤늦게 발견될 수도 있다. 예를 들어 “The Smiths”, “Smiths, The”, “the smiths”는 데이터셋 안에서는 별도의 아티스트 ID를 가 질지도 모르지만, 이 모두가 단 한 사람에게 붙여진 것일 수 있다. 그래서 데이터셋의 artist_ alias.txt 파일은 아티스트 명칭의 흔한 오기 패턴과 다양한 변형 표기법으로 기록된 아티스트 ID를 해당 아티스트의 대표 ID와 연결짓고 있다. 3.2 교차 최소 제곱 추천 알고리즘 우리는 암묵적 피드백 데이터에 적합한 추천 알고리즘을 선택해야 한다. 우리의 데이터셋은 전 적으로 사용자와 아티스트의 음악 사이의 상호작용으로만 구성되며, 아티스트 이름 외에 사용 자와 아티스트에 대한 어떤 정보도 포함하고 있지 않다. 우리는 사용자와 아티스트의 속성에 대해 아는 바가 없어도 학습이 가능한 알고리즘이 필요하다. 이런 알고리즘을 일반적으로 협업 필터링Collaborative Filtering (https://goo.gl/eK7KYG)이라고 한다. 예를 들어 두 사용자가 단지 동 년배라서 취향이 비슷하다고 이야기하는 것은 협업 필터링이 아니다. 두 사람이 들은 노래 중 같은 것이 많기 때문에 같은 노래를 좋아할 수도 있다고 예측하는 것이 협업 필터링의 예라고
  • 38.
    74 9가지 사례로익히는 고급 스파크 분석 (2판) 할 수 있다. 수천만 건의 재생 기록을 담은 이 데이터는 얼핏 방대해 보이지만, 다른 관점에서 보면 밀도가 낮기 때문에 꼭 그렇지도 않다. 한 사용자가 160만 명의 아티스트 중 평균 171명의 노래만 재 생했다. 어떤 사용자는 딱 한 아티스트의 노래만 듣기도 했다. 이런 사용자들에게도 괜찮은 추 천이 가능한 알고리즘이 필요하다. 어찌 되었든 음악을 듣는 누구라도 처음에는 딱 한 곡의 청 취 기록만 있었을 것이다! 결국 대규모 모델을 만들 수 있고 동시에 빠르게 추천해주는, 확장 가능한 알고리즘이 필요하 다. 일반적으로 추천 결과가 내일 나온다면 너무 늦다. 1초 이내의 준 실시간으로 나와야 한다. 이 예제에서는 잠재요인Latent-factor (https://goo.gl/w0isfF) 모델로 분류할 수 있는 많은 알고리 즘 중 하나를 사용하고자 한다. 잠재요인 모델은 다수의 사용자와 아이템 사이에서 관측된 상 호작용Observed Interaction을 상대적으로 적은 수의 관측되지 않은 숨은 원인Unobserved Underlying Reason 으로 설명하려 할 때 사용한다. 이는 수백만의 사람이 수천 개의 음반 중 특정 음반을 구입한 이유를 (직접 관측할 수 없고 데이터도 주어지지 않은) 수십 개 음악 장르에 대한 개인 취향으 로 설명하는 것과 유사하다. 예를 들어 메탈 밴드인 메가데스와 판테라의 음반뿐 아니라 클래식 작곡가 모차르트의 음반을 구매한 사람을 생각해보자. 왜 이런 음반만 구매하고 다른 음반은 구매하지 않았는지에 대한 정확한 이유를 설명하는 것은 어렵다. 그렇지만 이 음반들은 더 큰 음악 취향에서의 매우 작은 부분일 수 있다. 이 사람은 아마도 메탈 음악부터 프로그레시브 록, 클래식에 이르는 음악을 좋 아할 것이다. 이렇게 설명하는 것은 더 간단할 뿐 아니라 이 설명을 바탕으로 흥미를 유발할 수 있는 다른 많은 앨범을 제안할 수도 있다. 여기서 메탈, 프로그레시브 록, 클래식을 좋아한다는 것이 수만 개의 앨범 각각에 대한 선호도를 설명할 수 있는 세 개의 숨은 원인이다. 더 구체적으로는 행렬 분해Matrix Factorization (https://goo.gl/w0isfF) 모델을 사용할 것이다. 수학 적으로 이들 알고리즘에서는 사용자와 제품 데이터를 큰 행렬 A로 간주해 다루는데, A는 사용 자 i가 아티스트 j의 음악을 들었다면 A의 i행 j열에 값이 존재하는 행렬이다. A는 희소 행렬 Sparse Matrix이다. 사용자-아티스트의 가능한 모든 조합 중 오직 극소수만이 실제 데이터로 등장 하기 때문에, 이 행렬의 원소 대부분은 0이 된다. 이들 행렬 분해 알고리즘은 A를 더 작은 행렬 X와 Y의 행렬 곱으로 분해하는데, 이 X와 Y는 매우 길쭉하다. A가 다수의 행과 열을 가지기 때문에 X와 Y는 매우 많은 행을 가지게 되는 데 반해, 열은 몇 개(k) 되지 않는다. k개의 열은
  • 39.
    753장 음악 추천과Audioscrobbler 데이터셋 상호작용하는 데이터를 설명하는 데 사용하는 잠재요인에 해당한다. [그림 3-1]에서 볼 수 있듯, k가 작기 때문에 이 분해는 근사치일 수밖에 없다. 그림 3-1 행렬 분해 원래의 행렬 A는 매우 희소한 데 비해 행렬 곱 XYT 는 밀도가 매우 높아서 이 알고리즘을 행렬 채우기Matrix Completion 알고리즘이라고 부를 때도 있다. 설사 값이 0인 원소가 있다 할지라도 매 우 드물게 나타나므로, 이 모델은 A의 근삿값일 뿐이다. 원래의 행렬 A에서 결측된(즉, 값이 0 인) 많은 원소에 대한 값조차도 생성한다는(채워준다는) 점에서 행렬 분해는 하나의 모델이라 할 수 있다. 다행히도 선형대수학이 직관과 아주 잘 들어맞는다. 이 두 행렬은 각 사용자와 각 아티스트를 하나씩의 행으로 담고 있다. 이 행들은 매우 작은 수(k개)의 값만을 가진다. 그리고 각 값은 모 델에서 잠재특징Latent Feature에 대응한다. 그래서 행들은 사용자와 아티스트가, 아마도 취향이나 장르에 대응하리라 추측되는 이들 잠재 특징과 얼마나 밀접하게 관련되는지를 표시하게 된다. 그리고 간단히 사용자-특징 행렬과 특징-아티스트 행렬을 곱하는 것으로 사용자-아티스트 상호작용 밀집 행렬 전체의 근사치를 얻을 수 있다. 이 행렬 곱은 아이템을 아이템 속성들에 대 응시킨 뒤 사용자 속성들을 가중치로 준 것으로 생각할 수 있다. 안타까운 점은 A를 완벽하게 표현하기에는 X와 Y가 충분히 크지 않아(선형대수학에서는 계수 Rank가 너무 작다고 기술한다. https://goo.gl/49ymAa) 일반적으로 정확하게 A = XYT 를 만족 하는 해를 구할 수 없다는 것이다. 하지만 알고 보면 나쁘지 않다. A는 발생할 수 있는 모든 상
  • 40.
    76 9가지 사례로익히는 고급 스파크 분석 (2판) 호작용 중 아주 작은 표본일 뿐이다. 우리는 A 행렬의 정보가 매우 드문드문 존재해서 (단지 몇 가지 작은 k개의 요인으로 잘 설명되는) 훨씬 간단한 감춰진 진실의 모습을 설명하기 힘든 것으로 생각한다. 고양이 그림의 직소 퍼즐을 생각해보자. 완성된 퍼즐을 보고 고양이라고 설 명하기는 아주 쉬워도, 조각 몇 개만 쥐고 있다면 이것이 어떤 그림이라고 설명하기란 매우 어 렵다. XYT 은 여전히 A에 가능한 한 가까워야 한다. 어쨌든 이것이 우리가 해야 할 일이다. 정확하게 구하지는 못할 것이고 또 구할 수도 없다. 설상가상으로, X와 Y의 가장 좋은 답을 동시에 직접 적으로 구할 수조차 없다. 그나마 나은 소식은 Y를 알고 있을 때는 X의 정답을 구할 수 있음이 자명하고, 그 반대도 마찬가지라는 것이다. 뭐, 아직은 둘 다 모르는 상태지만! 다행히 이런 딜레마를 극복하고 제대로 된 해를 찾아주는 알고리즘이 있다. 더 구체적으로 설 명하면, 이 장의 예제에서는 X와 Y를 계산하기 위해 교차 최소 제곱Alternating Least Squares (ALS, https://goo.gl/hPoZq5) 알고리즘을 사용할 것이다. 이런 종류의 접근법은 넷플릭스 프라이즈 Netflix Prize (https://goo.gl/EtIzYO)가 열리던 시절에 발표된 「암묵적 피드백 데이터셋에 대한 협 업 필터링Collaborative Filtering for Implicit Feedback Datasets」 (https://goo.gl/8WZqmk)과 「넷플릭스 프라이 즈를 위한 대규모의 병렬 협업 필터링Large-scale Parallel Collaborative Filtering for the Netflix Prize」(https://goo. gl/tG99s9) 같은 논문 덕에 유명해졌다. 사실 스파크의 MLlib이 제공하는 ALS 알고리즘도 이 논문들에서 아이디어를 가져와 구현한 것이다. Y의 값을 모르지만, 무작위로 값이 선택된 행 벡터로 초기화할 수는 있다. 그런 다음 간단한 선 형대수를 통해 주어진 A와 Y에 대한 최적 X를 구할 수 있다. 사실, X의 각 행 i는 Y와 A의 한 행의 함수로 독립적으로 쉽게 계산할 수 있다. 독립적으로 수행할 수 있으니 병렬 처리가 가능 하며, 이는 대규모로 계산할 때 매우 훌륭한 장점이다. AiY(YT Y )-1 = Xi 이 수식의 양 변을 똑같이 만들기란 불가능하므로, 우리의 목표는 양 변의 차이인 |AiY (YT Y )-1 - Xi|, 즉 두 행렬에서 대응되는 원소 간 차의 제곱의 합을 최소화하는 것이다. 여기서 최소 제곱Least Squares이라는 이름이 유래되었다. 실전에서는 역행렬을 구하는 방법으로 계산하지 않고 QR 분해QR Decomposition (https://goo.gl/OvtPVU)와 같은 방법으로 더 빠르게 바 로 계산할 수 있다. 앞의 식은 단순히 행 벡터가 어떻게 계산되는지의 이론을 설명하기 위한 것
  • 41.
    1014장 의사 결정나무로 산림 식생 분포 예측하기 “예측은 매우 어려우며, 미래에 대해서는 특히 그렇다.” -닐스 보어 19세기 후반 영국의 우생학자 프랜시스 골턴 경Sir Francis Galton은 완두콩과 사람 등을 대상으로 그 키를 측정하는 데 집중했다. 그는 키가 큰 완두콩과 사람의 다음 세대 역시 평균보다 크다는 사 실을 발견했다. 놀라운 발견이라고 할 수는 없다. 하지만 자식 세대는 평균적으로 부모보다 조 금 작았다. 키가 2미터에 달하는 야구 선수의 자식은 물론 평균보다는 크겠지만, 그렇다고 2미 터까지 크지는 않는다는 뜻이다. 이 연구의 뜻하지 않은 결과 덕분에 골턴 경은 부모 세대의 키와 비교하여 자식 세대의 키를 정 리해보았고 둘 사이에 대략적인 선형 관계가 있음을 알아냈다. 큰 부모 완두콩은 큰 자식 완두 콩으로 이어졌지만, 부모보다는 조금 작았다. 작은 부모 완두콩도 작은 자식 완두콩으로 이어 지지만, 역시 부모보다는 조금 컸다. 이 선형 관계에서 직선의 기울기는 1보다 작은 양수였고, 골턴 경은 이 현상을 평균으로의 회귀Regression to the Mean라고 표현했다. 오늘날 우리도 이 표현을 사 용한다. 당시에는 인지하지 못했을지언정, 이 선형 관계는 예측 모델의 오래된 예로 보인다. 두 값을 연 결한 선이 있다는 것은 하나의 값이 다른 값에 대해 많은 것을 시사할 수 있음을 의미한다. 어 떤 완두콩의 자식의 크기는 그 완두콩과 비슷하리라고 가정하는 것보다 이 관계를 이용하여 그 크기를 계산하는 쪽이 훨씬 정확할 것이다. 의사 결정 나무로 산림 식생 분포 예측하기 CHAPTER 4 션 오언
  • 42.
    102 9가지 사례로익히는 고급 스파크 분석 (2판) 4.1 회귀로 돌아와서 통계학이 체계를 갖춘 지 한 세기 이상이 지나고 머신러닝과 데이터 과학이 등장한 오늘날에 도, 주어진 값들로부터 새로운 값을 예측하는 방법으로 ‘회귀(https://goo.gl/yFA7xy)’를 꼽는 다. 심지어 값이 평균에 가까워지거나 실제로 가까워지려는 움직임조차 없을지라도 말이다. 또 한, 회귀 기법은 분류 기법과 연관이 있다(https://goo.gl/Tq7xfG). 일반적으로 회귀는 크기, 수입, 온도와 같은 숫자를 예측하며, 분류는 ‘스팸 메일’, ‘고양이 사진’과 같은 레이블이나 범주 를 예측하는 데 사용한다. 회귀와 분류는 모두 하나 이상의 값이 주어졌을 때 하나 이상의 값을 예측해낸다. 이를 위해서 학습을 위한 입출력 체계가 구성되어 있어야 하며, 질문과 이에 대한 답변도 제공되어야 한다. 이러한 탓에 회귀와 분류는 지도 학습Supervised Learning (https://goo.gl/ktFn24) 유형에 들어간다. 분류와 회귀는 가장 오래되고 가장 잘 연구된 유형의 예측 분석이다. 서포트 벡터 머신Support Vector Machine, 로지스틱 회귀Logistic Regression, 나이브 베이즈 분류Naïve Bayes, 신경망Neural Network, 딥러 닝Deep Learning과 같은 분석 패키지나 라이브러리에서 자주 접하는 대부분의 알고리즘은 분류와 회귀 기법이다. 3장의 주제인 추천 엔진도 더 직관적이라는 이유로 앞 장의 주제로 사용했지 만, 역시 비교적 최근에 따로 떨어져나온 머신러닝의 하위 주제일 뿐이다. 이번 장에서는 분류와 회귀 모두에 적용할 수 있는 대중적이고 유연한 알고리즘인 의사 결정 나무(https://goo.gl/CT9gWE), 그리고 이 알고리즘의 확장판인 랜덤 포레스트(https://goo. gl/fC83b1)를 다루고자 한다. 이 알고리즘과 관련한 흥미로운 사실은 닐스 보어가 미래 예측 에 대해서 말한 것과 달리 미래 예측에 사용할 수 있으며, 적어도 아직은 우리가 명확히 알지 못하는 것을 예측할 수 있다는 것이다. 예를 들어 온라인에서의 행동 양식으로부터 자동차를 살 가능성을 예측한다든지, 이메일 본문의 어떤 단어로부터 그 이메일이 스팸인지 여부를 찾아 낸다든지, 위치와 토양의 화학성분비가 주어졌을 때 어느 부분의 땅이 작물을 가장 잘 키워낼 지와 같은 것이다. 4.2 벡터와 특징 특정 데이터셋과 알고리즘을 선택하는 방법, 그리고 회귀와 분류가 동작하는 방법을 설명하려
  • 43.
    1034장 의사 결정나무로 산림 식생 분포 예측하기 면 우선 입력과 출력을 나타내는 용어들을 간단하게 정의해둬야 한다. 오늘의 날씨를 전제로 내일 최고 기온을 예측하는 문제를 생각해보자. 별문제 없어 보이지만, 그저 ‘오늘의 날씨’라고 하면 너무 광범위한 개념이라 학습 데이터로 사용하려면 구조화해야 한다. 오늘 날씨의 다음과 같은 특징Feature으로부터 내일 기온을 예측할 수 있다. ● ‌‌‌오늘의 최고 기온 ● ‌‌‌오늘의 최저 기온 ● ‌‌‌오늘의 습도 ● ‌‌‌흐림(cloudy), 비(rainy), 맑음(clear)과 같은 날씨 유형 ● ‌‌‌내일 일시적 한파를 예상한 기상 예보관의 수 이 특징들은 종종 차원Dimension, 예측 변수Predictor 또는 단순히 변수Variable로 불린다. 각각의 특징 은 정량화될 수 있다. 예를 들어 최고 기온과 최저 기온은 섭씨온도로 측정하고, 습도는 0과 1 사이의 소수로 계량하고, 날씨 유형은 ‘cloudy’, ‘rainy’, ‘clear’로 표시할 수 있다. 물론 예보관 의 수는 정수다. 이에 따라 오늘의 날씨는 ‘13.1, 19.0, 0.73, cloudy, 1’과 같은 하나의 리스 트로 축약할 수 있다. 이 다섯 특징을 순서대로 묶어 특징 벡터Feature Vector라 하고, 어떤 날의 날씨를 표현할 수 있다. 이 벡터에 숫자형이 아닌 값이 포함될 수 있고, 또 어떤 값은 생략될 수도 있다는 점만 제외하면 선형대수에서의 벡터 사용법과 비슷하다. 이들 특징은 모두 형식이 제각각이다. 앞의 둘은 섭씨온도로 측정한 값이지만, 세 번째는 단위 가 없는 비율이다. 네 번째는 아예 수가 아니고, 다섯 번째는 음이 아닌 정수다. 논하는 바의 목적에 맞춰 이 책에서는 범주형 특징Categorical Feature과 수치형 특징Numeric Feature 두 종류 의 특징에 대해서만 다룰 것이다. 여기서 수치형 특징은 수를 사용해 정량화할 수 있고 순서가 의미가 있다. 예를 들어 오늘의 최고 기온인 23도가 어제 최고 기온인 22도보다 높다고 이야기 하는 것은 유효하다. 날씨 유형을 제외한 모든 특징은 수다. ‘clear’와 같은 용어는 수도 아니고 순서도 없다. 그래서 ‘cloudy’가 ‘clear’보다 크다고 말하는 것은 의미가 없다. 이는 범주형 특 징에 해당하며, 여러 불연속Discrete 값 중 하나를 취하게 된다.
  • 44.
    104 9가지 사례로익히는 고급 스파크 분석 (2판) 4.3 학습 예제 예측을 수행하려면 먼저 학습 알고리즘을 데이터로 학습시켜야 한다. 이를 위해 과거 데이터 로부터 얻은 많은 수의 입력 데이터와 그 각각에 대응하는 정확한 출력 데이터가 필요하다. 다 시 오늘의 날씨를 예로 들자면, 어느 날 기온은 최저 12도, 최고 16도이며, 습도는 10%에 날씨 는 맑고, 아무도 한파를 예상하지 않았다는 그 날의 날씨 정보가 입력 데이터가 되고, 다음 날 의 최고 기온인 17.2도가 출력 데이터가 된다. 이 둘을 동시에 학습 알고리즘에 제공하는 형태 로 학습이 이뤄진다. 이러한 예제 데이터가 충분히 많이 있어야 다음 날의 최고 기온을 예측하 는 학습 알고리즘을 제대로 학습시킬 수 있다. 특징 벡터는 학습 알고리즘용 입력을 표현하는 체계적인 방법을 제공한다. 여기에서는 {12.5, 15.5, 0.10, clear, 0}이 된다. 예측의 출력이나 목표Target 또한 특징으로 간주할 수 있는데, 예 를 들어 내일 최고 기온 17.2는 수치형 특징이다. 입력용 특징 벡터에 목표를 하나의 특징으로 포함시키는 것은 드문 일이 아니다. 학습을 위한 완전한 예는 목표인 다음 날의 최고 기온까지 포함한 {12.5, 15.5, 0.10, clear, 0, 17.2}로 봐야 하며, 이 예들의 집합을 학습 데이터셋Training Set이라고 한다. 회귀에서는 수를, 분류에서는 범주를 대상으로 삼는다는 점을 기억하자. 모든 회귀나 분류 알 고리즘이 범주형 특징을 다루거나 범주를 목적으로 할 수 있는 것은 아니다. 일부는 수치형 특 징으로만 제한된다. 4.4 의사 결정 나무와 랜덤 포레스트 의사 결정 나무Decision Tree에 속하는 알고리즘은 범주형 특징과 수치형 특징 모두를 자연스럽게 다 룰 수 있다. 단일 트리와 다중 트리 모두 병렬로 바로 구축할 수도 있다. 의사 결정 나무는 데이 터 내의 이상치Outlier에 잘 휘둘리지 않는다는 특성이 있는데, 몇몇 극단적인 오류를 내포한 값 들이 예측치에 영향을 줄 수 없음을 뜻한다. 그리고 전처리나 정규화 과정을 거치지 않고도 다 른 유형과 다른 척도의 데이터를 다룰 수 있다(이 내용은 5장에서 다시 소개할 것이다). 의사 결정 나무를 더 강력하게 일반화한 알고리즘이 랜덤 포레스트Random Decision Forest다. 이 장에서 는 스파크 MLlib이 제공하는 DecisionTree와 RandomForest를 데이터셋에 적용해서 이들
  • 45.
    1054장 의사 결정나무로 산림 식생 분포 예측하기 알고리즘의 유연함을 살펴볼 것이다. 의사 결정 나무 기반의 알고리즘은 직관적으로 이해할 수 있고 추론할 수 있다는 게 장점이다. 실제로 누구나 의사 결정 나무에 내재된 방식과 똑같은 추론을 일상에서 사용하리라 생각한다. 예를 들어 나는 모닝커피에 우유를 섞어 마시는데, 우유를 붓기 전에 ‘우유가 상했는지’를 예측 해보고 싶다. 확신이 없다면 유통기한이 지났는지를 확인한다. 유통기한이 지나지 않았다면 상 하지 않은 것으로 예측한다. 유통기한이 지났더라도 사흘이 넘지 않았다면 상하지 않은 것으로 예측하고, 사흘이 넘었다면 냄새를 맡아봐서 그 냄새가 이상하면 상한 것, 그렇지 않다면 상하 지 않은 것으로 예측한다. 예측으로 이어지는 일련의 예/아니오 선택이 의사 결정 나무에 내재된 추론 방식이다. 각각의 결정으로 두 결과 중 하나로 넘어가는데, [그림 4-1]에서 볼 수 있듯, 최종 결과일 수도 있고 또 다른 결정의 순간일 수도 있다. 이런 의미에서 이 프로세스는 각각의 결정을 내부 노드로, 최종 해답을 말단 노드로 가지는 트리 구조로 간주할 수 있다. 그림 4-1 의사 결정 나무 : 우유가 상했나? 이런 규칙은 어린 시절 수년에 걸쳐 직관적으로 습득해 적용해온 것으로, 상한 우유와 상하지 않은 우유를 구분하는 간단하면서도 쓸만한 규칙이자, 의사 결정 나무의 성격을 보여주는 좋은
  • 46.
    106 9가지 사례로익히는 고급 스파크 분석 (2판) 예다. 이것은 단순화한 의사 결정 나무로, 정밀하게 만들어지지는 않았다. 더 자세히 알아보기 위해 다른 예를 생각해보자. 로봇이 이색 애완동물 가게에서 일하고 있다. 로봇은 가게 문을 열기 전 에 어떤 동물이 아이에게 적절한지를 배우고 싶어 한다. 가게 주인은 서둘러 애완동물 아홉 마 리 각각이 아이에게 적절한지를 기록한 목록인 [표 4-1]을 작성한다. 이제 로봇은 애완동물을 조사하면서 [표 4-1]의 정보와 조합한다. 표 4-1 이색 애완동물 상점 ‘특징 벡터’ 이름 무게(Kg) 다리의 수 색 아이에게 적절한가? 초코 20.5 4 갈색 적절 콩이 3.1 0 녹색 부적절 호야 0.2 0 구릿빛 적절 치즈 1390.8 4 회색 부적절 나비 12.1 4 회색 적절 다롱이 150.9 2 구릿빛 부적절 은띵이 0.1 100 갈색 부적절 꾸꾸 1.0 2 회색 부적절 루비 10.0 4 갈색 적절 이름은 특징에 포함되지 않는다. ‘루비’라는 이름은 고양이한테도, 독거미한테도 붙일 수 있으 니 이름만으로 무엇인가를 예측할 수 있으리라 생각할만한 근거가 없기 때문이다. 그렇다면 수 치형 특징 두 개(무게와 다리의 수)와 범주형 특징 하나(색)가 남는다. 그리고 이 특징들로 예측할 범주인 “아이에게 적절한가?”가 있다. 처음에는 [그림 4-2]처럼 무 게를 유일한 판단 기준으로 삼는 간단한 의사 결정 나무를 이 데이터셋에 적합시켜보자.
  • 47.
    1355장 K-평균 군집화로네트워크 이상 탐지하기 “알고 있음이 알려진 것들이 있다. 즉, 우리가 알고 있음을 우리가 아는 것들이 있다. 또, 모르고 있음이 알려진 것들이 있다. 다시 말해서, 우리가 모르는 어떤 것들이 있음을 우리는 알고 있다. 그러나 역시 모르고 있음이 알려지지 않은 것들, 즉 우리가 모르고 있는지도 모르는 것들도 있다.” -도널드 럼즈펠드 분류와 회귀는 강력하고 깊이 연구된 머신러닝 기술이다. 4장에서는 모르는 값들을 예측하 는 데 쓰이는 분류기를 다루었다. 그러나 문제가 하나 있었다. 새로운 데이터에 대한 모르는 값들을 예측하려면 사전에 관측한 많은 사례의 목푯값들을 알고 있어야 했다. 분류기는 우 리 데이터 과학자가 찾고 있는 것이 무엇인지 이미 알고 있고, 입력과 그에 따른 결과가 알 려진 사례가 확보되었을 때만 도움이 될 수 있다. 학습 과정에서 사례별 정확한 결괏값을 입 력으로 받아들이기 때문에 이런 종류의 방법을 지도 학습이라 한다. 하지만 일부 또는 전체 사례의 정확한 결괏값을 알 수 없을 때도 종종 있다. 전자상거래 사이트 고객들을 쇼핑 습관이나 취향별로 분류하는 문제를 생각해보자. 입력 특징에는 구매 이력, 클 릭 정보, 인구통계학적 정보 등이 있다. 출력은 고객들을 나눈 집단들일 것이다. 아마도 어떤 집단은 유행에 민감한 구매자들을 나타낼 것이고, 또 다른 집단은 가격에 민감하며 싸고 질 좋 은 물건을 사려는 고객으로 밝혀질 것이고, 기타 등등의 집단이 있을 것이다. K-평균 군집화로 네트워크 이상 탐지하기 CHAPTER 5 션 오언
  • 48.
    136 9가지 사례로익히는 고급 스파크 분석 (2판) 새로운 고객이 가입할 때마다 그 고객이 어떤 목표 레이블Target Label에 해당하는지 결정해야 한 다면 분류기와 같은 지도 학습 기술은 곧 문제에 봉착하게 될 것이다. 누가 유행에 민감하다고 여겨야 할지에 대한 선험적 지식이 없기 때문이다. 사실 맨 처음에는 ‘유행에 민감함’이란 기준 이 사이트 고객을 의미 있게 군집화하는지조차 확신할 수 없을 것이다. 다행히도 비지도 학습Unsupervised Learning (https://goo.gl/U7mBF4) 방법이 도움이 될 수 있다. 비 지도 학습에서는 이용할 수 있는 목푯값이 하나도 없기 때문에 목푯값을 예측하기 위한 학습을 하지 않는다. 그러나 이 방법은 데이터의 구조를 학습할 수 있고, 비슷한 입력들의 집단을 찾을 수 있고, 발생 가능성이 높은 입력과 그렇지 않은 입력의 종류를 학습할 수 있다. 이번 장에서 는 MLlib의 군집화 구현을 사용하여 비지도 학습을 소개할 것이다. 5.1 이상 탐지 이상 탐지Anomaly Detection는 그 이름이 암시하듯 특이한 것들을 찾아내는 문제다. 특정 데이터셋 에서 ‘이상한’이 뜻하는 바를 이미 알고 있다면 지도 학습 방법으로도 이상한 부분을 쉽게 찾아 낼 수 있을 것이다. 지도 학습 알고리즘은 ‘정상Normal’이나 ‘이상Anomaly’ 레이블이 붙은 입력을 받 아서 그 둘을 구분하도록 학습될 것이다. 하지만 이상한 것들의 본질은 ‘모르고 있음이 알려지 지 않은 것’이라는 데 있다. 다시 말해, 관측하고 이해할 수 있게 된 ‘이상’은 더 이상 ‘이상’이 아 닌 것이다. 이상 탐지는 사기Fraud를 찾거나 네트워크 공격을 탐지하거나 서버의 문제점 또는 센서를 갖춘 설비의 문제점을 발견하는 데 주로 사용한다. 이런 경우에는 새로운 형태의 사기, 새로운 침입, 새로운 서버 장애 유형 등 지금까지 겪어보지 못한 새로운 종류의 이상을 찾아내는 능력이 중 요하다. 비지도 학습 기법은 이럴 때 유용하다. 왜냐하면, 비지도 학습 기법은 입력 데이터의 정상적인 형태를 학습해가며 새로운 데이터가 과거 데이터와 비슷하지 않을 때 이를 감지할 수 있기 때 문이다. 과거와 다른 새로움이 반드시 공격이나 사기인 것은 아니다. 하지만 단지 특이하다는 이유만으로도 더 조사해볼 가치가 있다.
  • 49.
    1375장 K-평균 군집화로네트워크 이상 탐지하기 5.2 K-평균 군집화 군집화는 가장 잘 알려진 비지도 학습 방법이다. 군집화 알고리즘은 데이터를 자연스럽게 군집 (집단)으로 묶는 것을 목적으로 한다. 데이터 포인트들 중 서로 비슷하지만 그 외의 것들과는 차이가 나는 것들이 의미 있는 군집일 가능성이 높으므로, 군집화 알고리즘은 이런 데이터끼리 같은 군집으로 묶기 위해 노력한다. K-평균 군집화K-means Clustering (https://goo.gl/AGqJ4n)는 가장 널리 사용되는 군집화 알고리 즘일 것이다. 이 알고리즘은 데이터셋에서 k개의 군집을 찾으려 시도하며, 여기서 k는 데이터 과학자가 정한다. k는 해당 모델의 하이퍼파라미터이고, 적절한 값은 데이터셋에 따라 다를 것 이다. 사실 좋은 k 값을 선정하는 것이 이번 장의 핵심이다. 고객의 행위와 같은 정보를 포함한 데이터셋에서 ‘비슷하다’는 말은 무슨 의미일까? 또 트랜 잭션과 같은 데이터셋에서는 어떠한가? 이 의미를 측량하기 위해 데이터 포인트 간 거리라는 개념이 필요한데, K-평균 알고리즘에서는 이 거리를 측정할 때 간단한 유클리드 거리Euclidean Distance를 가장 널리 사용하며, 이 책을 쓰는 시점에 MLlib이 유일하게 지원하는 거리 함수이기 도 하다. 유클리드 거리는 특징들이 모두 숫자인 데이터에서 사용할 수 있다. 데이터 포인트들 이 ‘비슷하다’는 것은 둘 사이의 유클리드 거리가 가깝다는 뜻이다. K-평균 알고리즘에서 군집은 그 군집을 이루는 모든 요소 점들의 중심을 나타내는 하나의 점 에 지나지 않는다. 사실 요소 점들은 모두 숫자로 이뤄진 특징 벡터일 뿐이며, 간단히 벡터라고 부를 수 있다. 하지만 여기서는 점으로 생각하는 게 더 직관적일 수 있다. 이들은 유클리드 공 간Euclidean Space에서는 점으로 취급하기 때문이다. 군집의 한가운데를 군집 중심Centroid이라 하며, 군집 내의 점들의 산술 평균에 해당한다. 그래서 K-평균이라고 부르는 것이다. 이 알고리즘은 우선 일부 데이터 포인트들을 초기 군집 중심으 로 선택한다. 그런 후에 모든 각각의 데이터 포인트는 가장 가까운 중심으로 할당된다. 그런 다 음에 군집별로 군집에 할당된 모든 데이터 포인트의 산술 평균을 구해서 새로운 군집 중심을 구한다. 이 과정이 반복된다. 이 알고리즘에 대해서는 당장은 이 정도면 충분하다. 더 흥미롭고 자세한 내용은 다음 활용 사 례에서 보게 될 것이다.
  • 50.
    138 9가지 사례로익히는 고급 스파크 분석 (2판) 5.3 네트워크 침입 뉴스를 보면 소위 사이버 공격이 점점 늘어나고 있다. 어떤 공격은 정상적인 네트워크 접근을 방해할 목적으로 대량의 네트워크 트래픽을 쏟아붓는다. 또 다른 공격은 네트워크 소프트웨어 의 취약점을 공격하여 승인되지 않은 권한을 확보하려고 시도한다. 트래픽을 이용한 공격은 매 우 명확한 상황인 데 비해, 익스플로잇Exploit이라고도 하는 취약점 공격을 감지하기란 네트워크 요청들의 거대한 건초 더미에서 바늘 찾기와 같을 수 있다. 몇몇 취약점 공격의 행동 패턴은 알려져 있다. 예를 들어 지속적으로 빠르게 모든 포트에 접근 해보는 일은 정상적인 소프트웨어가 할 만한 행동은 아니지만, 침입자라면 컴퓨터에서 악용할 만한 서비스를 찾기 위해서 맨 처음 하는 일반적인 행위다. 만약 짧은 시간에 원격 호스트가 서로 다른 포트에 접근한 횟수를 집계할 수 있다면 포트 스캐 닝 공격을 꽤 잘 예측할 수 있는 특징을 가진 것이다. 몇 건 정도는 아마도 정상이겠지만, 수백 건이 되면 공격일 것이다. 전송하고 수신한 바이트의 수, TCP 오류 등 네트워크 연결과 관련한 다른 특징도 동일한 방식을 활용해서 다른 종류의 침입을 탐지할 수도 있다. 하지만 알려지지 않은 미지의 패턴이라면 어떨까? 지금까지 한 번도 알려진 적이 없어서 분류 된 적도 없는 그런 공격이 가장 큰 위협일 수 있다. 잠재적 네트워크 침입을 찾아내는 일은 이 상 탐지에 해당한다. 이런 경우는 침입 행위로 알려져 있지는 않지만, 과거에 관측된 네트워크 연결들과는 양상이 다르다. 이상한 네트워크 연결을 찾아내는 데 K-평균과 같은 비지도 학습 기법을 사용할 수 있다. K- 평균 방법은 연결 각각에 대한 통계에 기반을 두어 연결들을 군집화할 수 있다. 결과로 나온 군 집들 자체에는 의미가 없다. 하지만 군집들은 전체적으로 과거의 연결들과 유사한 연결 유형들 을 정의하고 있다. 어떤 군집에도 속하지 않은 연결은 이상한 연결일 수 있다. 군집들이 정상 연결들의 영역을 정의할 때 그 군집들은 의미를 가진다. 그 범위 밖의 모든 연결은 특이하며 잠 재적으로 이상한 연결이다.
  • 51.
    1395장 K-평균 군집화로네트워크 이상 탐지하기 5.4 KDD 컵 1999 데이터셋 KDD 컵KDD Cup (http://www.kdd.org/)은 국제컴퓨터학회(ACM)의 특화 분야 분과에서 매 년 주최하던 데이터 마이닝 대회다. 해마다 하나의 머신러닝 문제가 데이터셋과 함께 출제되 며, 연구자들은 그 문제를 푸는 최선의 답을 상세히 기술한 논문을 제출한다. 캐글Kaggle (http:// www.kaggle.com/)이 열리기 전 시절, KDD 컵은 캐글과 비슷한 것이었다. 네트워크 침입을 주제로 한 1999년 대회의 데이터셋은 지금도 사용할 수 있다(http://bit.ly/1ALCuZN). 이번 장의 나머지 부분에서는 이 데이터를 학습하여 스파크를 사용한 이상 네트워크 트래픽 탐지 시 스템을 구축하는 방법을 보여주려 한다. NOTE_ 이 데이터셋을 실제 네트워크 침입 탐지 시스템을 구축하는 데 이용하지는 마라! 이 데이터가 그 당 시의 실제 네트워크 트래픽을 반영하는 것도 아니며, 혹 반영했더라도 17년도 더 전의 트래픽 패턴일 뿐이다. 다행히도 주최 측은 네트워크 패킷 원본을 개별 네트워크 연결에 관한 요약 정보 형태로 처리 해두었다. 데이터셋의 크기는 약 708MB이며 490만 개의 연결을 담고 있다. 방대하다고 말하 기는 그렇지만 제법 큰 데이터인데, 이 장에서 필요한 만큼은 된다. 데이터셋은 각 연결의 전송 된 바이트 수, 로그인 시도 횟수, TCP 에러 개수 등과 같은 정보를 담고 있다. 데이터의 한 줄이 연결 하나에 대응하며 다음과 같이 38개의 수치형 특징을 포함한 CSV 형식으로 만들어졌다.1 0,tcp,http,SF,215,45076, 0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,1, 0.00,0.00,0.00,0.00,1.00,0.00,0.00,0,0,0.00, 0.00,0.00,0.00,0.00,0.00,0.00,0.00,normal. 이 연결은 HTTP 서비스에 대한 TCP 연결로, 215바이트를 송신하고 45,706바이트를 수신했 다. 사용자는 로그인되어 있으며, 기타 다른 내용도 포함하고 있다. 많은 특징이 17번째 특징 인 num_file_creations와 같은 횟수 정보다.2 또 많은 특징이 15번째 특징인 su_attempted처럼 어떤 행위가 있음 혹은 없음을 나타내는 0 또는 1을 취한다. 4장에서 소개한 원-핫 인코딩을 사용해 범주형 특징을 수치형으로 다시 표 1 옮긴이_ 총 42개의 값 중 범주형 특징 3개와 레이블 1개를 빼서 38개다. 2 옮긴이_ 각 특징의 이름과 형태는 공개된 데이터셋의 kddcup.names 파일에 기록돼 있다. http://goo.gl/CBEZv5
  • 52.
    140 9가지 사례로익히는 고급 스파크 분석 (2판) 현한 것과 비슷해 보이지만, 사실 동일한 방법으로 묶거나 관련지은 것은 아니다. 이들은 예/ 아니오 특징 같은 것이고, 따라서 범주형 특징임에는 거의 틀림없다. 범주형 특징을 숫자로 바 꾸어 마치 순서가 있는 것처럼 취급하는 것이 항상 적절한 것은 아니지만, 이진Binary 범주형 특 징과 같이 특별한 경우에는 0과 1을 취하는 수치형 특징에 대응하더라도 대부분의 머신러닝 알 고리즘에서 잘 동작할 것이다. 끝에서 두 번째인 dst_host_srv_rerror_rate와 같이 나머지는 모두 비율을 나타내고 0.0~1.0 의 값을 가진다. 흥미롭게도 레이블은 마지막 필드로 제공된다. 대부분의 연결은 정상(normal.)이지만, 일부 는 다양한 유형의 네트워크 공격 사례로 기록되어 있다. 이를 이용하여 알려진 공격을 정상 연 결과 구분하도록 학습할 수 있다. 하지만 여기서 하려는 일은 이상을 탐지하여, 궁극적으로는 알려지지 않은 새로운 공격을 찾아내는 것이다. 레이블은 이런 목적과 맞지 않기 때문에 대부 분의 예제에서 사용하지 않는다. 5.5 첫 번째 군집화하기 kddcup.data.gz 파일의 압축을 풀고 HDFS로 복사하자. 다른 장과 마찬가지로 이 예제에 서도 파일이 /user/ds/ 디렉터리에 있다고 가정한다. spark-shell을 실행하고 다음과 같 이 CSV 데이터를 데이터프레임으로 읽어 들인다. CSV 파일이지만 헤더 정보가 없으므로 kddcup.names 파일에서 제공한 열 이름을 사용해야 한다. val dataWithoutHeader = spark.read. option(inferSchema, true). option(header, false). csv(hdfs:///user/ds/kddcup.data) val data = dataWithoutHeader.toDF( duration, protocol_type, service, flag, src_bytes, dst_bytes, land, wrong_fragment, urgent, hot, num_failed_logins, logged_in, num_compromised, root_shell, su_attempted, num_root, num_file_creations, num_shells, num_access_files, num_outbound_cmds, is_host_login, is_guest_login, count, srv_count,
  • 53.
    1616장 숨은 의미분석으로 위키백과 이해하기 “스노든의 무리는 작년에 어디 있었나?”1 -요사리안 대위 데이터 엔지니어링 과정의 대부분은 수집한 데이터를 질의가 가능한 형태로 가공하는 일이다. 테이블 형태로 구조화되어 있으면 SQL을 사용할 수 있듯, 데이터가 구조화되어 있으면 형식 언어로 질의할 수 있다. 높은 수준으로 구조화하는 일이 결코 쉬운 일은 아니지만, 데이터를 테 이블 형태로 만드는 일 자체는 간단할 수도 있다. 다양한 데이터 출처로부터 데이터를 가져다 가 테이블 하나에 쑤셔 넣은 다음, 정해진 방법에 따라 데이터를 정제하고 잘 합쳐내면 되는 일 이다. 구조화되지 않은 텍스트 데이터를 다루는 것은 완전히 다른 일이다. 사람이 가져다 쓸 수 있는 형태로 데이터를 준비하는 작업은 ‘조립Assembly’이라기 보다는 ‘색인 작업Indexing’에 가까운 데, 그나마도 ‘억지Coercion’스러운 작업이 되어버리곤 한다. 일반적으로 색인을 사용하면 주어진 단어들을 포함한 문서 집합을 빠르게 찾을 수 있다. 하지만 종종 정확한 문자열이 주어지지 않 더라도 특정 단어의 의미와 관련된 문서를 찾고자 할 때도 있는데, 표준적인 검색 색인에서는 주어진 텍스트의 ‘주제’와 관련한 숨어 있는 구조를 찾아내지 못할 때가 많다. 숨은 의미 분석Latent Semantic Analysis (LSA)은 문서 뭉치corpus의 이해를 돕고, 뭉치에 속한 문서 속 단 어들 사이의 관계를 찾는 자연어 처리Natural Language Processing (NLP) 및 정보 검색 기술이다. LSA 1 옮긴이_ 소설 『캐치-22』의 주인공인 요사리안 대위가 소설 중에서 던진, 답이 없는 질문이다. 숨은 의미 분석으로 위키백과 이해하기 CHAPTER 6 샌디 라이자
  • 54.
    162 9가지 사례로익히는 고급 스파크 분석 (2판) 는 뭉치들로부터 적절한 의미들의 집합을 뽑아낸다. 각각의 의미는 다양하게 변형되어 문서에 나타나는데, 그중에 해당 문서 뭉치가 다루는 주제에 부합되는 것이 있다. 수학적으로 접근하 기는 아직 이르지만, 모든 의미는 세 가지 속성을 갖는다. 첫째는 뭉치에 속한 각 문서가 가지 는 관련성의 정도, 둘째는 뭉치 내의 각 단어가 가지는 관련성의 정도, 셋째는 어떤 의미가 데 이터셋 내의 변형을 설명하는 데 얼마나 유용한가를 나타내는 중요도 점수다. 예를 들어 ‘아시 모프Asimov’와 ‘로봇Robot’이라는 단어 사이의 강한 연관성, 그리고 ​『파운데이션』 연작2 문서들과 과학 소설 문서들 사이의 강한 연관성에 LSA를 적용하면 (연관성이 지니는) 의미를 찾아낼 수 있을 것이다. LSA를 시행하면서 매우 중요한 의미들만 선택하면 관련성이 낮은 노이즈를 제거 하고 겹치는 부분을 합칠 수 있으며, 이를 통해서 데이터를 더 간단하게 표현할 수 있다. 이렇게 만들어진 간단한 표현을 다양한 작업에 적용할 수 있다. LSA로부터 단어와 단어 사이, 문서와 문서 사이, 그리고 단어와 문서 사이의 유사성 점수를 얻을 수 있다. 뭉치 안의 다양한 패턴을 잘 묶어내면, 단순히 특정 단어가 몇 번 나왔는지나 어떤 단어 조합이 함께 나온 게 몇 번인지를 세는 것보다 유사성 점수가 그 문서를 이해하는 데 더 도움이 될 것이다. 이러한 유사 성 척도는 특정 단어와 연관된 문서 찾기, 주제가 같은 문서끼리 묶기, 그리고 관련 단어 찾기 등과 같은 작업에 알맞은 방법이다. LSA는 특잇값 분해(SVD)라는 선형대수 기법을 활용하여 이러한 더 낮은 차원의 표현 방법을 찾아낸다. 특잇값 분해는 3장에서 본 ALS 분해의 더 강력한 버전으로 생각하면 된다. 먼저, 각 문서에 특정 단어가 나온 횟수를 세어 문서-단어 행렬Document-term Matrix을 만든다. 이 행렬에서 문 서는 각각의 행에, 단어는 각각의 열에 대응하며, 행렬의 원소는 특정 문서에 있어서 특정 단 어의 중요도를 나타낸다. 그런 다음 특잇값 분해를 적용하여 이 행렬을 세 개의 행렬로 분해한 다. 하나는 문서들과 관련된 의미들을 표현한 행렬, 다른 하나는 단어들과 관련된 의미들을 표 현한 행렬, 마지막 하나는 각 의미의 중요도를 담고 있는 행렬이다. 이런 구조를 가진 3개의 행렬에서 중요도가 낮은 의미에 대응하는 행과 열을 제거하여 원 행렬의 낮은 계수 근사Low-rank Approximation를 만들 수 있다. 각각의 행렬에서 행과 열을 제거한 후 다시 곱하면 원래 행렬의 근 사 행렬이 만들어지는데, 의미가 하나씩 제거될 때마다 근사의 정확성은 점점 떨어지게 된다. 이 장에서는 숨은 의미의 관계에 근거하여 인간 지식의 전 범위를 아우르는 질의를 가능하게 2 옮긴이_ 아이작 아시모프는 ‘로봇 3원칙’으로 유명한, 작고한 SF 소설가이며 ‘파운데이션(Foundation)’은 그의 연작 과학 소설의 제목 이다.
  • 55.
    1636장 숨은 의미분석으로 위키백과 이해하기 하는 소소한 작업에 착수하려 한다. 구체적으로 말하자면, 원문 텍스트 기준으로 약 46GB3 에 달하는 위키백과에 포함된 모든 문서로 구성된 문서 뭉치에 LSA를 적용할 것이다. 이 데이터 를 읽고, 정제하고, 수치 형태로 개조하는 데이터 전처리 과정에 스파크를 활용하는 방법을 다 루려 한다. 또, 특잇값 분해를 계산하는 방법과 이것을 어떻게 해석하고 활용해야 하는지를 보 여줄 것이다. 특잇값 분해는 LSA 외에도 폭넓게 활용되고 있다. 기후 변화 추세 파악(마이클 만의 유명한 하키 스틱 그래프 참고, https://goo.gl/MzbT56), 얼굴 인식, 이미지 압축과 같은 다양한 곳에 사용된다. 스파크는 엄청나게 커다란 데이터셋도 행렬분해할 수 있어서 또 다른 새로운 분야에 도 기술의 이기를 전파할 수 있을 것이다. 6.1 문서-단어 행렬 분석에 들어가기 전에, 문서 뭉치 내의 원문에서 LSA에 사용할 문서-단어 행렬을 만들어야 한 다. 이 행렬의 각 열은 문서 뭉치에서 등장하는 하나의 단어를 나타내고, 각 행은 하나의 문서 를 나타낸다. 대략, 행과 열이 만나는 지점의 값은 어떤 문서에 있어서 어떤 단어의 중요도에 대응되어야 한다. 중요도를 계산하는 방법이 몇 가지 있지만, 가장 널리 쓰이는 것은 단어 빈도 Term Frequency (TF)와 역문서 빈도Inverse Document Frequency (IDF)를 곱하는 방법이고, 줄여서 TF-IDF 라고 한다. 다음은 이를 구하는 스칼라 코드다. 하지만 스파크에서는 이를 계산하는 기능을 별 도로 제공하므로 이 코드를 사용하지는 않을 것이다. def termDocWeight(termFrequencyInDoc: Int, totalTermsInDoc: Int, termFreqInCorpus: Int, totalDocs: Int): Double = { val tf = termFrequencyInDoc.toDouble / totalTermsInDoc val docFreq = totalDocs.toDouble / termFreqInCorpus val idf = math.log(docFreq) tf * idf } TF-IDF는 문서를 적절하게 설명할 수 있는 단어에 대한 두 가지 직관을 담아내고 있다. 첫 번 3 옮긴이_ 이 책의 1판이 집필되던 때의 크기다.
  • 56.
    164 9가지 사례로익히는 고급 스파크 분석 (2판) 째 직관은 특정 문서에 어떤 단어가 많이 나올수록 그 문서에서 그 단어는 더욱 중요하다는 것 이다. 두 번째 직관은 전역적으로 볼 때 모든 단어의 가치가 똑같지는 않다는 것이다. 약방의 감초같이 항상 등장하는 단어보다 문서 뭉치의 다른 문서에는 잘 쓰이지 않는 단어가 등장하는 쪽이 더 의미가 있다. 그래서 뭉치의 전체 문서에서 단어가 출현하는 빈도의 역Inverse을 사용하 자는 것이다. 문서 뭉치에서 단어들의 출현 빈도는 기하급수적인 차이를 보인다. 흔히 쓰이는 단어들은 덜 흔한 단어들보다 수십 배 더 자주 등장하지만, 이러한 덜 흔한 단어들조차 드문드문 사용되는 단어들에 비하면 수십, 수천 배 더 자주 등장한다. 이 때문에 단순히 역문서 빈도를 그대로 사 용하면 드문드문 사용되는 단어들에 어마어마하게 큰 가중치를 부여해서 다른 모든 단어의 영 향력이 무시되는 문제가 생긴다. 그래서 실전에서는 역문서 빈도의 로그 값을 사용한다. 로그 값을 사용하면 곱의 차를 합의 차로 바꾸어서, 빈도로부터 오는 격차를 완화한다. 모델을 만들려면 몇 가지 가정이 필요하다. 문서를 ‘단어들의 가방’으로 생각하자. 이는 어순이 나 문장 구조, 또는 부정을 나타내는 꾸밈말 같은 것은 무시하겠다는 것이다. 또 각각의 단어는 한 가지 의미만을 가지며, 다의어多義語는 다루지 않는다. 예를 들어 이 모델에서는 “라디오헤드 는 역대 최고의 밴드다”에서의 밴드와 “고무 밴드가 끊어졌어”에서의 밴드의 차이를 구분하지 않겠다는 뜻이다. 만약 두 문장이 한 문서 뭉치에서 자주 등장하면 고무와 라디오헤드가 연결 된다. 우리가 사용할 문서 뭉치에는 천만 개의 문서가 포함되어 있다. 잘 알려지지 않은 기술 용어까 지 포함하면 영어 단어는 약 백만 개에 달하는데, 이 중 일부인 수만 개 정도면 문서 뭉치를 이 해하는 데 유용하지 않을까 한다. 단어의 수에 비해서 문서의 수가 훨씬 많으니, 문서-단어 행 렬을 각각이 하나의 문서에 대응하는 희소 벡터Sparse Vector들의 집합인 행 행렬Row Matrix 형태로 만 드는 것이 타당하다. 위키백과를 덤프한 원문은 하나의 커다란 XML 파일로, 그 안에 각 문서가 page 태그로 구 분되어 있다. 이를 문서-단어 행렬 형태로 바꾸는 전처리 과정은 다음과 같다. 먼저 이 XML 파일을 문서 단위로 쪼개고, 각 문서에서 위키 특화 태그를 제거해 플레인 텍스트 파일로 바 꿔야 한다. 그 다음, 이 플레인 텍스트 파일을 토큰으로 나눈다. 이때 여러 가지 형태4 로 표기 된 단어를 기본형으로 바꾸어 전체 토큰의 가짓수를 줄이는 과정을 거친다. 이 과정을 표제 4 옮긴이_ 복수형이나 과거 분사 등
  • 57.
    1656장 숨은 의미분석으로 위키백과 이해하기 어 추출이라고 한다. 그러고 나면 이 토큰을 대상으로 문서 빈도와 단어 빈도를 계산하여, 최 종적으로 실제 벡터 객체를 만들게 된다. 이 책에서 제공하는 깃허브 저장소에는 이 내용이 AssembleDocumentTermMatrix 클래스에 추상화되어 있다. 이 과정의 앞부분은 각각의 문서를 완전히 병렬로 처리할 수 있지만(스파크에서는 처리 과정 이 맵 함수들로 구성된다는 의미다), 역문서 빈도를 계산할 때는 모든 문서를 대상으로 집계해 야 한다. 몇몇 유용한 범용 자연어 처리 도구와 위키백과에 특화된 추출 도구들을 사용하면 도 움이 된다. 6.2 데이터 구하기 위키백과는 문서를 덤프하는 기능을 제공한다. 다음과 같이 http://dumps.wikimedia.org/ enwiki에 들어 있는 문서들을 하나의 커다란 XML 파일 형태로 덤프하여 HDFS에 저장한다.5 $ curl -s -L https://dumps.wikimedia.org/enwiki/latest/ $ enwiki-latest-pages-articles-multistream.xml.bz2 $ | bzip2 -cd $ | hadoop fs -put - wikidump.xml 이와 같이 많은 양의 데이터를 처리하는 데는 복수 개의 노드를 가진 클러스터로 작업하는 것 이 바람직하다. 이 장의 코드를 로컬 PC에서 실행하려면 위키백과 내보내기 페이지(https:// en.wikipedia.org/wiki/Special:Export)를 통해서 작은 덤프 파일을 만들어 사용하는 것이 좋다. ‘Megafauna’(대형 동물군)나 ‘Geometry’(기하학)와 같이 페이지 수는 많은데 하위 카테고리는 적은 카테고리를 덤프해 사용해보자. 이렇게 만든 덤프 파일을 이후에 이어지는 코 드에 사용하려면, 파일을 디렉터리에 복사하고 파일 이름을 wikidump.xml로 바꾸면 된다.6 5 옮긴이_ 코드의 위키백과 덤프 주소는 위키 덤프 상황에 따라 유효하지 않는 시점이 종종 있다. 이 경우 https://dumps.wikimedia.org/ enwiki/latest/ 에서 적당한 파일을 선택해서 저장하면 된다. 6 옮긴이_ Geometry 카테고리를 선택하였다면 이어지는 예제에서 단어와 관련된 질의어로 ‘minkowski’(민코프스키)를 사용해보자. 러 시아의 수학자인데, 민코프스키 공간 등 그와 관련된 다양한 주제가 Geometry 카테고리 내의 문서에 녹아 있다. 문서 관련 질의는 민코 프스키와 관련해서 나오는 문서 중 하나를 골라서 질의해보자.
  • 58.
    166 9가지 사례로익히는 고급 스파크 분석 (2판) 6.3 파싱하여 데이터 준비하기 덤프 파일의 앞부분은 다음과 같은 모양이다. page titleAnarchism/title ns0/ns id12/id revision id584215651/id parentid584213644/parentid timestamp2013-12-02T15:14:01Z/timestamp contributor usernameAnomieBOT/username id7611264/id /contributor commentRescuing orphaned refs (quot;autogenerated1quot; from rev 584155010; quot;bbcquot; from rev 584155010)/comment text xml:space=preserve{{Redirect|Anarchist|the fictional character| Anarchist (comics)}} {{Redirect|Anarchists}} {{pp-move-indef}} {{Anarchism sidebar}} '''Anarchism''' is a [[political philosophy]] that advocates [[stateless society| stateless societies]] often defined as [[self-governance|self-governed]] voluntary institutions,lt;refgt;quot;ANARCHISM, a social philosophy that rejects authoritarian government and maintains that voluntary institutions are best suited to express man's natural social tendencies.quot; George Woodcock. quot;Anarchismquot; at The Encyclopedia of Philosophylt;/refgt;lt;refgt; quot;In a society developed on these lines, the voluntary associations which already now begin to cover all the fields of human activity would take a still greater extension so as to substitute ... 스파크 셸을 시작해보자. 이 장에서는 작업을 좀 더 쉽게 만들어주는 몇몇 라이브러리를 활용 할 것이다. 의존하는 라이브러리들을 모두 포함한 JAR 파일을 빌드해주는 메이븐 프로젝트를 깃허브 저장소에 올려두었다. $ cd ch06-lsa/ $ mvn package
  • 59.
    1897장 그래프엑스로 동시발생네트워크 분석하기 “세상은 참 좁다. 계속해서 교차하고 있다.” -데이비드 미첼 데이터 과학자들은 다양한 분야, 다양한 깊이의 학문적 배경을 지니고 있다. 그중 다수는 컴퓨 터 과학, 수학, 물리학이 전공이겠지만, 신경과학, 사회학, 정치학 등을 전공한 사람도 있다. 후 자의 분야는 뇌, 사람, 정치기구 등 컴퓨터와 관련 없는 분야를 연구하고 학과생에게 프로그래 밍을 가르치진 않지만, 데이터 과학자로 성장하는 데 발판이 되는 중요한 특징 두 가지를 지니 고 있다. 첫째, 이들 분야는 대상들(신경세포든 개인이든 국가든 상관없이) 사이의 ‘관계’를 이해하고 그 관계가 대상의 행동에 어떻게 영향을 주는지를 이해하는 데 초점을 맞추고 있다. 둘째, 지난 10년간의 폭발적인 디지털 데이터의 증가로 대상들의 관계와 관련한 거대한 규모의 정보에 접 근할 수 있게 되었고, 이 데이터셋을 구하고 관리하기 위한 새로운 기술을 개발해야 했다. 각 영역의 과학자들이 서로, 그리고 컴퓨터 전문가들과 협업하기 시작하면서 대상들의 관계를 분석할 때 사용하던 많은 기술을 다른 분야에도 적용할 수 있음을 깨달았다. 그리하여 네트워크 과학 분야가 탄생했다. 네트워크 과학에는 대상(꼭짓점Vertex, Node ) 사이의 관계(변Edge, Link, Line )를 연구하는 수학 분야인 그래프 이론Graph Theory에서 탄생한 도구들이 사용된다. 또한, 그래프 이론 은 자료구조부터 컴퓨터 구조나 인터넷과 같은 네트워크 설계까지 컴퓨터 분야에서 폭넓게 활 용되고 있다. 그래프엑스로 동시발생 네트워크 분석하기 CHAPTER 7 조시 윌스
  • 60.
    190 9가지 사례로익히는 고급 스파크 분석 (2판) 그래프 이론과 네트워크 과학은 비즈니스 분야에도 큰 영향을 주었다. 대부분의 인터넷 회사가 영향력 있는 관계 네트워크를 구축하고 분석하는 데 경쟁자들보다 우위를 점하는 식으로 회사 의 가치를 높여 왔다. 아마존과 넷플릭스는 각 회사가 만들고 통제해온 사용자-제품구매(아마 존), 사용자-감상평(넷플릭스) 네트워크를 기반으로 추천 알고리즘을 만들었다. 페이스북과 링크드인은 콘텐트의 피드를 구성하고, 광고를 삽입하고, 새로운 관계를 맺어주기 위해서 사용 자를 분석하여 사람 사이의 관계 그래프를 만든다. 이 중에서도 가장 유명한 사례로는 웹 검색 을 근본적으로 개선하기 위해 창업자가 개발한 구글의 페이지랭크PageRank 알고리즘을 꼽을 수 있을 것이다. 이들 네트워크 중심 회사에 필요했던 엄청난 양의 계산과 분석 수요는 맵리듀스와 같은 분산 처리 프레임워크가 만들어지는 계기가 되었을 뿐 아니라, 계속해서 늘어만 가는 데이터를 분 석하여 가치를 만들어내는 도구를 사용할 줄 아는 데이터 과학자들을 고용하는 계기가 되었다. 맵리듀스의 초기 활용사례 중 하나가 페이지랭크의 핵심 공식을 풀어내는 확장 가능하고 신뢰 성 있는 방법을 구축하는 것이었다. 시간이 지나면서 그래프가 점점 커지자 데이터 과학자들 은 분석 속도를 더 높여야 한다는 압박에 시달렸다. 그 결과 구글의 프레겔Pregel, 야후의 지라프 Giraph, 카네기 멜런 대학교의 그래프랩GraphLab과 같이 그래프를 병렬로 처리하는 새로운 프레임 워크가 개발되었다. 이 프레임워크들은 결함 허용, 인메모리, 반복 가능, 그래프 중심의 분석을 지원했고, 특정 유형의 그래프 연산에서는 데이터 중심의 병렬 처리 프레임워크인 맵리듀스보 다 자릿수가 다를 정도로 더 빠른 모습을 보여주었다. 이 장에서는 그래프엑스GraphX라는 스파크 라이브러리를 소개하려 한다. 이 라이브러리는 프레 겔, 지라프, 그래프랩에서 처리하던 그래프 중심 병렬 작업의 많은 부분을 스파크가 처리할 수 있도록 확장한다. 비록 모든 연산을 전용 그래프 프레임워크만큼 빠르게 수행할 수는 없겠지 만, 그래프엑스가 스파크 라이브러리라는 사실은 일반적인 데이터 분석 워크플로에서 언제든 지 그래프(혹은 네트워크) 중심 데이터셋도 분석할 수 있음을 뜻한다. 즉, 지금까지 사용해온 익숙한 스파크 추상화에 병렬 그래프 처리 프로그래밍을 더할 수 있다. 그래프엑스와 그래프프레임 그래프엑스는 데이터프레임이 도입되기 전인 스파크 1.3 때 만들어졌기 때문에 그래프엑스 의 API는 RDD를 통해서 동작하도록 설계되었다. 최근에는 그래프엑스를 데이터프레임 기
  • 61.
    1917장 그래프엑스로 동시발생네트워크 분석하기 반인 그래프프레임GraphFrames이라는 새로운 API로 포팅하려는 노력이 진행되고 있다. 그래프 프레임은 데이터프레임 API와 그래프 질의를 통해서 직렬화된 데이터를 읽고 쓰는 기능을 폭넓게 지원하는 등 다양한 이점을 제공한다. 이 책의 2판을 집필하는 시점에는 스파크 2.1의 그래프프레임 API로는 이번 장에서 수행하 는 분석 일부를 진행할 수 없기 때문에 여기서는 그래프엑스 API를 사용하기로 하였다. 하 지만 그래프프레임은 그래프엑스로부터 많은 영감을 받고 있기 때문에 이 장에서 소개하는 모든 메서드와 개념은 그래프프레임에 일대일로 대응된다. 아직은 미정이지만, 이 책의 다 음 판에서는 그래프프레임으로 옮겨갈 수 있기를 기대하고 있다. 프로젝트의 진행 상황은 그 래프프레임의 프로젝트 페이지(http://graphframes.github.io/)에서 살펴볼 수 있다. 7.1 네트워크 분석 사례: MEDLINE의 인용 색인 온라인 의학 문헌 분석 및 검색 시스템인 MEDLINEMedical Literature Analysis and Retrieval System Online 은 생명과학과 의학 저널들에서 발행한 학술 논문의 데이터베이스로, 미국 국립 보건원National Institute of Health (NIH)의 한 부서인 미국 국립 의학도서관US National Library of Medicine (NLM)에서 관리 한다. 수천 개의 저널에 실린 기사들을 기록하는 인용 색인은 1879년부터 만들어지기 시작했 고, 1971년부터 의과 대학에 온라인으로 제공했으며, 1996년부터는 웹을 통해서 일반에 제공 하고 있다. 주 데이터베이스는 1950년대 초반 이후의 2천만 건이 넘는 기사를 담고 있으며, 공 휴일을 제외한 매일 갱신되고 있다. 엄청난 인용 데이터의 크기와 빈번한 갱신 주기 때문에 연구 커뮤니티에서는 MeSHMedical subject Headings (의학 주제 제목)라는 포괄적인 의미 태그를 개발하여 색인에 포함된 모든 인용에 적용 했다. 이들 태그는 문헌 검토를 위해서 문서 사이의 관계를 조사할 때 사용할 수 있는 중요한 프레임워크를 제공하며, 데이터 기반 제품을 만드는 기초 자료로 사용할 수도 있다. 2001년에 PubGene사는 생의학 텍스트 마이닝을 활용한 첫 번째 상용 제품을 선보였다. 이 제품은 사 용자가 관련 문서들을 연결하는 MeSH 키워드의 그래프를 탐색하게 해주는 검색 엔진이었다. 이 장에서는 스칼라, 스파크, 그래프엑스를 사용하여 MEDLINE 데이터 중 최근에 발행된 인 용 데이터 일부에 대한 MeSH 네트워크를 만들고 변환하고 분석해볼 것이다. 여기서 수행할
  • 62.
    192 9가지 사례로익히는 고급 스파크 분석 (2판) 네트워크 분석은 2014년 카스트린Kastrin 등이 쓴 「함께 사용된 MeSH 키워드 네트워크의 거대 한 구조: 거시적 특징들의 정적 분석Large-Scale Structure of a Network of Co-Occurring MeSH Terms: Statistical Analysis of Macroscopic Properties」(https://goo.gl/7hR1dc)에서 아이디어를 가져온 것이다. 다만, 이 논문에 서 사용한 인용 데이터와는 다른 부분집합을 사용할 것이며, 이 논문에서는 R과 C++를 사용 했지만 여기서는 그래프엑스로 분석할 것이다. 우리의 목적은 인용 그래프의 모양과 특성에 대한 감을 잡는 것이다. 우리는 데이터셋의 완전 한 조망을 얻기 위해서 여러 각도에서 공략할 것이다. 먼저 핵심 주제들, 그리고 이 주제들이 동시에 발생하는 정도를 살펴보는, 즉 그래프엑스를 사용할 필요가 없는 간단한 분석부터 시작 할 것이다. 그 다음으로는 연결 성분Connected Component을 찾을 것이다. 이를 통해서 “특정 주제에 서 다른 주제로 색인 경로를 따라갈 수 있을 것인가?” 또는 “데이터가 어떤 분리된 작은 그래프 들의 집합인가?”와 같은 질문에 대답할 수 있다. 그 후에, 그래프의 차수 분포Degree Distribution를 살 펴 특정 주제의 관련성이 얼마나 넓게 걸쳐 있는지에 대한 감을 잡고, 다른 주제들과 가장 많이 연결된 주제를 찾아볼 것이다. 마지막으로 군집계수Clustering Coefficient와 평균 경로 길이Average Path Length 를 구하는, 두 가지의 조금 전문적인 그래프 통계량을 계산할 것이다. 이들 통계량은 여러모로 사용되겠지만, 여기서는 인용 그래프가 웹이나 페이스북의 사회 관계망 같은 우리 주변의 현실 세상 그래프와 얼마나 비슷한가를 이해하게끔 해줄 것이다. 7.2 데이터 구하기 미국 국립 보건원의 FTP 서버에서 인용 색인 데이터의 표본을 얻을 수 있다. $ mkdir medline_data $ cd medline_data $ wget ftp://ftp.nlm.nih.gov/nlmdata/sample/medline/*.gz HDFS에 올리기 전에 인용 데이터의 압축을 풀고 검사를 하자. $ gunzip *.gz $ ls -ltr ... total 1814128
  • 63.
    1937장 그래프엑스로 동시발생네트워크 분석하기 -rw-r--r-- 1 jwills staff 145188012 Dec 3 2015 medsamp2016h.xml -rw-r--r-- 1 jwills staff 133663105 Dec 3 2015 medsamp2016g.xml -rw-r--r-- 1 jwills staff 131298588 Dec 3 2015 medsamp2016f.xml -rw-r--r-- 1 jwills staff 156910066 Dec 3 2015 medsamp2016e.xml -rw-r--r-- 1 jwills staff 112711106 Dec 3 2015 medsamp2016d.xml -rw-r--r-- 1 jwills staff 105189622 Dec 3 2015 medsamp2016c.xml -rw-r--r-- 1 jwills staff 72705330 Dec 3 2015 medsamp2016b.xml -rw-r--r-- 1 jwills staff 71147066 Dec 3 2015 medsamp2016a.xml 옮긴이_ 이 책의 1판에서는 책에서 사용한 데이터와 실제 얻을 수 있는 데이터에 차이가 있었다. 책에서는 이 름에 2014년을 의미하는 ‘2014’라는 숫자가 붙은 데이터를 사용하여 설명했지만, 번역하는 시점이 다소 늦 은 탓에 ‘2016’이 붙은 최신 데이터가 위 FTP 서버의 디렉터리에 들어 있었다. 그 탓에 이 책이 보여주는 예 제와 독자가 실습하면서 접하는 결과가 다소 다른, 난감한 상황을 겪었다. 다행히도, 2판을 번역하는 지금(2017년)은 앞의 파일 목록과 동일한 데이터를 저 위치에서 찾을 수 있다. 하 지만 독자가 읽는 시점에 다시 최근의 표본으로 바뀌어 있을지도 모른다. 이로 인하여 책에 실린 결과와 독자 의 실습 결과가 또다시 달라질 수 있겠지만, 그 결과가 다르다고 해서 대세에 큰 영향을 주지는 않음을 밝혀 둔다. 실제로 2014년 데이터로 결과를 보여준 1판과 2016년 데이터로 결과를 보여준 2판의 일부 숫자와 결 과는 차이가 있지만, 책의 논지와 대세에는 아무 영향이 없다. 아울러 이어지는 예제를 클러스터가 아닌 PC 환경에서 분석하고자 할 때는 유의할 사항이 있다. 가장 일반적 이라 추측하는 리눅스 환경에서는 시스템이 동시에 열 수 있는 파일의 수가 기본적으로 1,024개로 설정되어 있다. 만약 테스트 도중에 “열린 파일이 너무 많음” 또는 “Too Many Open Files”나 이와 유사한 오류 메 시지를 접하게 된다면 OS의 옵션을 조정해야 한다. 리눅스에서 ulimit -a 명령으로 동시에 열 수 있는 파일 의 수를 확인할 수 있으며(open files 값), ulimit -n 2048과 같이 이 수를 원하는 값으로 조정할 수 있다. 하 지만 이 방법은 일시적이며 OS의 제약으로 인해서 이와 같이 변경하는 일도 쉽지 않다. 대신 /etc/security/ limits.conf 파일에서 값을 변경하는 방법을 추천한다. 값을 4096으로 설정하고 테스트를 수행하면 아마도 앞의 오류 메시지를 피할 수 있을 것이다. 대부분의 시스템에서는 더 큰 값으로 변경하면 변경 설정이 적용되 지 않을 수 있다. 그리고 2장과 3장에서 소개한 몇 가지 프로세서와 메모리에 관한 설정도 사용하는 것이 좋 다. 하지만 가능하다면 PC 환경보다는 클러스터링 환경에서 테스트해보기를 권한다. 이 장의 후반부 예제, 특히 프레겔을 사용한 예제들은 일반 PC 환경에서는 수 시간씩이 소요될지도 모른다. 압축을 풀면 총 600MB의 XML 파일들이 나온다. 표본 파일의 각 엔트리는 MedlineCitation 레코드로, 저널 이름, 권호Issue, 출간일, 저자명, 초록Abstract, 해당 기사와 관련된 MeSH 키 워드 등, 생의학 저널의 기사와 관련된 정보가 들어 있다. 각 MeSH 키워드에는 그 키워 드가 나타내는 개념이 그 기사의 핵심 주제인지를 알려주는 속성도 포함되어 있다. 그러면 medsamp2016a.xml에 포함된 첫 번째 인용 레코드를 살펴보자.
  • 64.
    194 9가지 사례로익히는 고급 스파크 분석 (2판) MedlineCitation Owner=PIP Status=MEDLINE PMID Version=112255379/PMID DateCreated Year1980/Year Month01/Month Day03/Day /DateCreated ... MeshHeadingList ... MeshHeading DescriptorName MajorTopicYN=NHumans/DescriptorName /MeshHeading MeshHeading DescriptorName MajorTopicYN=YIntelligence/DescriptorName /MeshHeading MeshHeading DescriptorName MajorTopicYN=YRorschach Test/DescriptorName /MeshHeading ... /MeshHeadingList ... /MedlineCitation 6장에서 다룬 위키백과 문서 관련 숨은 의미 분석(LSA)에서는 주로 XML의 각 레코드에 담 긴 구조화되지 않은 텍스트에 관심을 두었다. 하지만 이번 장의 동시발생 분석에서는 XML의 구조를 직접 파싱하여 DesciptorName 태그에 담긴 값을 꺼내려 한다. 마침, 스칼라에는 XML 문서를 파싱하고 질의하기 위한 scala-xml이라는 훌륭한 라이브러리가 있어서 이 작업 을 쉽게 처리할 수 있다. 인용 데이터를 HDFS에 올리는 것부터 시작해보자. $ hadoop fs -mkdir medline $ hadoop fs -put *.xml medline 이제 스파크 셸을 시작할 준비가 되었다. 6장에서 언급한 XML 데이터 파싱 코드(XMLInput Format 클래스)를 이 장에서도 사용한다. 이 코드를 컴파일하고 JAR 파일로 만들어 사용할 것이다. 다음과 같이 깃 저장소의 ch07-graph/ 디렉터리로 이동한 다음, 메이븐을 사용해 빌 드하자.
  • 65.
    2278장 뉴욕 택시운행 데이터로 위치 및 시간 데이터 분석하기 “시간과 공간만큼 내게 혼란을 주는 것은 없다. 그러나 시간과 공간만큼 나를 괴롭히지 않는 대상도 없다. 왜냐하면 나는 그 주제를 한 번도 생각해본 적이 없기 때문이다.” -찰스 램 뉴욕은 노란 택시로 유명하다. 노점상에서 핫도그를 사 먹거나 엘리베이터를 타고 엠파이어 스 테이트 빌딩 꼭대기까지 올라가 보는 일과 마찬가지로 노란 택시 타보기는 뉴욕 관광의 필수 코스가 되었다. 뉴욕 주민들은 러시아워나 궂은 날씨에 택시를 잡을 때, 언제 혹은 어디가 좋은지와 같은 수많 은 (입증되지 않은 경험에 근거한) 정보를 알고 있다. 하지만 모든 사람이 매일 오후 4~5시 사이의 교대시간만큼은 그냥 지하철을 타라고 이구동성으로 이야기한다. 이 시간에 노란 택시 들은 (주로 퀸스에 위치한) 교대 장소로 돌아가 택시 기사를 교대하는데, 늦게 돌아오는 택시 기사에게는 벌금이 부과된다. 2014년 3월, 뉴욕 택시 리무진 위원회는 영업 중인 택시의 수와 승객을 태운 택시의 비율을 시 간대별로 정리한 인포그래픽을 트위터 계정 @nyctaxi(https://twitter.com/nyctaxi)로 공유 했다. 당연하게도, 오후 4~6시 사이에 영업 중인 택시의 수는 눈에 띌 만큼 적었고, 그중 2/3 정도가 승객을 태우고 있었다. 뉴욕 택시 운행 데이터로 위치 및 시간 데이터 분석하기 CHAPTER 8 조시 윌스
  • 66.
    228 9가지 사례로익히는 고급 스파크 분석 (2판) 이 트윗을 자칭 도시 계획 전문가이자 지도 제작자이자 데이터 광인 크리스 홍Chris Whong이 주목 했다. 그는 인포그래픽 제작에 이용된 데이터를 공개적으로 사용할 수 있는지를 알아보기 위해 @nyctaxi 계정으로 트윗을 보냈고, 택시 위원회는 정보공개법에 따른 공식 요청서와 데이터 를 담아 갈 하드디스크를 제출하면 데이터를 건네주겠다고 답했다. 크리스는 요청서를 작성하 고 500GB의 하드디스크 2개를 구입해 보냈고, 영업일 기준으로 이틀 후에 2013년 전체의 모 든 택시 운행 정보를 손에 쥐었다. 여기서 그치지 않고, 그는 모든 택시 요금 데이터를 인터넷 에 올렸고, 지금까지 이 정보는 뉴욕의 교통수단과 관련한 멋진 시각화 자료들의 기초 데이터 로 사용되고 있다. 택시의 경제학을 이해하는 데 중요한 통계 하나는 영업시간과 승객을 태운 시간의 비율인 이용 률Utilization이다. 승객의 목적지는 이용률에 영향을 주는 요소다. 예를 들어서 한낮에 유니언 광 장 근처에서 승객을 내린 택시는 단 1~2분 안에 다음 승객을 태울 가능성이 매우 높은 반면, 새벽 2시에 스태튼섬에서 승객을 내린 택시는 다음 승객을 찾으려면 맨해튼까지 돌아와야만 할 수도 있다. 우리는 이러한 영향을 수치화하고 택시에 다음 승객이 탈 때까지의 평균 시간을 승객이 내린 자치구의 함수로 만들어내고자 한다. 함수의 입력값으로는 맨해튼, 브루클린, 퀸 스, 브롱크스, 스태튼섬, 기타(뉴어크Newark 국제공항과 같은 뉴욕 바깥 지역)가 있다. 이 분석을 수행하려면 항시 마주하게 되는 두 종류의 데이터를 다뤄야 한다. 하나는 날짜와 시 각 같은 시간 데이터고, 다른 하나는 경도와 위도 및 지역 경계와 같은 위치 데이터다. 이 책 초판 이 출간된 이후로 스파크에서 시간 데이터를 다루는 방법에 몇 가지 개선이 있었다. 자바 8에 서 java.time이라는 신규 패키지가 소개되었고, Spark SQL에는 아파치 하이브 프로젝트의 사용자 정의 함수(UDF)들이 포함되었다. 이 사용자 정의 함수들에는 date_add와 from_ timestamp 같이 시간을 다루는 함수들이 다수 포함되어, 스파크 1 때보다 작업을 훨씬 수월 하게 해준다. 반면, 위치 데이터는 여전히 다소 특별한 종류의 분석이라서 이를 효과적으로 분 석하려면 서드파티 라이브러리들을 사용하고 필요한 사용자 정의 함수들을 우리가 직접 작성 해야 한다. 8.1 데이터 얻기 이번 분석에서 2013년 1월의 요금 데이터만 다룰 것인데, 압축을 풀면 2.5GB 정도 된다.
  • 67.
    2298장 뉴욕 택시운행 데이터로 위치 및 시간 데이터 분석하기 2013년의 월별 데이터는 http://www.andresmh.com/nyctaxitrips/에서 내려받을 수 있다. 사 용할 수 있는 스파크 클러스터가 충분히 크다면, 이제부터 수행할 분석을 2013년 전체 데이터 로도 해볼 수 있을 것이다. 먼저 클라이언트 노드에 작업 디렉터리를 만들고 요금 데이터의 구 조를 살펴보도록 하자. $ mkdir taxidata $ cd taxidata $ curl -O https://nyctaxitrips.blob.core.windows.net/data/trip_data_1.csv.zip $ unzip trip_data_1.csv.zip $ head -n 10 trip_data_1.csv 이 파일은 머릿줄을 제외하면 한 줄에 택시 운행 한 건씩 CSV 형식으로 기록되어 있다. 각 운 행 정보는 택시 정보(해시된 메달리온 번호1 )와 운전자 정보(해시된 핵 라이선스Hack License, 택시 면허), 운행 시작 시각과 종료 시각과 같은 시간 정보, 승객의 탑승 지점과 하차 지점의 경도·위 도 좌표 등의 속성으로 이뤄진다. 8.2 스파크에서 서드파티 라이브러리로 작업하기 자바 플랫폼의 최고 장점 하나는 이 플랫폼만을 위해서 수년간 개발되어온 코드의 양 그 자체 다. 어떤 자료형이나 알고리즘도 이미 다른 누군가가 자바 라이브러리로 개발해두었을 가능성 이 크며, 나아가 그 라이브러리의 오픈 소스 버전이 존재하여 무료로 사용할 수 있을 가능성이 크다. 물론, 단지 무료 라이브러리가 있다는 사실이 반드시 그 라이브러리를 사용해야 할 이유는 되 지 못한다. 오픈 소스 프로젝트는 품질, (버그 수정 및 신규 기능에 대한) 개발 진행 상황, (API 설계와 잘 작성된 문서와 튜토리얼의 유무에 따른) 사용 편의성 측면에서 편차가 매우 크다. 우리가 라이브러리를 선정하는 과정은 애플리케이션 개발자가 라이브러리를 선정하는 과정 과 약간 다르다. 우리는 대화형 데이터 분석에 사용하기 좋고, 분산 애플리케이션에서 쉽게 사 1 옮긴이_ 메달리온은 뉴욕 노란 택시의 전면에 장착하는 휘장을 말하고, 메달리온에는 번호가 부여되어 있다.
  • 68.
    230 9가지 사례로익히는 고급 스파크 분석 (2판) 용할 수 있는 라이브러리를 원한다. 특히 RDD 내에서 다룰 주요 자료형들은 Serializable 인 터페이스를 구현했거나 Kryo 같은 라이브러리를 통해 쉽게 직렬화된다는 점을 반드시 만족하 길 원한다. 거기다가 대화형 분석에 사용하는 라이브러리는 가능한 한 다른 외부 라이브러리에 대한 의존 성이 없는 것을 선호한다. 메이븐이나 SBT와 같은 도구는 개발자가 애플리케이션을 빌드할 때 복잡한 의존성 문제를 처리해주지만, 대화형 데이터 분석의 경우에는 단순히 필요한 모든 코드 를 JAR 파일에 다 담아버리고, 스파크 셸에서 읽어 들여 그대로 분석을 시작하는 편이 훨씬 좋 다. 게다가 라이브러리가 의존성을 다수 갖게 되면 스파크가 사용하는 다른 라이브러리와 버전 충돌이 발생할 수도 있다. 이 상황이 심해지면 개발자 사이에서 소위 ‘JAR 지옥’이라 불리는 진 단하기 어려운 오류 상황에 빠지게 된다. 마지막으로 추상 팩토리 패턴이나 방문자 패턴과 같은 자바 위주의 디자인 패턴을 많이 사용하 지 않는, 비교적 간단하고 풍부한 API를 선호한다. 디자인 패턴이 애플리케이션 개발자에게는 매우 유용하겠지만, 분석과 관련 없는 부분에서 코드를 훨씬 복잡하게 만드는 경향이 있다. 그 나마 나은 것은 많은 자바 라이브러리에 스칼라 래퍼가 있어, 라이브러리를 사용하는 데 필요 한 자질구레한 코드를 줄이고 스칼라의 장점을 살려주고 있다. 8.3 지리 데이터와 Esri Geometry API, 그리고 Spray JVM에서 시간 데이터를 다루는 일은 자바 8의 java.time 패키지 덕에 매우 쉬워졌다. 이 패키 지는 널리 사용되는 JodaTime 라이브리리를 기초로 설계되었다. 한편, 지리 데이터 쪽은 그 리 녹록지 않다. 관련 라이브러리와 도구가 다양하나, 기능, 개발 진행 상황, 성숙도에서 차이 를 보여 모든 상황에 압도적으로 널리 사용되는 라이브러리는 없다. 라이브러리를 선택할 때 첫째로 반드시 생각해봐야 하는 건 어떤 유형의 지리 데이터를 다루느 냐다. 주요한 두 유형으로 벡터Vector와 래스터Raster가 있으며, 각각은 지원하는 도구도 다르다. 우리 예제인 택시 운행 기록에는 경도와 위도라는 위치 값이 있고 뉴욕의 여러 자치구 경계를 표현하는 벡터 데이터도 있는데, 여기서 벡터 데이터는 GeoJSON 포맷으로 저장되어 있다. 그러므로 우리는 GeoJSON 데이터를 파싱할 수 있고, 주어진 경도, 위도 쌍이 (특정 자치구 경계를 표현하는) 다각형 내부에 있는지 알아내는 것과 같은 위치 관계를 다룰 수 있는 라이브
  • 69.
    2318장 뉴욕 택시운행 데이터로 위치 및 시간 데이터 분석하기 러리가 필요하다. 안타깝지만, 우리의 바람에 정확히 들어맞는 오픈 소스 라이브러리는 없다. GeoJSON 레코드 들을 자바 객체들로 변환하는 GeoJSON 파서 라이브러리가 있으나, 결과로 생성된 객체의 공 간 관계를 분석해줄 관련 지리 라이브러리가 없다. GeoTools 프로젝트라는 것도 있지만 다 른 컴포넌트에 대한 의존성이 크다. 따라서 스파크 셸에서 사용할 라이브러리를 고른다면 피해 야 할 대상에 해당된다. 마지막으로 자바용 Esri Geometry API가 있는데, 의존성이 거의 없 고 공간 관계도 분석할 수 있다. 하지만 GeoJSON 표준 중 일부 형태만 파싱할 수 있기 때문 에 몇 가지 데이터 전처리 없이는 우리가 내려받은 GeoJSON 데이터를 파싱할 수 없다. 적합한 분석 도구가 없다는 것은 데이터 분석가에게는 큰 난관이다. 그러나 우리는 데이터 과 학자다. 만약 도구의 한계로 문제를 해결하지 못한다면 새로운 도구를 만들면 된다. 이번 장 에서는 JSON 파싱을 지원하는 수많은 스칼라 프로젝트 중 하나를 이용하여, Esri Geometry API에서 처리할 수 없는 사례까지 포함한 모든 GeoJSON 데이터를 파싱할 수 있도록 스칼라 기능을 추가할 것이다. 이어지는 절들에서 다룰 코드는 이 책의 깃허브 저장소는 물론, 독립 라 이브러리로 형태로도 깃허브(https://github.com/jwills/geojson)에 따로 공개해뒀으니, 다른 스칼라 지리 분석 프로젝트에도 사용할 수 있다. 8.3.1 Esri Geometry API 살펴보기 Esri 라이브러리의 핵심 자료형은 Geometry다. Geometry는 기하학 형태와 그 기하학 형태 가 점유하는 지리적 위치 정보를 함께 기술한다. Esri는 기하학 구조물과 그들 사이의 관계를 분석하는 일련의 위치 연산 기능을 제공한다. 이러한 연산 기능들로 기하학 구조물의 영역을 계산하거나, 두 기하학 구조물이 겹치는지 알아내거나, 두 기하학 구조물을 합쳐 하나의 구조 물로 변환하는 등의 일을 할 수 있다. 우리의 분석 문제에서는 택시 승객의 하차 지점(경도와 위도)을 나타내는 Geometry 객체들 과 뉴욕 내 자치구 경계를 나타내는 Geometry 객체들을 가지게 될 것이다. 여러 위치 관계 중 우리의 관심사는 “주어진 지점이 맨해튼 자치구에 관련된 여러 다각형 중 하나의 내부에 위치 하는가?”와 같은 ‘포함 관계’다. Esri가 제공하는 GeometryEngine라는 편의 클래스는 contains 연산은 물론 모든 종류의
  • 70.
    232 9가지 사례로익히는 고급 스파크 분석 (2판) 위치 관계 연산을 수행하는 정적 메서드들을 가진다. contains 메서드는 3개의 인수를 받는 데, 2개는 Geometry 객체고 다른 1개는 SpatialReference 클래스의 인스턴스다. 여기서 SpatialReference 클래스는 지리공간 계산에 이용되는 좌표계Coordinate System를 나타낸다. 최대 한 정확하게 계산하기 위해서 우리는 일그러진 3차원 구체인 지구의 각 지점을 2차원 좌표계로 매핑하는 ‘좌표면에 관한 공간적 관계들’을 분석해야 한다. 지리공간 정보를 다루는 엔지니어들 은 좌표계를 표시할 때 흔히 사용하는 통용식별자Well-known Identifier (WKID)라는 표준을 사용한 다. 이 책의 예제에서는 GPS용 표준 좌표 시스템인 WKID 4326을 사용할 것이다. 스칼라 개발자로서 우리는 항상 스파크 셸로 수행하는 대화형 분석 작업 시의 타이핑 양을 줄 여주는 방법을 찾는다. 이클립스Eclipse나 인텔리제이IntelliJ 같은 IDE가 제공하는 메서드 이름 자 동 완성과 특정 연산을 더 읽기 편하게 하는 일부 편의 문법을 스파크 셸에서는 사용할 수 없는 상황이다. 그래서 우리는 Esri의 Geometry 클래스에 유용한 도우미 메서드를 몇 개 추가해 확장한 RichGeometry 클래스를 정의할 것이다. 여기서 명명규칙은 NScalaTime 라이브러 리가 래퍼 클래스 이름(RichDateTime, RichDuration 등)에 적용한 형태를 참고했다. import com.esri.core.geometry.Geometry import com.esri.core.geometry.GeometryEngine import com.esri.core.geometry.SpatialReference class RichGeometry(val geometry: Geometry, val spatialReference: SpatialReference = SpatialReference.create(4326)) { def area2D() = geometry.calculateArea2D() def contains(other: Geometry): Boolean = { GeometryEngine.contains(geometry, other, spatialReference) } def distance(other: Geometry): Double = { GeometryEngine.distance(geometry, other, spatialReference) } } 또 RichGeometry의 동반 객체를 선언하여 Geometry 클래스의 인스턴스를 RichGeometry 인스턴스로 변환하는 암묵적 형변환을 제공할 것이다. object RichGeometry {
  • 71.
    2539장 몬테카를로 시뮬레이션으로금융 리스크 추정하기 “지질학을 이해하고 싶다면 지진을 공부하라. 경제학을 이해하고 싶다면 경기 침체를 공부하라.” -벤 버냉키 합리적인 상황에서 여러분은 얼마만큼의 손실을 예상할 수 있는가? 이것이 최대손실예상액Value at Risk (VaR)이라는 금융 통계량이 측정하고자 하는 양이다. VaR은 1987년 주식 시장 붕괴 직후 개발되어 모든 금융 서비스 조직에서 널리 사용하고 있다. 이 통계량은 금융 기관들이 추구하 는 신용 등급을 만족하기 위해 보유해야 하는 현금의 양을 정하는 데 도움이 되기 때문에 자산 관리에서 필수적인 역할을 한다. 일부 기관은 대규모 포트폴리오들의 리스크 특성을 더 광범위 하게 이해하기 위해 사용하고, 또 다른 일부는 거래 실행 전에 이 값을 계산하여 즉각적인 결정 을 내리는 데 도움을 얻는다. VaR 통계량을 추정하는 여러 정교한 방법들 대부분은 계산량이 매우 많은 방법인 임의 상황 에서의 시장 시뮬레이션에 의존한다. 그리고 이런 방법 뒤에는 몬테카를로 시뮬레이션Monte Carlo Simulation이라는 기술이 있다. 이 기술은 수천에서 수백만의 임의 시장 시나리오를 제기하고, 그 상황이 포트폴리오에 어떤 영향을 주는지 관찰한다. 몬테카를로 시뮬레이션은 자연스럽게 대 규모로 병렬화되기 때문에 스파크는 이를 위한 최적의 도구다. 스파크는 수천의 코어를 활용하 여 임의 실험들을 수행하고 실험 결과들을 집계할 수 있다. 또한 범용 데이터 변환 엔진인 스파 크는 시뮬레이션 관련 전처리와 후처리에도 능숙하다. 스파크는 원시 금융 데이터를 여러 시뮬 몬테카를로 시뮬레이션으로 금융 리스크 추정하기 CHAPTER 9 샌디 라이자
  • 72.
    254 9가지 사례로익히는 고급 스파크 분석 (2판) 레이션 수행에 필요한 모델 파라미터들로 변환하는 일뿐만 아니라 시뮬레이션 결과들에 대한 애드혹Ad-hoc 분석도 지원한다. 스파크의 간단한 프로그래밍 모델은 HPC 환경을 이용하는 전 통적인 방법보다 개발 기간을 현저히 줄일 수 있다. ‘예상할 수 있는 손실의 양’을 좀 더 엄격하게 정의해보자. VaR은 간단한 투자 리스크 척도로, 투자 포트폴리오가 특정 기간에 입을 수 있는 최대 손실에 대한 합리적인 추정치를 제공하는 것이 목적이다. VaR 통계량은 포트폴리오, 보유 기간, 확률이라는 세 파라미터에 따라 값이 달 라진다. “5%의 확률로 보유 기간은 2주일 때의 VaR 통계량이 1백만 달러다”라는 말은 “해당 포트폴리오가 2주 동안 1백만 달러 ‘이상’의 손실을 볼 확률이 단 5%다”라는 의미다. VaR과 관련된 조건부 최대손실예상액Conditional Value at Risk (CVaR)이라는 통계량 계산 방법도 논의 할 것이다(기대 손실Expected Shortfall이라고도 한다). CVaR은 바젤 은행 감독 위원회가 VaR보다 나은 리스크 척도로써 최근 제안했다. CVaR 통계량은 VaR 통계량이 가지고 있는 세 파라미터 를 똑같이 가지나, 컷오프 값 대신 기대 손실 관점을 다룬다. “5%의 확률로 보유 기간은 2주일 때 CVaR 통계량이 5백만 달러다”라는 말은 “전체 시나리오 중 최악의 결과를 내는 5%의 시나 리오들에서의 ‘평균’ 손실이 5백만 달러다”라는 의미다. 이번 장에서는 VaR 모델링을 다루며 몇 가지 개념, 방법, 패키지를 소개할 것이다. 구체적으로 는 커널 밀도 추정, breeze-viz 패키지를 활용한 시각화, 다변량 정규분포를 활용한 표본추출 그리고 아파치 커먼즈 수학Apache Commons Math 패키지를 활용하여 통계 함수들을 다룰 것이다. 9.1 전문 용어 이 장에서는 금융 도메인에 특화된 용어들을 사용한다. 먼저 이들 용어를 간단히 정의해보자. 금융상품Instrument 거래 가능한 자산으로 채권, 대출, 옵션, 주식이 있다. 어떤 시점이든 금융상품은 판매 가 격을 가진다고 간주한다. 포트폴리오Portfolio 금융 기관이 소유한 금융상품들의 모음
  • 73.
    2559장 몬테카를로 시뮬레이션으로금융 리스크 추정하기 수익Return 금융상품 또는 포트폴리오의 일정 기간의 가격 변화 손실Loss 마이너스 수익 지수Index 가상의 금융상품 포트폴리오. 예를 들어서 나스닥 지수는 약 3,000개의 미국 혹은 국제 기 업들의 주식과 유사 금융상품을 포함한다. 시장 요인Market Factor 특정 시간에 재정 상황의 거시적 측면을 나타내는 지표로 사용될 수 있는 값. 예를 들어서 미국의 국내 총생산(GDP) 또는 달러-유로 환율과 같은 인덱스 값이 있다. 이 책에서는 종 종 시장 요인을 그냥 요인이라고 언급할 것이다. 9.2 VaR 계산 방법 지금까지 우리가 내린 VaR의 정의에는 정하지 않은 부분이 상당히 있다. 이 통계량을 추정하 려면 어떻게 포트폴리오가 동작하는지에 대한 모델을 제안하고 이 포트폴리오의 수익이 따를 법한 확률 분포를 선택해야 한다. 기관들은 VaR을 계산하기 위해 다양한 방법을 쓰고 있지만, 이 모든 방법은 몇 가지 일반적인 방법의 범주에 속하는 경향이 있다. 9.2.1 분산-공분산 분산-공분산Variance-Covariance은 단연코 가장 간단하고 가장 계산량이 적은 방법이다. 분산-공분 산 모델은 각 금융상품의 수익이 정규분포를 따른다고 가정하여 VaR 통계량을 해석적으로 유 도할 수 있게 한다.
  • 74.
    256 9가지 사례로익히는 고급 스파크 분석 (2판) 9.2.2 과거 기반 시뮬레이션 과거 기반 시뮬레이션Historical Simulation은 요약 통계에 의존하는 대신 과거 데이터의 분포를 직접 이용하여 리스크를 추정한다. 예를 들어서 포트폴리오의 5% VaR을 알아내기 위해 그 포트폴 리오의 지난 100일간의 성과를 보고 그중 5번째로 나쁜 날의 값으로 VaR 통계량 값을 추정할 수도 있다. 이 방법의 문제는 과거 데이터가 그만큼 많이 쌓여 있지 않을 수 있고, 지금 가정하 는 시나리오들을 포함하지 못할 수 있다는 것이다. 예를 들어, 시장붕괴를 겪어본 적 없는 금 융상품들로 구성된 포트폴리오를 가지고 시장붕괴가 일어났을 때 무슨 일이 일어날지를 모델 링하려 한다면 어떻게 해야 하느냐는 말이다. 역사적 시뮬레이션을 이러한 상황에 덜 민감하게 만들어주는 기술로 데이터 속에 쇼크Shock를 넣는 등의 기법이 있지만 여기서는 다루지 않기로 한다. 9.2.3 몬테카를로 시뮬레이션 이 장의 나머지에서 중점적으로 다룰 몬테카를로 시뮬레이션은 포트폴리오를 임의 상황에서 시뮬레이션함으로써 앞에서 소개한 방법이 취해야 했던 가정을 약화시키려 노력한다. 확률 분 포의 닫힌 형태Closed-form를 해석적으로 유도할 수 없다면, 보통 이 분포에 영향을 주는 더 간단 한 확률 변수Random Variable를 반복해서 표본추출한 다음, 이 변수들이 전체에 어떤 영향을 주는 지 관찰하여 확률 밀도 함수Probability Density Function (PDF)를 추정할 수 있다. 가장 일반적인 형태 에서 이 방법은 다음과 같다. ● ‌‌시장 상황들과 각 금융상품의 수익 사이의 관계를 정의한다. 이 관계는 과거 데이터에 적합된Fitted 모델의 형태 를 가진다. ● ‌‌시장 상황들이 따르는 분포들을 정의한다. 이 분포들은 과거 데이터에 적합된다. ● ‌‌임의 시장 상황들로 구성된 실험Trial들을 제기한다. ● ‌‌각 실험에서 전체 포트폴리오 손실을 계산하고, 이 손실값들을 이용하여 손실에 대한 경험적 분포Empirical Distribution를 정의한다. 이는 만약 실험을 100번 실행하고 5% VaR을 추정하길 원한다면, 손실이 5번째로 큰 실험으로부터 얻어진 손실값을 추정치로 선택할 것임을 뜻한다. 5% CVaR을 계산하려면 최악의 결과를 내 는 실험 5개의 평균 손실을 구할 것이다. 물론, 몬테카를로 방법 역시 완벽한 건 아니다. 몬테카를로 방법은 실험 상황들을 생성하는 모 델과 금융상품 성과를 추정하는 모델에 의존적이며, 여기서 이 모델들은 반드시 단순화한 가정 들을 하게 된다. 만약 이 단순화한 가정들이 현실을 반영하지 못한다면, 결과로 얻게 될 최종
  • 75.
    2579장 몬테카를로 시뮬레이션으로금융 리스크 추정하기 확률 분포 역시 현실을 반영하지 못할 것이다. 9.3 우리의 모델 몬테카를로 리스크 모델은 일반적으로 각 금융상품의 수익을 ‘시장 요인’ 항Term들로 표현한다. 공통적인 시장 요인은 SP 500, 미국 GDP, 환율 같은 지수값일 것이다. 그 후에 이런 시장 상황에서 각 금융상품 수익을 예측하는 모델이 필요하다. 우리 시뮬레이션에서는 간단한 선형 모델을 사용할 것이다. 앞에서 내린 수익의 정의에 따라, 요인 수익Factor Return은 특정 기간의 시장 요인 값의 변화다. 예를 들어서 특정 기간에 SP 500 지수가 2,000에서 2,100으로 움직였다 면 요인 수익은 100이다. 우리는 요인 수익들의 간단한 변형으로부터 일련의 특징들을 얻을 것 이다. 즉, 어떤 함수 Φ를 적용해서 실험 t용 시장 요인 벡터 mt를 변형하여 길이가 다를 수 있 는 특징 벡터 ft를 만들려는 것이다. ft = Φ(mt ) 금융상품별로 각 특징에 가중치를 부여하는 모델을 학습할 것이다. 실험 t에서 금융상품 i의 수 익인 rit를 계산하기 위해 우리는 금융상품에 대한 절편Intercept Term인 ci, 특징 j의 금융상품 i에 대한 회귀 비중Regression Weight인 wij, 그리고 실험 t에서 무작위로 생성된 특징 j의 값인 ftj를 사용 할 것이다. rit = ci + |wi| j=1 wij ∗ ftj 이 수식은 각 금융상품 수익이 시장 요인 특징들의 수익에 해당 금융상품에 대한 특징들의 가 중치를 곱한 값의 합으로 계산됨을 뜻한다. 우리는 과거 데이터를 활용하여 금융상품별 선형 모형을 적합시킬 수 있다(선형 회귀분석을 한다고도 한다). 만약 VaR 계산에서 보유 기간이 2 주라면, 회귀분석은 과거 이력에서의 모든 (겹쳐지는) 2주 간격을 레이블된 포인트로 취급한다. 또한, 우리가 더 복잡한 모델을 선택할 수도 있다는 점을 언급해두고자 한다. 예를 들어서 모델 이 꼭 선형일 필요는 없다. 모델은 회귀 트리여도 되고 명시적으로 특정 도메인 지식을 포함할
  • 76.
    258 9가지 사례로익히는 고급 스파크 분석 (2판) 수 있다. 시장 요인들로부터 금융상품 손실을 계산할 수 있는 모델이 생겼으니, 이제 시장 요인들의 움 직임을 시뮬레이션하는 절차가 필요하다. 간단히 각 시장 요인 수익은 정규분포를 따른다고 가 정할 수 있다. 시장 요인들은 흔히 서로 연관되어 있다는 사실(나스닥 지수가 내려가면 다우 지수도 악화될 가능성이 높다)을 반영하기 위해 우리는 비대각 공분산 행렬Non-diagonal Covariance Matrix을 가지는 다변량 정규분포를 사용할 수 있다. mt ( , )µ 여기서 μ는 요인들의 수익에 대한 경험적 평균Empirical Mean 벡터이고, Σ는 요인들의 수익에 대한 경험적 공분산 행렬Empirical Covariance Matrix이다. 이전과 마찬가지로, 더 복잡한 시장 시뮬레이션 방법을 선택하거나 시장 요인별로 다른 유형의 분포(꼬리 쪽이 두터운 분포라든지)를 가정해도 된다. 9.4 데이터 구하기 대규모로 잘 형식화된 과거의 가격 데이터를 찾기는 어려울 수 있으나, 야후!에서 다양한 주식 데이터를 CSV 형식으로 내려받을 수는 있다. 예제 깃허브 저장소 risk/data 디렉터리의 다음 스크립트는 일련의 REST 요청을 날려 나스닥에 등록된 모든 주식의 과거 데이터를 내려받아 stocks 디렉터리에 저장한다.1 $ ./download-all-symbols.sh 리스크 요인들에 대한 과거 데이터도 필요하다. 우리는 시장 요인으로 SP 500과 나스닥 지수 의 값들뿐만 아니라 미국 재무부가 발행한 5년, 30년 만기 국채 가격들을 사용할 것이다. 이들 역시 야후!에서 내려받을 수 있다. 1 옮긴이_ 이 책에서 사용한 야후!로부터 주식 데이터를 내려받는 API 서비스는 2017년 5월 17일 종료되었다. 이후 2017년 8월 4일에 예제 깃허브 소스에서 데이터 소스를 구글로 변경해두었으나, 역시 제대로 작동하지 않는 것으로 보인다. 그래서 작동하는 버전을 옮긴이 깃허브(https://goo.gl/VxPQTb)에 올려두었다. 단, 데이터 정렬 결과와 품질이 책의 내용과 살짝 달라질 수 있으니 참고하기 바란다. Σ
  • 77.
    28110장 BDG 프로젝트와유전체학 데이터 분석하기 “그래서 우리는 유전자의 구성 물질을 우주로 쏴 보내야 한다.”1 -조지 처치 차세대 염기서열 분석Next-generation DNA Sequencing (NGS) 기술의 출현으로 생명과학도 데이터 가 주도하는 분야로 급변하고 있다. 하지만 DRMAADistributed Resource Management Application API2 나 MPIMessage Passing Interface3 와 같은 사용하기 어려운 저수준의 개발 환경과 정형화 수준이 낮은 텍 스트 기반 파일 포맷이 난립하는 상황에서 개발된 전통적인 컴퓨팅 생태계 탓에, 이 데이터를 효율적으로 이용하기까지 많은 난관에 부딪히고 있다. 이 장의 주요 목적은 세 가지다. 먼저, 일반적인 스파크 사용자에게 하둡과 함께 사용하기 좋은 새로운 직렬화 방법과 파일 형식(에이브로Apache Avro와 파케이Apache Parquet )을 소개한다. 이 형식 들은 데이터를 관리할 때 마주치는 수많은 문제를 매우 단순하게 만들어준다. 압축된 바이너리 형태, 서비스 지향 아키텍처(SOA), 언어 간 상호 호환성을 위해서 보통은 이런 직렬화 방법 을 사용하도록 권장한다. 다음으로는, 숙련된 생물정보학자가 일반적인 유전체학 작업을 어떻 게 수행하는지를 스파크의 맥락에서 보여준다. 1 옮긴이_ 조지 처치는 그의 저서 『Regenesis: How Synthetic Biology Will Reinvent Nature and Ourselves』에서 인류의 역사 를 보존하기 위한 방법으로 인간의 유전체 정보를 담은 전파를 우주로 보내자고 제안한다. 2 옮긴이_ 그리드, 클라우드 컴퓨팅 등에서 사용할 수 있도록 정의된 분산 컴퓨팅 API다. 자세한 내용은 DRMAA 워킹 그룹 홈페이지를 참조하기 바란다. https://www.drmaa.org/ 3 옮긴이_ 분산 및 병렬 처리에서 정보 교환과 관련된 추상화 수준의 상위 표준이다. BDG 프로젝트와 유전체학 데이터 분석하기 CHAPTER 10 유리 레이저슨
  • 78.
    282 9가지 사례로익히는 고급 스파크 분석 (2판) 구체적으로 말하면, 처리 대상인 많은 양의 유전체4 데이터와 필터 데이터를 다루고, 전사인자 Transcription Factor (TF) 결합 부위 예측 모델을 세우고, 1000 지놈 프로젝트1000 Genome Project의 변이 체에 대해서 ENCODEEncyclopedia of DNA Elements 유전체 주석 데이터를 결합하는 일에 스파크를 사 용할 것이다.5 마지막으로, ADAM아담 프로젝트의 튜토리얼을 제공한다. 이 프로젝트는 대규모 유전체 분석을 위한 유전체 특화 에이브로 스키마와, 스파크 기반의 API, 명령줄 도구의 모음 이다. ADAM은 하둡과 스파크를 이용한 유전체 분석 툴킷Genome Analysis Toolkit (GATK) 모범 사 례를 분산 형태로 구현하여 제공한다. 이 장에서 유전체학 관련 부분은 일반적인 문제들에 익숙한 숙련된 생물정보학자를 대상으로 하지만, 데이터 직렬화 부분은 대량의 데이터를 다루는 모든 이에게 유용할 것이다. 이번 장에 서 다루는 분야를 처음 접하면서도 흥미가 생긴다면 에릭 랜더Eric S. Lander 등이 강의하는 edX 코 스(https://goo.gl/afZ6qk)를 추천한다. 생물정보학에 대한 소개는 옥스퍼드 대학교 출판부에 서 나온 아서 레스크Arthur Lesk의 『Introduction to Bioinformatics』(2014)를 참고하면 된다. 첨언하자면, 유전체는 1차원 좌표계라 할 수 있으므로 유전체 조작은 본질적으로 공간과 관련 된 작업이다. ADAM 프로젝트가 제공하는 유전체 맞춤 API는 예전의 RDD 인터페이스를 사 용하여 공간상의 조인을 분산으로 처리하도록 구현되어 있다. 그러므로 이 장에서는 현재 버전 스파크에서 제공하는 데이터셋이나 데이터프레임 인터페이스 대신 원래의 인터페이스를 그대 로 사용하기로 한다. RDD를 사용하는 것에 관하여 이 책의 많은 부분과 달리, 이 장과 다음 장에서는 스파크의 구식 탄력적 분산 데이터셋, 즉 RDD API를 사용한다. 가장 큰 이유는 유전체 처리에서 흔히 사용되는 1차원 기하학 연산 에 특화된 다수의 조인 연산을 ADAM 프로젝트에서 만들었기 때문이다. 이들 연산은 이식 4 옮긴이_ 게놈 또는 유전체는 한 개체의 유전자의 총 염기서열로, 한 생물종의 거의 완전한 유전 정보의 총합이다. 참고로, 일반적으로 쓰 이고 이 책의 원문에서도 사용한 genome이라는 단어는 영어식으로 지놈이라고 읽히는데, 유전체에 처음 이름을 붙인 독일인 한스 윙 클러Hans Winkler가 붙인 이름인 genom의 독일어식 발음인 게놈을 읽는 것이 바람직하다. 다만 1000 Genome Project는 이것 자체가 하나의 고유명칭으로 1000 지놈 프로젝트로 번역하는 것이 옳다. 이 책에서는 Genome은 유전체로 번역하며, 1000 지놈 프로젝트라 는 번역명이 Genome을 지놈으로 번역하는 것이 옳음을 의미하지는 않는다. 5 옮긴이_ 전사(transcription)는 DNA의 유전 정보를 RNA에 복사하는 과정이다. 이를 통해서 DNA 복제 과정에 필요한 단백질을 RNA가 형성하는 등의 대사가 이루어진다. 전사인자는 이 전사 과정에 개입하는 단백질을 뜻한다. 유전자의 발현은 이들 전사인자의 결 합 부위의 결합에 의해 조절되므로 이를 예측하는 것은 유전체학의 중요한 이슈 중 하나다. ENCODE와 1000 지놈 프로젝트는 각각 https://www.encodeproject.org/ 와 http://www.1000genomes.org/ 를 참조하기 바란다.
  • 79.
    28310장 BDG 프로젝트와유전체학 데이터 분석하기 계획은 있지만 아직 데이터셋 API로 이식되지 않았다. 게다가 데이터프레임 API는 분산 처 리와 관련된 상세한 부분을 지정할 수 없기 때문에 ADAM의 조인 연산을 포팅하려면 스파 크의 질의 플래너를 직접 사용해야 한다. 한편, 이 장은 독자가 여타 스파크 기반 라이브러리 나 다른 오래된 코드를 통해 RDD API를 사용해야 할 때 도움이 될 수 있을 것이다. 10.1 모델링과 저장소를 분리하기 많은 과학자가 자신이 사용하는 도구에 맞는 고유한 파일 포맷을 필수로 여기는 것처럼, 생 물정보학자도 파일 포맷에 대하여 고민하며 많은 시간을 보낸다. 파일 포맷의 예로는 .fasta, .fastq, .sam, .bam, .vcg, .gvcf, .bcf, .bed, .gff, .gtf, .narrowPeak, .wig, .bigWig, .bigBed, .ped, .tped 등이 있다. 이 중 많은 포맷의 명세가 불완전하고 모호하며(이러한 이 유로 일관되게 구현되리라 확신하기 어렵다) 데이터를 ASCII로 인코딩하도록 규정하고 있다. ASCII를 사용한 데이터는 생물정보학에서 매우 흔하지만, 효율이 떨어지고 상대적으로 압축 률도 낮다. 그래서 https://github.com/samtools/hts-specs처럼 명세를 개선해보자는 커뮤니 티도 생겨났다. 거기에다 데이터를 항상 파싱해야 하기에 추가 연산도 수행해야 한다. 이들 파 일 포맷 모두 서열 정렬 판독Aligned Sequence Read, 유전자형 명칭Called Genotype, 염기서열 특징Sequence Feature, 표현형Phenotype과 같은 몇 가지 공통 객체 타입만을 필수로 저장하기 때문에 문제가 두드 러진다. (‘염기서열 특징’이라는 용어는 유전체학에서 조금씩 다른 의미로 사용되는데, 이 장 에서는 UCSC 유전체 브라우저의 기록 요소라는 의미로 사용한다.) 유명한 라이브러리인 바 이오파이썬Biopython (http://biopython.org/)은 모든 파일 포맷을 소수의 공통된 인메모리 모델 (Bio.Seq, Bio.SeqRecord, Bio.SeqFeature 등)로 읽어 들이는 파서들(Bio.SeqlO 등)로 가득 차 있다. 이러한 모든 문제를 에이브로와 같은 직렬화 프레임워크를 사용하여 단번에 해결할 수 있다. 내부의 저장소 파일 포맷으로부터 데이터 모델(즉, 명시적인 스키마)을 분리할 수 있으며, 인 메모리 표현이 가능하다는 에이브로의 특징이 해결의 열쇠다. 에이브로는 특정 유형의 데이터 를 프로세스 사이에 전달하는 방법이나 데이터를 특정한 파일 포맷으로 기록하는 프로세스를 지정한다. 이때 프로세스들이 인터넷을 사이에 두고 멀리 떨어져 있더라도 상관없다. 예를 들
  • 80.
    284 9가지 사례로익히는 고급 스파크 분석 (2판) 어 에이브로를 사용하는 자바 프로그램은 에이브로의 데이터 모델과 완전히 호환되는 여러 기 본 파일 포맷으로 데이터를 기록할 수 있다. 각각의 프로세스가 여러 파일 포맷들과 모두 호환 되는지는 걱정할 필요가 없다. 프로세스는 에이브로 데이터를 해석할 수 있고, 파일시스템에서 에이브로로 데이터를 읽어올 수만 있으면 된다. 예제로 염기서열 특징을 들여다보자. 우선 에이브로의 인터페이스 정의 언어Interface Definition Language (IDL)를 사용하여 객체에 적합한 스키마를 지정한다. enum Strand { Forward, Reverse, Independent } record SequenceFeature { string featureId; string featureType; ➊ string chromosome; long startCoord; long endCoord; Strand strand; double value; mapstring attributes; } ➊ ‘conservation(보존)’, ‘centipede(지네)’, ‘gene(유전자)’ 등의 유형이 올 수 있다. 이 자료형은 유전체 특정 위치의 보존 수준, 프로모터Promoter 또는 리보솜Ribosome 결합 부위의 존 재, 전사인자 결합 부위 등을 인코딩하는 데 사용할 수 있다. 인코딩할 때 고려할 수 있는 방법 의 하나로, 제약은 많지만 성능은 훨씬 좋은 이진 버전의 JSON이 있다. 특정한 데이터 스키마 가 주어지면 에이브로는 객체에 맞는 정확한 이진 인코딩을 정하여 네트워크를 통하거나 디스 크에 저장된 상태로 프로세스끼리 쉽게 데이터를 주고받을 수 있다. 각각의 프로세스가 다른 프로그래밍 언어로 만들어져도 상관없다. 에이브로 프로젝트는 자바, C/C++, 파이썬, 펄Perl을 포함한 많은 언어에서 에이브로로 인코딩된 데이터를 처리할 수 있는 모듈을 제공한다. 그렇 게 통신이 이뤄지고 나면, 메모리상의 객체를 프로그래밍 언어에 가장 알맞다고 생각되는 방법 으로 자유롭게 저장하면 된다. 저장 포맷과 데이터 모델을 분리하여 한 차원 높은 유연성과 추
  • 81.
    28510장 BDG 프로젝트와유전체학 데이터 분석하기 상화를 제공하는 것이다. 에이브로 데이터는 열 기반 파일 포맷(파케이 파일) 속의 에이브로- 직렬화 이진 객체Avro-serialized Binary Object (에이브로 컨테이너 파일)의 형태나 텍스트 JSON 형태 로 저장할 수 있다. 전자는 빠른 질의를 위한 것이고, 후자는 유연성을 극대화하기 위한 것이다 (효율은 가장 낮다). 마지막으로 에이브로는 필요에 따라 사용자가 새로운 필드를 추가할 수 있는 스키마 개정Schema Evolution 기능을 지원한다. 그 덕분에 스키마를 추가해도 모든 소프트웨어 가 구 버전과 새 버전의 스키마를 문제없이 처리할 수 있다. 요약하자면, 에이브로는 개정될 수 있는 데이터 스키마를 쉽게 명시하고, 많은 프로그래밍 언 어가 같은 데이터를 처리하고 여러 가지 포맷을 사용하여 데이터를 저장할 수 있게 해주는 효 율적인 이진 인코딩 수단이다. 에이브로 스키마를 사용해서 데이터를 저장하기로 하면 계산 성 능을 높이는 동시에 점점 더 많은 특수 데이터 포맷을 다뤄야 하는 고통에서 벗어날 수 있다. 6 직렬화/RPC 프레임워크들 개발 현장에는 수많은 직렬화 프레임워크가 쓰인다. 빅데이터 커뮤니티에서 가장 널 리 사용하는 프레임워크로 에이브로, 쓰리프트Apache Thrift, 구글의 프로토콜 버퍼Protocol Buffers(protobuf)가 있다. 셋 모두 객체나 메시지의 스키마를 명시할 때 사용하는 인터페이 스 정의 언어(IDL)를 제공하며 다양한 프로그래밍 언어로 컴파일할 수 있다는 점이 핵심이 다. 쓰리프트는 IDL 외에도 RPC를 명시하는 방법도 제공한다(프로토콜 버퍼를 위한 구글의 RPC 프레임워크는 gRPC라는 이름으로 오픈 소스화 되어 있다). 그리고 에이브로는 IDL과 RPC 외에도 데이터를 디스크에 저장하기 위한 파일 포맷을 지정하는 기능도 제공한다. 구 글이 최근에 발표한 ‘직렬화’ 프레임워크는 통신상이건 메모리상이건 같은 크기의 같은 메시 지를 사용하기 때문에 직렬화 과정에 들어가는 비용을 효과적으로 줄여준다.6 이들 모두는 다른 언어를 지원하고 언어별로 성능이 다르므로 어떤 상황에 어떤 프레임워크 가 적당하다고 일반화해 말하기는 어렵다. 앞의 예제에서 본 SequenceFeature 모델은 실데이터에 사용하기에는 조금 단순했다. 하지만 빅데이터 유전체학 프로젝트BDG Project (http://bdgenomics.org/)를 보면 다음 예를 포함한 다양 6 옮긴이_ 2016년 7월자 프로토콜 버퍼 3.0.0 베타4 버전에 추가된 Deterministic Serialization 기능을 말한다. 유용한 기능이지만 현재는 C++ API만 제공하고 있다.
  • 82.
    286 9가지 사례로익히는 고급 스파크 분석 (2판) 한 객체를 표현하는 데 사용할 수 있는 에이브로 스키마를 이미 정의해두었다. ● ‌‌리드Read7 를 표현하기 위한 AlignmentRecord ● ‌‌알려진 유전체 변이와 메타데이터를 표현하기 위한 Variant ● ‌‌특정한 유전자좌위Locus8 에서 지정된 유전자형을 표현하기 위한 Genotype ● ‌‌염기서열 특징(유전체 세그먼트에 대한 주석)을 표현하기 위한 Feature 실제 스키마는 깃허브에서 bdg-formats(https://goo.gl/8t2yDn)를 보면 찾을 수 있다. BDG 형식은 BAM이나 VCF와 같은 흔한 ‘구닥다리’ 형식을 대체하는 것이기도 하지만, 일반 적으로는 고성능의 ‘중재자’ 형식의 역할을 한다(BDG 형식의 원래 목적은 BAM과 VCF의 사 용을 대체하는 것이었지만 기존 방식 사용자들의 완강한 저항으로 목표 달성이 험난할 것으로 보인다). 세계 유전체학 보건연대Global Alliance for Genomics and Health에서도 프로토콜 버퍼를 사용한 자체 스키마들을 개발해왔다(https://goo.gl/1NfS7q). 이것이 다음 풍자 그림과 같은 스키마 경쟁의 확산으로 변하지 않기를 바란다. 그렇기는 해도 에이브로는 현재의 사용자 정의 ASCII 보다 성능과 데이터 모델링 면에서 이점이 많다. 이 장의 나머지에서는 BDG 스키마 일부를 사용하여 몇몇 일반적인 유전체학 작업을 수행할 것이다. (출처: http://xkcd.com/927/) 7 옮긴이_ 유전자를 판독할 때 전체 유전자를 한 번에 죽 읽어내지 못하므로, 여러 조각을 내서 읽은 후 이를 병합하여 판독하는 방식을 사 용한다. 이때 조각의 판독된 정보를 흔히 리드(read)라 한다. 8 옮긴이_ 염색체 지도에서 특정 유전자의 위치를 말한다. 표준이 급증하는 원리 (대표적인 예: A/C 충전기, 문자 인코딩, 모바일 메신저 등) 상황: 총 14개의 표준이 서로 경쟁한다. 상황: 총 15개의 표준이 서로 경쟁한다. 14개? 말도 안 돼! 모든 용도에 적합한 하나의 범용 표준을 만들어야겠어. 좋아! 잠시 후:
  • 83.
    31111장 파이스파크와 썬더로신경 영상 데이터 분석하기 “우리는 뇌가 차가운 오트밀과 농도가 같다는 사실에는 관심이 없다.” -앨런 튜링 영상 장비와 자동화 분야의 발전으로 뇌 기능과 관련된 데이터가 넘쳐나게 되었다. 과거의 실 험은 몇 개의 전극으로부터 시계열Time Series 데이터를 만들거나 뇌 단면의 정지 영상 몇 장을 얻 는 데 그쳤지만, 오늘날의 기술은 유기체가 활발히 활동하는 동안 넓은 영역의 수많은 신경 세 포Neuron에서 뇌 활동을 샘플링할 수 있다. 실제로, 브레인 이니셔티브BRAIN Initiative1 는 예를 들어 장기간에 걸쳐 쥐의 뇌에서 모든 신경 세포의 전기적 활동을 동시에 기록하는 일과 같은 매우 높은 수준의 기술 개발을 목표로 하고 있다. 측정 기술의 혁신도 분명히 필요하겠지만, 엄청난 양의 데이터가 새로 생성되어 생물학 분야에 완전히 새로운 패러다임이 열릴 것이다. 이번 장에서는 파이썬으로 스파크를 구동하는 파이스파크PySpark API(https://goo.gl/JXhKDg) 를 소개한다. 더불어 일반적인 대량의 시계열 데이터, 특히 신경 영상Neuroimaging 데이터를 처리 하기 위해서 파이스파크 위에서 개발된 썬더Thunder 프로젝트(http://thunder-project.org/)도 소개할 것이다. 파이스파크는 시각화를 위한 맷플롯립Matplotlib이나 ‘실행 가능한 문서’를 만들기 위한 아이파이썬 노트북IPython Notebook (주피터Jupyter 프로젝트)까지 포함한 파이데이터PyData 생태 계와 잘 통합되어 있기 때문에 탐색적 빅데이터 분석에 특히 잘 맞는 도구다. 1 옮긴이_ 버락 오바마 미국 대통령은 2013년 4월 ‘브레인 이니셔티브’를 발표하였다. 이 프로젝트의 목표는 인간 두뇌 활동의 모든 경로 와 지도를 완성하여 뇌 속 신경 세포가 어떻게 상호작용하는지를 규명하는 것이다. https://www.braininitiative.nih.gov/ 파이스파크와 썬더로 신경 영상 데이터 분석하기 CHAPTER 11 유리 레이저슨
  • 84.
    312 9가지 사례로익히는 고급 스파크 분석 (2판) 이번 장에서는 제브라피쉬Zebrafish2 의 뇌 구조 일부를 이해하는 작업에 이들 도구를 사용할 것이 다. 썬더를 사용해서 시간의 흐름에 따른 제브라피쉬의 활동 패턴을 파악하기 위해 뇌의 서로 다른 영역(신경 세포의 그룹)을 군집화할 것이다. 썬더는 파이스파크 RDD API로 빌드되어 있어서 이번 장에서는 RDD API를 사용한다. 11.1 파이스파크 소개 파이썬은 고수준 문법과 광범위한 라이브러리 패키지 덕분에 다양한 도구 중에서도 수많은 데 이터 과학자가 선호하는 도구다(http://bit.ly/186ShId). 스파크 생태계는 데이터 분석 환경에 서 파이썬의 중요성을 인식해왔으며, 파이썬과 JVM을 통합해보려는 과거의 시도가 큰 성과를 거두지 못했음에도 불구하고 스파크용 파이썬 API에 투자하고 있다. 3 전문가용 계산과 데이터 과학을 위한 파이썬 파이썬은 전문가용 계산과 데이터 과학에서 널리 사용되는 도구다. 예전에는 매트랩MATLAB, R, 매스매티카Mathematica를 사용했을 애플리케이션에서 지금은 파이썬을 사용하고 있다. 그 이유는 다음과 같다. ● ‌‌파이썬은 사용하고 배우기 쉬운 고급 언어다. ● ‌‌수치 계산부터 웹 스크랩 유틸리티와 시각화 도구에 이르기까지 폭넓은 라이브러리가 있다. ● ‌‌C/C++ 코드와 쉽게 결합할 수 있어, BLAS/LAPACK/ATLAS를 포함한 고성능 라이브러리 를 활용하기에도 좋다.3 기억해두면 좋을 라이브러리를 몇 개 소개하자면 다음과 같다. 2 옮긴이_ 성체의 크기가 3~4cm 정도인 열대 민물고기로 인간의 유전자 구성과 상당 부분 비슷하여 다양한 질병 연구에 활용되고 있다. 3 옮긴이_ BLAS(Basic Linear Algebra Subprograms)는 벡터 곱, 행렬 곱과 같은 저수준 행렬과 벡터의 수치 연산을 위한 포트란 라 이브러리이며, LAPACK(Linear Algebra PACKage)은 이 책의 앞에서 등장한 특잇값 분해(SVD)와 같은 고수준 연산을 지원하는 포 트란 라이브러리다. ATLAS(Automatically Tuned Linear Algebra Software)는 BLAS와 LAPACK의 일부를 포트란 77과 C 언 어용으로 이식한 라이브러리다.
  • 85.
    31311장 파이스파크와 썬더로신경 영상 데이터 분석하기 numpy/scipy/matplotlib 고속 배열 연산, 전문가용 함수, 매트랩에서 아이디어를 가져온 플로팅 라이브러리를 포 함한 일반적인 매트랩의 기능을 재현한다. pandas R의 data.frame과 비슷한 기능을 제공한다. 보통은 성능도 더 뛰어나다. scikit-learn/statsmodels 분류, 회귀, 군집화, 행렬 분해와 같은 머신러닝과 통계 모델을 고품질로 구현하여 제공한 다. nltk 자연어 처리에 널리 사용되는 라이브러리다. awesome-python 깃허브 저장소(https://github.com/vinta/awesome-python)에서 다른 많은 라이브러리의 목록을 찾을 수 있다. 스파크처럼 파이스파크를 시작해보자. export PYSPARK_DRIVER_PYTHON=ipython # 파이스파크는 IPython 셸을 사용할 수 있다. export PYSPARK_PYTHON=path/to/desired/python # 작업자 노드를 위한 설정이다. pyspark --master ... --num-executors ... ➊ ➊ pyspark도 spark-shell과 spark-submit에서와 같이 동일한 스파크 인수를 받는다. spark-submit을 사용하면 우리 스크립트 중 확장자가 .py인 파일을 찾아 서브밋Submit해줄 것 이다. 작업자 노드와 드라이버(예, IPython)에서 사용할 파이썬 버전을 명시할 수 있으며 버 전이 일치해야 한다. 파이썬 셸을 시작하면 클러스터와 상호작용하는 (sc로 선언된) 파이썬 SparkContext 객체를 생성한다. SparkContext를 사용할 수 있게 되면 파이스파크 API는 스 파크 API와 매우 유사하게 동작한다. 예를 들어 다음은 CSV 데이터를 읽어 들이는 모습이다. raw_data = sc.textFile('path/to/csv/data') # RDD[string] # 필터링하고, 쉼표를 기준으로 나누고, 실수(float)를 파싱하여 RDD[list[float]]를 얻는다. data = (raw_data
  • 86.
    314 9가지 사례로익히는 고급 스파크 분석 (2판) .filter(lambda x: x.startswith(#)) .map(lambda x: map(float, x.split(',')))) data.take(5) 스칼라 RDD API를 사용할 때와 비슷하게 텍스트 파일을 읽어 #으로 시작하는 줄을 제거한 후, CSV 데이터를 float 값 목록으로 파싱한다. 인수로 전달된 (예를 들어 filter나 map에 전 달된) 파이썬 함수들은 매우 유연하다. 파이썬 객체를 인수로 받아 파이썬 객체를 반환해야 한 다(filter의 반환값은 불리언으로 해석된다). 제약이 없는 것은 아니다. 먼저, 파이썬 함수 객 체는 클라우드피클Cloudpickle로 직렬화할 수 있어야 한다. 익명(람다) 함수도 마찬가지다. 그리고 클로저에서 참조하는 모든 모듈은 실행자 파이썬 프로세스가 실행되는 환경의 PYTHONPATH 환경변수에서 지정한 위치에 설치되어 있어야 한다. 참조 모듈을 사용하려면 그 모듈을 클러스 터 전체에 설치하고 모듈의 위치를 실행자 프로세스 구동 환경의 PYTHONPATH에 명시한다. 혹은 해당 모듈의 ZIP/EGG 파일을 스파크로 명시적으로 배포하면 PYTHONPATH에 추가 된다. 후자의 방식은 sc.addPyFile( )을 호출하여 수행할 수 있다. 파이스파크 RDD는 단지 파이썬 객체들의 RDD일 뿐이다. 파이썬 리스트처럼 이 RDD에는 혼합된 자료형의 객체도 저장할 수 있다(모든 객체가 PyObject의 인스턴스인 덕분이다). 11.1.1 파이스파크 내부 구조 디버깅을 간소화하고 잠재적인 성능 저하의 원인을 알고 대처하려면 파이스파크의 구현 원리 를 어느 정도 이해해두는 것이 좋다. [그림 11-1]을 보자. 그림 11-1 파이스파크 내부 구조
  • 87.
    31511장 파이스파크와 썬더로신경 영상 데이터 분석하기 파이스파크의 파이썬 인터프리터가 시작될 때 JVM도 함께 실행되며, 둘은 소켓을 통해 통신하 게 된다. 이 통신에는 Py4J 프로젝트가 사용된다. JVM은 실제 스파크 구동자로서의 역할을 하 며, 클러스터 노드의 스파크 실행자들과 통신하는 JavaSparkContext를 로드한다. 그 후에는 SparkContext 객체가 호출한 파이썬 API는 JavaSparkContext에서 호출하는 자바 API로 변환된다. 예를 들어 파이스파크의 sc.textFile( )은 JavaSparkContext의 .textFile 메서드 를 호출하며, 마지막에는 HDFS에서 데이터를 읽어 들이기 위해서 스파크 실행자의 JVM들과 통신한다.4 클러스터의 스파크 실행자들은 파이썬 인터프리터를 코어마다 실행하는데, 사용자 코드를 실 행해야 할 때는 데이터 통신에 유닉스 파이프Unix Pipe (stdin, stdout)를 이용한다. 로컬 파이스 파크 클라이언트의 파이썬 RDD는 로컬 JVM의 PythonRDD 객체에 대응한다. RDD와 관 련한 데이터는 실제로는 스파크를 구동하는 JVM의 자바 객체로 되어 있다. 예를 들어 파이 썬 인터프리터에서 sc.textFile( )을 실행하면 JavaSparkContext의 textFile 메서드를 호출 하고 이 메서드가 데이터를 클러스터상의 자바 String 객체로 읽어 들인다. 비슷한 방식으로 newAPIHadoopFile을 사용하여 파케이/에이브로 파일을 읽으면 자바 에이브로 객체로 읽 어 들인다. 파이썬 RDD에서 API가 호출되면 파이썬 람다 함수 같은 모든 연관 코드는 클라우드피클 모 듈을 통해서 직렬화되어 실행자들에 배포된다. 그런 다음, 데이터는 자바 객체에서 파이썬에서 사용할 수 있는 형태(예를 들어 피클Pickle 객체)로 변환되고 파이프를 통해 실행자와 관련된 파 이썬 인터프리터로 흘러 들어간다. 필요한 모든 파이썬 처리는 인터프리터에서 실행되며, 결과 (기본 설정으로는 피클 객체)는 다시 JVM에 있는 RDD로 저장된다. 파이썬의 실행 코드 직렬화 기능은 스칼라의 직렬화만큼 강력하지는 않다. 파이스파크 개발자 들이 지금은 없어진 파이클라우드PiCloud에서 만든 클라우드피클이라는 별도 모듈을 사용해야 했던 이유다. 4 옮긴이_ Py4J는 파이썬 인터프리터에서 파이썬 프로그램이 JVM의 자바 객체에 동적으로 접근할 수 있도록 처리해준다.
  • 88.
    316 9가지 사례로익히는 고급 스파크 분석 (2판) 11.2 썬더 라이브러리 개요와 설치 썬더 라이브러리의 예제와 문서 썬더 패키지는 훌륭한 문서와 튜토리얼을 제공한다. 이어지는 예제는 썬더 문서의 데이터셋 과 튜토리얼을 참조했다. 썬더는 스파크에서 대용량의 공간과 시계열 데이터셋(즉, 커다란 다차원 행렬)을 처리하기 위 한 파이썬 도구 모음이다. 행렬 계산에는 넘파이NumPy 모듈을, 몇몇 통계 기법을 분산 처리하는 데에는 MLlib 라이브러리를 적극적으로 사용한다. 파이썬으로 만들어져서 매우 유연하고, 또 수많은 개발자가 이용할 수 있다. 다음 절에서는 썬더 API를 소개하고 썬더와 파이스파크로 감 싸진 MLlib의 K-평균 군집화 구현을 사용하여 몇몇 신경 활동을 추적해 패턴을 분류해볼 것 이다. 썬더를 설치하려면 pip install thunder-python을 호출하기만 하면 되지만, 모든 작 업자 노드에 설치해야 한다. 설치를 끝내고 SPARK_HOME 환경변수를 설정하면 다음과 같이 파이스파크 셸을 실행할 수 있다. $ export PYSPARK_DRIVER_PYTHON=ipython # 일반적으로 추천하는 설정이다. $ pyspark --master ... --num-executors ... [...some logging output...] Welcome to ____ __ / __/__ ___ _____/ /__ _ / _ / _ `/ __/ '_/ /__ / .__/_,_/_/ /_/_ version 2.0.2 /_/ Using Python version 2.7.6 (default, Apr 9 2014 11:54:50) SparkContext available as sc. Running thunder version 0.5.0_dev A thunder context is available as tsc In [1]:
  • 89.
    31711장 파이스파크와 썬더로신경 영상 데이터 분석하기 11.3 썬더로 데이터 읽어 들이기 썬더는 특별히 신경 영상 데이터셋을 염두에 두고 설계되었다. 그래서 시간별로 여러 번 촬영 한 대량의 영상 데이터를 분석하는 데 특화되었다. 먼저, S35 안의 썬더 저장소(s3://thunder-sample-data/images/fish/)에서 제공하는 예 제 데이터셋 중 제브라피쉬 뇌 영상 몇 장을 읽어보자. 동작 방식을 설명하는 것이 목적이므로 이 예제는 엄청나게 다운샘플링된 데이터로 수행한다. 데이터를 추가하거나 더 큰 데이터셋을 사용하고자 한다면 썬더 문서를 참조하자. 제브라피쉬는 생물학 연구에서 널리 사용하는 모델 생물Model Organism이다. 크기가 작고 짧은 주기로 번식하여 척추동물 발생의 모델로 사용한다. 또 한, 재생이 특출나게 빠르다는 점도 흥미롭다. 제브라피쉬가 신경과학 연구에 훌륭한 모델인 이유는 몸이 투명하고 뇌가 작아서 개별 신경을 구분할 수 있고, 그 전체를 고해상도 영상으로 녹화할 수 있기 때문이다. 다음은 데이터를 읽어 들이는 코드다. import thunder as td data = td.images.fromtif('/user/ds/neuro/fish', engine=sc) ➊ print data print type(data.values) print data.values._rdd ... Images mode: spark ➋ dtype: uint8 shape: (20, 2, 76, 87) class 'bolt.spark.array.BoltArraySpark' ➌ PythonRDD[2] at RDD at PythonRDD.scala:48 ➍ ➊ ‌SparkContext 객체를 전달하는 방법에 주목하자. 썬더는 동일한 API를 사용하여 로컬 모드 동작을 지원 한다. ➋ ‌스파크에서 지원하는 Images 객체를 볼 수 있다. ➌ ‌BoltArray는 기저의 데이터 컨테이너를 추상화한 것으로, 이 프로젝트에서는 로컬 데이터 표현과 스파크 RDD 표현을 추상화한다. ➍ ‌PythonRDD가 기저의 RDD 객체다. 5 옮긴이_ S3는 아마존의 클라우드 저장소 서비스다.
  • 90.
    330 찾아보기 INDEX 숫 자 3D화소319 1000 지놈 프로젝트 282 ㄱ 가우시안 혼합 모델 160 거짓 양성 67 거짓 음성 67 경로 206 고계함수 43 고윳값 분해 269 곡선 아래 면적 90 과거 기반 시뮬레이션 256 과적합 93, 108, 126 교차 검증 데이터셋 90 교차 최소 제곱 73, 76 구동자 82 군집계수 192 군집 중심 137 군집화 72, 137 그래프엑스 190 그래프 이론 189 그래프프레임 190 꼭짓점 189 꼭짓점 속성 203 ㄴ 낮은 계수 근사 162 네트워크 평균 군집계수 220 ㄷ 다변량 정규분포 268 단어 빈도 163 단어빈도-역문서빈도 170 데이터 정제 29 데이터프레임 50, 51 동시발생 그래프 202 동시발생 네트워크 201 ㄹ 람다 93 랜덤 포레스트 104, 129 레코드 링크 33 ㅁ 마할라노비스 거리 160 메르센 트위스터 272 몬테카를로 시뮬레이션 253 문서-단어 행렬 162, 163 밀도 기반 공간 군집화 160 ㅂ 범주형 변수 154 범주형 특징 103 변 189 변 속성 203 복원추출 275 부분 적용 함수 93 부트스트래핑 275 분류 72, 102 분산-공분산 255 불용어 168 브레인 이니셔티브 311 브로드캐스트 변수 83 브로드캐스트 해시 조인 83 비지도 학습 136 비편향 추정 123 빅데이터 유전체학 프로젝트 285 ㅅ 세션화 248 수신자 조작 특성 90 수치형 특징 103 숨은 의미 분석 161 스크로블링 72 스파크R 146 스파크 셸 34 스파크 스트리밍 25, 159 실루엣 계수 160 썬더 316 ㅇ 암묵적 자료형 60 액션 42 어간 추출 168 엔트로피 120 역문서 빈도 163 연결 성분 192, 206 연구를 위한 분석 22 예측 함수 91 온전성 검사 153 완전 그래프 218 운영을 위한 분석 23 원-핫 인코딩 110 유클리드 거리 137, 143 의사 결정 나무 104 이상 탐지 136 ㅈ 자연어 처리 161 작은 세상 네트워크 217 잠재특징 75 정규직교 기저 172 지니 불순도 120 지도 학습 102 집계 함수 55
  • 91.
    331찾아보기 INDEX ㅊ 차수 210 차수 분포192 차원 감소 150 최대 깊이 119 축 회전 59 ㅋ 카이제곱 검정 212 카이제곱 분포 213 카이제곱 통계량 213 캐시 52 커널 밀도 추정 265 케이스 클래스 65 코사인 유사도 179 콘틱 292 콜모고로프-스미르노프 검정 278 클로저 83 클릭 218 ㅌ 탄력적 분산 데이터셋 26, 37 테스트 데이터셋 90 통 119 특잇값 분해 172 특징 64, 103 특징 벡터 85, 103 특징 선택 63 특징 정규화 152 ㅍ 파이스파크 312 파이프라인 API 113 파케이 형식 294 파티션 37 평균 경로 길이 192 표제어 추출 164, 168 표준점수 152 품질 평가 89 프레겔 190, 220 ㅎ 하이브 56 하이퍼파라미터 86, 94 학습 데이터셋 90, 104 함수형 프로그래밍 43 행렬 분해 74 행렬 채우기 75 협업 필터링 73 형태변환 59 혼합 정규분포 278 화소 319 확률 밀도 함수 256 회귀 102 A ~    C Action 42 ADAM CLI 287 ADAM 프로젝트 287 ALS 76 Anomaly Detection 136 AUC 90 AUC 계산 91 Average Path Length 192 BDG Project 285 Bin 119 Bootstrapping 275 BRAIN Initiative 311 Broadcast Hash Join 83 Case Class 65 Categorical Feature 103 Centroid 137 ChIP-seq 296 Chi-squared Distribution 213 Chi-squared Statistic 213 Chi-squared Test 212 Classification 72 Clique 218 Closure 83 Clustering 72 Clustering Coefficient 192 Collaborative Filtering 73 Complete Graph 218 Connected Component 192 Contig 292 Co-occurrence Graph 202 Co-occurrence Network 201 Cosine Similarity 179 Covtype 데이터셋 108 D ~    F DataFrame 27 Dataset 27 DBSCAN 160 Decision Tree 104 Degree 210 Degree Distribution 192 Dimension Reduction 150 Document-term Matrix 162 Driver 82 Edge Attribute 203 EdgeRDD 203 Eigendecomposition 269 Entropy 120 Esri Geometry API 231 Euclidean Distance 137 False-negative 67
  • 92.
    332 찾아보기 INDEX False-positive 67 Feature103 Feature Vector 85, 103 G ~    K Gaussian Mixture Model 160 GeoJSON 233 Gini Impurity 120 GraphX 190 Higher-order Function 43 Historical Simulation 256 Hyperparameter 86 IDF 163 Implicit Type 60 Kernel Density Estimation 265 k-fold Cross-validation 92 K-means Clustering 137 Kolmogorov-Smirnoff Test 278 k-겹 교차 검증 92 K-평균++ 145 K-평균‖ 145 K-평균 군집화 137 L ~    N Lambda 93 Latent Feature 75 Lemmatization 168 Low-rank Approximation 162 LSA 161 Mahalanobis Distance 160 Matrix Completion 75 Matrix Factorization 74 Mersenne Twister 272 Monte Carlo Simulation 253 Multivariate Normal Distribution 268 Network Average Clustering Coefficient 220 NLP 161 Numeric Feature 103 O ~    Q One-hot Encoding 110 Orthonormal Basis 172 Overfitting 93 Partition 37 Path 206 PDF 256 Pixel 319 QR Decomposition 76 QR 분해 76 R ~    S R 146 Random Decision Forest 104 RDD 26, 37 Record Linkage 33 REPL 40 ROC 90 Sampling with Replacement 275 Sanity Check 153 Sessionization 248 Silhouette Coefficient 160 SparkContext 34 SparkR 146 Spark SQL 56 spray-json 234 Standard Score 152 Stemming 168 Stop Word 168 Supervised Learning 102 T ~    Z TF 163 TF-IDF 170 Training Set 104 Unbiased Estimate 123 Unsupervised Learning 136 Variance-Covariance 255 Vertex Attribute 203 VertexRDD 203 Voxel 319 z-스택 319