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


Archive»


 
 

노트7의 소셜 반응을 분석해 보았다. 


#3 제플린 노트북을 이용한 상세 분석



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



데이타 스튜디오는 편리하게 사용할 수 있지만, 쿼리 사용등이 불가능하기 때문에, 원본 데이타를 이용한 상세 분석에는 어려움이 있다. 원본 데이타를 이용해서 상세 분석을 하려면 노트북 계열의 애플리케이션이 효과적인데, 빅쿼리를 연동할 수 있는 노트북으로는 이전에 소개한 주피터 노트북 기반의 데이타랩 (datalab)과, 스파크나 다른 빅데이타 솔루션과 함께 많이 사용되는 제플린 노트북(zeppelin.apache.org) 이 있다.


지난 글에서 데이타랩에 대한 연동 방법은 이미 소개하였으니, 이번에는 제플린을 통하여, 빅쿼리의 데이타를 분석해보도록 한다.


제플린 설치

제플린을 설치 하는 방법은 간단하다. Zeppelin.apache.org 에서, 설치 파일을 다운로드 받는다.

빅쿼리 연동 인터프리터는 제플린 버전 0.61 버전 이상에 포함되어 있기 때문에, 0.61 버전 이상을 다운로드 받는다.  이 때 모든 인터프리터가 포함된 버전을 다운 받아야 한다. (아니면 별도로 인터프리터를 설치해야 하는 번거로움이 따른다.)


다운 로드 받은 파일의 압축을 푼다. 다음으로 제플린 설치 디렉토리로 들어가서 다음 명령어를 수행한다.

% ./bin/zeppelin.sh

윈도우의 경우에는 %./bin/zeppelin.cmd 를 실행하면 된다.

자바 애플리케이션이기 때문에 별도의 설치 과정이 필요없고, 제플린 애플리케이션을 실행하기만 하면 된다.

제플린이 기동되었으면 브라우져에서 http://localhost:8080 으로 접속하면 다음과 같이 제플린 콘솔을 볼 수 있다.

노트북 생성

제플린 콘솔에 들어왔으면 초기화면에서 Create new note 라는 메뉴를 이용하여 새로운 노트북을 생성하자. 여기서는 편의상 “BQ 노트북" 이라는 이름으로 노트북을 생성하였다.


분석 쿼리 작성

이제 분석할 내용은 수집된 트윗의 명사들에 대해서, 시간 단위로 그룹핑을 한 다음에, 각 단어에 대해서 발생한 횟수를 카운트해서 보여주는 내용을 구현하려고 한다.

예를 들어서 9월20일에는 “유행" 이라는 단어가 200회 발생하였고, “패션" 이라는 단어가 100회 발생하였다. 라는 식으로 조회를 하려고 한다.


현재 테이블 구조는 다음과 같다.

Date (발생 시간)

Noun (명사)

count (발생 횟수)


SQL 문장을 작성해보자

select date,noun,sum(count) from 테이블명

group by date,noun


이렇게 쿼리를 하면, 시간대 별로, 명사와 그 명사의 발생 횟수를 리턴을 해주는데, 우리는 앞의 데이타 플로우 프로그램에서 30초 단위로 통계를 집계하도록 하였기 때문에, 30초 단위로 결과가 리턴된다. 우리가 원하는 결과는 30초 단위가 아니라 1시간 단위의 결과 이기 때문에, 다음과 같이 쿼리를 수정한다.


select  DATE(date) as ddate,HOUR(date) as dhour,noun,sum(count) from 테이블명

group by ddate,dhour,noun


DATE와 HOUR라는 함수를 사용하였는데, DATE는 타임 스탬프 형태의 컬럼에서 날짜만을 추출해주는 함수 이고, HOUR는 타임 스탬프 형태의 컬럼에서 시간만을 추출해주는 함수 이다.

이렇게 날짜와 시간만을 추출한 다음에, group by 절을 이용하여, 날짜와,시간 그리고 명사로 그룹핑을 하게 되면 우리가 원하는 것과 같이 각 날짜의 시간대별로 명사별 발생횟수 ( sum(count)) 값의 통계를 얻을 수 있다.


제플린에서 빅쿼리 명령을 수행하려면 다음과 같이 %bigquery.sql 이라고 첫줄에 선언을 한 다음에 SQL 문장을 수행하면 된다.




결과는 디폴트로 테이블 형태로 나오는데, 아래 아이콘 중에서 그래프 아이콘을 누르면 그래프 형태로 볼 수 가 있는데, 이 때 X,Y축의 변수를 지정할 수 있다.

아래 그림과 같이 Keys (X축을) ddate,dhour를 선택하고 Values(Y축)을 dhour SUM을 선택하면, 시간별 나타난 단어수를 볼 수 있다.



그런데 이 쿼리를 수행하면, 각 시간별로 발생한 명사 단어의 수가 매우 많기 때문에, 보기가 매우 어렵다.

그렇다면 시간대별로 발생한 명사중에서 각 시간대별로 많이 발생한 명사 5개씩만을 볼 수 없을까? 즉 group by를 전체 데이타 구간이 아니라, 각각 시간대 별로 계산을 해줄 수 는 없을까 하는 필요가 발생한다.

빅쿼리 파티셔닝

데이타를 구간 별로 나눠서 연산할 수 있는 기능으로 빅쿼리에는 파티션이라는 기능이 있다.

예를 들어서 group by를 전체 결과에 대해 그룹핑을 하는 것이 아니라, 앞에서 언급한 요건 처럼 일 단위로 짤라서 그룹핑을 하는 것이 가능하다.




파티션을 이용해서 할 수 있는 것은 파티션별로 합계나, 통계를 내거나, 파티션의 각 로우의 값의 백분율(%)나 또는 소팅한 순서등을 볼 수 있다. 여기서는, 시간으로 파티션을 나누고  파티션내에서 명사의 수가 많은 수 순서대로 소팅을 한후에, RANK라는 함수를 이용하여 그 파티션에서 그 명사가 몇번째로 많이 나타났는지를 출력하도록 해보겠다.


파티션의 사용법은 다음과 같다.

“파티션 함수 OVER (PARTITION BY 파티션을할 키 목록)”

여기서는 일/시간 별로 파티션을 나눈 후에, 그 순위별로 소팅을 할 것이기 때문에, 다음과 같은 식을 쓴다.

RANK() OVER (PARTITION BY ddate,dhour ORDER BY ncount DESC  ) as rank


이를 쿼리에 적용하면 다음과 같다.

   SELECT

       DATE(date) as ddate,HOUR(date) as dhour

       ,noun

       ,sum(count) as ncount

       , RANK() OVER (PARTITION BY ddate,dhour ORDER BY ncount DESC  ) as rank

   FROM [useful-hour-138023:twitter.noun]

   group by noun,ddate,dhour

   order by ddate,dhour,ncount desc


그러면 다음과 같이 일/날짜 파티션별로 많이 발생한 명사 순으로 발생횟수와 순위(rank)를 출력해준다.



그런데 쿼리를 돌려보면 알겠지만, 시간대별로 수집한 명사의 종류가 많기 때문에, 일자별 데이타가 매우 많다. 그래서 파티션별로 많이 등장하는 단어 5개만을 보려고 하면 rank <5 인것만 걸러내면 된다. 이는 중첩 쿼리를 이용해서 수행이 가능하다

다음은 이를 적용한 예이다.


SELECT ddate,dhour

   ,noun

   , rank

from (

   SELECT

       DATE(date) as ddate,HOUR(date) as dhour

       ,noun

       ,sum(count) as ncount

       , RANK() OVER (PARTITION BY ddate,dhour ORDER BY ncount DESC  ) as rank

   FROM [useful-hour-138023:twitter.noun]

   where noun != "note7" and noun != "samsung" and noun !="galaxy"

   group by noun,ddate,dhour

   order by ddate,dhour,ncount desc

   )

where rank < 6


이렇게 하면, 각 시간대별로 자주 등장하는 단어 6개만을 보여준다.


이 쿼리를 이용하여 데이타를 어떻게 분석하는지는 예전글 http://bcho.tistory.com/1136 을 참고하세요.


간단하게나마 트위터 피드에서 특정 키워드를 기반으로 하여, 명사와 형용사를 추출하여 소셜 반응을 분석하는 애플리케이션 개발과 데이타 분석 방법에 대해서 설명하였다.

아이폰7을 분석해보니, 명사 분석도 의미가 있었지만, 아이폰7에 대한 기대를 형용사 분석을 통해서도 많은 인사이트를 얻을 수 있었다. Awesome, excellent와 같은 기대치가 높은 형용사가 많이 검출되었고 bad, fuck 과 같은 부정적인 의미의 형용사는 다소 낮게 검출되었다. (아마 이즈음이 노트7 폭발로 인하여 반사 이익을 얻은게 아닐까 추정되는데.)


이외에도, 이모콘티만 추출하여 분석을 한다거나, 부사등을 통해서 분석을 하는 것도 가능하고, 구글 자연어 처리 API는 글을 통해서 사람의 감정을 분석해주는 기능도 있기 때문에 응용 분야는 훨씬 더 넓다고 볼 수 있다.

Storm을 이용한 실시간 데이타 처리 #1-데이타 스트림 개념 이해하기

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

 


Apache Storm 은 실시간 데이타 처리를 위한 시스템이다.. 나온지는 꽤 오래됬지만 요즘 빅데이타와 실시간 분석과 함께 다시 화두가 되고 있는데, Apache Storm에 대해서 알아보도록 하자.


 

스트리밍 처리에 대한 개념

Storm을 이해하기 위해서는 먼저 데이타 스트리밍9(Data Streaming) 에 대한 개념을 이해 해야 한다. 비유를 하자면 데이타가 흘러가는 강(river)와 같은 의미라고나 할까?

예를 들어보면, 트위터에서 생성되는 데이타 피드들은 일종의 데이타 스트림이다, 시간이 지나감에 따라서 끊임 없이 데이타 들이 생성된다.



<그림. 트위터의 트윗 데이타 스트림>

또는 공장의 팬베이어 벨트의 센서를 통해서 생성되는 각종 계측 값들도 데이타 스트림으로 볼 수 있다. 신용카드 트랜젝션, 전자 상거래 사이트의 구매 트렌젝션등. 이러한 데이타는 시간을 축으로 하여, 계속해서 생성되는 데이타 이다.

그렇다면 이런 스트림 데이타로 무엇을 할 수 있는가? 다시 트위터를 예를 들어보자


트위터 스트림을 이용한 소셜 마케팅 반응 분석

트위터 데이타 피드 스트림을 모니러링 하면서, 스마트폰과 관련된 키워드가 나오면 A社와 B社에 대한 스트림만을 수집하여, 각사별로 피드의 내용이 긍정적인지 부정적인지를 판단하는 시스템이 있다고 하자

이를 데이타 스트림 분석 개념으로 표현하면 다음과 같다.



<그림. 트위터 데이타 스트림 분석을 통한 제품 반응 분석>

먼저 스마트폰 관련 데이타 스트림을 모두 수집한다.

그 중에서, A사가 언급된 피드와, B사가 언급된 피드를 분리한다.

각 피드에 대해서, 문자의 구문이 긍정인지 부정인지를 판단한다. 예를 들어, Good,Awesome 등의 긍정적인 단어가 들어가 있으면 긍정적인 것으로 판단하고, Bad,fuck 등 부정적인 단어가 들어가 있으면 부정적인 반응으로 판단한다.

그후에, 각각의 반응에 대해서 카운트를 한다음에, 시계열(Time series) 그래프로 대쉬 보드에 표현한다.

정리해보면, 계속해서 들어오는 데이타들의 흐름을 여러 방향으로 분류하고 처리해서 계속해서 결과를 업데이트해주는 일종의 work flow와 같은 개념을 가지는 것이 데이타 스트림 처리이다.

이러한 데이타 스트림 처리는 일종의 중첩 함수의 개념으로도 볼수 있는데,

A사 제품에 대한 긍정적인 반응 = [“긍정적인 단어 필터 함수”(
[“A
사 제품에 대한 필터 함수”](“트위터의 스마트폰 관련 피드”)
);

와 같은 형태로 나타내어 줄 수 있다. (결국 실시간 데이타 스트림 처리는 실시간으로 들어오는 데이타 에 대해서 중첩으로 여러개의 함수 처리를 순차적으로 하는 것이다.)

물론 이러한 작업들은 데이타를 모두 모아서 수집해놓고 데이타 베이스에 저장해놓고 주기적으로 배치르 통해서 분석하는 것도 가능하다. 그러나 선거나 마케팅과 같이 실시간 대응이 중요한 경우에는 실시간 데이타 분석이 중요하기 때문에, 데이타 스트림을 실시간으로 분석하는 것이 필요하다.


이벤트 감지를 통한 신용 카드 이상 거래 감지

이번에는 데이타 스트림 처리에 이벤트 처리라는 개념을 추가해보자.

신용 카드 결재시, 결재 내용을 저장하는 것 뿐만 아니라, 사용자의 결재 내역이 문제가 없는지를 검출하는 시나리오이다.

이상거래 검출 요건은, 사용자가 평상시 결재 액보다 많은 금액이 결재되거나, 사용자가 결재할때, 물리적으로 이상한 곳에서 결재가 이루어 졌을때, 여를 들어 서울에서 카드 결재 후에, 10분 후에 부산에서 같은 카드로 결재가 이루어진 경우는 이상 거래로 검출하는 시스템이다.

다음 플로우를 보자



<그림. 실시간 신용 카드 이상 거래 검출>

신용 카드 결재 정보 데이타 스트림이 들어오면 결재 내용을 저장하는 스트림과 이상 거래를 검출하는 스트림 두가지로 분리되서 스트림이 처리된다.

이상 거래 검출 스트림에서는, 사용자의 구매 패턴을 분석하고 계속해서 학습한 후에, 이를 통해서 사용자 구매 패턴 검증단계에서 구매 금액이 일상적인 구매 패턴인지를 판단한다.

판단의 기준은 머신 러닝을 이용하여, 해당 사용자의 구매 패턴을 알고리즘화 해놓을 수 있다.

다음으로 결재 위치를 저장한 다음에 사용자 결재 위치 검증단계에서 지난 결재 가맹점 정보를 기반으로 이번 결재의 가맹점의 위치가 시간상으로 이동이 가능한 곳인지를 판단한다.

서울 강남에서 결재 한 후에, 30분후 서울 잠실에서 결재한 것은 정상 거래로 보지만 서울에서 결재했다가 10분후에 부산에서 결재 하는 것등은 이상거래로 취급한다.

이러한 시나리오는 결재가 이루지는 동시에 같이 실행되어야 하기 때문에 데이타 베이스 기반의 배치 처리로는 불가능하면 실시간 데이타 스트림을 분석해야 한다.

이외에도 시스템의 로그 스트림을 이용한 분석이라던지, 이벤트 처리, 데이타 가공, 머신러닝등 아주 다양한 부분의 실시간 처리에 데이타 스트리밍 처리는 사용될 수 있다.


데이타 스트림 처리를 이루는 기술들

앞의 신용카드 이상 거래 검출 시나리오를 보면 데이타 스트림을 분석하는데, 몇가지 추가적인 기술일 사용되었음을 볼 수 있다.


스트리밍 처리

먼저 데이타 스트림을 처리하기 위한 스트리밍 시스템이 필요하다, 데이타 스트림을 여러가지 경로로 분산하여, 각각의 단계별로 처리(사용자 구매 패턴 분석, 구매 패턴 검증,…)하는 워크 플로우 기능이 필요하다.

이러한 프레임웍은 앞으로 살펴보고자 하는 Apache Storm이 대표적이고 근래에는 Apache Spark도 많이 사용되고 있다.


대용량 분산 큐

다음으로 대용량으로 여러 경로를 통해서 들어오는 데이타를 수집하기 위한 터널(수집용 깔때기)이 필요한데, 비동기 처리를 위한 큐가 적절하다 그중에서도, 많은 데이타를 동시에 처리하기 위한 대용량 지원성이 필수적인데, 이를 위해서는 Kafka와 같은 대용량 분산 큐 솔루션이 적절하다.


머신러닝

사용자의 거래 패턴을 분석하여, 이상거래인지 검출을 하려면, 컴퓨터에서 사용자의 거래 패턴을 알려줄 필요가 있는데 이는 기존의 사용자 거래 내역을 학습하여 하여 패턴을 분석해내는 머신러닝 기술이 필요하며, 이는 Apache Mahout, Microsoft Azure ML (Machine Learning), Spark ML등이 있다.


이벤트 처리

마지막으로 이벤트 처리 부분이 있는데

카드 결재 장소가 지난 장소에 비해서 시간*20km 이상이면 이상거래로 판단해라”. 라는 이벤트를 정의할 수 있다. (※ 한시간에 20km를 이동할 수 있다고 가정)

특정 조건에 대해서 이벤트를 발생 시키는 것을 이벤트 처리라고 이런 처리를 CEP (Complex Event Processing) 라고 부르고, 이를 구현한 아키텍쳐를 EDA (Event Driven Architecture)라고 한다.

이러한 이벤트 처리 프레임웍으로는 JBoss Drool이나, Esper와 같은 프레임웍이 있다.


이외에도 데이타 스트림 분석을 위해서는 시나리오에 따라 더 많은 기술이 사용된다. 추가 사용되는 기술은 기회가 되면 향후에 추가로 소개하도록 한다. (아직도 공부 中)

지금까지 간략하게 나마 데이타 스트림의 개념과 이를 처리 하는 방법에 대해서 알아보았다.

그러면 다음에는 이런 데이타 스트림을 처리하기 위한 대표적인 프레임웍중의 하나인 apache storm에 대해서 소개해도록 한다.