반응형

pandas로 데이터 분석을 실행함에 있어, 어떻게 절차를 구분하는 것이 좋을지 정리해 놓은 글이 있어 번역해 보았다. 

특히 Pandas로 실행하고 있기 때문에 향후 pandas의 각 기능에 대해 정리해 보려고 한다.

먼저, 오늘은 데이터에서 필요한 정보를 만들어내는 7단계에 대해 간략히 정리하도록 하겠다.

데이터 분석 프로세스




1. 개념화(Ideation)

첫단계는 알아내고 싶은 것이 무엇인지 밝히는 것이다. 

이것은 우리가 하고 싶은 것이 무엇인지 생각해 보고 증명하기 위한 개념화에 대한 것이다. 개념은 일반적으로 지식을 바탕으로 결정을 내리기 위해 사용할 수 있는 데이터 패턴에 대한 가설과 관련이 있다. 

이러한 결정은 비즈니스 차원에서 이루어 지지만 과학 및 연구 분야에서도 발생한다. 

그럼 데이터를 통해 우리가 내리는 결정의 종류는 어떤 것이 있을까? 다음과 같은 것을 많이 요청한다고 본다.

- 어떤 일이 왜 일어났는가?

- 과거 데이터를 사용해서 미래를 예측할 수 있는가?

- 앞으로 어떻게 운영을 최적화할 수 있을까?

위 목록이 개념화를 정의하려는 노력에 있어 많은 부분을 차지할 것이라 생각한다. 

위와 같은 질문에 대한 답변을 얻기 위해 문제와 관련된 데이터를 수집하고 이해해야 하는 것이다. 여기에는 어떤 데이터가 조사될 것인지, 연구의 이점이 무엇인지, 데이터를 어떻게 얻을 것인지, 성공 기준이 무엇인지, 최종적으로 정보가 어떻게 전달될 것인지를 정의해야 하는 지를 포함한다.

Pandas 자체는 개념을 보조하기 위한 도구를 제공하지는 않는다. 그러나 Pandas 사용에 대한 이해와 기술을 습득하면 Pandas가 아이디어를 공식화하는 데 어떻게 도움을 주는지 자연스럽게 알게될 것이다.


2. 검색(Retrieval)

아이디어가 있으면 가설을 뒷받침할 데이터를 찾아야 한다. 

이 데이터는 조직 내에서 또는 외부 데이터 공급자로부터 가져올 수 있다. 이 데이터는 일반적으로 보관된 데이터로 제공되거나 실시간으로 제공될 수 있다.

데이터를 작성했거나 조직 내에서 가져온 경우에도 원시 데이터는 종종 매우 불완전하다. 원시 데이터는 데이터가 혼란스럽거나 다양한 형식일 수 있으며 오류가 있을 수 있음을 의미한다. 분석 지원과 관련하여 불완전할 수 있으며 수동으로 개선해야 할 수도 있다.

세상에는 무료 데이터가 아주 많다. 많은 데이터는 무료가 아니며 실제로는 상당한 금액의 비용을 요구한다. 일부는 공개 API에서 무료로 사용할 수 있으며 다른 일부는 구독으로 사용할 수도 있다. 비용을 지불한 데이터는 종종 더 클린하지만 종종 그렇지 않을 수도 있음을 알아야 한다.

데이터가 불완전하거나 클린할 경우 모두 pandas는 다양한 출처의 데이터를 검색할 수 있는 견고하고 사용하기 쉬운 도구 집합을 제공하며 다양한 형식을 지원한다. pandas는 데이터를 검색할 뿐만 아니라 다른 툴이나 프로그래밍 언어에서 필요할 수 있는 복잡한 코딩을 수동으로 생성할 필요없이 pandas 데이터 구조를 통해 데이터의 초기 구조화 기능을 제공한다.


3. 준비(Preparation)

준비 중에 원시 데이터를 탐색할 준비가 된다. 이 준비 과정은 매우 흥미로운 과정이다. 데이터가 품질과 관련된 문제로 가득차 있는 경우가 매우 빈번하기 때문이다. 이러한 품질 문제를 처리하는 데 많은 시간을 할애할 가능성이 높다(종종 매우 아까운 시간).

왜 시간을 많이 할애해야 할까?

- 데이터가 단순히 잘못되어 있다

- 데이터 세트의 일부가 누락되어 있다

- 분석에 적합한 측정 값을 사용하여 데이터가 표현되지 않았다

- 데이터가 분석에 적합하지 않은 형식이다

- 데이터가 분석에 적합하지 않은 세부 수준에 있다

- 필요한 모든 필드가 단일 소스에서 제공되는 것이 아니다

- 데이터 표현이 공급자에 따라 다르다


4. 탐색(Exploration)

탐색에는 대화식으로 데이터를 작은 여러 조각들로 분해한 후 다양한 시각으로 볼 수 있게 함으로써 신속하게 살펴보는 것을 포함한다. 

탐색은 다음과 같은 다양한 테스크를 포함한다.

- 변수가 서로 어떻게 관련되어 있는지 조사

- 데이터 배포 방법 결정

- 특이점 찾아서 제외시키기

- 빠른 시각화 만들기

- 보다 영구적으로 상세한 모델링 프로세스를 지원할 수 있도록 새로운 데이터 표현이나 모델을 신속하게 생성

탐색은 pandas의 위대한 강점 중 하나다. 탐색은 대부분의 프로그래밍 언어에서 수행할 수 있지만 pandas가 얼마나 탐색적 노력을 수월하게 하는지가 관건일 것이다.

IPython 및 / 또는 Jupyter 노트북의 REPL (read-eval-print-loop) 특성과 함께 사용하면 pandas는 매우 자유로운 탐색 환경을 만든다. pandas 구문의 표현력을 통해 복잡한 데이터 조작 구조를 간략하게 설명할 수 있으며 데이터를 처리할 때 수행한 모든 작업 결과가 즉각적인 검사를 통해 표시될 수 있다. 이를 통해 프로그램을 다시 컴파일하여 재실행하지 않고 방금 수행한 작업의 유효성을 신속하게 판별할 수 있다.


5. 모델링(Modeling)

모델링 단계에서 탐색 중에 발견된 발견을 공식화하여 데이터 내에 포함된 원하는 의미를 얻는 데 필요한 단계와 데이터 구조를 명시적으로 설명한다. 이 모델은 원시 데이터에서 정보와 결론까지 얻을 수 있는 코드 단계 뿐 아니라 두 데이터 구조의 조합이다.

모델링 프로세스는 데이터 탐색을 통해 분석을 지원하는 데 필요한 변수를 선택하고 분석 프로세스에 대한 입력 변수를 구성한다. 모델을 실행하며 모델이 원래의 가정을 얼마나 잘 지원하는지를 결정하는지 확인하는 반복 프로세스라고 할 수 있다. 데이터 구조의 공식 모델링을 포함할 수 있지만 통계, 기계 학습 및 운영 연구와 같은 다양한 분석 도메인의 기술을 결합할 수도 있다.

이를 촉진하기 위해 pandas는 광범위한 데이터 모델링 기능을 제공한다. 데이터 탐색으로부터 한발 더 나아가, DataFrame에서 데이터 모델을 형식화하고, 이 모델들을 간결하게 만들어 주는 절차를 확보해 주는 단계라고 할 수 있다. 파이썬 기반을 통해, 처음부터 마지막 프로세스까지 자동화하는 프로그램을 생성하는 파워를 사용할 수 있다. 즉, 작성한 모델은 실행 가능한 것이다.

분석적 관점에서 pandas는 다양한 유형의 문제에 대한 목표를 달성할 수 있는 기술 통계에 대한 통합 지원과 같은 몇 가지 기능을 제공한다. 그리고 pandas는 파이썬 기분이기 때문에 고급 분석 기능이 필요하다면 광범위한 파이썬 라이브러리와 쉽게 통합될 수 있다.


6. 프리젠테이션(Presentation)

이 프로세스의 마지막에서 두번째 단계는 결과를 다른 사람들에게, 일반적으로 보고서나 프리젠테이션 형태로 제시하는 것이다. 설득력있고 철저한 솔루션 설명을 만들고 싶을 때, 바로 이용할 수 있다. 

Jupyter Notebook은 pandas 분석을 위한 프리젠테이션을 작성하는 강력한 도구다. 이 노트북은 코드를 실행하고 응용 프로그램의 여러 지점에서 주석을 달고 실행을 설명하기 위한 다양한 마크다운 기능을 제공한다. 또한 이 도구는 코드, 스타일이 지정된 텍스트, 그래픽과 함께 시각적으로 풍부한 매우 효과적인 실행 가능한 프리젠테이션을 만들 수 있다.


7. 재생산(Reproduction)

중요한 연구는 연구를 공유하고 재현할 수 있게 만들어야 한다. 다른 연구자가 실혐과 결과를 재현할 수 없다면 어떤 것을 증명하지 못했다고 할 수 있기 때문이다.

다행스럽게도 pandas와 파이썬을 사용함으로써 분석을 쉽게 재현할 수 있다. pandas 코드를 구동하는 파이썬 코드와 데이터를 공유함으로써 가능하다.

또한, Jupyter Notebook은 다른 사람들과 쉽게 공유할 수 있는 방법으로 코드와 응용 프로그램을 패키징하는 편리한 방법을 제공한다.


<Source : Learning pandas Second Edition, Packt>


반응형
반응형

머신러닝 프로젝트 실행 1~3단계에 이어, 4단계를 정리하도록 하겠습니다.

4. 기본 데이터 패턴을 머신러닝 알고리즘에 더 잘 노출할 수 있도록 데이터 준비하기

머신러닝 알고리즘을 위한 데이터를 준비할 시간입니다. 이것을 수동으로 하는 대신에, 자동으로 생성할 함수들을 사용해야 합니다. 

그 이유는 다음과 같습니다.

  • 어떤 데이터셋이든(예, 다음 번에 새로운 데이터셋을 얻게 되었을 때), 이들 변환을 쉽게 재적용할 수 있도록 해줍니다.
  • 미래의 프로젝트에서 재사용할 수 있는 변환 함수 라이브러리를 만들 수 있습니다.
  • 이들 함수들을 알고리즘에 피딩하기 전에 새로운 데이터를 변환하기 위해 실제 사용하는 시스템에서 사용할 수 있습니다. 
  • 다양한 변환을 쉽게 시도하고 어떤 변환 조합이 가장 잘 동작하는지 알 수 있도록 해줍니다.
이제 트레이닝 셋을 클리닝하기 위해 되돌려 봅시다(다시 한번strat_train_set을 복사하면 됩니다). 그리고 불필요하게 예측변수와 목표 값들에 동일한 변환이 적용되기를 원하지 않기 때문에 예측변수와 레이블을 분리하도록 합시다.
(drop()이 데이터 복사본을 만들고, strat_train_set에는 영향을 주지 않는 것에 주의하시기 바랍니다) 

>>> housing = strat_train_set.drop("median_house_value", axis=1)
>>> housing_labels = strat_train_set["median_house_value"].copy()

데이터 클리닝

대부분의 머신러닝 알고리즘은 누락된 값이 있는 피처들(features)로는 작업할 수 없습니다. 따라서, 그것들을 다루기 위한 몇가지 함수들을 만들어 봅시다. 전 단계에서 total_bedrooms 속성에 누락된 값들이 있다는 것을 보았습니다. 이것을 고쳐보도록 합시다. 
다음의 3가지 옵션을 선택할 수 있습니다.

  • 상응하는 지구(districts)를 제거합니다.

  • 전체 속성을 제거합니다.

  • 값들을 특정 값으로 설정합니다(제로, 평균, 중앙값 등).
이것들을 DataFrame의 dropna(), drop(), 그리고 fillna() 메서드를 사용해 쉽게 처리할 수 있습니다.

>>> housing.dropna(subset=["total_bedrooms"]) # 옵션1
>>> housing.drop("total_bedrooms", axis=1) # 옵션2
>>> median = housing["total_bedrooms"].median()
>>> housing["total_bedrooms"].fillna(median) # 옵션3

만약 옵션3을 선택한다면, 트레이닝 셋에 대한 중앙값을 계산해야만 합니다. 그리고 트레이닝 셋의 누락된 값들에 이것을 적용해야 합니다. 
하지만, 위 코드처럼 계산했던 중앙값을 저장하는 것을 잊지 말아야 합니다. 
나중에 시스템을 평가하고 싶을 때, 테스트 셋에서 누락된 값들을 대체하는 것이 필요할 것입니다. 그리고, 시스템을 운영한 후에는 신규 데이터에서 누락된 값들을 즉석에서 대체해야 합니다.

>>> from sklearn.preprocessing import Imputer
>>> imputer = Imputer(strategy="median")

중앙값은 수치 속성들에 대해서만 계산될 수 있기 때문에, 텍스트 속성의 ocean_proximity를 제외한 데이터의 복사본을 생성하는 것이 필요합니다.

>>> housing_num = housing.drop("ocean_proximity", axis=1)

이제 fit() 메서드를 사용해 트레이닝 데이터에 imputer 인스턴스를 적용할 수 있습니다.

>>> imputer.fit(housing_num)

imputer는 간단하게 각 속성의 중앙값을 계산하고, 그 결과를 statistics_ 인스턴스 변수에 저장합니다. 
total_bedrooms 속성만이 누락된 값이 있지만, 이 시스템이 실제 운용되었을 때 신규 데이터에 어떤 누락된 값들이 있을지 확신할 수 없을 것입니다. 
그래서, 모든 수치 속성들에 대해 imputer를 적용하는 것이 더 안전합니다.

>>> imputer.statistics_
array([ -118.51 , 34.26 , 29. , 2119. , 433. , 1164. , 408. , 3.5414])
>>> housing_nim.median().values
array([ -118.51 , 34.26 , 29. , 2119. , 433. , 1164. , 408. , 3.5414]) 

이제 학습된 중앙값으로 누락된 값들을 대체함으로써 트레이닝 셋을 변환하기 위해 "훈련된" imputer를 이용할 수 있습니다. 

>>> X = imputer.transform(housing_num)

결과물은 변환된 피쳐들(features)을 포함한 평이한 넘파이(Numpy) 배열입니다. 
판다스(Pandas) DataFrame으로 다시 넣고 싶다면, 간단히 처리할 수 있습니다.

>>> housing_tr = pd.DataFrame(X, columns=housing_num.columns)


텍스트 다루기와 범주 속성들

앞에서 범주 속성인 ocean_proximity를 제외했습니다. 
그 이유는 텍스트 속성이기 때문에 중앙값을 계산할 수 없기 때문입니다. 
대부분의 머신러닝 알고리즘은 숫자를 가지고 작업하는 것을 선호합니다. 
그렇기 때문에 이들 텍스트 라벨을 숫자로 변환해 봅시다.
사이킷 런(Scikit-Learn)은 이 작업에 필요한 LabelEncoder라 불리는 변환기를 제공합니다.

>>> from sklearn.preprocessing import LabelEncoder
>>> encoder = LabelEncoder()
>>> housing_cat = housing["ocean_proximity"]
>>> housing_cat_encoded = encoder.fit_transform(housing_cat)
>>> housing_cat_encoded
array([1, 1, 4, ..., 1, 0, 3])

이러면 더 좋아집니다: 이제 어떤 ML 알고리즘에서도 이 숫자 데이터를 사용할 수 있습니다. 
이 인코더가 classes_ 속성을 사용하여 학습한 매핑을 볼 수 있습니다("<1H OCEAN"이 0에 매핑되었고, "INLAND"가 1에 매핑되었습니다).

>>> print(encoder.classes_)
['<1H OCEAN' 'INLAND' 'ISLAND' 'NEAR BAY' 'NEAR OCEAN']

위 인코더로 처리한 데이터의 한가지 이슈는 ML 알고리즘이 두개의 근접한 값들이 거리가 있는 두개의 값들보다 더 유사하다고 가정한다는 것입니다. 
분명히 이것은 그런 경우가 아닌데 말입니다(예를 들어, 범주 0과 4가 범주 0과 1보다 더 유사합니다). 
이 이슈를 수정하기 위한, 일반적인 솔루션은 각 범주에 대한 하나의 바이너리 속성을 생성하는 것입니다: 범주가 "<1H OCEAN"일 때 하나의 속성은 1과 같습니다(그렇지 않으면 0). 범주가 "INLAND"일 때 또 다른 속성이 1과 같습니다(그렇지 않으면 0) 등등. 
이것을 원-핫 인코딩이라 부릅니다. 범주들을 원-핫 벡터들로 인코딩합시다. 
fit_transform()은 2D 배열을 기대하지만, housing_cat_encoded는 1D 배열이라는 것을 주의하시기 바랍니다. 
그래서 이것을 재구성하는 것이 필요합니다.

>>> from sklearn.preprocessing import OneHotEncoder
>>> encoder = OneHotEncoder()
>>> housing_cat_1hot = encoder.fit_transform(housing_cat_encoded.reshape(-1,1))
>>> housing_cat_1hot
<16513x5 sparse matrix of type '<class 'numpy.float64'>'
        with 16513 stored elements in Compressed Sparse Row format>

산출물이 NumPy 배열이 아니라 SciPy 스파스(sparse) 매트릭스인 것에 유의하시기 바랍니다. 
이것은 수천 개의 범주들을 가진 범주 속성을 가질 때 매우 유용합니다. 
원-핫 인코딩 후, 수천개의 컬럼을 가진 매트릭스를 얻었습니다. 
그리고 그 매트릭스는 각 열마다 하나의 1을 가진 것 말고는 0으로 가득합니다. 엄청난 메모리를 0을 저장하는데 사용하는 것은 매우 비효율적입니다. 
그래서 대신 스파스(sparse) 매트릭스는 오직 0이 아닌 요소들의 위치만 저장합니다. 대개 일반적인 2D 배열처럼 사용할 수 있습니다. 하지만 정말 NumPy 배열로 전환하고 싶다면, toarray() 메서드를 호출하기만 하면 됩니다. 

>>> housing_cat_1hot.toarray()
array([[ 0.,  1.,  0.,  0.,  0.],
    [0.,  1.,  0.,  0.,  0.],  
    [0.,  0.,  0.,  0.,  1.], 
    [1.,  0.,  0.,  0.,  0.],  
    [0.,  0.,  0.,  1.,  0.]])

  
LabelBinarizer 클래스를 사용해서 (텍스트 범주에서 숫자 범주로 바꾸고, 숫자 범주에서 원-핫 벡터로 바꾸는) 두개의 변환을 한번에 적용할 수 있습니다. 

>>> from sklearn.preprocessing import LabelBinarizer
>>> encoder = LabelBinarizer()
>>> housing_cat_1hot = encoder.fit_transform(housing_cat)
>>> housing_cat_1hot
array([[ 0,  1,  0,  0,  0],
    [0,  1,  0,  0,  0],  
    [0,  0,  0,  0,  1], 
 ...,
    [0,  0,  0,  0,  1], 
    [1,  0,  0,  0,  0],  
    [0,  0,  0,  1,  0]])

기본적으로 고밀도 NumPy 배열을 돌려준다는 것에 유의하시기 바랍니다. 
sparse_output=True를 LabelBinarizer 컨스트럭터(constructor)를 전달함으로써 스파스(sparse) 매트릭스를 얻을 수 있습니다. 

사용자 정의 트랜스포머(Transformers)

사이킷런(Scikit-Learn)이 많은 유용한 트랜스포머(Transformers)를 제공하지만, 사용자 정의 클린업 또는 특정 속성들을 결합하는 것과 같은 작업을 위해 자신만의 트랜스포머를 작성하는 것이 필요할 것입니다. 
사이킷런(Scikit-Learn)의 기능들(pipelines과 같은)을 가지고 완벽하게 작동하는 자신만의 트랜스포머를 원할 수 있습니다. 
사이킷런(Scikit-Learn)이 덕 타이핑(상속이 아닌)에 의존하기 때문에, 클래스를 생성하고 3개의 메서드 구현하는 것이 필요한 전부입니다: fit(), transform(), 그리고 fit_transform(). 간단히 기본 클래스로써 TransformerMixin을 추가함으로써 무료로 하나를 얻을 수 있습니다. 
또한, 기본 클래스로 BaseEstimater를 추가한다면(컨스트럭터(constructor)에 *args와 *kargs를 피하세요), 자동 하이퍼파라미터를 조율하는데 유용한 두개의 특별 메서드(get_params()와 set_params())를 얻을 수 있습니다. 
예를 들어, 아래 코드는 앞에서 논의한 결합된 속성들을 추가하는 작은 트랜스포머(transformer) 클래스입니다. 

컴퓨터 프로그래밍 분야에서 덕 타이핑(duck typing)은 동적 타이핑의 한 종류로, 객체의 변수 및 메소드의 집합이 객체의 타입을 결정하는 것을 말합니다. 

>>> from sklearn.base import BaseEstimator, TransformerMixin
>>> rooms_ix, bedrooms_ix, population_ix, household_ix = 3,4,5,6
>>> class CombineAttributesAdder(BaseEstimator, TransformerMixin):
def __init__(self, add_bedrooms_per_room = True): # *args와 *kargs를 피하세요
self.add_bedrooms_per_room = add_bedrooms_per_room
def fit(self, X, y=None):
return self # 할 일은 없습니다
def transform(self, X, y=None):
rooms_per_household = X[:, rooms_ix] / X[:, household_ix]
population_per_household = X[:, population_ix] / X[:, household_ix]
if self.add_bedrooms_per_room:
bedrooms_per_room = X[:, bedrooms_ix] / X[:, rooms_ix]
return np.c_[X, rooms_per_household, population_per_household, bedrooms_per_room]
else:
return np.c_[X, rooms_per_household, population_per_household]

>>> attr_adder = CombineAttributesAdder(add_bedrooms_per_room=False)
>>> housing_extra_attribs = attr_adder.transform(housing.values)

이 예에서, 트랜스포머(transformer)는 기본적으로 True를 설정한(흔히 민감한 기본값을 제공하는데 도움이 됨)하나의 하이퍼파라미터, add_bedrooms_per_room를 가지고 있습니다. 
이 하이퍼 파라미터는 이 속성을 추가하는 것이 머신러닝 알고리즘에 도움이 되는지 안되는지 쉽게 찾을 수 있도록 해줄 것입니다. 
더 일반적으로, 100% 확신할 수 없는 어떤 데이터를 준비하는 단계에서 점검하기 위한 하이퍼파라미터를 추가할 수 있습니다. 
이들 데이터의 준비 단계를 더 많이 자동화하고, 자동화를 시도할 수 있는 결합을 더 많이 할수록, 매우 좋은 결합을 발견할 가능성이 매우 높아질 것입니다(그리고 많은 시간을 절약하게 해 줄 것입니다).

피처(Feature) 스케일링(Scaling)

데이터에 적용이 필요한 가장 중요한 변환 중 하나는 피처(feature) 스케일링(scaling)입니다. 
몇 가지 예외가 있지만, 머신러닝 알고리즘은 입력 숫치 속성들이 매우 다른 스케일링을 가지면 잘 수행되지 않습니다. 
housing 데이터가 그런 경우입니다: 중간 소득이 0에서 15까지의 범위를 가지는 것에 비해, 전체 방수는 6에서 39,320까지의 범위를 가집니다. 목표 값의 스케일링은 일반적으로 필요하지 않다는 것에 유의하시기 바랍니다.
모든 속성들이 동일한 스케일을 갖도록 하는 두가지 일반적인 방법이 있습니다: min-max scaling과 standardization.
Min-max scaling(많은 사람들이 normalization이라 부릅니다)은 매우 간단합니다: 값들이 이동되어, 결국 0에서 1사의 범위에서 재스케일링 됩니다. 최소값을 뺀 값에, 최대값에서 최소값을 마이너스한 값을 나눔으로써 구합니다. 
사이킷런(Scikit-Learn)에서는 이를 위해 MinMaxScaler라는 트랜스포머를 제공합니다. 
어떤 이유로 0-1의 범위를 원하지 않을 때 범위를 변경할 수 있도록 feature_range라는 하이퍼트랜스포머를 갖습니다.

표준화(Standardization)는 전혀 다릅니다: 먼저 평균값을 구합니다(그래서 표준화된 값은 항상 제로 평균값을 갖습니다). 그런 다음 분산으로 나누어, 그 결과 분포가 단위 분산을 갖도록 합니다. 
min-max scaling과 달리, 표준화(Standardization)는 값을 특정 범위로 한정하지 않습니다. 
이것이 몇몇 알고리즘에서는 문제가 될 수도 있습니다(예를 들어, 뉴럴 네트워크는 흔히 입력 값의 범위를 0에서 1이라고 기대합니다). 하지만, 표준화(Standardization)는 특이값(outliers)에 의한 영향을 훨씬 덜 받습니다. 
예를 들어, 한 지구(district)의 중간 소득이 100과 같다고(실수로) 가정합시다. Min-max scaling은 모든 다른 값들이 0-15에서 0-0.15로 망가트립니다. 반면에 표준화(Standardization)는 별로 영향을 받지 않습니다. 
사이킷런(Scikit-Learn)은 표준화(Standardization)를 위해 StandardScaler라는 트랜스포머를 제공합니다.

변환 파이프라인(Pipeline)

보시다시피, 올바른 순서로 실행해야 하는 데이터 변환의 많은 단계가 있습니다. 
사이킷런(Scikit-Learn)은 그러한 일련의 변환을 도와줄 수 있는 파이프라인(Pipeline) 클래스를 제공합니다.
수치 속성들에 대한 작은 파이프라인 코드를 보시기 바랍니다:

>>> from sklearn.pipeline import Pipeline
>>> from sklearn.preprocessing import StandardScaler
>>> num_pipeline = Pipeline([
('imputer', Imputer(strategy="median")),
('attribs_adder', CombinedAttributesAdder()),
('std_scaler', StandardScaler()),
])
>>> housing_num_tr = num_pipeline.fit_transform(housing_num)

파이프라인(Pipeline) 생성자(constructor)는 일련의 단계를 정의하는 이름(name)/추정량(estimator) 쌍 리스트를 가집니다. 
마지막 추정량을 제외한 모든 것이 트랜스포머여야 합니다(예, 그것들은 fit_transform() 메서드를 가져야만 합니다). 
이름들(names)은 좋아하는 어떤 것으로도 정할 수 있습니다.
파이프라인의 fit() 메서드를 호출할 때, 마지막 추정량에 도달할 때까지, 파라미터로써 각 호출의 결과물을 다음 호출에 전달합니다. 
모든 트랜스포머에 대해 순차적으로 fit_transform()을 호출하며, 이를 위해서 fit() 메서드를 호출하기만 하면 됩니다.
파이프라인은 마지막 추정량으로써 동일한 메서드를 제공합니다. 마지막 추정량은 StandardScaler입니다. 
이것은 트랜스포머이기 때문에 파이프라인은 순차적으로 데이터에 모든 변환을 전달하는 transform() 메서드를 가집니다(또한 fit()과 함께 transform()을 호출하는 대신에 사용했던 fit_transform 메서드를 가집니다).
이제 수치 값들에 대한 파이프라인을 가지고 되었습니다. 그리고, LabelBinarizer를 범주 값들에 대해 적용하는 것이 필요합니다: 이러한 변환을 어떻게 단일 파이프라인에 결합시킬 수 있을까요? 사이킷런(Scikit-Learn)은 이것을 위해 FeatureUnion 클래스를 제공합니다. 변환 리스트를 제공하고(전체 변환 파이프라인이 될 수 있습니다), transform() 메서드가 호출되었을 때 각각의 변환에 대한 transform() 메서드가 병행으로 실행됩니다. 
결과물을 기다린 후, 그것들을 결합하고 결과값으로 돌려줍니다. 
수치와 범주 속성 양쪽을 핸들링하는 전체 파이프라인은 다음처럼 보여질 수 있습니다:

>>> from sklearn.pipeline import FeatureUnion
>>> num_attribs = list(housing_num)
>>> cat_attribs = ["ocean_proximity"]
>>> num_pipeline = Pipeline([
('selector', DataFrameSelector(num_attribs)),
('imputer', Imputer(strategy="median")),
('attribs_adder', CombinedAttributesAdder()),
('std_scaler', StandardScaler()),
])
>>> cat_pipeline = Pipeline([
('selector', DataFrameSelector(cat_attribs)),
('label_binarizer', LabelBinarizer()),
])
>>> full_pipeline = FeatureUnion(transformer_list=[
("num_pipeline", num_pipeline),
("cat_pipeline", cat_pipeline),
])

그리고 전체 파이프라인을 간단하기 실행할 수 있습니다:

>>> housing_prepared = full_pipeline.fit_transform(housing)
>>> housing_prepared
array([[ 0.73225807,  -0.67331551,  0.58426443,  ...,  0.           ,  0.          ,  0.           ],
 [-0.99102923,   1.63234656, -0.92655887,  ...,  0.           ,  0.          ,  0.           ],
 [...]
>>> housing_prepared.shape
(16513, 17)

각 서브 파이프라인은 선택기(selector) 파이프라인으로 시작합니다: 간단히 원하는 속성(수치 또는 범주)을 선택함으로써 데이터를 변환합니다. 
나머지를 버리고, 결과 DataFrame을 넘파이(NumPy) 배열로 전환합니다. 
사이킷런(Scikit-Learn)에서는 판다스(Pandas) DataFrame을 핸들링할 수 없기 때문에, 이 작업을 위해 간단한 사용자 정의 트랜스포머를 작성하는 것이 필요합니다.

>>> from sklearn.base import BaseEstimator, TransformerMixin
>>> class DataFrameSelector(BAseEstimator, TransformerMixin):
def __init__(self, attribute_names):
self.attribute_names = attribute_names
def fit(self, X, y=None):
return self
def transform(self, X):
return X[self.attribute_names].values

4단계는 여기까지입니다. 갈수록 어려워지는 것 같습니다. 다시 앞 단계 내용을 복습하면서 머리속에 정리해 넣어야겠습니다. ㅜㅜ
  

머신러닝 프로젝트 실행-1

(1~2단계: 1. 문제정의하고 전체 그림 바라보기/ 2. 데이터 얻기바로가기 


머신러닝 프로젝트 실행-2

(3단계: 인사이트를 찾기 위해 데이터 탐색하기바로가기 


참고)'Hands-On Machine Learning with Scikit-Learn and TensorFlowchapter 2' 

주피터 노트북에서 볼 수 있는 전체 코드 얻기


반응형
반응형

4차 산업혁명 시대의 데이터 사이언티스트(Data Scientist)를 위한 파이썬 라이브러리(Python Library)

요즘 파이썬을 배워서 진출할 수 있는 직업 중에 데이터 사이언티스트가 핫한 것 같다. 4차 산업혁명과 함께 많이들 선호하고 있는 상태가 되었다.

하지만, 언론, 소셜 등에서 너무 많은 관심을 보이는 것이 거품이 될까 우려가 좀 된다. 2000년 초에 인터넷 기업 붐이 엄청나게 일어나고, 갑자기 거품이 꺼졌을 때 처럼 될 것 같아 보이기 때문이다. 


요즘 가장 열광하는 단어는 단연 AI일 것이라고 생각한다. 

그런데, 머신러닝(machine learning), 그 중에서 딥 러닝(deep learning)에 집중하는 것은 인터넷 자체가 혁신을 일으킬 것처럼 말했던 상황을 답습하는 것이 아닐까 하는 생각이 든다.


가장 중요한 것은 고객에게 제공하는 서비스, 제품일 것이다. 그래서 고객의 요구사항(애로사항)을 파악하는 것이 무엇보다 중요할 것이다. 

이런 관점을 갖고, 데이터와 AI의 결합을 바탕으로 고객들이 원하는 서비스(제품)을 만드는 기업 또는 사람이 되어야 한다고 믿는다.


'소프트웨어(데이터)가 모든 세계를 지배하는 세상'이라는 말은 디지털화된 데이터와 그것을 다루는 기술인 AI(그 중에서 머신 러닝)가 보편화된 세상을 말한다고 본다. 인터넷처럼 우리 생활에 스며들 것이기 때문에,  AI를 다루는 것과 데이터를 다루는 것은 기본이 될 것이다. 

앞으로 이것을 통해 어떤 가치를 고객에게 제공하느냐가 중요한 생존의 문제가 될 것이라는 것이다. 

사람들이 필요로 하는 가치(서비스, 제품)을 제공하는 수준까지 가기 위한 여정을 막 시작했다고 생각한다.

 

그럼, 가장 기본이 되는 라이브러리부터 알아보도록 하자.


데이터 사이언티스트들이 파이썬에서 사용하는 라이브러리들은 Numpy, Scipy, Pandas, Scikit-Learn 등이 있다. 


요즘에는 구글의 딥 러닝 라이브러리인 tensorflow의 인기가 높다.

tensorflow에 대해서는 따로 알아보도록 할 것이다.


1. Numpy, Scipy

Numpy와 Scipy는 숫자 및 과학 계산을 수행하기 위한 라이브러리라고 할 수 있다

Numpy는 기본 계산 기능을 가진 다차원 배열과 유용한 선형대수학 함수를 지원한다.

Scipy는 숫자 알고리즘 집합과 신호 처리, 최적화, 통계 등을 포함한 도메인에 특화된 기능을 지원한다.


(참고로, Matplotlib는 데이터 시각화를 위한 많은 툴을 가지고 있다)


2. Pandas

Pandas는 고성능의 데이터 구조와 데이터 분석 툴을 제공한다. 

Pandas의 주요 특징은 통합된 인덱싱과 함께 데이터 조작이 가능한 빠르고 효율적인 DataFrame 객체이다. 

DataFrame 구조는 매우 유연한 방법들로 작업이 가능한 스프레드시트처럼 볼 수 있다.

 재구조화하고, 행과 열을 추가하거나 제거하는 것을 통해 원하는 방식으로 어떤 데이타셋으로든 쉽게 변경할 수 있다. 

또한 데이터셋 간에 계산을 하고, 병합하고, 합류하는 고성능의 기능을 제공한다. 


또한, Pandas는 다른 형태의 포멧(CSV, EXCEL, SQL 데이터베이스, HDF5)으로부터 데이터를 가져오거나 내보낼 수 있는 툴을 가지고 있다. 

많은 경우, 이들 포멧들에 있는 데이터는 완벽하거나 전체적으로 구조화되어 있지 않을 것이다. 그런 경우, Pandas는 빠진 데이터를 핸들링하고 지능적으로 데이터를 정렬할 수 있도록 해준다. 

게다가, Pandas는 편리한 Matplotlib 인터페이스를 제공한다.


3. Scikit-learn

Scikit-learn은 Numpy, Scipy와 Matplotlib로 만들어진 머신 러닝 라이브러리이다.

Scikit-learn은 계층화, 회귀, 클러스터링, 차원 감소, 모델 선택과 전처리 같은 데이터 분석에 필요한 단순하고 효과적인 툴을 제공한다.



PS) 라이브러리별로 첨부한 정리 시트를 제공하는 원본 출처 및 원본 시트를 받고자 하시면 아래 링크를 보시기 바랍니다.


https://www.continuum.io/blog/developer-blog/learning-python-data-science-cheat-sheets



다음 편에는 Jupyter Notebook 환경에 대해 알아보도록 할 예정이다.


그럼 이만...



반응형

+ Recent posts