블로그 이미지
평범하게 살고 싶은 월급쟁이 기술적인 토론 환영합니다.같이 이야기 하고 싶으시면 부담 말고 연락주세요:이메일-bwcho75골뱅이지메일 닷컴. 조대협


Archive»


 
 

t-SNE를 이용한 차원 감소


조대협 (http://bcho.tistory.com)


PCA 기반 차원 감소의 문제점

앞의 글에서 차원 감소에 대한 개념과, 차원 감소 알고리즘의 하나인 PCA 알고리즘에 대해서 살펴보았다.

PCA의 경우 선형 분석 방식으로 값을 사상하기 때문에 차원이 감소되면서 군집화 되어 있는 데이타들이 뭉게져서 제대로 구별할 수 없는 문제를 가지고 있다. 아래 그림을 보자


출처 https://www.youtube.com/watch?v=NEaUSP4YerM


이 그림은 2차원에서 1차원으로 PCA 분석을 이용하여 차원을 줄인 예인데, 2차원에서는 파란색과 붉은색이 구별이 되는데, 1차원으로 줄면서 1차원상의 위치가 유사한 바람에, 두 군집의 변별력이 없어져 버렸다.

t-SNE

이런 문제를 해결하기 위한 차원 감소 방법으로는 t-SNE (티스니라고 읽음) 방식이 있는데, 대략적인 원리는 다음과 같다.


먼저 점을 하나 선택한다. 아래는 검정색점을 선택했는데, 이 점에서 부터 다른점까지의 거리를 측정한다.



다음 T 분포 그래프를 이용하여, 검정 점(기준점) 을 T 분포 상의 가운데 위치한다면, 기준점으로부터 상대점 까지 거리에 있는 T 분포의 값을 선택(위의 T 분포 그래프에서 파란점에서 위로 점섬이 올라가서 T분포 그래프상에 붉은 색으로 X 표가 되어 있는 값)하여, 이 값을 친밀도 (Similarity)로 하고, 이 친밀도가 가까운 값끼리 묶는다.


이 경우 PCA 처럼 군집이 중복되지 않는 장점은 있지만, 매번 계산할때 마다 축의 위치가 바뀌어서, 다른 모양으로 나타난다. 단 데이타의 군집성과 같은 특성들은 유지 되기 때문에 시각화를 통한 데이타 분석에는 유용하지만, 매번 값이 바뀌는 특성으로 인하여, 머신러닝 모델의 학습 피쳐로 사용하기는 다소 어려운점이 있다.


아래 그림은 같은 데이타로 t-SNE 분석을 각각 한번씩한 결과를 시각화 해서 표현한 결과 인데, 보는 것과 같이 군집에 대한 특성은 그대로 유지 되지만 값 자체는 변화가 된것을 확인할 수 있다.




sklearn 을 이용한 t-SNE 구현

전체 코드는 https://github.com/bwcho75/dataanalyticsandML/blob/master/dimension%20reduction/2.%20t-SNE%20visualization.ipynb 에 공개되어 있으니 참고하기 바란다.


# Perform the necessary imports
import matplotlib.pyplot as plt
from sklearn.manifold import TSNE

model = TSNE(learning_rate=100)
transformed = model.fit_transform(feature)

xs = transformed[:,0]
ys = transformed[:,1]
plt.scatter(xs,ys,c=labels)

plt.show()


사실 코드가 너무 간단해서 설명할것이 없다. TSNE 객체를 선언하고 학습속도 (learning_rate)를 지정한다음 fit_transform 하면 끝이다. (싸이킷런 만세…)


다음글에서는 차원 감소 방법중에 마지막을 Matrix Factorization (행렬 인수 분해) 방법에 대해서 알아보도록 하겠다.






파이썬을 이용한 데이타 시각화 #1 - Matplotlib 기본 그래프 그리기


조대협 (http://bcho.tistory.com)


백앤드 엔지니어와 백그라운드를 가진 경험상, 머신러닝을 공부하면서 헷갈렸던 부분중 하나가, 데이타에 대한 시각화이다. 머신러닝은 모델을 구현하는 것도 중요하지만, 학습할 데이타를 선별하고, 만들어진 모델을 검증하기 위해서는 데이타를 이해하는 것이 필수적이고 이를 위해서는 데이타를 시각화 해서 보는 것이 매우 중요하다.


그동안 그래프를 그리는 것을 스택오버플로우등에서 찾아서 복붙을 해서 사용하다가 matplotlib를 정리해야겠다고 해서 메뉴얼을 봤지만 도무지 이해가 되지 않아서, 결국 온라인 강좌를 들어서 정리해봤는데, 역시 강좌를 들으니까는 훨씬 빠르게 이해가 된다.

참고한 코스는 datacamp에 있는 “Introduction to Data Visualization with Python” 코스이다.


오늘은 matplotlib를 이용하여 기본적인 그래프를 그리는 방법에 대해서 정리하도록 한다.

기본 그래프 그리기

기본적인 그래프를 그리기 위해서는 matplotlib.pyplot에서  plot(x,y)를 사용하면 된다. x,y는 각각 X축과 Y축의 값이 된다.


from matplotlib import pyplot as plt
import numpy as np

x = np.arange(1,10)
y = x*5

plt.plot(x,y)
plt.show()


색깔 바꾸기

그래프를 그릴때 선의 색을 지정하기 위해서는 plot에서 인자로 컬러를 주면된다. 컬러표는 아래를 참고하면 되고 붉은색은 r, 파란색은 b으로 정의한다.

from matplotlib import pyplot as plt
import numpy as np

x = np.arange(1,10)
y = x*5

plt.plot(x,y,'r')
plt.show()





선 종류 변경하기

선을 그릴때, 다양한 선의 종류를 선택할 수 있다. 디폴트가 직선이고, 점으로 표현하는 마커나 점선등을 선택할 수 있다.

선의 선택은 plot에서 세번째 인자에 선의 종류를 지정하면 되고, 색을 같이 지정하려면 다음문자에 색을 지정하면 된다 다음은 동그란 마커 ‘o’를 붉은색 ‘r’로 표현하기 때문에, 세번째 인자를 ‘or’로 전달하였다.


from matplotlib import pyplot as plt
import numpy as np

x = np.arange(1,10)
y = x*5

plt.plot(x,y,'or')
plt.show()




다음은 선에 대한 종류표이다.



라벨과 타이틀

그래프를 그릴때 그래프의 타이틀과 X,Y축의 라벨을 표현하기 위해서는 타이틀은 plt.title(“타이틀명"),  X,Y축에 대한 라벨은 plt.xlabel(‘X축 라벨명'), plt.ylabel(‘Y축 라벨명') 을 사용한다.


from matplotlib import pyplot as plt
import numpy as np

x = np.arange(1,10)
y = x*5

plt.plot(x,y)
plt.xlabel('x axis')
plt.ylabel('y axis')
plt.title('matplotlib sample')
plt.show()



구간 확대/축소

그래프는 입력되는 x,y의 최소,최대 구간으로 자동으로 그려지는데, 이 구간을 키우거나 줄이기 위해서 x,y의 구간을 정의할 수 있다. x축은 plt.xlim(최소,최대),  y축은 plt.ylim(최소,최대)로 정의하면 된다.

아래는 x축을 2~3, y축을 5~20으로 확대해서 그래프를 그리는 예제이다.


from matplotlib import pyplot as plt
import numpy as np

x = np.arange(1,10)
y = x*5

plt.xlim(2,3)
plt.ylim(5,20)
plt.plot(x,y)
plt.xlabel('x axis')
plt.ylabel('y axis')
plt.title('matplotlib sample')
plt.show()



레전드

그래프를 그릴때 여러개의 그래프를 같이 그릴 수 있는데, 이경우 각 그래프가 구분이 안되기 때문에, 그래프마다 라벨을 달고 이 라벨명을 출력할 수 있는데, 이를 legend라고 한다.

아래는 first와 second 라는 두개의 그래프를 그리고, 우측 상단에 legend를 표현한 예이다.

legend를 사용하기 위해서는 plt.plot에서 label 변수에 그래프의 이름을 정의하고, plt.legend(‘위치')를 정해주면  legend를 그래프상에 표현해주는데, legend의 위치는 아래 표를 참고하면 된다.


from matplotlib import pyplot as plt
import numpy as np

x = np.arange(1,10,0.1)
y = x*0.2
y2 = np.sin(x)

plt.plot(x,y,'b',label='first')
plt.plot(x,y2,'r',label='second')
plt.xlabel('x axis')
plt.ylabel('y axis')
plt.title('matplotlib sample')
plt.legend(loc='upper right')
plt.show()



어노테이션

다음은 어노테이션이라는 기능으로, 그래프에 화살표를 그린후, 그 화살표에 문자열을 출력하는 기능이다. 예를들어 “이값이 최소값" 이런식으로 화살표를 그려서 표현할때 사용하는데 plt.annotate 함수를 사용하면 된다.

plt.annotate(‘문자열',xy,xytext,arrowprops) 식으로 사용한다.

문자열은 어노테이션에서 나타낼 문자열이고, xy는 화살표가 가르키는 점의 위치, xytext는 문자열이 출력될 위치, arrowprops는 화살표의 속성으로 칼라등을 정의한다.


from matplotlib import pyplot as plt
import numpy as np

x = np.arange(1,10)
y = x*5

plt.plot(x,y)
plt.annotate('annotate',xy=(2,10),xytext=(5,20),arrowprops={'color':'green'})
plt.show()



서브플롯

여러개의 그래프를 그리고 싶을때가 있는데, 이 경우 서브플롯이라는 것을 사용한다. 서브플롯은 그래프가 그려질 위치를 격자형으로 지정하는데, plt.subplot(nrow,ncol,pos) 식으로 사용한다.

nrow,ncol은 그래프를 그린 plain의 크기를 지정하는데, 3,2면 3줄로, 가로는 2칸으로 된 그래프 plain 설정한다. 그리고 마자막 pos는 몇번째 plain에 그래프를 그릴지 지정하는데, 아래와 같이 상단에서 부터 우측,아래 방향으로 1,2,3,4,5,6 순서가 된다.


1

2

3

4

5

6



아래 그림은 2,1 크기의 plain 을 만들어놓고 그래프를 위,아래로 두개를 그리는 예제이다.


from matplotlib import pyplot as plt
import numpy as np

x = np.arange(1,10)
y1 = x*5
y2 = x*1
y3 = x*0.3
y4 = x*0.2

plt.subplot(2,1,1)
plt.plot(x,y1)
plt.subplot(2,1,2)
plt.plot(x,y2)
plt.show()



아래 그림은 한줄의 두칸 plain을 만들어놓고, 좌우에 두개의 그래프를 그린 예제이다.


from matplotlib import pyplot as plt
import numpy as np

x = np.arange(1,10)
y1 = x*5
y2 = x*1
y3 = x*0.3
y4 = x*0.2

plt.subplot(1,2,1)
plt.plot(x,y1)
plt.subplot(1,2,2)
plt.plot(x,y2)
plt.show()




다음은 2x2 plain으로 4개의 그래프를 그린 예제이다.


from matplotlib import pyplot as plt
import numpy as np

x = np.arange(1,10)
y1 = x*5
y2 = x*1
y3 = x*0.3
y4 = x*0.2

plt.subplot(2,2,1)
plt.plot(x,y1)
plt.subplot(2,2,2)
plt.plot(x,y2)
plt.subplot(2,2,3)
plt.plot(x,y3)
plt.subplot(2,2,4)
plt.plot(x,y4)
plt.show()


그래프 사이즈

그래프를 크게 그리고 싶을때 그래프 자체의 크기를 변경할 수 있는데, plt.figure를 이용하여 figsize=(가로,세로)를 인자로 주면 그래프가 그려질 전체 그림의 크기를 조절할 수 있다. 아래는 20x5 크기로 그래프를 그릴 크기를 지정하는 예제이다.


import numpy as np

x = np.arange(1,10)
y1 = x*5
y2 = x*1
y3 = x*0.3
y4 = x*0.2

plt.figure(figsize=(20,5))
plt.subplot(2,2,1)
plt.plot(x,y1)
plt.subplot(2,2,2)
plt.plot(x,y2)
plt.subplot(2,2,3)
plt.plot(x,y3)
plt.subplot(2,2,4)
plt.plot(x,y4)
plt.show()




지금까지 간단하게 matplotlib를 이용하여 기본 그래프를 그리는 방법에 대해서 알아보았다. 다음글은 바차트,히스토그램등 다양한 그래프 타입에 대해서 알아본다.


파이어베이스 애널러틱스를 이용한 모바일 데이타 분석

#4 주피터 노트북을 이용한 파이어베이스 데이타 분석 및 시각화

조대협 (http://bcho.tistory.com)

노트북의 개념

빅데이타 분석에서 리포팅 도구중 많이 사용되는 제품군 중의 하나가 노트북이라는 제품군이다. 대표적인 제품으로는 오픈소스 제품중 주피터(https://ipython.org/notebook.html) 와 제플린(https://zeppelin.apache.org/) 이 있다.

노트북은 비지니스에 전달하기 위한 멋진 액셀이나 대쉬보드와 같은 리포트 보다는 데이타를 다루는 데이타 과학자와 같은 사람들이 사용하는 분석도구인데, 제품의 이름 처럼 노트북의 개념을 가지고 있다.

예를 들어서 설명해보자 우리가 수학문제를 풀려면 연습장을 펴놓고 공식을 사용해가면서 하나하나 문제를 풀어나간다. 이처럼, 빅데이타 분석을 하려면, 여러데이타를 분석해가면서 그 과정을 노트하고 노트한 결과를 기반으로 다음 단계의 문제를 풀어나가는 것이 통상적인데, 노트북 소프트웨어는 문제 풀이에 있어서 기존의 연습장 노트와 같은 사용자 경험을 제공한다.

이러한 노트북 소프트웨어의 특징은 메모를 위한 글과, 계산을 위한 소스 코드를 한페이지에 같이 적을 수 있고, 이 소스 코드는 노트북 내에서 실행이 가능하고 결과도 같은 페이지에 출력해준다.


다음 화면은 본인이 작성했던 노트북의 일부로 딥러닝 프레임웍인 텐서플로우에 대해서 공부하면서 간단하게 문법과 샘플 코드를 노트북에 정리한 예이다.



데이타랩

구글의 데이타랩(https://cloud.google.com/datalab/) 은 오픈소스 주피터 노트북을 구글 클라우드 플랫폼에 맞게 기능을 추가한 노트북이다. 기본이 되는 주피터 노트북이 오픈소스이기 때문에, 데이타랩 역시 오프소스로 코드가 공개되어 있다.


데이타랩은 기본으로 파이썬 언어를 지원하며, 빅쿼리 연동등을 위해서 SQL과, 자바 스크립트를 지원한다.

또한 머신러닝의 딥러닝 프레임웍인 텐서플로우도 지원하고 있다.

데이타랩에서 연동할 수 있는 데이타는 구글 클라우드상의 VM이나, 빅쿼리, Google Cloud Storage

데이타랩은 오픈소스로 별도의 사용료가 부가되지 않으며, 사용 목적에 따라서 VM에 설치해서 실행할 수 도 있고, 로컬 데스크탑에 설치해서 사용할 수 도 있다. 도커로 패키징이 되어 있기 때문에 도커 환경만 있다면 손쉽게 설치 및 실행이 가능하다.

데이타 랩 설치

이 글에서는 로컬 맥북 환경에 데이타랩을 설치해서 데이타를 분석 해보도록 하자.

데이타 랩은 앞에서 언급한것과 같이 구글 클라우드 플랫폼 상의 VM에 설치할 수 도 있고, 맥,윈도우 기반의 로컬 데스크탑에도 설치할 수 있다. 각 플랫폼별 설치 가이드는  https://cloud.google.com/datalab/docs/quickstarts/quickstart-local 를 참고하기 바란다. 이 문서에서는 맥 OS를 기반으로 설치하는 방법을 설명한다.


데이타 랩은 컨테이너 솔루션인 도커로 패키징이 되어 있다. 그래서 도커 런타임을 설치해야 한다.

https://www.docker.com/products/docker 에서 도커 런타임을 다운 받아서 설치한다.

도커 런타임을 설치하면 애플리케이션 목록에 다음과 같이 고래 모양의 도커 런타임 아이콘이 나오는 것을 확인할 수 있다.



하나 주의할점이라면 맥에서 예전의 도커 런타임은 오라클의 버추얼 박스를 이용했었으나, 제반 설정등이 복잡하기 때문에, 이미 오라클 버추얼 박스 기반의 도커 런타임을 설치했다면 이 기회에, 도커 런타임을 새로 설치하기를 권장한다.

다음으로 도커 사용을 도와주는 툴로 Kitematic 이라는 툴을 설치한다. (https://kitematic.com/) 이 툴은 도커 컨테이너에 관련한 명령을 내리거나 이미지를 손쉽게 관리할 수 있는 GUI 환경을 제공한다.


Kitematic의 설치가 끝났으면 데이타랩 컨테이너 이미지를 받아서 실행해보자, Kitematic 좌측 하단의 “Dokcer CLI” 버튼을 누르면, 도커 호스트 VM의 쉘 스크립트를 수행할 수 있는 터미널이 구동된다.


터미널에서 다음 명령어를 실행하자


docker run -it -p 8081:8080 -v "${HOME}:/content" \

  -e "PROJECT_ID=terrycho-firebase" \

  gcr.io/cloud-datalab/datalab:local


데이타랩은 8080 포트로 실행이 되고 있는데, 위에서 8081:8080은  도커 컨테이너안에서 8080으로 실행되고 있는 데이타 랩을 외부에서 8081로 접속을 하겠다고 정의하였고, PROJECT_ID는 데이타랩이 접속할 구글 클라우드 프로젝트의 ID를 적어주면 된다.

명령을 실행하면, 데이타랩 이미지가 다운로드 되고 실행이 될것이다.

실행이 된 다음에는 브라우져에서 http://localhost:8081로 접속하면 다음과 같이 데이타랩이 수행된 것을 볼 수 있다.


데이타랩을 이용한 파이어베이스 애널러틱스 데이타 분석 (책에서는 위치 이동 할것 파이어 베이스로)

데이타랩이 설치되었으면, 파이어베이스 애널러틱스를 이용하여 빅쿼리에 수집한 로그를 분석해보자

데이타 랩에서 “+Notebook” 버튼을 눌러서 새로운 노트북을 생성하자

생성된 노트북으로 들어가서 “Add Code” 버튼을 누르고, 생성된 코드 블록 박스에 아래와 같은 SQL을 추가하자


%%sql

SELECT user_dim.app_info.app_instance_id, user_dim.device_info.device_category, user_dim.device_info.user_default_language, user_dim.device_info.platform_version, user_dim.device_info.device_model, user_dim.geo_info.country, user_dim.geo_info.city, user_dim.app_info.app_version, user_dim.app_info.app_store, user_dim.app_info.app_platform

FROM [terrycho-firebase:my_ios.app_events_20160830]


%%sql은 빅쿼리 SQL을 수행하겠다는 선언이다.

다음에 SQL 문장을 기술했는데, 테이블은 terrycho-firebase 프로젝트의 my_ios 데이타셋의 app_events_20160830 테이블에서 쿼리를 하였다.

2016년 8월 30일의 iOS 앱에서 올라온 사용자 관련 정보를 쿼리하는 내용이다. (디바이스 정보, 국가등)

다음은 쿼리 결과 이다.



다음 쿼리는 2016년 6월 1일의 안드로이드와 iOS 접속자에 대해서 국가별 사용자 수 통계를 내는 쿼리이다.


%%sql

SELECT

 user_dim.geo_info.country as country,

 EXACT_COUNT_DISTINCT( user_dim.app_info.app_instance_id ) as users

FROM

[firebase-analytics-sample-data:android_dataset.app_events_20160601],

 [firebase-analytics-sample-data:ios_dataset.app_events_20160601]

GROUP BY

 country

ORDER BY

 users DESC




다음은 2016년 6월 1일 사용자중, 안드로이드와 iOS 모두에서 사용자가 사용하는 언어별로 쿼리를 하는 내용이다.


%%sql

SELECT

 user_dim.user_properties.value.value.string_value as language_code,

 EXACT_COUNT_DISTINCT(user_dim.app_info.app_instance_id) as users,

FROM [firebase-analytics-sample-data:android_dataset.app_events_20160601],

 [firebase-analytics-sample-data:ios_dataset.app_events_20160601]

WHERE

user_dim.user_properties.key = "language"

GROUP BY

language_code

ORDER BY

users DESC


쿼리 결과



이번에는 차트를 사용하는 방법을 알아보자, 안드로이드 로그에서 이벤트 로그중에, 많이 나오는 로그 20개에 대한 분포도를 파이 차트로 그려내는 예제이다.

%%sql --module events

SELECT event_dim.name as event_name, COUNT(event_dim.name) as event_count  

FROM [firebase-analytics-sample-data:android_dataset.app_events_20160601]

GROUP BY event_name

ORDER BY event_count DESC

LIMIT 20


쿼리 결과를 --module 명령을 이용하여 events라는 모듈에 저장한후


%%chart pie --fields event_name,event_count --data events

title: Event count

height: 400

width: 800

pieStartAngle: 20

slices:

 0:

   offset: .2


구글 차트 명령을 이용하여 pie 차트를 그린다. 필드는 앞의 모듈에서 쿼리한 event_name과 event_count 필드를 이용하고, 데이타는 앞에서 정의한 “events” 모듈에서 읽어온다.

차트 실행 결과는 다음과 같다.



이외에도 Tensorflow 연동이나 GCS를 연동하는 방법, 그리고 구글 차트 이외에 일반 plot 함수를 이용하여 그래프를 그리는 등 다양한 기능을 제공하는데, 이에 대한 자세한 설명은 데이타랩을 설치하면 /docs/README.md 파일을 참조하면 다양한 가이드를 찾을 수 있다.