特征的转换_01-自然语言相关特征转换
来源:互联网 发布:java生成时间戳 编辑:程序博客网 时间:2024/05/22 06:32
笔记整理时间:2017年1月11日
笔记整理者:王小草
SparkML 2.1.0的官方文档给出了21类特征转换的方法,其中关于自然语言处理领域的有3类,分别是:Tokenizer分词,StopWordsRemover去停用词,n-gram。本文主要介绍这三种方法的使用。
1. Tokenizer分词
在对文本做数据挖掘的时候,分词往往是第一步:将一个句子拆分成单词的集合。
在文本特征的提取笔记中,讲到可以用TF-IDF文档矩阵,word2vec词嵌入矩阵来做词或文档的向量表征,这些都是基于分词的基础上的。准确的分词是接下来特征提取与模型建立的成功垫脚石。
英文的分词很简单,只需按照标点与空格就可以提取word,而中文的分词就有点让人头痛了呢。sparkml此处提供的只是基于英文的分词方法。关于中文分词,我们还需要对其在巨大的语料库上进行训练而得到,常见的模型有隐马尔科夫模型HMM,条件随机场模型CRF等,这些模型的介绍请参见我的机器学习笔记哦~
Sparkml的分词提供了两种方法:
1.Tokenization,将英文句子分成单个的term。
// 创建一个dataframe,第二列是句子 val sentenceDataFrame = spark.createDataFrame(Seq( (0, "Hi I heard about Spark"), (1, "I wish Java could use case classes"), (2, "Logistic,regression,models,are,neat") )).toDF("id", "sentence") // 默认的分词(自动转成小写) val tokenizer = new Tokenizer().setInputCol("sentence").setOutputCol("words") val tokenized = tokenizer.transform(sentenceDataFrame) tokenized.show(false)
输出结果:
+---+-----------------------------------+------------------------------------------+|id |sentence |words |+---+-----------------------------------+------------------------------------------+|0 |Hi I heard about Spark |[hi, i, heard, about, spark] ||1 |I wish Java could use case classes |[i, wish, java, could, use, case, classes]||2 |Logistic,regression,models,are,neat|[logistic,regression,models,are,neat] |+---+-----------------------------------+------------------------------------------+
2.RegexTokenizer ,根据正则表达式去匹配单词。
默认情况下是pattern的参数是(regex, default: “\ \s+”) ,即按照正则表达式匹配的词进行分割。
\ \s表示 空格,回车,换行等空白符,
+号表示一个或多个的意思
// 利用正则表达式分词 val regexTokenizer = new RegexTokenizer() .setInputCol("sentence") .setOutputCol("words") val regexTokenized = regexTokenizer.transform(sentenceDataFrame) regexTokenized.show(false)
输出结果:
+---+-----------------------------------+------------------------------------------+|id |sentence |words |+---+-----------------------------------+------------------------------------------+|0 |Hi I heard about Spark |[hi, i, heard, about, spark] ||1 |I wish Java could use case classes |[i, wish, java, could, use, case, classes]||2 |Logistic,regression,models,are,neat|[logistic,regression,models,are,neat] |+---+-----------------------------------+------------------------------------------+
另外,还可以这样做:在pattern中传入要取出的东东的正则表达式,比如说想得到一句话中的word,就可以设置.setPattern(“\ \W”),如果光这样,表示是按照词去分割,输出结果是酱紫的:
+---+-----------------------------------+------------------+|id |sentence |words |+---+-----------------------------------+------------------+|0 |Hi I heard about Spark |[ , , , ] ||1 |I wish Java could use case classes |[ , , , , , ]||2 |Logistic,regression,models,are,neat|[,, ,, ,, ,] |+---+-----------------------------------+------------------+
需要再设置.setGaps(false),表示把正则表达式匹配的东东取出来而不是用其去分割。
val regexTokenizer = new RegexTokenizer() .setInputCol("sentence") .setOutputCol("words") .setPattern("\\w+").setGaps(false) val regexTokenized = regexTokenizer.transform(sentenceDataFrame) regexTokenized.show(false)
输出结果:
+---+-----------------------------------+------------------------------------------+|id |sentence |words |+---+-----------------------------------+------------------------------------------+|0 |Hi I heard about Spark |[hi, i, heard, about, spark] ||1 |I wish Java could use case classes |[i, wish, java, could, use, case, classes]||2 |Logistic,regression,models,are,neat|[logistic, regression, models, are, neat] |+---+-----------------------------------+------------------------------------------+
2. StopWordsRemover去停用词
分词之后,句子变成了单词的集合,但是并非每一个单词都有意义,比如冠词the, 人称代词I,等等出现频率高单又缺乏意义的词。在很多需求中去掉这些无意义的停用词可以使得建模更加准确。
StopWordsRemover这个方法,输入一个字符串组成的列表,输出一个去掉了停用词的列表。
不同需求中的停用词有不同的定义,这个我们可以自己出传入参数设置。若要使用默认的停用词可以调用StopWordsRemover.loadDefaultStopWords(language),目前有的language有: “danish”, “dutch”, “english”, “finnish”, “french”, “german”, “hungarian”, “italian”, “norwegian”, “portuguese”, “russian”, “spanish”, “swedish” and “turkish”.(恩,看了好几遍的确没有中文。。再见,朋友。。。)
还有一个布尔类型的参数 caseSensitive,表示是都对大小写敏感,默认是false.
看一个例子:
比如有这样2句话:
然后去停后输出了新的过滤后的分词组合:
停用词“I”, “the”, “had”, and “a” 被过滤掉了。
代码:
// 创建一个DataFrame val dataSet = spark.createDataFrame(Seq( (0, Seq("I", "saw", "the", "red", "balloon")), (1, Seq("Mary", "had", "a", "little", "lamb")) )).toDF("id", "raw") // 创建一个新的对象,并设置参数 val remover = new StopWordsRemover() .setInputCol("raw") .setOutputCol("filtered") // 转换 remover.transform(dataSet).show(false)
输出:
+---+----------------------------+--------------------+|id |raw |filtered |+---+----------------------------+--------------------+|0 |[I, saw, the, red, balloon] |[saw, red, balloon] ||1 |[Mary, had, a, little, lamb]|[Mary, little, lamb]|+---+----------------------------+--------------------+
3. n-gram
经常有这样的需求,需要将词进行窗口为n的遍历,说多了更混乱,一个例子一目了然:
输入一句分好词的句子:
[Hi, I, heard, about, Spark]
如果窗口大小设置为2,那么输出的是:
[Hi I, I heard, heard about, about Spark]
可见,每个词都在窗口为2的组合中被遍历了一次。
这个在中文分词中其实可以应用,将中文按字拆分,如果某个组合出现的次数很多,是不是可以换衣这个组合的词是一个真正的词语呢。
来看一下代码的实现:
//创建dataframe val wordDataFrame = spark.createDataFrame(Seq( (0, Array("Hi", "I", "heard", "about", "Spark")), (1, Array("I", "wish", "Java", "could", "use", "case", "classes")), (2, Array("Logistic", "regression", "models", "are", "neat")) )).toDF("id", "words") // 创建新对象,并设置参数,窗口长度为3 val ngram = new NGram().setN(3).setInputCol("words").setOutputCol("ngrame") //转换 val ngramDataFrame = ngram.transform(wordDataFrame) ngramDataFrame.show(false)
输出结果:
+---+------------------------------------------+---------------------------------+|id |words |ngrame |+---+------------------------------------------+---------------------------------+|0 |[Hi, I, heard, about, Spark] |[Hi I, I heard, heard about, about Spark] ||1 |[I, wish, Java, could, use, case, classes]|[I wish, wish Java, Java could, could use, use case, case classes]||2 |[Logistic, regression, models, are, neat] |[Logistic regression, regression models, models are, are neat] |+---+------------------------------------------+---------------------------------+
- 特征的转换_01-自然语言相关特征转换
- 特征的转换_04-探索最优特征组合
- 特征的转换_06-特征降维PCA
- 特征提取与转换
- 特征提取和转换
- 特征的选择_01:特征向量的切分
- Kaldi中特征文件格式的转换
- Kaldi中特征文件格式的转换
- Spark2.0 特征提取、转换、选择之二:特征选择、文本处理,以中文自然语言处理(情感分类为例)
- 【机器学习】特征选择与特征转换
- sparkmllib 特征抽取、特征转换及特征选择
- 特征的转换_05-标签索引的转换与特征的组合
- 尺度不变特征转换SIFT
- 尺度不变特征转换SIFT
- Spark-mllib特征转换算法
- 声学特征转换 kaldi工具
- 特征的转换_02-连续变量的离散化
- 谁动了我的特征?——sklearn特征转换行为全记录
- Java03接口与内部类
- Android画一条虚线
- 23种设计模式之_享元模式
- 设置GridView某个单元格显示的字数,其余的使用省略号显示
- C++读取BIOS信息
- 特征的转换_01-自然语言相关特征转换
- Android File类
- 找球号(一)
- 特征的转换_02-连续变量的离散化
- 关于微信小程序
- TensorFlow 1.0.0rc1上玩量化神经网络 ——转自 慢慢学TensorFlow 微信公众号
- 抓住神经猫的学习与实践
- SpringMVC注解@initbinder解决类型转换问题
- Qt之可重入与线程安全