2016-10-05 9 views
1

各バイグラムの頻度を数えたいと思います。Scala - Sparkワードカウント、なぜ動作しないのですか?

だから私は

val intputFile = "bible+shakes.nopunc" 
val sentences = sc.textFile(intputFile) 

val bigrams = sentences.map(sentence => sentence.trim.split(' ')).flatMap(wordList => 
    for (i <- List.range(0, (wordList.length - 2))) yield ((wordList(i), wordList(i + 1)), 1) 
) 

val bigrams2 = sentences.map(sentence => sentence.trim.split(' ')).flatMap(wordList => 
    wordList.sliding(2).map{case Array(x, y) => ((x,y), 1)} 
) 

を書いたそして彼らは同じ型を持っているようです。

scala> bigrams 
res11: org.apache.spark.rdd.RDD[((String, String), Int)] = MapPartitionsRDD[7] at flatMap at <console>:28 

scala> bigrams2 
res12: org.apache.spark.rdd.RDD[((String, String), Int)] = MapPartitionsRDD[11] at flatMap at <console>:28 

スカラ> bigrams.collect res15:配列[((文字列、文字列)、INT)] =配列(((神聖、聖書)、1)、((聖書、承認)、1)、 1)、((king、james)、1)、((james、version)、1)、((version、textfile)、1)、((in、the)、1)、 1)、((神、創造)、1)、((創造)、1)、((天国)、1)、 1)、1)、1)、1)、1)、((土)、1)、1) 1)、((形式、および)、1)、((および)void)、1)、((void、and)、1)、 1)、1)、1)、1)、1)、((顔)、1)、(笑) 1)、((the、the)、1)、((deep、and)、1)、((deep、and)、1)、 1)、((神)、1)、((神)、1)、((霊))、1 ((on、the)、1)、((the、face)、1)、 1)、((神)、1)、(1)、((顔、of)、1)、((of、the)、1) 、私がそうするとき

scala> bigrams.collect 
res13: Array[((String, String), Int)] = Array(((holy,bible),1), ((bible,authorized),1), ((authorized,king),1), ((king,james),1), ((james,version),1), ((version,textfile),1), ((in,the),1), ((the,beginning),1), ((beginning,god),1), ((god,created),1), ((created,the),1), ((the,heaven),1), ((heaven,and),1), ((and,the),1), ((and,the),1), ((the,earth),1), ((earth,was),1), ((was,without),1), ((without,form),1), ((form,and),1), ((and,void),1), ((void,and),1), ((and,darkness),1), ((darkness,was),1), ((was,upon),1), ((upon,the),1), ((the,face),1), ((face,of),1), ((of,the),1), ((the,deep),1), ((deep,and),1), ((and,the),1), ((the,spirit),1), ((spirit,of),1), ((of,god),1), ((god,moved),1), ((moved,upon),1), ((upon,the),1), ((the,face),1), ((face,of),1), ((of,the),1), ((and,god),1), ((god,said),1), ((... 

scala> bigrams2.collect 
16/10/05 10:17:52 ERROR Executor: Exception in task 1.0 in stage 11.0 (TID 20) 
scala.MatchError: [Ljava.lang.String;@3224ea91 (of class [Ljava.lang.String;) 
    at $line27.$read$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$anonfun$2$$anonfun$apply$1.apply(<console>:29) 

bigrams2.take(5) 
res25: Array[((String, String), Int)] = Array(((holy,bible),1), ((bible,authorized),1), ((authorized,king),1), ((king,james),1), ((james,version),1)) 

それを評価する第2の方法はエラーを引き起こした。

なぜですか?それを修正するには?私は第二の、正確な方法を好む。

答えて

0

問題は{case Array(x, y) => ((x,y), 1)はパターンのみArray(x, y)に一致する入力に対処する方法を知っているwhcih partial-functionであるということです。

このようにマップすると、1つの要素しか持たないウィンドウを扱うことができなくなります。あなたはここに

wordList.sliding(2).flatMap { 
    case Array(x, y) => Some((x, y), 1) 
    case _ => None 
} 

flatMapは、このように結果が唯一の有効な双方向グラムが含まれていることを保証するOption Sを平らになり、次のようなものに変更する必要があります。

+0

'Option'は空であるか1の項目を持つとみなすことができると言わなければなりません。 –

+1

@ShihaoXu実際には' Option'は空であるか1項目であるシーケンスと似ていません。 Scalaの初心者(またはプログラミング初心者)が、「Option」の実際の定義を説明することは実現不可能であるため、人々は「Option」をそのように考えるように言います。あなたは今のところ「Option」と考えることができますが、実際にはそうではないことに留意してください。 'Monad'という関数型プログラミングの概念を習得すれば、自然に' Option'を理解することができます。 –

0

あなたbigrams2式は問題があります。wordListには一つだけのアイテムを持っている場合

wordList.sliding(2).map{case Array(x, y) => ((x,y), 1)} 

マップケースはケースを処理しませんが、それはなぜあなたの取得MatchErrorです。それは、単一の言葉である文のために現れる。

は、一つの項目の配列のためのケース構造を追加する修正するには:あなたのwordList.sliding(2).map{case Array(x, y) => ((x,y), 1)

wordList.sliding(2).map { 
    case Array(x, y) => ((x,y), 1) 
    case Array(x) => ??? 
} 
関連する問題