Spark中分散式使用HanLP(1.7.0)分詞d
阿新 • • 發佈:2018-12-17
Spark中分散式使用HanLP(1.7.0)分詞
HanLP分詞(https://github.com/hankcs/HanLP),如README中所說,如果沒有特殊需求,可以通過maven配置,如果要新增自定義詞典,需要下載“依賴jar包和使用者字典".
本人一些經驗:
- 是直接"java xf hanlp-1.6.8-sources.jar" 解壓原始碼,把原始碼加入工程(依賴本地jar包,有些麻煩,有時候到伺服器有找不到jar包的情況)
- 按照文件操作,在Spark中分詞,預設找的是本地目錄,所以如果是在driver中分詞是沒有問題的。但是如果要分散式分詞,是要把詞典目錄放在HDFS上面,因為這樣每臺機器才可以訪問到 【參考程式碼】
- 最好把新增詞典放在首位(我沒有放在首位好像沒有生效).第一次使用時,HanLP會把新增txt檔案,生成bin檔案,這個過程比較慢。但是隻需要跑一次,它會把bin檔案寫到HDFS路徑上面,第二次以後速度就快一些了。
注意到issue中說,只可以在mapPartition中使用(https://github.com/hankcs/HanLP/issues/588)
參考scala程式碼
class HadoopFileIoAdapter extends IIOAdapter { override def create(path: String): java.io.OutputStream = { val conf: Configuration = new Configuration() val fs: FileSystem = FileSystem.get(URI.create(path), conf) fs.create(new Path(path)) } override def open(path: String): java.io.InputStream = { val conf: Configuration = new Configuration() val fs: FileSystem = FileSystem.get(URI.create(path), conf) fs.open(new Path(path)) } } def myfuncPerPartition_ ( iter : Iterator [String] ) : Iterator[(Int, mutable.Buffer[String])] = { println("run in partition") val keyWordNum = 6 HanLP.Config.IOAdapter = new HadoopFileIoAdapter val ret = iter.filter(_.split(",",2).length==2) .map(line=>(line.split(",",2)(1).trim.hashCode, HanLP.extractKeyword(line.split(",",2)(0),keyWordNum) .map(str=>str.filterNot(stopChar.contains(_))).filter(w=>(w.length>1 || ( w.length==1 && white_single_word.contains(w(0))) )) .filterNot(stopWords.contains(_)).take(keyWordNum).distinct)) ret } //呼叫 raw_data.repartition(100).mapPartitions(myfuncPerPartition_)