본문 바로가기

Data Analysis

기계학습 - Spark(2) - TF-IDF 샘플코드 이해

Spark 교재중 TF-IDF 설명 페이지에는 샘플코드가 있다. 스칼라로 코딩된 것을 이해해보고자 한다. [링크]


val sentenceData = spark.createDataFrame(... 이 것은 DataFrame 을 생성하는 코드인데, API 레퍼런스에서 찾는데 애를 먹었다. 먼저 spark 생뚱맞다. 대체 이 변수 아니면 오브젝트의 인스턴스는 어디서 나온거지? 한참을 찾아보니, 이 인스턴스는 SparkSession객체의 것인데, spark-shell을 구동할 때 시작시 출력을 보면 내부적으로 선언했다고 알려준다.


Spark context available as 'sc' (master = local[*], app id = local-1493634526691).

Spark session available as 'spark'.

Welcome to

      ____              __

     / __/__  ___ _____/ /__

    _\ \/ _ \/ _ `/ __/  '_/

   /___/ .__/\_,_/_/ /_/\_\   version 2.1.0


그리고 반환 객체인 DataFrame은  스칼라 API를 뒤져봐도 "DataFrame"형 선언이 없어서 조금 헤매었다. 찾고 보니 DataFrame = DataSet[Row]이었다. 즉, DataSet을 구성하는 데이터형(객체)이 Row인 것이 DataFrame이다.


근데, .toDF는 무엇을 의미할까? 자바 코드를 참조해보니, 열의 이름을 정의하는 것 같다. API설명에 따르면 toDF함수는 열의 이름을 재정의 하는 함수이다.

여튼 여기까지가 "Extracting"에 해당할 것 같다. "Collection"이라고 해도 될 듯 하다.


다음은 Tokenizer와 HasingTF를 통해서 원본데이터를 우리가 원하는 결과를 얻기 위해 사용할 녀석으로 변환을 시킨다.

Tokenizer는 문장을 단어로 쪼개는 작업을 한다. 이 부분은 쉬운데 HashingTF를 이해하는 것이 어려웠다. 대체 뭐하는 녀석인가?


단어들을 해싱알고리즘을 통해 맵을 구성하고, 그 인덱스만을 이용해서 단어의 횟수를 센다. 당연히 다른 단어가 하나의 단어로 여겨질 수 있으며, 그 때는 같이 횟수가 세어진다. 이렇게 하는 이유는 오직 처리성능을 높이기 위해서다. 또한 가능한 많은 단어들이 중복되지 않고 고르게 분포되려면 해싱알고리즘이 중요할 것으로 생각된다. 우리나라 말에 적합한 알고리즘이 있을 것도 같다.


마지막으로 idk 모델을 구성해서 데이터를 다시 한번 변환시키면 TF-IDF에 의해 특이점을 추출해 낼 수 있다.


샘플코드를 개인적으로 돌려서 나온 결과이다. 값이 0이 나온 것은 아마도 "I"에 해당하는 것이다.

scala> for ( cc <- rd.select("features") ) println(cc)

[(20,[0,2,7,9,13,15],[0.28768207245178085,0.6931471805599453,0.6931471805599453,0.0,0.28768207245178085,0.28768207245178085])]

[(20,[0,5,9,17],[0.28768207245178085,0.6931471805599453,0.0,1.3862943611198906])]

[(20,[4,6,9,13,15,18],[0.6931471805599453,0.6931471805599453,0.0,0.28768207245178085,0.28768207245178085,0.6931471805599453])]