스파크에서 제공하는 spark-shell을 이용한  Tokenizer 예이다.



 데이터 프레임을 생성한다.



scala>

val sentence = spark.createDataFrame(Seq(

(0, "Tokenization,is the process of enchanting words,from the raw text"),

(1, " If you want,to have more advance tokenization,RegexTokenizer,is a good option"),

(2, " Here,will provide a sample example on how to tockenize sentences"),

(3, "This way,you can find all matching occurrences"))).toDF("id","sentence")



이제 다음과 같이 Tokenizer API를 인스턴스화해서 토큰나이저를 생성한다.


import org.apache.spark.ml.feature.Tokenizer


val tokenizer = new Tokenizer().setInputCol("sentence").setOutputCol("words") 





이제 다음과 같이 UDF를 사용해 각 문장의 토큰 개수를 계산한다.




import org.apache.spark.sql.functions._


val countTokens = udf { (words: Seq[String]) => words.length } 




이제 각 문장에서 토큰을 얻는다.



val tokenized = tokenizer.transform(sentence) 







tokenized.show(false) 



+---+------------------------------------------------------------------------------+------------------------------------------------------------------------------------------+

|id |sentence                                                                      |words                                                                                     |

+---+------------------------------------------------------------------------------+------------------------------------------------------------------------------------------+

|0  |Tokenization,is the process of enchanting words,from the raw text             |[tokenization,is, the, process, of, enchanting, words,from, the, raw, text]               |

|1  | If you want,to have more advance tokenization,RegexTokenizer,is a good option|[, if, you, want,to, have, more, advance, tokenization,regextokenizer,is, a, good, option]|

|2  | Here,will provide a sample example on how to tockenize sentences             |[, here,will, provide, a, sample, example, on, how, to, tockenize, sentences]             |

|3  |This way,you can find all matching occurrences                                |[this, way,you, can, find, all, matching, occurrences]                                    |

+---+------------------------------------------------------------------------------+------------------------------------------------------------------------------------------+




마지막으로 각 토큰을 다음과 같이 각 원본 문장에 대해 표시한다. tokens 개수가 있다. 





scala> 

tokenized.select("sentence", "words").withColumn("tokens", countTokens(col("words"))).show(false)
+------------------------------------------------------------------------------+------------------------------------------------------------------------------------------+------+
|sentence                                                                      |words                                                                                     |tokens|
+------------------------------------------------------------------------------+------------------------------------------------------------------------------------------+------+
|Tokenization,is the process of enchanting words,from the raw text             |[tokenization,is, the, process, of, enchanting, words,from, the, raw, text]               |9     |
| If you want,to have more advance tokenization,RegexTokenizer,is a good option|[, if, you, want,to, have, more, advance, tokenization,regextokenizer,is, a, good, option]|11    |
| Here,will provide a sample example on how to tockenize sentences             |[, here,will, provide, a, sample, example, on, how, to, tockenize, sentences]             |11    |
|This way,you can find all matching occurrences                                |[this, way,you, can, find, all, matching, occurrences]                                    |7     |
+------------------------------------------------------------------------------+------------------------------------------------------------------------------------------+------+



원본 문장, 단어 모음, 토큰 수를 포함하는 토큰 데이터 프레임 정보를 출력한다.




그러나 RegexTokenizer API를 사용하면 더 좋은 결과를 얻을 수 있다. 다음과 같이 RegexTokenizer API를 인스턴스화하여 정규식 토큰나이저를 생성한다.




import org.apache.spark.ml.feature.RegexTokenizer



val regexTokenizer = new RegexTokenizer()

                    .setInputCol("sentence")

                    .setOutputCol("words")

                    .setPattern("\\W+")

                    .setGaps(true)




이제 다음처럼 각 문장에서 토큰을 얻는다.



val regexTokenized = regexTokenizer.transform(sentence)


regexTokenized.select("sentence", "words")

             .withColumn("tokens", countTokens(col("words")))

             .show(false)





+------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------+------+

|sentence                                                                      |words                                                                                      |tokens|

+------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------+------+

|Tokenization,is the process of enchanting words,from the raw text             |[tokenization, is, the, process, of, enchanting, words, from, the, raw, text]              |11    |

| If you want,to have more advance tokenization,RegexTokenizer,is a good option|[if, you, want, to, have, more, advance, tokenization, regextokenizer, is, a, good, option]|13    |

| Here,will provide a sample example on how to tockenize sentences             |[here, will, provide, a, sample, example, on, how, to, tockenize, sentences]               |11    |

|This way,you can find all matching occurrences                                |[this, way, you, can, find, all, matching, occurrences]                                    |8     |

+------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------+------+






이전 코드 라인은 원본 문장, 단어 모음, 토큰 수를 포함하는 RegexTokenizer를 사용해 토큰화된 데이터 프레임 정보를 출력한다.  RegexTokenizer를 사용해 토큰화가 훨씬 좋아졌다.





이제 여기서 정지 (stop word)를 삭제해 보자.



스톱 워드(stop word)는 일반적으로 단어가 자주 나타나지만 많은 의미를 지니지 않아서 일반적으로 입력에서 제외되야 하는 단어이다. 


스파크의 StopWordsRemover는 입력으로 일련의 문자열을 받는다. 


일련의 문자열은 Tokenizer 또는 RegexTokenizer에 의해 토큰화된다. 


그리고 입력 문자열에서 모든 중지 단어를 제거한다. 중지 단어 목록은 stopWords 매개 변수에 의해 지정된다. 




StopWordsRemover API의 현재 구현은 덴마크어, 네덜란드어, 핀란드어, 프랑스어, 독일어, 헝가리어, 이탈리아어, 노르웨이어, 포르투갈어, 러시아어, 스페인어, 스웨덴어, 터키어, 영어에 대한 옵션을 제공한다. (한국어는 없다.)



예를 제공하기 위해 이전 Tokenizer 예를 이미 토큰화되어 있기 때문에 간단하게 확장할 수 있다. 그러나 이 예에서는 RegexTokenizer API를 사용한다.



먼저 StopWordsRemover API에서 다음과 같이 StopWordsRemover 인스턴스를 생성한다.


import org.apache.spark.ml.feature.StopWordsRemover


val remover = new StopWordsRemover()

            .setInputCol("words")

            .setOutputCol("filtered")




이제 다음과 같이 모든 중지 단어를 제거하고 결과를 출력하자.


scala>

val newDF = remover.transform(regexTokenized)


newDF.select("id", "filtered").show(false)


+---+-----------------------------------------------------------+

|id |filtered                                                   |

+---+-----------------------------------------------------------+

|0  |[tokenization, process, enchanting, words, raw, text]      |

|1  |[want, advance, tokenization, regextokenizer, good, option]|

|2  |[provide, sample, example, tockenize, sentences]           |

|3  |[way, find, matching, occurrences]                         |

+---+-----------------------------------------------------------+




이전 코드 라인은 필터링된 데이터 프레임에서 중지 단어를 제외하고 출력한다.








Posted by 김용환 '김용환'

댓글을 달아 주세요