시계열 모형의 작성

방통대 “금융 데이터의 이해”를 듣다가 간략하게 메모, 100% 이해하고 있지는 못해서, 부족한 부분은 계속 추가할 예정

시계열의 안정화

  • 평균과 분산이 일정한지 파악하고 그렇지 않을 경우 차분 또는 로그를 통해 안정화시킨다.

모형의 식별

  • 상관계수(ACF)와 부분상관계수(PACF)를 보고 모형이 잘 설명되는지 판단한다.
    • 상관도표에서 시차별로 기준선보다 높은 상관계수가 나오는 영역이 많다면 해당 구간의 경우 일정한 관계가 있음을 확인
  • 대표적인 모형은 AR, MA, ARMA 등이 있다.
    • AR: 백색 잡음의 현재값과 자기 자신의 과거값의 선형 가중합으로 이루어진 정상 확률 모형
      • Yt=−ϕ1Yt−1−ϕ2Yt−2−⋯−ϕpYt−p+ϵt
    • MA: 오늘의 수치는 어제의 오차에 영향을 받아 만들어진다.
      • Yt=μ+et−θet−1
    • AR과 MA를 혼합한 모형
  • 주기의 경우 스펙트럼 분석을 통해서 확인

모수의 추정

  • Φ1, …Φn, Θ1…Θn, μ와 δ^2를 추정

모형의 진단

  • 잔차분석을 통해서 Rando한 분포를 보여주는지 통계적인 검정을 통해서 확인한다.
  • 적절치 않을 경우 모형의 식별단계부터 다시 시작

모형을 이용한 예측

  • 예측!

더 읽어보면 좋을 링크

탐색적 데이터 분석(EDA)

R을 활용한 데이터 과학(해들리위컴, 개럴 그롤문드 저)를 보면서 정리하였으며 지속 업데이트 예정.
EDA는 말그대로 탐색이기 때문에 자칫하면 무한정 헤매는 상황을 겪기 쉽기 때문에 풀고자 하는 질문이 무엇인지등에 대한 명확한 정의가 선행되어야 한다.

탐색적 데이터 분석은 다음과 같은 반복적 작업으로 구성되어 있음

  • 데이터에 대한 질문을 만든다.
  • 데이터를 시각화, 변형 및 모델링하여 질문에 대한 잡을 찾는다
  • 질문을 개선하거나, 새로운 질문을 만들기 위해 학습한 방법을 찾는다.

크게 다음과 같은 질문을 시도해볼 수 있다.

  • 변수 내에서 어떤 유형의 변동이 발생하는가?
  • 변수 간에 어떤 유형의 공변동이 발생하는가?

변동

  • 범주형 변수의 경우 Bar Chart, 연속형 변수의 경우 Histogram
    • Histogram의 경우 Bins Size에 따라서 패턴이 달라질 수 있기 때문에 다양한 Bin Size 탐색
    • 여러 Histogram을 겹쳐서 그리고 싶다면 geom_freqpoly() 사용
  • 질문
    • 어떤 값이 가장 일반적인가? 그 이유는 무엇인가?
    • 드물게 나타나는 값은 무엇인가? 그 이유는 무엇인가?
    • 비정상적인 패턴을 볼 수 있는가?
    • 유사한 값들의 군집이 있다면
      • 해당 데이터 내에 어떤 하위집단이 존재하는가? 어떻게 설명하거나 묘사가 가능한가?

공변동

  • 범주형 – 연속형의 경우 box plot을 사용
  • 범주형 – 범주형의 경우 geom_count을 사용
  • 연속형 – 연속형의 경우 scatter plot / geom_bin2d/ geom_hex 등을 사용
    • 연속형 변수의 경우 그룹화 사용
  • 모델링을 통해서 강력한 상관관계를 지닌 변수를 제거하고 탐색

1월 배달업종별 통화건수[SK Data hub]

서론

아직까지는 SQL을 통해서 데이터를 핸들링하는 일이 잦다 보니 R, Python 실력이 자꾸 녹스는 듯하다. 특히 시각화 부분은 분석하다보면 분석의 즐거움 속에 자꾸 놓치고 지나가는 듯해서 꾸준히 데이터를 틈틈히 다퉈보기로 하였다.

그런 차원에서 오늘 만지는 데이터는 SK Data Hub에서 제공하는 19년 1월 서울 배달업종별 이용 통화량이다. 데이터 자체는 양이 11만건정도로 많지는 않은 편이나 서울 구, 동에서 발생하는 주문수를 일자 및 시간대 레벨로 제공해주기 때문에 여러 재미있는 인사이트를 줄 수 있을 것으로 기대한다. 여기서는 통화건수 = 주문건수라고 가정하고 데이터를 확인해보았다

일 주문수 – 주말로 갈 수록 주문 증가, 외부이벤트에 영향을 많이 받음

일평균 전화주문수(01/01 – 01/31)

보통 주문수는 월요일에서 일요일로 가면서 주문수가 대폭 상승하는 편이다. 그렇게 생각해보면 높게 상승한 봉우리가 주차 수만큼 나와야 하는데 지금 보는 것과 같이 14일 주차와 21일 주차에 다소 높게 주문수가 높게 온 날이 있다. 아마 아시안컵 일자가 아닐까 싶다. 16일과 22일에 한국은 각각 중국과 바레인을 상대로 경기를 진행한 바 있다.

일평균 주문수 – 매일 약 34,000건 주문 발생

  • Min: 27,907 건
  • 1st Qu.: 30,957건
  • Median: 33,594건
  • Mean: 34,496건
  • 3rd Qu.: 38,518건
  • Max: 42,840건

일평균 주문수는 대략 약 34,000건 정도 나온다. 가게수를 알면 대략 한 업소별 일평균 주문수를 알 수있텐데 그 정보는 제공되지 않는다. 요즘은 배달의민족, 요기요 등의 플랫폼으로 주문이 이루어지기 때문에 전화 주문수는 많지 않은 것을 감안한다면 사람들은 정말 배달을 많이 시켜먹는다는 것을 새삼 느끼게 해준다. 그리고 최소 주문과 최대 주문간의 차이는 약 15,000건으로 평균의 43%에 해당 하는 양이다. 생각보다 주문의 편차가 꽤 있다는 생각이 들었다.

카테고리별 주문수 – 스포츠 경기를 볼 때 주로 우리는 치킨을 먹는다.

역시 치킨이다. 한국은 치킨이다. 그리고 중국음식도 꽤나 선전하고 있다. 배달하면 떠오르는 음식 역시 치킨과 피자이다. 특히 치킨은 1월 22일 한국 vs 카타르 전에 20,000건이 넘는 전화 주문수를 기록하고 있다.

시간대별 주문수 – 점심,저녁, 야식 이 세 꼭지를 중심으로 배달시킨다.

크게 보면 00시, 12시, 18시, 3개의 봉우리가 있다. 각각 야식, 점심, 저녁에 해당한다. 피크시간은 18~19시로 이후에는 주문수가 빠르게 하락하는 것을 볼 수 있다.

지역별 주문수 – 예상외로 강서구의 높은 주문수, 관악구, 광진구의 저조한 주문수

가장 의외의 결과가 나왔다. 양천구, 관악구, 광진구, 도봉구, 금천구는 타 지역 대비 전화 주문수가 매우 낮았다. 앞서 언급한 것처럼 배달플랫폼을 통한 주문이 주로 이뤄져서 그럴 수도 있겠다는 생각이 들었다. 특이점으로는 중구에서 나타난 Outlier였다. 1월 1일에 최소 주문수를, 1월 11일에 최대 주문수를 기록하였다. 회사가 밀집되어 있는 지역으로 연초와 불금에 각각 최소, 최대 주문수를 기록하였다.

결론

치킨집의 규모가 다른 음식보다는 월등함은 이미 정성적으로도 알고 있었지만 저렇게까지 차이가 날 것이라고 생각하지는 못했다. 그리고 각 구 별로 생각보다 많은 차이가 나는 것이 놀라웠다. 특히 강서구가 그러했다. 조금 더 파볼까 했지만 월요일이 코앞인 관계로 다음 번에 보는 것으로 하자.

TIL – Interaction Variable, Removing features with low or zero variance, Feature Selection with a Random Forest

Summary

Feature Engineering시 파생변수 생성 방법 중의 하나인 Interaction Variable를 생성하는 방법과 Random Forest의 Feature Importance를 통해 Feature Selection을 하는 방법을 정리한다. 관련 참고 소스코드에 대한 출처는 이전 글에 정리해놓았다

Interaction Variable

보통 선형모델에서는 각 설명변수들이 반응변수에 미치는 영향은 서로 독립적이라고 가정을 한다. 하지만 그렇지 않을 수도 있다. 예를 들어 매체들을 선형변수라고 놓고 매출을 반응변수라고 놓을 때 특정매체(예: 라디오)를 지출을 높이면 높일 수록 다른 매체(예: TV)가 매출에 미치는 영향도가 높아지는 경우가 발생할 수 있다. 마케팅에서는 이런 경우를 시너지효과라고 말하고 통계학에서는 상호작용 효과라고 말한다. 이런 경우를 선형모델에 반영하기 위해서 Y= e + B1X1 + B2X2 + B3X1X2 에서 B3X1X2와 같이 상호작용 변수를 만드는 경우가 있다. 이런 상호작용 변수(Interaction Variable)를 만드는 방법은 아래 코드와 같다. PolynomialFeature Library를 통해 만든다.

Removing Features with Low or Zero Variances

분산도가 0에 가까운 변수들의 경우 모델링시 참고할 필요가 없어서 제거를 하는게 좋은데 그 때 VarianceThreshold 라이브러리를 쓰면 된다.

Selecting features with a Random Forest and SelectFromModel

RandomForest 모델을 통해서 Feature를 톨해 선택할 수 있다. 우선 Random Forest Classifier로 Fitting을 한다음에 Selection From Model로 Feature를 선택할 수 있고 이후 get_support()로 Column List를 추출하면 된다.

TIL – 전처리시 Meta 생성, UnderSampling, Imputer

목적

TIL이란 Today I Learned의 목적으로 매일 배우는 것들에 대해서 접하는 데에서 그치지 않고 기록으로 재생산함으로써 내 것으로 만들고자함.

Meta Information

EDA시, 데이터에 대한 타입, 이후 모델링시 사용 여부 및 타입 등을 Meta로 관리함으로써 이후 분석, 시각화 및 모델링 설계시 편이성을 높일 수 있다.

Meta Data 생성 과정

아래 코드를 보면 컬럼별로 Grouping을 해주고 있다. 예를 들어 Label Column인 Target은 Target으로, 분석시 사용될 컬럼에 대해서는 input으로 정의하고 있으며, “Keep” Column을 통해 각 변수들의 사용 여부를 기록하는 Column을 만들어서 분석시 사용할 컬럼에 대해서 어떤 컬럼을 train에서 쓸지 정리해놓고 있다.

사용 예시

ordinal 타입의 변수들만 선별해서 기술통계수치를 확인하고 있다.

Undersampling

Descriptive Stats 확인 과정에서 Label Column인 Target컬럼에 대해서 Target == 0 인 경우가 Target == 1인 경우에 비해 지나치게 많은 것이 확인되어서 동일한 비율로 맞춰주기 위해 Under Sampling을 하였다.

각각 편중된 Class 레코드 수에 Under-sampling Rate를 적용해서 적정 레코드 수를 계산한 다. 이후 해당 수만큼 랜덤으로 인덱스를 선별한 다음 이에 기반해서 최종적으로 각 Class 별 1:1로 데이터가 남도록 Train Dataset을 조정한다.

Imputation

Missing Value 나 Null에 대해서 치환해주는 방식으로 sklearn.preprocessing 라이브러리 내 Imputer 패키지를 사용한다. 아래 예시는 Continuous Variable의 경우 Mean으로 치환하고, Ordinal Variable의 경우 Mode로 치환하고 있다.

서울시 무인발급기 위치 파이썬(Python)으로 확인해보기

동사무소에 서류를 발급받으러 갈 일이 생겼다. 언택트 트렌드(Untact Trend)에 익숙한 나로서는, 동사무소보다는 무인발급기를 더 선호하하기에 무인발급기가 서울에 어디 위치하고 있는지 문득 알고 싶었다.

 

1. 데이터 다운로드

민원24(링크)에 접속해서 설치장소 안내를 클릭해서 설치된 장소가 안내된 Excel 파일을 받는다. 필자가 받았을 때는 5.31일 기준으로 업데이트 된 파일이었다.

해당 파일을 적절한 위치에 놓고 Python Jupyter를 켠다.

 

 

2. 데이터 로딩

Jupyter 상에서 데이터를 로딩하기 전에 항상 기본적으로 하는 셋팅이다. 개인적으로 D2Coding Font를 선호하기 때문에 에디터의 Font를 D2 Coding으로 바꿔준다.

 

해당 파일을 read_excel로 Loading한다. Windows 환경이기 때문에 별도로 Encoding Option을 주지는 않았다.

 

 

 

지도를 그리기 위해서는 위도, 경도 데이터가 필요하다. 해당 데이터는 Google Maps API를 사용하면 쉽게 구할 수 있다. Google Maps Library(gmaps)가 설치되어 있지 않다면 “pip install gmaps”를 통해서 설치해준다. 그리고 해당 API를 사용하기 위해서는 Key를 발급받아야 한다. Key를 발급받았다면 아래 코드 상에 입력해준다.

위 “도로명주소” 컬럼을 보면 알 수 있듯이, 신주소와 구주소가 함께 입력되어 있다. 그래서 필자는 “(“와 “,” 기준으로 왼쪽에 있는 신주소 부분만 도로명주소를 남겨두었다. 그리고 서울 외지역에 설치된 곳은 필요가 없기 때문에 서울지역의 데이터만 남겨놓았다.

 

이 부분이 가장 중요한 부분이다. pinkwink님의 블로그를 참고해서 위도와 경도 데이터를 구해서 기존 데이터에 새로운 컬럼으로 추가시켰다.

혹시 위도, 경도 데이터가 없는 경우가 있는지 확인하였다. 없을 경우 아래 Folium 라이브러리 사용시 Error가 발생한다.

3. 맵에 띄우기

Folium 라이브러릴 이용해서 위도/경도 기준으로 위치를 모두 지도 상에 찍어보았다. 확대/축소를 통해서 무인발급기의 정확한 위치를 파악할 수 있다. 그리고 내 집 주위에는 무인발급기가 없다는 것을 알게 되었다.

 

Jupyter로 작업할 때 기본으로 Loading하는 녀석들.

jupyter 사용시 기본으로 Loading하는 녀석들.  눈에 보기 좋은 폰트로 분석해야지 분석도 더 잘 된다.

 

Python Cookbook Data Structures and Algorithms Day 2 정리

Dictionary

Problem:  You have two dictionaries and want to find out what they might have in common (same
keys, same values, etc.).

Problem:  You have a list of dictionaries and you would like to sort the entries according to one
or more of the dictionary values.

 

 

Most_common() methods

Problem:  You have a sequence of items, and you’d like to determine the most frequently occurring
items in the sequence.

 

itertools.groupby()

Problem:  You have a sequence of dictionaries or instances and you want to iterate over the data in groups based on the value of a particular field, such as date.

 

 

Python Cookbook Data Structures and Algorithms Day 1 정리

Star Expression

Problem: You need to unpack N elements from an iterable, but the iterable may be longer than N elements, causing a “too many values to unpack” exception.

Deque

Problem:  You want to keep a limited history of the last few items seen during iteration or during
some other kind of processing.

※Deque:  Using deque(maxlen=N) creates a fixed-sized queue. When new items are added and
the queue is full, the oldest item is automatically removed.

Heapq

Problem: You want to make a list of the largest or smallest N items in a collection.

Caution: If you are looking for the N smallest or largest items and N is small compared to the overall size of the collection, these functions provide superior performance. If you are simply trying to find the single smallest or largest item (N=1), it is faster to use min() and max(). Similarly, if N is about the same size as the collection itself, it is usually faster to sort it first and take a slice (i.e.,use sorted(items)[:N] or sorted(items)[-N:]).

 

Problem:  You want to implement a queue that sorts items by a given priority and always returns
the item with the highest priority on each pop operation

 

[SQL] Case When과 COALESCE / NullIF 번갈아 써보기

하루에 하나씩 Codewar에서 SQL 문제를 풀고 있다. 그 중 필요한 부분은 기록으로 남긴다.

1) COALESCE / NullIF 사용시

  • NULLIF(exp1, exp2): exp1값과 exp2값이 동일하면 NULL을 그렇지 않으면 exp1을 반환
  • COALESCE(expr1,expr2,expr3,…): expr1이 NULL이 아니면 expr1값을, 그렇지 않으면 COALESCE(expr2,expr3,…)값을 반환

2) Case-When 구문

3) With를 통한 임시 테이블 생성