data.frame melt 시키기

테이블의 컬럼들을 한 컬럼으로 내리고 값을 따로 빼는 것을 melt(melting)라고 합니다.그 반대로 값을 컬럼으로 올리는  작업을 cast (casting)라고 합니다.
이런 것을 엑셀이나 DB에서는 pivot(pivoting 추축) 이라고도 하고 또 transform이라고도 말합니다.

R과 python에서 melt하는 간단한 코드 스니펫을 올립니다.  Google에 검색을 하면 다 나오는 것이지만 순전히 제 편의를 위해서 올려둡니다.

R은 특히 ggplot2를 사용할 때 facet을 쓰려면 melt된 상태여야 하는 것이 있어서 연습이 필요합니다만 늘 까먹습니다. (전 바보인가봐요)

R코드입니다.
다른 방법도 많지만 R은 reshape2 패키지를 쓰는 것이 편합니다.

python코드입니다.
python은 당연히 Pandas에 melt 함수가 있습니다.

 

RStudio 1.1 릴리즈

지난 10월 9일 RStudio 1.1이 릴리즈되었습니다.

설치를 하고 나면 다크테마로 설정된 달라진 분위기의 애플리케이션 모습을 볼 수 있습니다.

RStudio v1.1

공식 내용은 RStudio blog에서 확인할 수 있습니다.

https://blog.rstudio.com/2017/10/09/rstudio-v1.1-released/

업데이트 내용은

  • 다크테마 지원
  • 데이터베이스 컨넥터 지원 및 탐색 기능
  • 오브젝트 탐색 기능 강화
  • 터미널 탭 지원
  • 기타 소소한 업데이트

입니다.

당연한 것이겠지만 Rstudio server 1.1도 몇가지 기능 개선과 더불어 릴리즈 되었습니다.

 

포항공대 POSTECHX AI 및 데이트사이언스 관련 온라인 무료 강의

포항공대에서 개설한 MOOC(온라인 오픈 강의) 가 있습니다.

http://www.postechx.kr/ko/school/gsit

2017-10-13 기준으로 총 6개의 온라인 강의가 개설되서 진행중입니다. 밑에 강의 정보가 간단히 있습니다. 관심이 있으시면 직접 사이트에 접근해서 수강신청하시면 됩니다. 무료입니다.

Big Data
컴퓨터공학
2017-09-04 ~ 2017-12-03
Big Data
컴퓨터공학
빅데이터의 개념, 기술적인 챌리지와 다양한 접근 방법에 대한 이해를 토대로 빅데이터 문제를 직접 실습하고…

컴퓨터 공학 입문 (SPOC)
컴퓨터공학
2017-09-22 ~ 2017-11-30
컴퓨터 공학 입문 (SPOC)
컴퓨터공학
본 강좌는 포스텍 및 포항제철고 재학생 대상 SPOC (Small Private Online Course…

SDN – NFV
컴퓨터공학
2017-09-04 ~ 2017-12-10
SDN – NFV
컴퓨터공학
SDN 및 NFV 기술을 소개하고 오픈 네트워킹 에코시스템을 구성하는 다양한 오픈소스 프로젝트의 사용방법에…

Software Development Process
컴퓨터공학
2017-09-04 ~ 2017-11-26
Software Development Process
컴퓨터공학
소프트웨어가 개발되는 방법을 공학적인 관점에서 살펴보고 개발 방법론이 시대의 요구에 따라서 어떻게 변해왔고…

Advanced Computer Architecture
컴퓨터공학
2017-09-04 ~ 2017-12-10
Advanced Computer Architecture
컴퓨터공학
컴퓨터 구조 개념들을 깊이 있게 이해하는 것을 목표로 하는 강좌입니다.

Internet of Things
컴퓨터공학
2017-09-04 ~ 2017-12-10
Internet of Things
컴퓨터공학
This course aims at introducing the general concepts and…

Google Cloud Engine IP 대역 알아내기

Google Cloud Engine (줄여서 이하 GCE)로부터 회사의 서비스에 발생시키는 기계적인 트래픽을 알아내기 위해서 GCE의 전체 IP대역을 알아내서 확인해 보려고 했는데 여기저기 검색해 본 결과 DNS lookup을 하면 되는 것을 알아냈습니다.

이렇게 하시면 됩니다.

명령의 결과는 밑에 있습니다.

많지 않은 것 처럼 보이지만 CIDR를 모두 풀어서 IP주소로 바꿔 놓으면 무지하게 많습니다. (구글 스케일. ‘ㅡ’;)

CIDR 형식으로 리턴되기 때문에 start, end 형식으로 바꾸시려면 Python을 사용하던지 해서 CIDR에서 Start IP와 End ip를 추출하면 됩니다. 시간이 되면 간단한 예제를 업데이트 해보겠습니다.

 

오픈소스 Yahoo Vespa

2017년 9월 26일에 Yahoo가 Vespa를 오픈해서 오픈소스로 공개했습니다.

먼저 밑에 프로젝트의 URL을 올려드립니다.
http://vespa.ai/

개인적으로 상당히 큰 사건이라고 생각합니다.

우선 Yahoo가 가진 핵심 기술 중에 절대로 공개하지 않을 것만 같은 것 중에 항상 언급이 되는 것 중에 다섯손가락 안에 꼽히는 것이 Vespa입니다.

하지만 Vespa가 뭔지 대부분의 분들은 모를 것입니다.  간단히 설명하면 Vespa는 원래는 검색엔진이었습니다. 하지만 최초에 만들어지고 Yahoo 내에서 계속 사용하면서 발전시켜서  기능이 많이 확장되었고 성숙하게 발전해서 통합 콘텐츠 처리 플랫폼이 되었습니다.

저도 Vespa를 이용해서 일을 했던 적이 있습니다만 매우 오래전이기 때문에 제가 봤던 것보다는 지금의 버전이 훨씬 더 많이 확장되었고 발전했을 것이라고 생각합니다.

조금 구체적으로 설명하면

앞서 말씀드린 것 처럼 Vespa는 검색엔진을 중심으로 둔 통합 콘텐츠 처리 플랫폼의 콤포넌트 셋입니다.  간단히 생각하면 검색엔진이라고 보면 되지만 일반적인 Solr이나 Elastic과 같은 검색엔진 보다는 주변에 가진 부속 컴포넌트들이 훨씬 더 많습니다.

Vespa의 역사를 보면 Vespa는 노르웨이의 엔지니어들이 주축으로 만든 한때 유럽의 Top1 검색엔진이었던 Fast검색엔진의 갈래입니다. Fast검색엔진은 후에 시장 주도권을 뺏긴후 차츰 회사 자체가 분할 매각되어서 지금은 거의 자취가 사라졌습니다.

분할된 Fast사는 Yahoo가 일부를 인수했고 시간의 간격을 두고 Microsoft가 일부를 인수했고 나머지 분할된 파트는 지금은 어찌되었는지 지금은 잘 모르겠습니다.

이 중에 Yahoo가 Fast에서 인수한 분할 부분은 Web search를 담당하는 쪽이었는데 인수한 Web search engine 중에  crawler같은 것을 버리고 vertical 검색 및 content platform으로 발전시킨 것이 Vespa입니다.  Vespa가 crawler같은 것을 버리고 web search 엔진을 추구하지 않은 이유는 Yahoo는 그당시에 이미 Inktomi web search를 가지고 있었기 때문에 Web search가 또 필요하지 않은 상태여서 Vertical search engine으로 방향을 전환하게 됩니다.

Vespa는 오토바이 브랜드명이기도 하지만 Vertical Search Plafrom의 약어입니다. 이름에 추구하는 바를 넣었듯이 한창때에는 세계 최고의 Vertical  Search Platform이라고 부를만 했습니다만 지금은 모르겠습니다. 검색 엔진쪽 만의 기능은 Elastic Search와 비교를 해봐야 하겠습니다.

Hadoop의 창시자인 더그커팅도 Yahoo에 근무하던 시절이 있었기 때문에 루씬도 Vespa에도 상당한 영향을 주었다고 알려져 있습니다. 때문에 Elastic이니 Solr이니 하는 Lucene기반의 것들과 비슷한 면도 많습니다.

검색엔진의 측면에서는 현재 주류라고 할 수 있는 Elastic Search와 비교를 해봐야 하겠습니다만 전체 기능의 광범위함과 성능을 볼 때는 Elastic Search가 Vespa를 따라가지 못할 것 같습니다.  하지만 편리함의 측면이라면 Elastic search가 더 나을 것입니다.

Vespa를 보면 코어 모듈의 튼튼함과 오랜 역사, 깔끔한 구조, 다양한 주변기능은 유럽 엔지니어들의 탁월한 능력을 엿볼 수 있게 해줍니다. 소스코드도 매우 깔끔하고 구조화가 잘 되어 있는 편이고 작동도 일관성있게 작동하는 것이 특징입니다.  소스코드를 들여다 보는 것 만으로도 많은 공부가 됩니다.

부속 콤포넌트 및 주변 콤포넌트로는 ML ranking(MLR이라고 부릅니다)을 비롯한 자체 개발한 문서저장용 NoSQL, 분산 데이터 파이프라인, 페더레이션(Federation)을 위한 컨테이너 등도 모두 가지고 있습니다.

그리고 여기에 Yahoo의 또 하나의 오픈 소스 선물인  Hadoop과 결합해서 사용하면 최고의 Content Agility Platform을 구성할 수 있게 됩니다.

MLR은 기계학습 기반의 검색결과 랭킹 기능입니다. GBDT기반으로 되어 있었습니다만 오픈 소스 버전에 탑재가 되었는지는 모르겠습니다.  (아마 되어 있을 것입니다. 분리하기 어렵기 때문에) 그리고 다국어 형태소 분석기와 Yahoo의 강력한 언어처리 모듈이 결합되어 비교적 매끈한 언어처리 기능까지도 지원했었습니다. 형태소 분석기와 언어처리 모듈은 오픈소스 버전에는 아마도 포함되지 않을 것입니다.

페더레이션 컨테이너 여러 검색엔진의 결과를 하나로 병합해주는 플랫폼을 말합니다.

분산 데이터 파이프라인은 소스로부터 검색엔진까지의 데이터 파이프라인으로 검색엔진으로 가기전까지 콘텐츠를 가공, 병합, 변형하는 플랫폼입니다.

이외에도 Phrase match와 Proximity 계산을 위한 고속 FSA 라이브러리와 그 외에 부속품들이 잔뜩 들어 있는 종합선물세트입니다.

대략 여기까지만 보셔도 알겠지만 대형 인터넷 포털사이트에서 사용하던 수십억건의 콘텐트를 관리, 가공, 활용, 서비스하는데 사용했던 솔루션을 이제는 누구나 사용할 수 있다는 것입니다.

기쁜일이지만 개인적으로는 서글픈 감상에도 젖어봅니다. Yahoo가 저렇게 하나씩 보따리를 풀고 사라져 가네요.

TFIDF – Term Frequency Inverse Document Frequency

TFIDF(TF-IDF)에 대한 포스트입니다.

강연을 하기 위해서 전에 작성해 놓은 자료를 찾다가 못찾고 말았습니다. 그래서 혹시 이 블로그에 적어 놨는지해서 찾아봤는데 없더군요(‘ㅡ’).  결국 다시 작성해야 하게 생겼는데 했던걸 도로 하려고하니 정말 하기 싫더군요. 그래서 먼저 블로그로 포스팅을 하기로 했습니다.

이걸 강연자료로 다시 바꿀겁니다.

언제나 그렇듯이 이런 것에 대한 설명은 위키피디아에도 잘 나와 있습니다.  위키피디아의 설명이 잘 되어 있긴하지만 이해하기 쉽게 아주 자세히 된 것은 아닌 것 같습니다.

어떤 분들은 위키피디아 설명이 아주 잘되어 있다고도 하시던데 저는 대부분의 위키피디아의 내용은 너무 어렵게 적혀 있다고 생각합니다. ‘-‘;

영문 위키피디아의 내용이 한글 위키피디어 내용 보다 더 상세합니다만 영어에 압박을 느끼는 분들은 한글을 보시고 그것도 싫으시면 위키피디아를 읽는 것은 통과하셔도 됩니다.

TFIDF에 대한 내용은 누군가의 이해를 돕기 위해서 주욱 풀어서 설명하다보면 제 경험으로 내용이 매우 장황해집니다.

TFIDF는 간단히 잘 설명하기 어려운 것 중에 하나입니다.
쉽게 설명하려면 설명을 매우 길게 해야하고 길게하면 너무 늘어져서 맥락을 놓칩니다.

너무 간단하게 짧게 적어버리면 처음 접하는 분들께는 오해와 착각을 유발할 여지가 있는 부분도 생깁니다. 그것은 장황해지는 것 보다는 더 큰 문제가 있습니다.

가능한 쉽게 풀어서 쓴다는 블로그의 취지에 맞게 이 포스트는 어째든 길게 풀어서 작성하겠습니다. 장황하다는 말이지요.

긴 글을 싫어하시는 분들은 인터넷의 다른 글들도 한 번 찾아보세요. 짧게 잘 설명된 글도 많이 있습니다. 관련지식이 있는 분들은 그 정도로도 충분할 것입니다.

TFIDF는 어디 쓰이는가?

먼저 어디 쓰이는지 알면 이해하는데 도움이 될 것입니다.

검색엔진(Google, Bing, Naver 이런것들이요)이나 텍스트마이닝에서 흔히 볼 수 있을텐데요.  문서의 유사도나 중요도 같은 것을 계산하기 위해서 문서내의 단어들을 계량화(quantization)를 하는데 그 계량화를 할 때 중요한 단어와 중요하지 않은 단어를 다르게 가중치 고려하고 싶을 때 사용하는 가장 잘 알려진 방법입니다.

간단히 말해서 “문서 내의 단어들에 각각 부여한 중요도를 나타내는 숫자값” 입니다.

TFIDF의 정의

TFIDF의 포괄적인 의미에서의 정의는 이렇습니다.

여러 개의 문서가 있을 때 각 문서 내의 있는 텀(term)들에 가중치가 적용된 어떤 수치값을 부여해 놓는 방법

텀(term)이 뭔지는 뒤에서 설명합니다.

이렇게 TFIDF값을 부여해 놓고 나중에 코사인 유사도(Cosine Similarity)등을 이용해서 문서들의  유사도를 구하는데 흔히 사용합니다. (코사인 유사도는 제 블로그의 다른 포스트를 참조하셔도 되고 역시 위키피디아를 보셔도 됩니다)

TFIDF를 계산하면 문서 내에서 상대적으로 더 중요한 단어가 어떤 것인지 알 수는 있지만 그 외에 문서끼리의 유사도라든가 이런것은 계산이 되어 있지 않은 상태입니다.

즉 문서와 문서의 유사도를 구하거나 여러가지 용도로 사용하기 이전에 단어들에게 부여하는 어떤 수치라고 기억해 두고 시작하시면 됩니다.

문서는 글들이 적혀 있는 텍스트(text)를 말합니다.

TFIDF 공식

우선 TFIDF scheme 공식을 잠깐 확인하고 넘어갑니다.  당장은 이 공식이 아주 중요하지 않습니다. 그래서 너무 공식을 자세히 볼 필요는 없습니다.

초간단 버전의 공식입니다. 공식이라기 보다는 의사코드(Pseudo code)에 가깝습니다.

  \begin{aligned}  \huge{  \mbox{tf-idf}_{t,d} = \mbox{tf}_{t,d} \times \mbox{idf}_t  }  \end{aligned}

그냥 공식대로라면 TF와 IDF를 곱하면 됩니다. 물론 TF와 IDF가 뭔지는 나와있지 않습니다. 사기이지요.

밑에 제대로 된 공식이 나옵니다만 사실 기본 컨셉으로는 저 공식이 전부라고도 할 수 있습니다.

사실 TFIDF의 공식은 수치계산 부분 보다는 프로세싱을 어떻게 하는지에 대한 주변의 설명 부분이 더 많습니다. 그래서 처음보면 저 공식만 보고는 아무것도 이해할 수 없습니다.

이해를 위해서 이제 TFIDF를 각각 파트별로 3단계로 구분해서 적어보면 다음과 같습니다. 각각 TF, IDF그리고 TFIDF를 구하는 공식으로 나뉘어 있습니다.
다음은 덜 간단한 공식입니다.

\begin{aligned}\huge{t{f_{ij}} = \frac{{{f_{ij}}}}{max\{ {f_{1j}},{f_{2j}},{f_{3j}},\ldots,{t_{\left| v \right|j}} \}},}\end{aligned}

\begin{aligned}\huge{id{f_i} = \log \frac{N}{{d{f_i}}}.}\end{aligned}

\begin{aligned}\huge{{w_{ij}} = t{f_{ij}} \times id{f_i}.}\end{aligned}

하지만 주변설명이 여전히 안되어 있습니다. 이것만 가지고는 이해하는 것은 불가능합니다.

공식내에 있는 각 문자에 대한 정의나 설명도 하지 않고 f나 df같은 것을 어떻게 추출해서 뽑아내는지도 설명을 하지 않았습니다.
이것은 뒤에 설명할테니 위의 공식도 그냥 훑어 보고 넘어가셔도 됩니다.

위에 적은 공식은 텍스트마이닝의 대학원 과정의 교재에서 복사해 온 것으로 TFIDF 공식의 생김새는 대충 저렇습니다만 미리 말씀드리지만 TFIDF의 공식은 딱 1개가 아닙니다.
그래서 무조건 하나를 보고 “그게 맞다”라고 생각하시면 안됩니다. 공식은 상황이 수집된 문서의 내용들 등에 따라 다르게 변형해서 쓸 수 있습니다. 이 부분은 다른 포스트에서 기회가 되면 따로 적어보겠습니다.

내가 알고 있는 공식과 다르므로 무효! 이러시면 곤란해요

공식부분은 우선 대충 넘어가고 나중에 다시 설명하겠습니다.
이제 TFIDF란 용어의 해설부터 먼저 분해해서 확인해 보겠습니다.

TFIDF란?

앞서 설명했지만 반복해서 말하자면 TFIDF는 정보검색(그러니까 검색엔진)이나 텍스트마이닝과 관련된 곳에서 흔히 등장하는 용어입니다.  조금 구체적이면서도 간단히 정의를 적어보면 이렇습니다.

TFIDF = 검색엔진, 텍스트마이닝, 텍스트 처리와 관련된 것으로 텀에 부여된 가중치 값

TFIDF는 단어자체가 주는 알파벳의 나열과 다소 딱딱한 발음으로 인해 처음 접하는 사람들에게 공포감을 조성합니다만 알고보면 그렇게 공포스러운 것은 아닙니다.

TFIDF는 “티에프아이디에프”라고 침을 튀기면서 공격적으로 읽습니다. 발음이 주는 포스가 조금 있긴합니다.

단어를 다 풀어서 원래 제목으로 적어서 해석을 시도해 보면 좀 더 이해가 쉽습니다.  TFIDF의 원래 명칭은 다음과 같습니다.

Term Frequency  Inverse Document Frequency weighting scheme

TFIDF는 Term Frequency Inverse Document Frequency의 앞글자만 따서 줄여놓은 단어입니다.
짧게 TF-IDF weighting scheme 라고 합니다.

줄임말을 펼쳐봤지만 여전히 이해 안가기는 마찬가지일 것입니다.
다시 명칭을 단어들을 각각 더 자세히 풀어보겠습니다.

Term 텀

Term Frequency에서의 Term은 “색인어”를 말합니다. 색인어는 흔히 교과서나 기술서적의 맨 뒤에 단어를 알파벳순(또는 가나다순) 나열하고 몇 페이지에 등장하는지 적어 놓은 것을 보셨을텐데요. 거기에 있는 단어 목록을 색인어라고 합니다. 그렇게 단어들을 정리한 것들을 “색인”이라고 합니다. (Term은 원래 포괄적인 의미로 “용어”라는 뜻이긴 하지만 다소 협소한 의미이긴 하지만 여기에서는 “색인어”라고 이해하는 것이 더 도움이 될 것입니다)

색인어=Term이고 색인=Index 입니다.

IT계열에 몸을 담고 계신분들 중에 일부는 검색엔진과 관련된 용어나 RDBMS(데이터베이스)에서 인덱싱(indexing)한다고 말하는 것을 들으신 적이 있을텐데요. 그것들과 하는 것이 사실상 같아서 기계를 이용해서 색인을 만들어서 정리해 두는 것을 말합니다.

보통 책같은 것에서 색인어를 구성할 때는 책의 내용중에 포함된 중요한 명사만 골라서 색인으로 만들고 과거에는 검색엔진도 그런 방식을 사용했던 적이 있습니다.
최근의 검색엔진에서는 그렇지만은 않습니다. 검색엔진의 색인을 어떻게 구성하느냐는 하기 나름입니다.  하지만 잘 이해하기 어려우시면 우선 명사 위주로 하는 것이 검색엔진이나 텍스트마이닝에서 가장 기본적인 쉬운 방법이다라고 기억해 두시면 됩니다.

색인의 예를 간단히 적어보면 다음과 같이 색인어와 색인어의 위치를 매핑한 것입니다.

마이닝 – 23, 56, 128
텍스트 – 12, 23, 59

요약해서 어떤 단어가 어디에 있는지(어느 문서에 있는지)를 기록해 놓은 것에서 그 기록의 대상이 되는 단어들을 말합니다.

저 위에서 “마이닝”, “텍스트” 같은 것이 텀(term)입니다.

Term Frequency

Term Frequency를 그대로 해석해 보면 텀(term)의 빈도수입니다. 색인어의 빈도수를 말합니다. 즉 색인어가 몇 번 나왔는지 숫자를 센 것입니다.

Frequency를 주파수 같은 것으로 해석을 해버리시면 아주 이상해지지요.

어디에서의 빈도수인지는 설명이 안되어 있는데 특별한 언급이 없으면 어떤 한 문서내에서 색인어가 출현한 빈도수를 말합니다.

Inverse Document Frequency

Inverse는 우선 나중에 설명하고 Document Frequency(문서 빈도)부터 설명하면 다음과 같습니다.

Document Frequency = Term이 출현한  문서의 빈도수

Document Frequency는 그냥 해석하면 문서 빈도수가 될텐데요. 처음 보는 분들은 여기서 부터 조금 헷갈릴 것 같습니다.

제목에 Term이 출현한다는 말은 없지만 텀(term)이 출현하는 문서의 수를 세어 놓은 것입니다.

텍스트마이닝이나 검색엔진이 다루는 문서는 수십개에서 수십억개까지의 문서가 있을 수 있습니다. 1개는 아닙니다. 여기에서 말하는 것은 가지고 있는 모든 문서를 다 뒤져서 텀(term)이 포함된 모든 문서의 숫자를 세어 놓는다는 의미입니다.

단, 한 문서에 term이 여러번 나와도 1번(한 번)만 카운트합니다.

요약해서 다시 설명하면

  • TF(Term Frequency)는 한 문서에서 term이 몇  번 나왔는지를 모두 카운트한 것이고
  • DF(Document Frequency)는 한 단어가 몇개의 고유한 문서에서 나왔는지를 카운트한 것입니다.

이제 Inverse Document Frequecy에서 Inverse부분입니다.

Inverse = 역수

역수는 사실 초급 수학에 나오는 것이지만 기억이 안나는 분들을 위해서 다시 설명합니다. 역수는 쉽게 설명하면 어떤 수를 1로 나누라는 것입니다. 즉 1을 분자로 두고 그 숫자를 분모로 두라는 것입니다. (수학책에서는 저렇게 정의해 놓지는 않았을 것입니다만)

예를 들어 \huge{x}의 역수는 \huge{\frac{1}{x}} 입니다. \huge{x^{-1}}라고 표현하기도 합니다.

그래서

Inverse Document Frequency는 Document Frequency의 역수입니다.

\huge{idf = \frac{1}{df}}

위와 같습니다.
나누기를 하지 않고 역수를 쓴 것은 수학적으로 이쁘게 쓰기 위함도 있고 하다보니 그렇게 된 것도 있습니다. TF와 IDF가 원래 각각 별도로도 쓰일 수 있기 때문이기도 합니다.

Document Frequency를 왜 역수를 취하는지는 뒤에 설명하겠습니다.

TFIDF 계산

자 이제 TF와 IDF를 합치면 공식이 완성 됩니다. IDF는 DF의 역수이므로 TF를 DF로 나누면 그게 TFIDF가 됩니다.

물론 이게 전부가 아닙니다. 아직 계산법 연습도 안했고 설명을 안한 것이 더 많습니다.

TFIDF weighting scheme

TFIDF를 대충 알았으니 이제 원래의 전체 명칭을 다시 살펴보죠. TFIDF는 위에서 설명했고 (예제를 두고 다시 설명할 것입니다만)

나머지 부분을 해석하면 다음과 같습니다.

  • weighting = 가중치를 부여하는
  • scheme = 계획, 방안

완전하게 해석하면

TFIDF weighting scheme = TFIDF를 사용하는 가중치를 부여하는 방법

이 됩니다.
간단히 의역하자면 “TFIDF: 가중치를 주는 방안(또는 설계)”이라는 뜻이 됩니다. 방안이기 때문에 원래 TFIDF는 정해진 공식은 없고 TF를  DF로 나누는 컨셉을 가진 것을 모두 TFIDF weighting scheme이라고 부릅니다.

앞서 공식에서는 단순히 TFIDF가 TF를 DF로 나누지만은 않고 뭔가 계산을 좀더 한 것을 볼 수 있습니다. 그런 의미로  공식이 여러 개 존재할 수 있다는 얘기입니다.

TFIDF scheme

방안이라고 해야하지만 단어가 좀 어색하니 여기에서는 이제 컨셉(concept, scheme)이라고 하겠습니다. 이 부분에 대해서 명확히 설명하지 않고 넘어왔습니다. 사실 이게 가장 중요한 것입니다. TFIDF는 문서에서 term을 추출하고 term들에 대해 가중치값을 부여하는 방법입니다. 가중치에 대해서는 나중 설명하고 TFIDF를 사용하는 컨셉이라는 것이 중요할 뿐입니다.

TF를 DF로 나누는 것에 대한 것을 이해하면 사실 TFIDF의 가장 중요한 부분을 이해한 것입니다.

TFIDF는 여러 단계를 거쳐 고쳐지고 발전했는데 대략 초기에 다음과 같은 순서로 고안되었다고 이해하시면 좋습니다.

1

어떤 문서 내에서 그 문서를 표현할 수 있는 또는 구성하는 term들 중에 상대적으로 중요한 term과 상대적으로 중요하지 않은 term이 있을 것이고 그런 방법을 누군가가 고민했습니다.  그래야 문서를 검색해서 찾거나 다룰때 더 중요한 term을 다뤄서 정확도도 더 높이고 다른 용도로도 더 유용하게 수 있다고 생각했었습니다.

2

우선 term에 어떤 중요도라는 수치를 부여할 수 있는 가장 쉬운 방법이 그 문서에서 가장 빈번하게 나오는 term의 수를 세서 가중치로 주자는  방법이었습니다.  단순하게 term이 그 문서에서 몇 번 나오는지 세서 그냥 부여하고 쓰자는 것입니다.
이게 앞에서 설명한 TF이지요.
그런데 이게 문제가 있습니다.
우리말에서는 은, 는,이, 가와 같은 조사들이 너무 빈번하게 나오는데 사실 이 조사들은 어느 문서에서나 흔하게 나오는 것들입니다. 물론 조사를 겉어내고 명사면 쓰면 되지만 명사만 쓰더라도 사람, 생각 같은 정말 흔하디 흔한 것에 가중치가 높아지는 문제가 생깁니다.
영어라면 be 동사나 전치사, 관사 같은 것이 같은 문제를 발생시킵니다.

보통 stop word(불용어, 실제 문서에서 그리 중요하지 않은 쓸모가 없는 것들)라고 부르는 것들에 가중치가 높게 부여되는 문제가 있고 불용어가 아니더라도 정도는 덜하지만 중요하지 않은 것들 중에 문서내에서 빈번히 발생하는 것들 때문에 단순히 횟수를 카운트해서 중요도로 사용하면 문제가 생깁니다.

가장 흔한 것은 가장 중요한 것일 수도 있지만 반대로 가장 특징없이 것일 수도 있습니다.

3

그래서 다른 문서에서는 잘 안 나오지만 그 문서에서 굉장히 많이 나오거나 상대적으로 더 많이 나오는 term이 있다면 그 term에 가중치를 더 주자고 생각했습니다. 그렇게만 할 수 있다면 그 문서를 더 잘 대표하게 할 수도 있고 굉장히 중요하게 그 문서의 특징을 표현할 수 있는 것들을 잘 골라낼 수도 있을 것입니다.

이게 TFIDF의 핵심입니다.

이것을 위해서 DF(Document Frequency)를 구합니다. 즉 전체 문서를 다 스캔(scan, 다 뒤져서)해서 term이 몇개의 문서에서 나오는지를 따로 세둡니다.  모든 term들에 대해서 이것을 다 구합니다.

여기에서 중요한 것은 많은 여러 문서에서 공통으로 나오는(출현하는) term일 수록 덜 중요한 것이라고 볼 수 있습니다. 흔하디 흔한 term이라는 것입니다.
즉 결론적으로 DF의 값이 큰 term일수록 특정 문서의 관점에서 볼 때는 가치가 떨어지는 term입니다.

많은 문서에서 출현하는 term이면 중요한 term이 아닌가?
라고 생각하실 수도 있는데요.  전체 문서를 다 모아놓은 것의 입장에서는 중요할지 모르지만 각각의 문서 입장에서는 중요한 것이 아니게 됩니다.  바꿔 말하면 특정 문서의 입장에서 특정 문서의 특징을 발현해서 대표할 만큼 가치 있는 term이 아닐 가능성이 높습니다.

자 이제 2개의 컨셉을 결합합니다.

문서내에서 term의 출현횟수 / term이 출현한 문서의 (중복을 제거한) 수

위와 같이 하는데 정규화(Normalization) 비슷한 작업입니다. 위에 것을 잘 곰곰히 생각해보시면 실제로 특징을 가진 것들, 중요한 것들의 가중치가 높아진다는 것을 이해할 수 있습니다.

TFIDF값은 1보다 클 수 있기 때문에 정규화라고 부르기에 무리가  있다고 볼 수 있습니다만 이것도 정규화 과정이라고 고전 문서에 적혀 있습니다.

앞에서 말한 공식도 이런 골격으로 되어 있습니다.

이게 TFIDF의 컨셉입니다.
앞서 말했듯이 TFIDF는 TF를 DF로 나누는 방법을 말합니다.

하지만 그냥 나누지는 않고 나눌 때 단어의 출현 빈도에 의한 스케일의 문제나 여러 문제로 약간의 변형을 하게 됩니다. 그래서 여러 변형들이 생기고 여전히 조합해서 쓰고 있어서 공식에 이름을 TFIDF 1,2,3,4 라고 이름을 일일히 붙일 수도  없겠구요.
그래서 TFIDF weighting scheme이라고 묶어서 부릅니다.

TFIDF의 간단한 계산 예제

TF는 앞서 말씀드렸지만 1개의 문서내에 있는 term들이 그 문서에서 얼마나 나오는가 횟수를 센 것을 말합니다. 각각 term별로 숫자가 달라붙습니다.

이제 간단한 예제를 풀어볼텐데요.

계산방식은 공식과 다르게 기본 컨셉대로만 해보겠습니다.

아래와 같이 doc1이라는 id를 가진 짧은 문서가 있다고 하고 여기에서 명사만을 term으로 취급하고 조사와 기타 의미와는 직접 관련이 없는 품사 등은 다버리고 TF를 아주 간단한 방법으로 구해봅니다.

형태소 분석기가 있으면 좋습니다만 그건 설명 안하겠습니다.

doc1 = 무궁화꽃이 한라산에 피었습니다. 한국의 무궁화꽃은 아름답습니다.

doc1의 TF들은 구해보면 다음과 같습니다.

  • 무궁화꽃: 2
  • 한라산: 1
  • 한국: 1

단순히 단어가 몇 번 나왔는지 확인하는 것이므로 어렵지 않습니다.

doc2 라는 id의 문서를 하나 더 가지고 있다고 하겠습니다. 그리고 명사로만 TF를 뽑아봅니다.

doc2 = 무궁화꽃이 백두산에 피었습니다. 대한민국의 무궁화꽃은 아름답습니다.

doc2의 TF들

  • 무궁화꽃: 2
  • 백두산: 1
  • 대한민국: 1

2개만 하면 너무 쉬우니까

doc3이라는 문서 1개를 하나 더 추가해 보겠습니다.

doc3 = 무궁화꽃은 대한민국의 국화입니다.

doc3의 TF들

  • 무궁화꽃: 1
  • 대한민국: 1
  • 국화: 1

자 이제 지금 가진 문서가 위의 3개 밖에 없다고 가정하고 위의 것들에 DF를 구하겠습니다. 실제 현실에서는 문서가 3개밖에 없는데 굳이 TFIDF를 구하거나 그런 낭비는 하지 않겠지요. 현실에서는 적게는 수만개 많게는 수억개가 있다고 생각해야 합니다.

DF는 term이 나오는 문서가 몇개인지를 세는 것이기 때문에 문서별로 계산하는 것이 아니라 전체 문서에 걸쳐서 한 벌이 계산됩니다.

3개의 문서 전체의 DF들

  • 무궁화꽃: 3 (무궁화꽃이 출현하는 문서는 3개, doc1과 doc2, doc3)
  • 백두산: 1 (백두산이 출현하는 문서는 1개, doc2에만)
  • 한라산: 1 (한라산이 출현하는 문서는 1개, doc1에만)
  • 한국: 1 (한국이 출현하는 문서는 1개, doc1에만)
  • 대한민국: 2 (대한민국이 출현하는 문서는 1개, doc2, doc3)
  • 국화: 1 (국화가 출현하는 문서는 1개, doc3)

자 이제 이걸로 각 문서들에 대해서 TFIDF를 구합니다. 공식에 있는 것처럼 IDF를 구할 때 log같은거 쓰지 않고 그냥 TF를 DF로 나누겠습니다.
설명을 쉽게 하기 위함입니다.

log를 꼭 해줘야 한다고 되어 있지 않습니다. 그래서 꼭 써야 하는 것도 아닙니다

doc1의 TFIDF 값들 (log 안 쓴 어설픈 버전)

  • 무궁화꽃: 2/3=0.66
  • 한라산: 1/1=1
  • 한국: 1/1=1

doc2의 TFIDF 값들 (log 안 쓴 어설픈 버전)

  • 무궁화꽃: 2/3 = 0.66
  • 백두산: 1/1=1
  • 대한민국: 1/2=0.5

doc2의 TFIDF 값들 (log 안 쓴 어설픈 버전)

  • 무궁화꽃: 1/3 = 0.33
  • 대한민국: 1/2=0.5
  • 국화:1/1=1

위의 결과를 보시면 모든 문서 3개에서 공통으로 출현하는 “무궁화꽃”은 각 문서의 TFIDF값을 보면 상대적으로 낮은 것을 알 수 있습니다.
반면 백두산, 한라산, 국화 같은 것은 1로 비교적 높습니다.

각 문서에서 계산된 TFIDF값이 가장 높은 것이 각 문서내에서는 가장 중요한 단어들입니다. 가중치가 부여된 것입니다.

스스로 예제를 조금씩 바꿔서 문장을 만들어가면서 해보시면 이해가 더 빠릅니다.
위의 예제는 너무 단순하고 억지로 만든 것입니다. 실제 계산을 할 때는 log를 사용해서 스케일을 맞춰가면서 하면 더 합리적이라는 것을 알 수 있습니다.

Bag of words – 단어 가방

공식을 다시 설명하기 전에 “bag of words”라는 것을 설명하고 넘어가겠습니다. 보통 TFIDF를 설명할 때 같이 설명을 하기 때문입니다.

“문서가 유사하다 유사하지 않다”는 사람이라면 문서를 읽어버고 판단하면 되지만 기계는 모든 것을 수치화해서 수리적으로 계산할 수 있게 해주어야 합니다.
그러려면 문서를 숫자로 표현해야 합니다.
그런데 문서를 숫자로 표현하기가 참 애매하기 그지 없습니다.

그래서 문서내 출현하는 단어들을 출현 순서를 고려하지 않고 갯수를 세거나 TFIDF처럼 이렇게 쿵 저렇게 쿵해버립니다. 이렇게 순서를 고려하지 않고 단어의 집합으로 취급하는 것을 “bag of words”라고 합니다. TFIDF가 부여된 단어 집합들을 순서 없이 쓰면 “bag of words”가 됩니다. 코사인 유사도역시 순서를 고려하지 않게 계산하기 때문에 “bag of words”방식의 유사도 계산이 됩니다. 순서를 고려하게 되면 매우 복잡해지는데 그것도 여기서는 다루지 않겠습니다.

TFIDF 공식 설명

아직까지도 공식 설명을 제대로 하지 않았습니다.

어차피 컨셉은 TF를 DF로 나누면 되는 것이니까요. 아주 오래전에는 TFIDF는 그냥 TF를 DF로 나눠서 쓰기도 했다고 합니다. 하지만 상황이나 문서의 집합이나 문서의 종류들이나 이런 것 주변 문제들로 인해 공식을 조금더 각각의 문제를 해결하는데 더 합리적인 방법으로 변형하거나 계량하기도 했습니다. 그래서 공식은 많습니다만 여기서는 아래의 공식으로 하겠습니다.

TF 공식 설명

\begin{aligned}\huge{t{f_{ij}} = \frac{{{f_{ij}}}}{max\{ {f_{1j}},{f_{2j}},{f_{3j}},\ldots,{t_{\left| v \right|j}} \}},}\end{aligned}

보통 TF에 대해서 term의 빈도수를 구하라는 것은 공식으로 되어 있지 않고 의사코드(Pseudo code)나 설명으로 하는 것이 많습니다. 그래서 공식에 왜 TF구하는 것이 없냐고 의문을 갖지 마세요.

앞의 예제에서는 TF는 갯수만 세면 된다고 했는데 위의 공식을 보면 갯수를 세고 난 뒤에 계산을 한 번 더 하는 것이 조금 다르다는 것을 알 수 있습니다.

우선 표기(annotation)에 대한 설명이 빠졌는데 j는 문서들 중에 1개를 말합니다. 문서가\begin{aligned}\huge{N}\end{aligned}개 있다고 생각하시면 됩니다.\begin{aligned}\huge{N}\end{aligned}는 뒤의 공식에 나옵니다. i는 문서 내에서의 term의 순번을 말합니다. 즉 문서내에 있는 term 중에 하나라는 뜻입니다. \begin{aligned}\huge{f}\end{aligned} 는 frequency를 뜻합니다. 그냥 갯수를 세면 됩니다.
max가 들어간 것이 문제인데 max를 구하고 term의 수를 나누게 되는데 문서에서 구한 TF값들 중에 가장 큰 것으로 각각을 모두 나누라는 것을 말합니다.

문서들은 단어가 몇개 안되는 것도 있고 굉장히 많은 단어들을 가진것도 있습니다. 길이가 각각 다르지요. 길이가 긴 문서내에서 한 단어가 너무 반복해서 나오면 수치가 커지는 경향이 있어서 정규화를 한 것입니다.
그것 뿐입니다.

IDF 공식 설명

\begin{aligned}\huge{id{f_i} = \log \frac{N}{{d{f_i}}}.}\end{aligned}

DF도 다른 것은 없습니다.  DF를 구하는데  1/DF가 아닌 N/DF 이고 log를 취했습니다.
이 부분 설명이 쉽게하기 어려운데요. 사실 IDF의 공식이 왜 저렇게 되어 있는지를 이해했다면 TFIDF를 다 이해한 것이나 마찬가지입니다.

Spa¨rck Jones라는 사람이 IDF에 대한 논문을 처음 썼을때 이 부분에 대해서 자세히 설명하지도 않았다고 합니다. 그래서 다른 논문에서 이게 원리가 왜 이런지에 대한 해석이 있습니다.

IDF는 DF로 단순히 TF를 나누는 무식한 방법을 그대로 쓰기 보다는 IDF를 하나의 확률값으로 처리하는 것으로 개선했다고 합니다. 확률이론을 도입한 것입니다. 확률 이론을 도입한 이유는 가장 DF가 큰 것을 1이 되게 하고 싶은 것이고 그래서 IDF들의 덧셈 연산이 가능하도록 하고 싶었다고 합니다.

확률이 가장 큰 것은 1이고 확률은 항목이 같으면 더할 수 있습니다.

IDF의 덧셈연산이 왜 필요했는지는 정확히 이해하지는 못하겠습니다. 제 생각으로는 증분 업데이트 때문 일 것 같습니다.

계속해서 문서에서 어떤 term이 출현할 확률이 얼마인가로 IDF를 계산하도록 바꿔서 써보면 원래 이렇게 됩니다.
\begin{aligned}\huge{\frac{df}{N}}\end{aligned}

N은 전체 문서의 수이고 DF는 term이 출현한 문서의 수 이니까요.
역수(inserse)를 하기 때문에 위아래를 바꿉니다.
\begin{aligned}\huge{\frac{N}{df}}\end{aligned}
이렇게 됩니다.

공식에서 볼 때 log를 씌운 것도 의문일텐데요.  이건 위키피디아 문서 지프의 법칙과 Zipf’s law를 읽어 보면 됩니다.  물론 시간관계상 나중에 읽어 보셔도 됩니다.

log를 씌운 이유에 대해서 먼저 복잡하게 설명하면
문서 집합 내에서 단어의 빈도에 대한 분포를 보면 가장 적게 나타나는 것 부터 2의 배수로 증가하는 경향이 있습니다. 이것을 선형스케일로 바꾸려면 밑수가 2인 log를 씌우면 됩니다. 하지만 밑수가 2인 log나 자연로그나 별차이가 없어 그냥 자연로그인 log를 씌운 것입니다.

간단하게 설명하면
단어의 문서내에서 출현 빈도를 테스트해서 구해봤더니  가장 많이 출현하는 것에서 부터 그 다음으로 갈 수록 반절씩 감소하는 경향이 있더라! 라는 것입니다.

실제로 몇개의 문서에서 term들을 추출하고 빈도를 시각화해 보면 그렇다는 것을 볼 수 있습니다

그래서 모든 문서에서 빈번하게 나타타는 단어와 아닌 단어의 빈도수의 정도가 서로 다르고 차이도 커서 그것을 고르게 차이가 나도록 보정한 것입니다. 이 것도 정규화(Normalization)의 일종이고 스케일을 보정해 준 것입니다.  더 자세한 원리가 궁금하시면 관련 논문을 찾아보는것이 좋겠습니다.

TFIDF 공식 설명

\begin{aligned}\huge{{w_{ij}} = t{f_{ij}} \times id{f_i}.}\end{aligned}

w는 weight를 말하는 것입니다.  즉, TFIDF를 말합니다. TFIDF는 TF와 IDF를 그대로 곱하면 됩니다. 뭐 별것이 없습니다.

위의 예제에서의 계산법도 실제로는 위의 공식으로 계산하셔야 합니다. 계산은 사실 계산기를 쓰거나 짜면 됩니다만 시간 날 때 직접 해 보시는 것을 권합니다.

Term vector – 텀벡터

위에서 “bag of words” 방식으로 각 문서들을 term에 수치값(TFIDF값 같은 것들)을 부여해 놓은 것을 텀벡터(term vector)라고도 합니다. 이 텀벡터를 이용해서 유사도 같은 것을 구할 수 있거나 여러가지 연산을 할 수 있습니다.

코사인 유사도(Cosine Similarity)도 이 텀벡터를 가지고 계산하는 것입니다. 텀벡터에 부여된 수치가 반드시 TFIDF여야 한다는 것은 없습니다만 일반적으로 TFIDF를 가장 많이 쓰는 것 같습니다.

부족한 것은 나중에 보강하기로 하고 설명은 여기까지입니다.
역시 써놓고 보니 두서없이 무지 장황해졌습니다.

여기까지 읽으셨다면 인간승리입니다.

R 3.4.1 릴리즈

2017년 6월 30일자로 R 3.4.1 버전이 릴리즈(release) 되었습니다.

패키지 설치시 문제와 펑션에 유니코드가 포함되어 있을 때 디스플레이에서 발생하는 문제를 비롯한 패키지 개발관련의 버그들이 수정되었다고 합니다.

3.4.1의 코드네임은 “Single Candle”입니다. 3.4.0의 코드네임은 “You stupid darkness” 이더군요. R은 늘 코드네임을 이해가 쉽게 안가는 것을 붙이는데 이번에는 코드네임이 왜 이런가 하고 링크를 봤더니 아래의 “피너츠”(찰리브라운과 스누피?) 만화의 대사이더군요.

전 귀찮아서 아직 업그레이드를 안했습니다만…

 

Hive server 2에 python impyla 패키지로 접속하기

ipyhton 또는 그냥 python script로 Hive에 접속해서 SQL을 실행하고 결과 데이터를 가져오게 하려면 굉장히 고통스럽습니다.

Python에서 사용할 수 있는 Hive 접속관련 패키지들이 상당히 불안하고 버그가 많습니다. 다 해결해주는 깔끔한 끝판왕이 하나 나와줬으면 싶은데 Hive가 일반 RDBMS 처럼 쓰는 것은 아니어서 그런지 아직까지 깔끔하게 해결해 주는 패키지가 없습니다.

Hive 자체에서 제공하는 python client라는 것이 있긴한데 이걸 쓰려고하면 설정을 위해서 상당히 귀찮은 작업들을 해야 합니다.  예전에 했을 때는 되긴했었습니다만 다시하고 싶지 않습니다.

배보다 배꼽이커요.

그런데
Cloudera에서 impala용 client를 만들어서 제공하는데 이 패키지가 impala 뿐만 아니라 HiveServer2에 접속하는 기능도 제공합니다.
이것 말고도 HiveServer2에 접속할 수 있게 해주는 Python 패키지중에 pyhs2라는 것이 있는데 이 패키지도 동일한 기능을 제공하지만 더 이상 업데이트 하지 않고 impyla를 사용하라고 github에 pyhs2 제작자가 적어놨더군요.  그 외에도 몇개의 패키지가 있습니다만 모두 불편했습니다.

그래서 현재까지 가장 쉽게 Python에서 Hive에 연결해서 쿼리를 실행하거나 작은 실행 결과를 바로 가져오는 방법은 Python에서 HiveServer2에 접속하게 하고  HiveServer2에 접속하기 위해서  impyla 패키지를 쓰는 것입니다. (다른 더 쉬운 방법이 있으면 알려주세요)

impyla 패키지를 사용하려면 당연히 Hive server 2가 어딘가 네트워크로 접속할 수 있는 서버에서 작동하고 있어야 합니다. 이 패키지는 Hive server 2에 접속하는 것이니까요.

그냥 Hive하고 Hive server 2가 다른 것이라는 것은 아시지요? Hive server 2는 Hive를 별도로 Daemon으로 띄워서 사용하게 해주는 일종의 add-on 입니다. Hive에 같이 포함되어 있으니 설정을 잡아주고 구동만 시키면 됩니다.

그런데 이 impyla 패키지도 의존성으로 가진 Thrift 관련된 패키지가 여러단계로 조금씩 의존성이 꼬여 있어서 설치할 때 조금 귀찮게 합니다. 그래서 impyla 패키지를 설치할 때 조금 고생하게 되는데 그때 필요한 것들을 정리도 할겸 포스트로 올립니다.

CentOS Linux에서는 다음과 같은 문제를 고려해서 설치하면 현재는 작동이 됩니다.  각 환경마다 사정이 다르기 때문에 모두 동일하게 해결된다는 보장은 없습니다. Ubuntu에서는 안해봤습니다.

Ubuntu에서도 잘 될 것이라고 생각합니다.

impyla 관련 패키지 설치하기

우선 python package이름이 impala가 아니고 impyla 인것에 주의하시구요. 패키지 이름이 “임팔라”가 아니고 “임파일라”입니다. 무척 헷갈립니다. 게다가 python 코드 내에서 import 할때는 impala를 호출해야 합니다. (왜 그랬는지…)

설치할 때 주의해야 할 중요한  내용입니다.

  • Thrift에 접속할 때 인증을 위해서 sasl 관련 library가 필요합니다.  CentOS에서는 yum으로 검색해서 cyrus로 시작하는 sasl 패키지들을 설치해 주어야 합니다. 특히 cyrus-sasl-plain을 설치해야 Hive Server 2에 plain 방식으로  id/password를 입력하고 접속할 수 있습니다. 현재는 Hive Server 2 plain 방식이 아니면 접속할 수 없었습니다. cyrus sasl의 기본 설치에서 제외되므로  빼먹지 말고 찾아서 설치해야 합니다.
  • impyla 패키지가 thrift 패키지에 의존성을 가지는데 현재 0.9.3 이하가 아니면 작동하지 않도록 되어 있습니다. 나중에는 고쳐질 수 있겠습니다만 지금은 아닙니다.  thrift의 현재 시점에서의 최신 버전은 0.10.0 입니다. 그래서 이미 0.10.0 버전으로 설치되어 있으면 0.9.3 이하로 downgrade해야합니다.
  • 기타 thrift 패키지 설치에 필요한 의존성 패키지가 있습니다만 환경에 따라 이미 설치가 되어 있을 수도 있습니다. 의존성 오류가 발생하면 그 패키지를 설치하면 됩니다. 이 것들은 대충 막 설치해도 큰 충돌은 없는 것들입니다.
  • impyla 패키지가 pypi에 등록된 것은 위와 같이 해도 trans관련 오류를 내면서 제대로 접속하지 못합니다. 즉 pip 같은 것으로 빌드된 것을 설치하면 안될 수 있습니다. 그래서 impyla를 설치할 때는 소스를 clone받아서 빌드하고 설치해야 합니다.
  • 이때 thrift_sasl 패키지도 설치해 주어야 thrift를 통한 인증과 암호화 문제를 해결할 수 있습니다.

제가 작업하는 환경에서 작업한 shell command를 정리한 것입니다. python 2.7 버전 기준입니다. 3.x 도 되었던 것 같습니다만 기억이 가물가물하네요.

이렇게 설치하고 나서 간단하게 작동하는지 다음과 같이 테스트해 보면됩니다. 서버주소와 ID, password, query는 환경에 맞게 수정하셔야 합니다. 당연한 것이지만 아래의 코드는 그대로 실행하면 접속을 못해서 에러입니다.

impyla 패키지의 github 레파지토리는 다음과 같습니다.

https://github.com/cloudera/impyla

향 후 패키지가 업데이트 되고 더 안정화되면 위의 자질구레한 문제들이 자동으로 해결될 수도 있을지도 모릅니다. 그런데 Cloudera 사람들이 저 패키지에 신경을 별로 안쓰는 것 같아서 조금 걱정은 됩니다.

타임라인 광고 타겟팅 – timeline ad targeting

 

지금 하는 일과 관련이 있는 것이라서 zdnet기사에 앱넥스트라는 회사에서 제안했다고 하는 타임라인 타겟팅이라는 기법(아이디어)에 대한 기사를 스크랩해 놓은적이 있는데 내용도 정리할겸 그림툴도 써볼겸(사실은 이게 본래의 포스팅 목적입니다 ‘ㅡ’;;) 해서 포스트를 올립니다.

직접 기사를 읽어보시면 되겠지만 저는 그림툴을 사용해 보는 것이 목적이므로 정리를 좀 해보자면 이렇습니다.

최근의 앱인스톨 광고 그러니까 앱인스톨을 유도하는 배너 광고들이 실적이 좋지 않다고 합니다.  그 이유 중의 하나가 이제 사람들은 자기 스마트폰에 더 이상 새로운 앱을 설치하지 않는다고 합니다.

  1. 이미 필요한 것을 대부분 설치했고 사용하는 것들이 몇개에 한정되어 있기 때문입니다.
  2. 그리고 필요한 것이 생기면 그때그때 찾아서 설치해도 되니 미리 설치해 둘 필요는 없습니다.
  3. 게임이 아니라면 그런 배너에 반응을 잘 안하게 되는 게임도 설치 광고가 그렇게 큰 효과를 보지 못한다는 말이 많습니다. (다 그런것은 아니겠지만요)

그래서 위 기사에서 말하는 아이디어는 이렇습니다.

일종의 개인화 타겟팅(personalized targeting)인데 위의 그림처럼 사람들의 타임라인을 추적(감시한다기 보다는 엿본다는 것이 맞겠습니다)해서 상황들을 모니터링하다가 특정 상황이 되면 그 상황에 필요한 앱인데 아직 사용자가 설치하지 않은 앱이 있다면 광고로 추천해서 바로 설치하도록 유도한다는 것입니다.

그러기 위해서 사용자가 사용하고 있는 스마트폰에 항상 사용자의 액션을 모니터링하는 앱이 필요한데 사실 대부분의 회사들이 이걸 하기가 현실적으로 불가능합니다. 스마트폰의 모든 상황을 전역으로 감시하는 장치를 스마트폰에 심을 수가 없기 때문입니다.

앱넥스트라는 회사는 자사의 SDK(스마트폰 애플리케이션에 광고를 노출할 수 있도록 해주는 킷)를 사용한 제휴 앱들을 이용해서 사용자의 행적(activity)를 보고 있다가 다른 앱을 설치하도록 유도할 수 있다는 것입니다. 알려주는 것은 아마 Push 기능 같은 것을 사용하지 않을까 싶습니다.

실현이 가능하다면 “앱을 설치할 수 밖에 없는 적절한 상황을 찾아서 그때 광고를 보여주면 설치를 많이 하겠지” 라는 것을 이용한 것인데요.

이걸 하기 위해서는 사실 앱 매체(광고를 보여주는 앱들)을 많이 제휴하고 있어서 그 앱들을 사용자가 늘 쓰고 있거나 빈번하게 쓰고 있어야 합니다. 즉 앱 매체 커버리지가 좋아야 합니다. 이것은 사실 진입장벽이 매우 높아서 말이 후발주자(모바일 광고 플랫폼 회사)들이 제휴한 앱들이 많지 않으면 힘듭니다. 아니면 끝판왕 하나를 제휴하던지요(카카오톡 같은 것?)

위의 앱 매체 제약 조건이 걸린다면 일반적인 PC 온라인 광고에서는 응용할 수 있는 방법은 라이프타임에 대한 모니터링을 길게 해서 상품을 추천해 주는 방법을 얼른 생각해도 할 수 있을것만 같습니다.

어떤 온라인 사용자가 추정 모델 또는 데이터온보딩(data on-boarding)으로 20대 여성이라는 것을 알고 다음과 같은 순서로 제품에 관심을 보였거나 구매를 했다면 그 다음 상황에 필요한 것을 유추해서 추천해 줄 수 있습니다.

청바지 → 워킹용 신발 → 워터프루프 화장품 → 수영복 → 카메라방수팩

다소 억지로 만든 예입니다만 저런 시퀀스가 있다면 카메라방수팩을 광고해서 구매하도록 유도할 수 있습니다.  물론 이것도 앱매체의 커버리지 문제처럼 온라인 웹페이지와 제휴가 많이 되어 있어야 하고 제품도 골고루 보여줘서 어떤 행동(behavior)를 하는지 시차를 두고 기록해 둬야 하는 문제가 있습니다. 물론 광고에 잘 반응하는 사람일 수록 하기 쉽고 그렇지 않은 사람이나 특정 쇼핑몰(G마켓 이랄지)에서만 구매를 하는 사람들이라면 조금 어렵습니다.

이런 사람들에게는 다 포기하고 조건을 만족하는 사람들에게만 해도 충분할 것 같은 느낌입니다.

필요한 상품의 세트나 연관상품의 세트는 데이터만 있다면 노출이나 클릭, 구매 기록으로부터 연관 규칙 탐사(sequence association rule mining)같은 간단한 방법으로도 정보를 추출해서 확보 할 수도 있을 것 같은데  실제로 해보지는 않았지만 간단한 시뮬레이션 정도는 해볼 수 있을 것 같습니다.

다시 앱의 문제로 돌아와서 만약 카카오톡 같은 사람들이 매우 많이 쓰는 앱이라면 사용자의 메세지 텍스트를 분석해서 (윤리적으로 그러면 안되는 것은 당연하고) 문맥을 파악한 뒤 필요한 것을 알아내서 카톡내에서 광고를 보여주고 추천해 주는 방법도 고민해 볼 수 있겠습니다. (그냥 상상입니다. 현실적으로 안되겠지요)

 

R – yaml 파일 읽어오기

R로 작성한 script에서 가끔 복잡한 설정들 읽어야하는 경우가 있습니다. 여러 방법을 사용할 수 있겠지만 설정파일을 만들어 놓고 읽어서 사용하는 방식을 선호하는 편인데 전에는 json 포맷을 쓰다가 너무 너저분해서 이번에 yaml으로 바꿔봤습니다.

R이 너저분해지는 이유가  이런 종류의 tree 구조의 파일을 읽어서 자료구조로 바꿀때 R에서는 list 타입을 사용해서 맵핑하게 되는데 list의 하위 아이템이 1개인 경우 다른 랭귀지와는 많이 다르게 굉장히 복잡해 집니다. 이렇게 복잡한 이유가 R에는 모든 데이터타입이 기본적으로 vector 취급되기 때문입니다.

그런데 yaml을 사용해보니 json을 사용할 때보다는 데이터타입을 훨씬 잘 변환해 주는 것 같습니다.

패키지는 yaml을 설치해서 사용하면됩니다.
전체 코드는 아래에 있습니다.

test_configuratino.yml 파일의 내용

주의할 것은 하위 항목이 1개인 것은 여전히 [[1]] index를 지정해주지 않으면 안됩니다. 그래도 JSON보다는 훨씬 쓰기도 편하고 좋은것 같습니다.