페이지

2018년 7월 3일 화요일

CHAPTER 1 한눈에 보는 머신러닝

기존 주위 머신러닝
- 광학 문자 판독기 Optical Character Recognition(OCR)
- 스팸 필터 spam filter

추천과 음성 검색으로 발전

기계가 배운다는 것이 정학히 무엇을 의미?

머신러닝

- 지도학습
- 비지도학습

- 온라인 학습
- 배치 학습

- 사례 기반 학습
- 모델 기반 학습

전형적인 머신러닝 프로젝트의 작업 흐름에서 나타나는 주요 문제점과 머신러닝 시스템을 평가하고 튜닝하는 방법

데이터 과학자가 꼭 알아야 할 여러 가지 기초 개념과 용어를 소개


5. 올바른 자료구조 선택하기

파이썬에서 가장 빈번하게 사용하는 자료구조는 리스트, 튜플, 셋, 딕셔너리다. 이 네가지 구조는 모두 데이터의 컬렉션(collection)이다.

파이썬은 리스트를 배열처럼 취급한다. 리스트에서 아이템을 검색할 때 걸리는 시간은 선형적으로 증가하기 때문에, 검색이 가능한 대용량의 데이터를 저장하는 용도로는 실용성이 떨어진다.

투플은 변형이 불가능한 리스트로 한 번 생성되면 변형할 수 없다. 튜플 역시 검색에 걸리는 시간이 선형적으로 증가한다.

리스트나 튜플과 달리 셋에는 순서가 없고, 셋이 담고 있는 아이템은 인덱스가 없다. 셋에는 같은 아이템이 중복으로 저장될 수 없으며, 검색 시간은 준선형적인 O(log(N))으로 증가한다. 회원 명단을 조회하거나 중복 항목을 삭제하는 데 셋을 유용하게 사용할 수 있다(중복된 아이템이 들어 있는 리스트를 셋으로 변환하면 중복된 아이템을 모두 삭제한다).

mList = list(set(myList)) # myList에서 중복된 아이템들을 삭제한다.

리스트 데이터를 셋으로 변환해 더 빠르게 회원 명단을 조회해 보자. 예를 들어 bigList라는 리스트에는 정수 1 부터 1000만까지가 문자열로 변환되어 들어 있다고 하자.

bigList = [str(i) for i in range(10000000)]
"abc" in bigList # 0.2초가 걸린다
bigSet = set(bigList)
"abc" in bigSet #15~30마이크로초가 걸린다. 1만 배나 더 빠르다!

딕셔너리는 키(key)를 값(value)에 매핑한다. 숫자, 불, 문자열, 튜플처럼 해시화 할 수 있는 데이터 타입은 키가 될 수 있고, 같은 딕셔너리에 들어 있다 하더라도 키들은 서로 다른 데이터 타입에 속할 수 있다. 값의 데이터 형식에도 별도의 제약 사항은 없다. 딕셔너리의 검색 시간은 준선형적인 O(log(N))으로 증가한다. 키-값으로 검색해야 할 때 딕셔너리는 매우 유용하다.

튜플(키, 값)이 여러 개 있는 리스트에서 딕셔너리를 만들 수 있다. 그리고 내장된 클래스 생성자(constructor)인 enumerate(seq)를 사용해 seq안의 아이템 순분을 키로 지정한 딕셔너리를 만들 수 있다.

seq = ["alpha", "bravo", "charlie", "delta"]
dict(enumerate(seq))
>>>
{0: 'alpha', 1: 'bravo', 2: 'charlie', 3:'delta'}

딕셔너리를 만드는 또 다른 방법은 키 순서열(kseq)과 값 순서열(vseq)에 클래스 생성자인 zip(kseq, vseq)를 사용하는 것이다.

kseq = "abcd"  # 문자열 또한 순서열이다.
vseq = ["alpha", "bravo", "charlie", "delta"]
dict(zip(kseq, vseq))
>>>
{'a': 'alpha', 'c': 'charlie', 'b': 'bravo', 'd': 'delta'}

파이썬에서 enumerate(seq)와 zip(kseq, vseq) 함수는 (자주 쓰는 range() 함수 또한) 리스트 제너레이터(generator)로 사용한다. 리스트 제너레이터는 이터레이터(iterator)인터페이스를 제공하는데, 이는 for 루프를 사용 가능하게 한다. 실제 리스트와 달리 리스트 제너레이터는 요청이 있을 때만 다음 아이템을 생산하는 지연 방식(lazy way)으로 작동한다. 제너레이터는 대용량의 리스트를 소화할 수 있으며, 심지어 '무한한'리스트도 허용한다. list() 함수를 사용해 제너레이터를 리스트로 명시적으로 변환할 수 있다.

2018년 7월 1일 일요일

4. 기본 문자열 함수 이해하기

문자열은 컴퓨터와 인간의 세계를 잇는 상호 작용의 기본 단위다. 거의 모든 원천 데이터는 문자열 형태로 저장되어 있다. 여기서는 텍스트 문자열을 읽고 변형하는 방법을 배운다.
여기서 다루는 모든 함수는 내장된 str클래스의 멤버다.

대.소문자 변환(case conversion)함수는 원래 문자열 s의 복사본을 반환한다. lower()함수는 모든 문자를 소문자로 변환하고, upper() 함수는 모든 문자를 대분자로 변환한다. 그리고 capitalize() 함수는 첫 번째 문자를 대문자로 변환하고, 나머지 문자들은 소문자로 변환한다. 이 함수들은 아파벳이 아닌 문자는 무시한다. 대.소문자 변환 함수는 62쪽에서 다룰 정규화의 가장 중요한 요소다.

프레디케이트(predicate)함수는 해당 문자열 s가 특정 클래스에 속하는지에 따라 True나 False를 반환한다. islower()함수는 모든 알파벳 문자가 소문자인지 체크한다. isupper()함수는 모든 문자가 대문자인지 확인한다. isspace()함수는 모든 문자가 공백인지 체크한다. isdigit()함수는 모든 문자가 0에서 9 사이 숫자인지 확인한다. 그리고 isalpha() 함수는 모든 문자가 a~z, A~Z사이의 아파벳 문자인지 체크한다. 여러분도 이 함수들을 사용해 단어가 정확하지, 정수가 양수인지, 올바르게 뛰어쓰기를 했는지 등을 테스트할 수 있다.

외부 파일이나 데이터베이스, 웹에서 데이터를 가져왔다면 때때로 파이썬은 문자열 데이터를 문자열이 아닌 바이너리 배열로 표현한다. 이때 파이썬에서는 바이너리 배열 앞에 b를 붙여서 표기한다. 예를 들어 bin = b"Hello"는 바이너리 배열이고, s="Hello"는 문자열이다. 여기서 s[0]은 'H'이고 b[0]은 72인데 72문자 'H'에 해당하는 ASCII문자코드(CHARCODE)다. 디코딩(decoding)함수는 바이너리 배열을 문자열로 변환한다. bin.decode()는 바이너리 배열을 문자열로 변환하고, s.encode()는 문자열을 바이너리 배열로 변환한다. 많은 팡썬 함수는 문자열로 변환된 상태의 바이너리 데이터를 처리한다.

문자열 처리의 첫 번째 단계는 원치 않는 공백(새로운 줄과 탭을 포함한)을 제거하는 것이다. lstrip()(왼쪽 공백 제거)과 rstrip()(오른쪽 공백 제거), strip() 함수는 문자열의 모든 공백을 제거한다(문자 사이의 공백은 제거하지 않는다). 이렇게 공백을 제거하다 보면 아무것도 없는 빈 문자열이 될 수도 있다.!

"Hello, world! \t\t\n".strip()
>>>
'Hello, world!'

때때로 문자열은 공백, 클록이나 쉼표 등 구분자로 분리된 여러 개의 토큰으로 구성되어 있다. split(delim=" ") 함수는 delim을 구분자로 사용해 문자열 s를 부분 문자열의 리스트로 쪼갠다. 구분자를 지정하지 않았다면 파이썬이 공백을 사용해 문자열을 쪼개고, 연속해서 공백이 있으면 이를 하나의 공백으로 인식한다.

"Hello,  world!".split()  # Hello, 와 world!사이에 2개의 공백이 있다.
>>>
['Hello', 'world!']


"Hello,  world!". split(" ")  # Hello, 와 world! 사이에 2개의 공백이 있다.
>>>
['Hello', ' ', 'world!']

"www.networksciencelab.com".split(".")
>>>
['www', 'networksciencelab', 'com']

자매 함수인 join(ls)는 객체 문자열을 접착제로 사용해 문자열 리스트 ls를 하나의 문자열로 붙인다. join()함수를 사용하면 문자열 조각을 재조합할 수 있다.

", ".join(["alpha", "bravo", "charlie", "delta"])
>>>
'alpha, brawo, chalie, delta'

앞의 예제에서 join() 함수는 접착제 문자열 사이에만 넣고, 첫 번째 문자열 앞이나 마지막 문자열 뒤에는 넣지 않는 것을 볼 수 있다. 문자열을 자르고 다시 합치는 것은 구분자를 다른 문자열로 치환하는 것과 같다.

"-".join("1.617.305.1985".split("."))
>>>
'1-617-305-1985"

이따금 여러분은 이 두가지 함수를 같이 사용해서 필요 없는 공백을 문자열에서 제거하고 싶을 것이다. 정규 표현식에 기반한 치환을 사용하면 같은 결과를 얻을 수 있다.

"  ".join("This string\n\r has many\t\tspaces".split())
>>>
'This string has many spaces'

find(needle) 함수는 해당 문자열에서 부문 문자열 needle이 처음 등장하는 인덱스를 반환하며, 부분 문자열이 없ㅇ르 때는 -1을 반환한다. 이 함수는 대.소문자를 구분(case-sensitive)한다. 문자열에서 특히 관심 있는 부분을 찾는데 find()함수를 활용할 수 있다.

"www.networksciencelab.com".find(".com")
>>>
21

count(needle) 함수는 대상 문자열에서 부문 문자열 needle이 등장하는 횟수를 반환한다. 이 함수 역시 대.소문자를 구분한다.

"www.networksciencelab.com".count(".")
>>>
2

문자열은 데이터 처리 프로그램을 구성하는 요소이지만 유일한 구성 요소는 아니며, 가장 효율적인 요소라고도 할 수 없다. 여러분은 앞으로 리스트(list), 튜플(tuple), 셋(set), 딕셔너리(dictionary)를 사용해 문자열과 수치형 데이터를 묶고, 더 효율적인 방법으로 검색하고 정렬하게 될 것이다.



3. 보고서 구조

프로젝트 보고서는 우리가 데이터 분석 의뢰인(고객)에게 전달하는 결과물이다. 보고서는 보통 다음 항목으로 구성된다.

- 요약(짧은 프로젝트 설명)
- 서론
- 데이터 수집과 처리에 사용한 방법
- 분석 결과(중간 결과나 중요도가 떨어지는 내용은 포함하지 않고 부록에 삽입)
- 결론
- 부록

부록에는 부차적이 결과와 차트뿐만 아니라 데이터를 처리하는 데 사용한 모든 재사용 코드를 기록한다. 스크립트에는 주석을 충실히 달아서 별도의 파라미터 입력이나 사용자 상호 작용 없이도 실행할 수 있어야 한다.

마지막으로 원천 데이터를 제출하는 것도 매우 중요하다. 의뢰인이 데이터를 제공했거나 해당 파일을 변형하지 않았다면, 제출하는 원천 데이터는 코드를 재사용 가능한 방법으로 실행할 수 있어야 한다. 보통 첨부한 모든 데이터 파일의 출처와 포맷은 README 파일에 기록한다.

이러한 보고서 구조를 반드시 지켜야 할 필요는 없다. 데이터 분석 의뢰인의 요청이나 상식적인 판단에 따라 다른 대안을 사용해도 좋다.


2. 데이터 수집 파이브 라인

데이터 수집은 다음과 같이 다양한 출처에서 입력 데이터 포함된 아티팩트(artifact)를 획득하고, 아트팩트에서 데이터를 추출하며, 추출한 데이터를 추가적인 처리에 적합한 형태로 변환하는 것이다.

데이터를 얻는데 주로 사용하는 출처 세가지는 인터넷(즉, 월드 와이드 웹), 데이터베이스, 로커 파일(다른 프로그램으로 만들거나 인터넷에서 내려받은 파일)이다. 다른 파이썬 프로그램을 사용해 만들거나 '압축(pickled)'한 파일도 역시 로컬 파일이다('UNIT 12. pickle로 데이터 압축하기'에서 더 자세히 알아보자).

아티팩트에 들어 있는 포맷은 매우 다양하다. 다음 장부터 가장 인기 있는 데이터 포맷들을 다루는 방법을 자세히 알아볼 것이다.

- 자연어로 된 비정형 플레인 텍스트 데이터(영어나 중국어)
- 정형 데이터
   - 쉼표로 구분된 텍스트(CSV) 파일 형식의 데이블형 데이터
   - 하이퍼텍스트 마크업 언어(HTML)나 다목적 마크업 언어(XML)로 된 태그 데이터
   - JSON(JavaScript Object Notation) 형식의 태그 데이터

추출한 데이터의 원래 구조, 추가적인 처리의 목적과 특성에 따라 이 책에 수록된 예제에서 사용한 데이터의 파이썬에 내장된 데이터 구조(리스트와 딕셔너리)나, 특수한 연산(numpy 배열이나 pandas 데이터 프레임)을 지원하는 고급 데이터 구조로 표현한다.

필자는 데이터 처리 파이프라인(원천 데이터의 수립, 전처리, 변환, 기술 통계의 탐색적 데이터 분석, 데이터 모델링과 예측)을 완전히 자동화하려고 노력했다.
인터팩티브 GUI도구는 가급적 사용하지 않는데, 배치(batch)모드에서 실행하기가 쉽지않고 작동 로그를 남기지 않기 때문이다. 필자는 모듈성, 재사용성, 복구용이성을 높이려고 긴 파이프라인을 작은 서브 파이브라인으로 쪼개 중간 결과를 pickle이나 JSON 파일로 저장할 것이다.

파이프라인 자동화는 자연스럽게 재사용 가능한 코드로 이어진다. 재사용 가능한 코드를 사용하면 별도의 상호 작용 없이도 누구나 원천 데이터로 보고서에 기록된 최종 결과물을 얻을 수 있다. 다른 연구자들은 재사용 가능한 코드로 여러분의 모델과 결과를 검증하고, 여러분이 개발한 프로세스를 적용해 문제를 해결할 수 있다.

2018년 6월 30일 토요일

1. 데이터 분석 과정

전형적인 데이터 분석 과정은 일반적인 과학적 발견의절차와 같다.
데이터 과학에서는 대답해야 할 질문과 적용해야 할 분석 방법에서 발견이 시작된다. 가장 단순한 형태의 분석 방법은 기술(descriptive) 통계로 데이터셋을 취합해 시각화한 형태로 표현한다. 주어진 샘플 데이터의 크기가 작고, 이것으로 더 큰 모수를 알고 싶다면 통계에 기반한 추정(inferential)이 적합하다. 예측(predictive)을 하고자 하는 분석가는 과거에서 배워 미래를 예측하낟. 인과(causal)분석은 서로에게 영향을 미치는 변수들을 식별한다. 마지막으로 역학(mechanistic)데이터 분석은 변수가 다른 변수에 정학히 어떤 여향ㅇ을 주는지 탐구한다.

여러분이 진행하는 분석은 퀄리티는 결국 얼마나 좋은 데이터를 사용하느냐에 달렸다. 무엇이 가장 이상적인 데이터셋일까? 이 이상적인 세계에서 어떤 데이터가 여러분의 질문에 답을 가졌을까? 하지만 현실에서는 이상적인 데이터셋이 존재하지 앟거나 구하기가 매우 어려울 수있다. 그렇다면 데이터가 많지 않거나 측정값이 적확하지 않은 데이터셋이더라도 원하는 목적을 이룰수 있을까?

다행이도 웹이나 데이터베이스에서 원천 데이터를 얻기는 그리 어렵지 않으며, 내려받기와 문자 해독을 지원하는 파이썬 코드가 널려 있다. 'UNIT 02. 데이터수집 파이프라인'에서 더 자세히 알아보자.

우리가 살고 있는 불완전한 세상에서 완전한 데이터란 없다. '더러운(dirty)'데이터에는 누락된 값, 이상치, 여러 '비정삭적인' 아이템이 들어 있다. 몇 가지 '더러운' 데이터의 예로 미래의 생년월일, 음수로 표현된 나이와 체중, noreply@처럼 사용할 수 없는 이메일 주소를 들 수 있다. 원천 데이터를 얻으면 다음 데이터 정제 도구와 여러분의 통계학적 지식을 활용해서 데이터셋을 정규화해야 한다.

데이터를 정제했다면 이제 기술 통계 분석과 탐색적 분석을 해보자. 이 단계에서는 결과물은 통상적으로 산포도(scatter plot),히스토그램, 통계학 요약이다. 이 과정을 거쳐 데이터셋에감을 잡아 후속 분석 방향을 정할 수 있다.특히 데이터셋을 구성하는 변수가 많다면 감을 잡는 과정은 반드시 필요하다.

그리고 이제 미래를 예측할 차례다. 데이터 모델을 적절하게 학습했다면 이를 사용해 과거를 배워 미래를 예측할 수 있다. 만든 모델과 그 예측 정확도를 평가해야 한다는 것을 잊지 말자!

지금부터는 통계학자와 프로그래머로서가 아니라 도메인 전문가로서 역할을 수행할 때다. 몇 가지 결과를 얻기는 했는데 이것이 정말 의미가 있을까? 바꿔 말하면 이 결과가 다른 사람의 관심을 끌거나 어떤 변화로 이어지는가? 이번에는 여러분이 지금까지 만든 결과물을 평가하는 사람이라고 차자. 무엇을 잘했고, 잘못했고, 기회가 주어지면 어떤 부분을 개선할 수 있을까? 다른 데이터를 사용하거나 다른 종류의 분석을 수행하거나 다른 질문을 하거나 다른 모델을 만드는 것이 나을까? 다른 누군가가 이러한 질문을 할 바에야 스스로가 먼저 하는 것이 더 낫다. 아직 프로젝트 맥락을 이해하고 있다면 이것의 답을 찾아보자.

마지막으로 어떻게, 왜 데이터를 처리했는지, 어떤 모델을 만들었는지, 어떤 결론과 예측이 가능한지 보고서를 만들어야 한다. 이 장 마지막인'UNIT 03. 보고서 구조'에서 더 자세히 알아보자.

여러분의 학습을 돕는 동반자로서 이 책은 특히 데이터 분석의 준비 단계에 초점을 마춘다. 준비 단계에서는 데이터를 수집.전처리.정리.분류하며, 다른 단계에 비해 정형화되어 있지 않아 다양한 창의적 접근이 가능하다. 예측 모델링을 생략하지는 않았다. 거기서 진짜 마법 같은 일이 일어나니까 말이다.) 결과 해석, 비판, 보고는 분석 주제에 따라 보통 다른 접근 방식을 취해야 한다.






2018년 6월 2일 토요일

Convolutional Neural Networks

Neurons in Human Vision

The human sense of vision is unbelievably advanced. Within fractions of seconds, we can identify objects within our field of view, without thought or hesitation. Not only can we name objects we are looking at, we can also perceive their depth, perfectly distingush their contrours, and separate the objects from their backgrounds. Somehow our eyes take in raw voxels of color data, but our brain transforms that information into more meaningful primitives-lines, curves, and shapes - that might indicate, for example, that we're looking at a house cat.

Foundational to the human sense of vision is the