전통적인 프로그래밍 기법을 사용해 어떻게 스팸 필터를 만들 수 있을지 생각해 봅시다.
1. 먼저 스팸에 어떤 단어들이 주로 나타나는지 살펴봅니다. 그러면 '4U', '신용카드', '무료', '굉장한' 같은 단어나 구절이 제목에 많이 나타나는 경향이 있다는 것을 알 수 있습니다. 어쩌면 보낸이의 이름이나 메일 주소, 본문 등에서 다른 패턴을 감지할 수도 있습니다.
2. 발견한 각 패턴을 감지하는 알고리즘을 작성하여 프로그램이 이런 패턴을 발견했을 때 그 메일을 스팸으로 분류하게 합니다.
3. 프로그램을 테스트하고 충분한 성능이 나올 때까지 1단계와 2단계를 반복합니다.
전통적인 접근 방법에서는 문제가 단순하지 않아 규칙이 점점 길고 복잡해지므로 유지 보수하기 매우 힘들어집니다
반면 머신러닝 기법에 기반을 둔 스팸 필터는 일반 메일에 배해 스팸에 자주 나타나는 패턴을 감지하여 어떤 단어와 구절이 스팸 메일을 판단하는 데 좋은 기준인지 자동으로 학습합니다. 그러므로 프로그램이 훨씬 짧아지고 유지 보수하기 쉬우며 대부분 정확도가 더 높습니다.
더군다나 스팸 메일 발송자가 '4U'를 포함한 모든 메일이 차단된다는 것을 안다면 '4U' 대신 'For U'를 쓰기 시작할지도 모릅니다. 전통적인 프로그래밍 방식의 스팸 필터는 'For U' 메일을 구분하기 위해 수정이 필요합니다. 스팸 메일 발송자가 스팸 필터에 대항해 계속 단어를 바꾸면 영원히 새로운 규칙을 추가해야 합니다.
하지만 머신러닝 기반의 스팸 필터는 사용자가 스팸으로 지정한 메일에 유독 'For U'가 자주 나타나는 것을 자동으로 인식하고 별도의 작업을 하지 않아도 자동으로 이 단어를 스팸으로 분류합니다.
머신러닝이 유용한 또 다른 분야는 전통적인 방식으로는 너무 복잡하거나 알려진 알고리즘이 없는 문제입니다. 음성 인식speech recognition을 예로 들 수 있습니다. 'one'과 'two'두 단어를 구부하는 프로그램을 작성한다고 합시다. 단어 'tow'는 높은 피치pitch의 사운드('T')로 시작하므로 높은 피치의 사운드 강도를 측정하는 알고리즘을 하드코딩해서 'one'과 'two'를 구분할 수 도 있습니다. 당연히 이 방법은 소음이 있는 환경에서 수백만명이 말하는 여러 언어로 된 수천개의 단어를 구분하는 것으로 확장하기 어렵습니다. 각 단어를 녹음한 샘플을 사용해 스스로 학습하는 알고리즘을 작성하는 것이 현재 가장 좋은 솔루션입니다.
우리는 머신러닝을 통해 배울 수도 있습니다. 즉, 머신러닝 알고리즘이 학습한 것을 조사할 수 있습니다. 예를 들어 스팸 필터가 충분한 스팸 메일로 훈련되었다면 스팸을 예측하는데 가장 좋은 단어와 단어의 조합이 무엇인지 확인할 수 있습니다. 가끔 예상치 못한 연관 관계나 새로운 추세가 발견되기도 해서 해당 문제를 더 잘 이해하도록 도와줍니다.
머신러닝 기술을 적용해서 대용량의 데이터를 분석하면 겉으로는 보이지 않던 패턴을 발견할 수 있습니다. 이를 데이터 마이닝(data mining)이라고 합니다.
요약하면 머신러닝은 다음 분야에 뛰어납니다.
- 기존 솔루션으로는 많은 수동 조정과 규칙이 필요한 문제: 하나의 머신러닝 모델이 코드를 간단하고 더 잘 수행되도록 할 수 있습니다.
- 전통적인 방슥으로는 전혀 해결 방법이 없는 복잡한 문제: 가장 뛰어난 머신러닝 기법으로 해결 방법을 찾을 수 있습니다.
- 유동적인 환경: 머신러닝 시스템은 새로운 데이터에 적응할 수 있습니다.
- 복잡한 문제와 대량의 데이터에서 통찰 얻기
2018년 7월 3일 화요일
1.1 머신러닝이란?
일반적인 정의
[머신러닝은] 명식적인 프로그래밍 없이 컴퓨터가 학습하는 능력을 갖추게 하는 연구 분야다.
- 아서 사무엘Arthur Samuel, 1959
공학적인 정의
어떤 작업 T에 대한 컴퓨터 프로그램의 성능을 P로 측정했을 때 경험 E로 인해 성능이 향상됐다면, 이 컴퓨터 프로그램은 작업 T와 성능 측정 P에 대해 경험 E로 학습한 것이다.
- 톰 미첼 Tom Mitchell, 1997
ex) 스팸 필터 = (스팸 메일 + 일반 메일) 샘플
시스템이 학습하는 데 사용하는 샘플 -> 훈련 세트(training set)
훈련 데이터 -> 훈련 사례(training instance, 혹은 샘플)
작업 T = 새로운 메일 스팸인지 구분 경험 E는 훈련 데이터(training data) 성능 측정 P는 직접 정의 이 성능 측정을 정확도(accuracy)라고 부르며 분류 작업에 자주 사용
[머신러닝은] 명식적인 프로그래밍 없이 컴퓨터가 학습하는 능력을 갖추게 하는 연구 분야다.
- 아서 사무엘Arthur Samuel, 1959
공학적인 정의
어떤 작업 T에 대한 컴퓨터 프로그램의 성능을 P로 측정했을 때 경험 E로 인해 성능이 향상됐다면, 이 컴퓨터 프로그램은 작업 T와 성능 측정 P에 대해 경험 E로 학습한 것이다.
- 톰 미첼 Tom Mitchell, 1997
ex) 스팸 필터 = (스팸 메일 + 일반 메일) 샘플
시스템이 학습하는 데 사용하는 샘플 -> 훈련 세트(training set)
훈련 데이터 -> 훈련 사례(training instance, 혹은 샘플)
작업 T = 새로운 메일 스팸인지 구분 경험 E는 훈련 데이터(training data) 성능 측정 P는 직접 정의 이 성능 측정을 정확도(accuracy)라고 부르며 분류 작업에 자주 사용
CHAPTER 1 한눈에 보는 머신러닝
기존 주위 머신러닝
- 광학 문자 판독기 Optical Character Recognition(OCR)
- 스팸 필터 spam filter
추천과 음성 검색으로 발전
기계가 배운다는 것이 정학히 무엇을 의미?
머신러닝
- 지도학습
- 비지도학습
- 온라인 학습
- 배치 학습
- 사례 기반 학습
- 모델 기반 학습
전형적인 머신러닝 프로젝트의 작업 흐름에서 나타나는 주요 문제점과 머신러닝 시스템을 평가하고 튜닝하는 방법
데이터 과학자가 꼭 알아야 할 여러 가지 기초 개념과 용어를 소개
- 광학 문자 판독기 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() 함수를 사용해 제너레이터를 리스트로 명시적으로 변환할 수 있다.
파이썬은 리스트를 배열처럼 취급한다. 리스트에서 아이템을 검색할 때 걸리는 시간은 선형적으로 증가하기 때문에, 검색이 가능한 대용량의 데이터를 저장하는 용도로는 실용성이 떨어진다.
투플은 변형이 불가능한 리스트로 한 번 생성되면 변형할 수 없다. 튜플 역시 검색에 걸리는 시간이 선형적으로 증가한다.
리스트나 튜플과 달리 셋에는 순서가 없고, 셋이 담고 있는 아이템은 인덱스가 없다. 셋에는 같은 아이템이 중복으로 저장될 수 없으며, 검색 시간은 준선형적인 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)를 사용해 문자열과 수치형 데이터를 묶고, 더 효율적인 방법으로 검색하고 정렬하게 될 것이다.
여기서 다루는 모든 함수는 내장된 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 파일에 기록한다.
이러한 보고서 구조를 반드시 지켜야 할 필요는 없다. 데이터 분석 의뢰인의 요청이나 상식적인 판단에 따라 다른 대안을 사용해도 좋다.
- 요약(짧은 프로젝트 설명)
- 서론
- 데이터 수집과 처리에 사용한 방법
- 분석 결과(중간 결과나 중요도가 떨어지는 내용은 포함하지 않고 부록에 삽입)
- 결론
- 부록
부록에는 부차적이 결과와 차트뿐만 아니라 데이터를 처리하는 데 사용한 모든 재사용 코드를 기록한다. 스크립트에는 주석을 충실히 달아서 별도의 파라미터 입력이나 사용자 상호 작용 없이도 실행할 수 있어야 한다.
마지막으로 원천 데이터를 제출하는 것도 매우 중요하다. 의뢰인이 데이터를 제공했거나 해당 파일을 변형하지 않았다면, 제출하는 원천 데이터는 코드를 재사용 가능한 방법으로 실행할 수 있어야 한다. 보통 첨부한 모든 데이터 파일의 출처와 포맷은 README 파일에 기록한다.
이러한 보고서 구조를 반드시 지켜야 할 필요는 없다. 데이터 분석 의뢰인의 요청이나 상식적인 판단에 따라 다른 대안을 사용해도 좋다.
2. 데이터 수집 파이브 라인
데이터 수집은 다음과 같이 다양한 출처에서 입력 데이터 포함된 아티팩트(artifact)를 획득하고, 아트팩트에서 데이터를 추출하며, 추출한 데이터를 추가적인 처리에 적합한 형태로 변환하는 것이다.
데이터를 얻는데 주로 사용하는 출처 세가지는 인터넷(즉, 월드 와이드 웹), 데이터베이스, 로커 파일(다른 프로그램으로 만들거나 인터넷에서 내려받은 파일)이다. 다른 파이썬 프로그램을 사용해 만들거나 '압축(pickled)'한 파일도 역시 로컬 파일이다('UNIT 12. pickle로 데이터 압축하기'에서 더 자세히 알아보자).
아티팩트에 들어 있는 포맷은 매우 다양하다. 다음 장부터 가장 인기 있는 데이터 포맷들을 다루는 방법을 자세히 알아볼 것이다.
- 자연어로 된 비정형 플레인 텍스트 데이터(영어나 중국어)
- 정형 데이터
- 쉼표로 구분된 텍스트(CSV) 파일 형식의 데이블형 데이터
- 하이퍼텍스트 마크업 언어(HTML)나 다목적 마크업 언어(XML)로 된 태그 데이터
- JSON(JavaScript Object Notation) 형식의 태그 데이터
추출한 데이터의 원래 구조, 추가적인 처리의 목적과 특성에 따라 이 책에 수록된 예제에서 사용한 데이터의 파이썬에 내장된 데이터 구조(리스트와 딕셔너리)나, 특수한 연산(numpy 배열이나 pandas 데이터 프레임)을 지원하는 고급 데이터 구조로 표현한다.
필자는 데이터 처리 파이프라인(원천 데이터의 수립, 전처리, 변환, 기술 통계의 탐색적 데이터 분석, 데이터 모델링과 예측)을 완전히 자동화하려고 노력했다.
인터팩티브 GUI도구는 가급적 사용하지 않는데, 배치(batch)모드에서 실행하기가 쉽지않고 작동 로그를 남기지 않기 때문이다. 필자는 모듈성, 재사용성, 복구용이성을 높이려고 긴 파이프라인을 작은 서브 파이브라인으로 쪼개 중간 결과를 pickle이나 JSON 파일로 저장할 것이다.
파이프라인 자동화는 자연스럽게 재사용 가능한 코드로 이어진다. 재사용 가능한 코드를 사용하면 별도의 상호 작용 없이도 누구나 원천 데이터로 보고서에 기록된 최종 결과물을 얻을 수 있다. 다른 연구자들은 재사용 가능한 코드로 여러분의 모델과 결과를 검증하고, 여러분이 개발한 프로세스를 적용해 문제를 해결할 수 있다.
데이터를 얻는데 주로 사용하는 출처 세가지는 인터넷(즉, 월드 와이드 웹), 데이터베이스, 로커 파일(다른 프로그램으로 만들거나 인터넷에서 내려받은 파일)이다. 다른 파이썬 프로그램을 사용해 만들거나 '압축(pickled)'한 파일도 역시 로컬 파일이다('UNIT 12. pickle로 데이터 압축하기'에서 더 자세히 알아보자).
아티팩트에 들어 있는 포맷은 매우 다양하다. 다음 장부터 가장 인기 있는 데이터 포맷들을 다루는 방법을 자세히 알아볼 것이다.
- 자연어로 된 비정형 플레인 텍스트 데이터(영어나 중국어)
- 정형 데이터
- 쉼표로 구분된 텍스트(CSV) 파일 형식의 데이블형 데이터
- 하이퍼텍스트 마크업 언어(HTML)나 다목적 마크업 언어(XML)로 된 태그 데이터
- JSON(JavaScript Object Notation) 형식의 태그 데이터
추출한 데이터의 원래 구조, 추가적인 처리의 목적과 특성에 따라 이 책에 수록된 예제에서 사용한 데이터의 파이썬에 내장된 데이터 구조(리스트와 딕셔너리)나, 특수한 연산(numpy 배열이나 pandas 데이터 프레임)을 지원하는 고급 데이터 구조로 표현한다.
필자는 데이터 처리 파이프라인(원천 데이터의 수립, 전처리, 변환, 기술 통계의 탐색적 데이터 분석, 데이터 모델링과 예측)을 완전히 자동화하려고 노력했다.
인터팩티브 GUI도구는 가급적 사용하지 않는데, 배치(batch)모드에서 실행하기가 쉽지않고 작동 로그를 남기지 않기 때문이다. 필자는 모듈성, 재사용성, 복구용이성을 높이려고 긴 파이프라인을 작은 서브 파이브라인으로 쪼개 중간 결과를 pickle이나 JSON 파일로 저장할 것이다.
파이프라인 자동화는 자연스럽게 재사용 가능한 코드로 이어진다. 재사용 가능한 코드를 사용하면 별도의 상호 작용 없이도 누구나 원천 데이터로 보고서에 기록된 최종 결과물을 얻을 수 있다. 다른 연구자들은 재사용 가능한 코드로 여러분의 모델과 결과를 검증하고, 여러분이 개발한 프로세스를 적용해 문제를 해결할 수 있다.
피드 구독하기:
글 (Atom)