2016년 3월 31일 목요일

구글 애널리틱스 플랫폼 활용

구글 애널리틱스 플랫폼을 탐색하는 데모와 도구들을 제공하는 페이지이다.

https://ga-dev-tools.appspot.com

다음과 같이 흥미로운 기능들을 가이드 하고 있다.

  • GA 측정기준 및 측정항목을 탐색할 수 있다.
  • 질의 도구를 통해서 통계 데이터를 조회할 수 있다. 
  • 구글 문서(스프레드시트)에서 주기적으로 갱신 가능한 리포트를 생성할 수 있다.
  • 강력한 내장 API들을 활용하여 손쉽게 사용자 솔루션을 만들 수 잇다.
  • 사이트 외부에도 삽입할 수 있는 추적코드 생성 도구를 제공한다. (1)

특히 (1)번을 통해서 다양한 행위에 대한 통계 자료를 손쉽게 모을 수 있다.
예를 들면,
이메일 공지에 대한 반응을 조사한다고 할때 다음과 같은 코드를 HTML 메일에 심어서 발송한다면, 메일 수신자에 대한 반응 확인이 가능하다. 나머지는 상상의 나래를 펼쳐보자.

-- sample code --
<img src="http://www.google-analytics.com/collect?v=1&t=event&tid=UA-XXXXX-1&cid=1&ec=email&ea=click&el=notice&ev=100”>

2016년 3월 18일 금요일

행렬 인수분해 3가지

인수분해는 노이즈 제거 및 데이터 압축 기법으로 유용하게 활용된다. 근래에는 기계학습 붐과 함께 패턴인식 분야에서도 유용하게 쓰인다.
본문은 일반적으로 사용하는 인수분해 기법(PCA, SVD, NMF)를 활용한 예제를 다룬다.

먼저 실험에 사용할 이미지 20개다.


위 이미지 중 하나는 45x40 이고, 일렬로 나열하면 1x1800 이 된다.
20개의 이미지를 합치면 다음과 같이 20x1800의 이미지로 만들수 있다.
(20개 이미지로는 육안 상의 의미 전달이 약해서 출력을 5번을 반복했다.)
성분의 수를 1개로 지정할때 변형(인수분해된 값을 복원)된 이미지다. 노이즈가 제거된다.
**
n_components (성분 수)
scikit-learn의 PCA, SVD, NMF의 필수 입력 인자이다.
PCA에서는 주요 인자의 개수이고 SVD에서는 S(시그마)의 인자 개수이고, NMF에서는 W, H의 특징의 개수이다. 값이 작을 수록 핵심 요소만 부각되고, 보관할 사이즈가 줄어든다.

성분 값 20, 1의 2가지의 복원된 이미지 값을 보자.
성분 값이 20일때,

성분 값이 1일때,
**
PCA, SVD, NMF 모두 유사한 형태를 보인다.
위에서 부터 PCA, SVD, NMF 순서대로 나열했다.

활용적인 측면에서는 개성있는 다양한 사람들의 사진에서 공통적인 요소를 부각해 사람이라는 객체의 일반적인 형태를 만들어 낼 수 있다는 점이다. 이 것은 다른 객체들에도 동일하게 적용 가능하다.


참조

사진 출처 및 영감을 받은 사이트
http://darkpgmr.tistory.com/110

주성분 분석(主成分分析, Principal component analysis; PCA)
고차원의 데이터를 저차원의 데이터로 환원시키는 기법이다. 서로 연관 가능성이 있는 고차원 공간의 표본들을 선형 연관성이 없는 저차원 공간(주성분)의 표본으로 변환하기 위해 직교 변환을 사용한다. 주성분의 차원수는 원래 표본의 차원수보다 작거나 같다.
**
각 성분(벡터 방향, 차원, 속성)의 평균 지점을 0으로 만드는 지점(점)으로 부터의 성분별로 거리를 추출하고 성분의 분산이 가장 큰 순으로 정렬한다.
n_components = min(n_samples, n_features)
n_components는 성분의 개수이다.

특이값 분해(Singular Value Decomposition, SVD)
행렬을 특정한 구조로 분해하는 방식으로, 신호 처리와 통계학 등의 분야 에서 자주 사용된다.
**
A = U(투영회전,직교형렬) x S(형태변환,대각형렬,components) x V(회전,직교형렬)
모든 m x n 행렬에 대해 적용 가능함으로 유연하게 쓰인다.

음수 미포함 행렬 분해(Non-negative matrix factorization, NMF)
음수를 포함하지 않은 행렬 V를 음수를 포함하지 않은 행렬 W와 H의 곱으로 분해하는 알고리즘이다. 행렬이 음수를 포함하지 않는 성질은 분해 결과 행렬을 찾기 쉽게 만든다. 일반적으로 행렬 분해는 정확한 해가 없기 때문에 이 알고리즘은 대략적인 해를 구하게 된다. 음수 미포함 행렬 분해는 컴퓨터 시각 처리, 문서 분류, 음파 분석, 계량분석화학, 추천 시스템 등에 쓰인다.
**
A = W * H
n_components = min(n_samples, n_features)
다른 기법에 비해서 성능이 느리다.

본문 사용 파이썬 코드 요약

사용된 라이브러리
import scipy, pandas as pd
from sklearn.decomposition import PCA, TruncatedSVD, NMF

이미지 읽고 쓰고 보이기
scipy.misc.imread(파일이름)
scipy.misc.imsave(파일이름, 행렬)
scipy.misc.toimage(행렬)

이미지 읽기
scipy.misc.imread(파일이름, mode='L').reshape(45 * 40)
#이미지의 간편한 처리를 위해서 8bit 흑백 모드로 읽기

행렬 결합하기
pd.concat(결합할 행렬의 리스트, axis=1)
# axis=1 가로(열)로 합치기, 0 세로(행)로 합치기

인수분해하기
# 모델 선언, 성분 개수 지정
model = PCA(n_components=성분개수)
# 인수 분해 (압축 저장)
repo = model.fit_transform(학습 및 변형할 행렬)
# 복원 하기
final_img = model.inverse_transform(repo)
# 복원된 이미지 보기
scipy.misc.toimage(final_img)

tensorflow 접근 퀵가이드

본문은 알파고로 유명세를 타고있는 tensorflow에 대한 접근 과정에 필요한 정보들을 요약한다.
tensorflow를 편하게 사용하기 위해서 만들어진(wrapped) skflow를 통해서 tensorflow를 다루는 간략한 예제와 기존의 유명한 학습 기법과 성능을 비교해 본다.

1. skflow 소개 및 DNN 사용 예제

skflow는 파이썬의 대표적인 기계학습 라이브러리인 scikit-learn과 구글에서 공개한 딥러닝 도구 tensorflow를 조합한 라이브러리다.
익숙한 scikit-learn의 인터페이스를 통해서 tensorflow를 참조 모델 셋으로 사용하기 때문에, 기존 기계학습 사용자들이 편하게 접근 할 수 있게 도와준다.

사용 방법:
# 텐서 플로우 DNN 설정
clf = skflow.TensorFlowDNNClassifier(hidden_units=h, n_classes=n)
# 학습 데이터 입력
clf.fit(mf.train_data, mf.train_target, logdir='log_dnn')
# 실험 데이터의 실제 결과와 모델의 예측치와 비교
score = metrics.accuracy_score(mf.test_target, clf.predict(mf.test_data))
print("Accuracy: %f with TF_DDN" % score)
# 모니터링 보기
command$ tensorboard --logdir=log_dnn/2016-03-18_18-15-08
# tensorboard에서 Loss 추이 화면 (MNIST 학습 과정)
**
hidden_units은 복수개의 은닉 계층을 뜻한다.
예를 들면, [10,20]의 입력 값은 10개의 unit과 20개의 unit으로 이루어진 2개의 은닉계층을 표현한다. 최적의 값을 위한 은닉계층의 수나 유닛의 수는 실험적인 결과를 통해 유추는 것으로 보인다. (좀 더 학습이 필요한 부분이다.)

주요 알고리즘 정리

자주 사용하는 알고리즘에 대한 정의 및 개인적인 포인트를 메모한다.

심층 신경망(Deep Neural Network, DNN)
입력 계층(input layer)과 출력 계층(output layer) 사이에 복수개의 은닉 계층(hidden layer)들로 이뤄진 인공신경망(Artificial Neural Network, ANN)이다.[17][18] 심층 신경망은 일반적인 인공신경망과 마찬가지로 복잡한 비선형 관계(non-linear relationship)들을 모델링할 수 있다. 예를 들어, 사물 식별 모델을 위한 심층 신경망 구조에서는 각 객체가 이미지 기본 요소들의 계층적 구성으로 표현될 수 있다.[19] 이때, 추가 계층들은 점진적으로 모여진 하위 계층들의 특징들을 규합시킬 수 있다. 심층 신경망의 이러한 특징은, 비슷하게 수행된 인공신경망에 비해 더 적은 수의 유닛(unit, node)들 만으로도 복잡한 데이터를 모델링할 수 있게 해준다.

딥러닝 (Deep Learning)
사람의 사고방식을 컴퓨터에게 가르치는 기계학습의 한 분야이다.
과학습(OverFitting)은 항상 주의 해야할 문제이다.
하드웨어 (GPU)와 분산 처리 기술의 발전으로 다시 주목 받고 있다.
컴퓨터 비전과 같은 특정 분야에서는 압도적인 성과를 보인다.

잠재변수(Latent Variable)
직접적으로 관찰되거나 측정이 되지 않는 변수를 의미한다.
딥러닝(deep learning)의 핵심 요소이다.

이미지 처리
convolution nxm
필터 효과를 만들어낸다.
subsampling nxm
이미지 분석에서는 일반적으로 Max 값을 추출한다. (max-pooling)

인공신경망 (artificial neural network)
생물학의 신경망에서 영감을 얻은 통계학적 알고리즘이다.
시냅스의 결합으로 네트워크를 형성한 인공 뉴런(노드)이 학습을 통해 시냅스의 결합 세기를 변화시켜, 문제 해결 능력을 가지는 모델 전반을 가르킨다.

서포트 벡터 머신(support vector machine, SVM)
기계 학습의 분야 중 하나로 패턴 인식, 자료 분석을 위한 지도 학습 모델이며, 주로 분류와 회귀 분석을 위해 사용한다. 두 카테고리 중 어느 하나에 속한 데이터의 집합이 주어졌을 때, SVM 알고리즘은 주어진 데이터 집합을 바탕으로 하여 새로운 데이터가 어느 카테고리에 속할지 판단하는 비확률적 이진 선형 분류 모델을 만든다. 만들어진 분류 모델은 데이터가 사상된 공간에서 경계로 표현되는데 SVM 알고리즘은 그 중 가장 큰 폭을 가진 경계를 찾는 알고리즘이다. SVM은 선형 분류와 더불어 비선형 분류에서도 사용될 수 있다. 비선형 분류를 하기 위해서 주어진 데이터를 고차원 특징 공간으로 사상하는 작업이 필요한데, 이를 효율적으로 하기 위해 커널 트릭을 사용하기도 한다.
**
최대 마진 경계를 찾는다.
비선형의 경우 새로운 차원 공간으로의 사상작업이 필요하다.

나이브 베이지안 (Naive Bayes, NB)
기계 학습 (Machine Learning) 분야에서, 나이브 베이즈 분류 (Naïve Bayes Classification)는 특성들 사이의 독립을 가정하는 베이즈 정리를 적용한 확률 분류기의 일종으로 1950 년대 이후 광범위하게 연구되고 있다.
**
올바른 클래스가 다른 클래스 보다 확률이 높을 경우 선택된다.
조건부 확률의 독립성을 가정한 알고리즘이다.
실제 확률로 볼 수는 없지만 분류에 있어 매우 효율적이다.
자연어 처리를 비롯한 많은 영역에서 사용되고 있다.

회귀분석(回歸分析, 영어: regression analysis)
관찰된 연속형 변수들에 대해 독립변수와 종속변수 사이의 상관관계를 나타내는 선형 관계식을 구하는 기법 및 이렇게 얻은 모형의 적합도를 측정하는 분석 방법이다
회귀분석은 시간에 따라 변화하는 데이터나 어떤 영향, 가설적 실험, 인과 관계의 모델링등의 통계적 예측에 이용될 수 있다.
**
표본에서 모집단 모수를 추정하기 위한 대표적인 방법이다.
최소제곱법(최소자승법)는 근사적으로 구하려는 해와 실제 해의 오차의 제곱의 합이 최소가 되는 해를 구하는 방법이다.
최대우도법(최대가능도방법)은 어떤 모수가 주어졌을 때, 원하는 값들이 나올 가능도를 최대로 만드는 모수를 선택하는 방법이다

오차와 잔차
모수에서는 실제 값과 추정 값과의 차이를 오차라 하고,
표본에서는 통계량의 개념을 갖는 잔차라는 단어를 사용한다.

결정 트리 학습법(decision tree learning)
어떤 항목에 대한 관측값과 목표값을 연결시켜주는 예측 모델로써 결정 트리를 사용한다
신경말 알고리즘이 여러 변수를 동시에 고려하지만 결정트리는 한개의 변수를 선택한다.
**
엔트로피 계수를 통해 분기의 우선 순위를 결정한다.
지니 불순도가 0이 될때 까지 분기한다.

엔트로피(독일어: Entropie)
열역학적 계의 유용하지 않은 (일로 변환할 수 없는) 에너지의 흐름을 설명할 때 이용되는 상태 함수다. 통계역학적으로, 주어진 거시적 상태에 대응하는 미시적 상태의 수의 로그로 생각할 수 있다. 엔트로피는 일반적으로 보존되지 않고, 열역학 제2법칙에 따라 시간에 따라 증가한다.

로렌츠 곡선
경제학에서 로렌츠 곡선은 하위 x%의 가구가 y%의 소득이 분배될 때의 확률 분포를 누적 분포 함수의 그래프로 나타낸 것이다. 로렌츠 곡선은 소득 분배 정도를 나타낼 때 주로 이용된다

지니 계수(Gini coefficient, 이탈리아어: coefficiente di Gini)
소득 격차를 계수화 한 것이다. 서로 다른 로렌츠 곡선들이 교차하는 경우 비교하기가 곤란하다는 로렌츠 곡선의 단점을 보완할 수 있다. 지니 계수는 소득 분배의 불평등함 외에도, 부의 편중이나 에너지 소비에 있어서의 불평등함에도 응용된다.
인구의 누적비율과 소득의 누적 점유율 사이의 상관관계를 나타내는 로렌츠 곡선은 소득분배가 완전히 평등하다면 기울기가 1인 대각선의 형태가 될 것이다.

로지스틱 회귀(영어: logistic regression)
D.R.Cox가 1958년에 제안한 확률 모델로서 독립 변수의 선형 결합을 이용하여 사건의 발생 가능성을 예측하는데 사용되는 통계 기법이다.
흔히 로지스틱 회귀는 종속변수가 이항형 문제(즉, 유효한 범주의 개수가 두개인 경우)를 지칭할 때 사용된다.
**
플롯으로 의미 들여다 보기
X = np.arange(-20,20)
e = 2.71828182846 # 근사치
logistic = lambda x: e ** x / ( 1 + e ** x)

with xkcd():
    title('logistic function')
    plot(X,[ logistic(x) for x in X ])
    ylim([-0.1,1.1])
    #grid()
    hlines(xmin=-20,xmax=20,y=0.5,linestyle='dashed')
    vlines(ymin=0,ymax=1,x=-10,lw=167,alpha=.3,color='blue')
    vlines(ymin=0,ymax=1,x=10,lw=167,alpha=.3,color='red')
    text(s='judged 0',x=-15,y=.2,fontsize=14)
    text(s='judged 1',x=10,y=1-.2,fontsize=14)

2016년 3월 14일 월요일

파이썬 2.x 한글 에러

본문은 파이썬 버전 3.5로 작성된 코드를 2.7로 변형 할때, 간혹 생겼던 한글 문제를 해소하는 방법을 다룬다.

1. 코드에 한글이 들어 갔을 때 발생하는 문법 에러

에러 코드:
SyntaxError: Non-ASCII character …

해결 방안:
스크립트 첫번째 줄에 사용할 코드 타입을 명시해 준다.
#-*- coding: utf-8 -*-

2. 변수에 한글이 들어 갔을 때 간혹 발생하는 에러

에러코드:
UnicodeDecodeError: 'ascii' codec can't decode byte …

해결 방안:
스크립트 서두에 기본 인코딩을 지정한다.
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

**
데이터에 직접 명세할 수도 있다.
‘한글’.decode(‘UTF-8’)
or
u’한글’

**
기본 인코딩으로 python 2.x에서는 ASCII, 3.x에서는 UNICODE를 사용한다.

2016년 3월 10일 목요일

테이블 데이터 샘플링 방법

테이블에서 샘플을 추출하는 두 가지 쿼리를 다룬다.

가. ORDER BY random() LIMIT n

정확한 샘플 개수를 지정할 수 있다.
정렬(sort) 수행이 발생한다.

예상 비용
cook=> explain SELECT * FROM sample_1000 ORDER BY random() LIMIT 10;
                                 QUERY PLAN                                
----------------------------------------------------------------------------
 Limit  (cost=44.01..44.03 rows=10 width=686)
   ->  Sort  (cost=44.01..44.89 rows=352 width=686)
         Sort Key: (random())
         ->  Seq Scan on sample_1000  (cost=0.00..36.40 rows=352 width=686)
(4 rows)


나. WHERE  random() <= x (%) LIMIT n

샘플의 개수가 지정한 %를 기준으로 확률 분포를 가진다.
전체 카운트를 비교해서 적절한 샘플 x(%) 지정이 필요하다.
성능이 빠르다.

예상 비용
cook=> explain SELECT * FROM sample_1000 WHERE random() < 0.1 LIMIT 10;
                              QUERY PLAN                            
----------------------------------------------------------------------
 Limit  (cost=0.00..3.19 rows=10 width=686)
   ->  Seq Scan on sample_1000  (cost=0.00..37.28 rows=117 width=686)
         Filter: (random() < 0.1::double precision)
(3 rows)

2016년 3월 4일 금요일

파이썬 로그 관리하기

파이썬에서 기본적으로 제공하는 로깅(logging) 라이브러리의 퀵 가이드이다.

로그 이름 및 레벨을 정의 한다.
import logging
# create logger
logger = logging.getLogger('simple_example')
logger.setLevel(logging.DEBUG)

핸들러를 통해서 포맷을 명시한다.
# create console handler and set level to debug
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
# create formatter
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
# add formatter to ch
ch.setFormatter(formatter)
# add ch to logger
logger.addHandler(ch)

응용프로그램에서 레벨에 따른 로그를 남긴다.
# 'application' code
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')


참조

파이썬 가이드 문서
https://docs.python.org/3.5/howto/logging.html#logging-advanced-tutorial

LEVEL (명세한 레벨의 수치 보다 높을 경우 로그를 남긴다.)

MySQL 참조 가이드

본문은 MySQL 참조를 위한 메모이다.

도움말 보기
help
아이템(item) 보기
help <item>

**
포그리(postgresql)에서는  pg_hba.conf 파일에서 하는 접근 제어를
메타 테이블을 통해서 설정한다.
schema와 database를 혼용하여 사용한다.

테이블 명세서 뽑기
SELECT
    table_name '테이블이름',
    ordinal_position '속성순번',
    column_name '속성명',
    data_type '데이터타입',
    column_type '필드타입',
    column_key '키종류',
    is_nullable '널허용여부',
    extra '자동여부',
    column_default '속성기본값',
    column_comment '속성설명'
FROM
    information_schema.columns
WHERE
    table_schema = '<database>'
ORDER BY table_name , ordinal_position;

BINARY 코드 비교
binary는 blob 블럭으로 출력 됨으로, Hex 코드로 변환해서 비교하면 된다.
hex(<binary_column>)