提取:从“原始”数据提取特征
转换:缩放,转换或修改要素
选择:从一组较大的要素中选择一个子集
Feature Extractors
TF-IDF (HashingTF and IDF)
TF:HashingTF是一个transfor,它使用term的集合并将这些集合转换成固定长度的特征向量。 在文本处理中,“一组term”可能是一组词的结合。 该算法将term频率(TF)计数与用于降维的散列技巧组合。
IDF:IDF是一种作用于数据集(fit method)并生成IDFModel的估计器。 IDFModel取特征向量(通常由HashingTF创建)并缩放每个列。 直观地,它会降低在语料库中频繁出现的列的权重。
在下面的代码段中,我们从一组句子开始。 我们使用Tokenizer将每个句子分成单词。 对于每个句子(词袋),我们使用HashingTF将句子散列成特征向量。 我们使用IDF重新缩放特征向量; 这通常会提高使用文本作为功能时的性能。 然后我们的特征向量可以被传递到学习算法。
Word2Vec
每个文本都是根据文本中的词生成的一个向量,可以用于预测,文本相似度。。。
CountVectorizer
用向量表示文档中每个词出现的次数
id | texts | vector
----|---------------------------------|---------------
0 | Array("a", "b", "c") | (3,[0,1,2],[1.0,1.0,1.0])
1 | Array("a", "b", "b", "c", "a") | (3,[0,1,2],[2.0,2.0,1.0])
Feature Transformers
Tokenizer
RegexTokenizer允许基于正则表达式(regex)匹配的更高级的符号化。 默认情况下,参数“pattern”(regex,default:\ s +)用作分隔符以分隔输入文本。 或者,用户可以将参数“gap”设置为false,指示正则表达式“模式”表示“令牌”,而不是分割间隙,并且找到所有匹配的出现作为令牌化结果。
import org.apache.spark.ml.feature.{RegexTokenizer, Tokenizer} val sentenceDataFrame = sqlContext.createDataFrame(Seq( (0, "Hi I heard about Spark"), (1, "I wish Java could use case classes"), (2, "Logistic,regression,models,are,neat") )).toDF("label", "sentence") val tokenizer = new Tokenizer().setInputCol("sentence").setOutputCol("words") val regexTokenizer = new RegexTokenizer() .setInputCol("sentence") .setOutputCol("words") .setPattern("\\W") // alternatively .setPattern("\\w+").setGaps(false) val tokenized = tokenizer.transform(sentenceDataFrame) tokenized.select("words", "label").take(3).foreach(println) val regexTokenized = regexTokenizer.transform(sentenceDataFrame) regexTokenized.select("words", "label").take(3).foreach(println)
StopWordsRemover
移除停用词
Examples
Assume that we have the following DataFrame with columns id
and raw
:
id | raw
----|----------
0 | [I, saw, the, red, baloon]
1 | [Mary, had, a, little, lamb]
Applying StopWordsRemover
with raw
as the input column and filtered
as the output column, we should get the following:
id | raw | filtered
----|-----------------------------|--------------------
0 | [I, saw, the, red, baloon] | [saw, red, baloon]
1 | [Mary, had, a, little, lamb]|[Mary, little, lamb]
In filtered
, the stop words “I”, “the”, “had”, and “a” have been filtered out.
-gram
该模型基于这样一种假设,第n个词的出现只与前面N-1个词相关,而与其它任何词都不相关,整句的概率就是各个词出现概率的乘积。这些概率可以通过直接从语料中统计N个词同时出现的次数得到。常用的是二元的Bi-Gram和三元的Tri-Gram。
NGram将字符串序列(例如,Tokenizer的输出)作为输入。 参数n用于确定每个nn-gram中的项的数量。 输出将包括一个nn-gram序列,其中每个n-gram由nn个连续字的空格分隔的字符串表示。 如果输入序列包含少于n个字符串,则不会生成输出。
Binarizer
二值化是将数字特征阈值为二进制(0/1)特征的过程。Binarizer接受通用参数inputCol和outputCol以及二进制阈值。 大于阈值的特征值被二进制化为1.0; 等于或小于阈值的值被二进制化为0.0。
import org.apache.spark.ml.feature.Binarizer val data = Array((0, 0.1), (1, 0.8), (2, 0.2)) val dataFrame: DataFrame = sqlContext.createDataFrame(data).toDF("label", "feature") val binarizer: Binarizer = new Binarizer() .setInputCol("feature") .setOutputCol("binarized_feature") .setThreshold(0.5) val binarizedDataFrame = binarizer.transform(dataFrame) val binarizedFeatures = binarizedDataFrame.select("binarized_feature") binarizedFeatures.collect().foreach(println)
PCA
用来降低维度PCA是一种统计过程,其使用正交变换将可能相关的变量的观察值的集合转换成称为主分量的线性不相关变量的值的集合。 PCA类训练模型使用PCA将向量投影到低维空间。 下面的示例显示了如何将5维特征向量投影到3维主成分中。
import org.apache.spark.ml.feature.PCA import org.apache.spark.mllib.linalg.Vectors val data = Array( Vectors.sparse(5, Seq((1, 1.0), (3, 7.0))), Vectors.dense(2.0, 0.0, 3.0, 4.0, 5.0), Vectors.dense(4.0, 0.0, 0.0, 6.0, 7.0) ) val df = sqlContext.createDataFrame(data.map(Tuple1.apply)).toDF("features") val pca = new PCA() .setInputCol("features") .setOutputCol("pcaFeatures") .setK(3) .fit(df) val pcaDF = pca.transform(df) val result = pcaDF.select("pcaFeatures") result.show()
PolynomialExpansion
多项式扩展
多项式展开是将特征扩展到多项式空间的过程,该多项式空间由原始尺寸的n度组合表示。 PolynomialExpansion类提供此功能。 下面的示例显示了如何将您的要素扩展到3度多项式空间。
Discrete Cosine Transform (DCT)
离散余弦变换(DCT)压缩算法,降低空间冗余度
StringIndexer
根据某个列生成index,比如categoryStringIndexer将标签的字符串列编码为标签索引列。 索引在[0,numLabels)中,按标签频率排序。 因此,最常见的标签获取索引0.如果输入列是数字,我们将其转换为字符串并索引字符串值。 当下游管道组件(例如Estimator或Transformer)使用此字符串索引标签时,必须将组件的输入列设置为此字符串索引的列名称。 在许多情况下,可以使用setInputCol设置输入列。
Examples
Assume that we have the following DataFrame with columns id
and category
:
id | category
----|----------
0 | a
1 | b
2 | c
3 | a
4 | a
5 | c
category
is a string column with three labels: “a”, “b”, and “c”. Applying StringIndexer
with category
as the input column and categoryIndex
as the output column, we should get the following:
id | category | categoryIndex
----|----------|---------------
0 | a | 0.0
1 | b | 2.0
2 | c | 1.0
3 | a | 0.0
4 | a | 0.0
5 | c | 1.0
“a” gets index 0
because it is the most frequent, followed by “c” with index 1
and “b” with index 2
.
抛出异常(这是默认值)
请完全跳过包含未看见标签的行
Examples
Let’s go back to our previous example but this time reuse our previously defined StringIndexer
on the following dataset:
id | category
----|----------
0 | a
1 | b
2 | c
3 | d
If you’ve not set how StringIndexer
handles unseen labels or set it to “error”, an exception will be thrown. However, if you had called setHandleInvalid("skip")
, the following dataset will be generated:
id | category | categoryIndex
----|----------|---------------
0 | a | 0.0
1 | b | 2.0
2 | c | 1.0
Notice that the row containing “d” does not appear.
import org.apache.spark.ml.feature.StringIndexer val df = sqlContext.createDataFrame( Seq((0, "a"), (1, "b"), (2, "c"), (3, "a"), (4, "a"), (5, "c")) ).toDF("id", "category") val indexer = new StringIndexer() .setInputCol("category") .setOutputCol("categoryIndex") val indexed = indexer.fit(df).transform(df) indexed.show()
IndexToString
对称到StringIndexer,IndexToString将一列标签索引映射回包含原始标签的列作为字符串。 常见的用例是使用StringIndexer从标签生成索引,使用这些索引训练模型,并使用IndexToString从预测索引列中检索原始标签。 但是,您可以自由提供您自己的标签。把index转换成之前的string category
Examples
Building on the StringIndexer
example, let’s assume we have the following DataFrame with columns id
and categoryIndex
:
id | categoryIndex
----|---------------
0 | 0.0
1 | 2.0
2 | 1.0
3 | 0.0
4 | 0.0
5 | 1.0
Applying IndexToString
with categoryIndex
as the input column, originalCategory
as the output column, we are able to retrieve our original labels (they will be inferred from the columns’ metadata):
id | categoryIndex | originalCategory
----|---------------|-----------------
0 | 0.0 | a
1 | 2.0 | b
2 | 1.0 | c
3 | 0.0 | a
4 | 0.0 | a
5 | 1.0 | c
OneHotEncoder
单热编码将一列标签索引映射到二进制向量列,最多具有单个一值。 此编码允许期望连续特征(例如逻辑回归)的算法使用分类特征将前面的stringindex 转变成 向量
VectorIndexer
基于不同值的数量确定哪些特征应是分类的,其中最多maxCategories的特征被声明为分类。
为每个分类特征计算基于0的类别索引。
索引分类特征并将原始特征值转换为索引。
Normalizer
StandardScaler
MinMaxScaler
上面3个对特征进行规范化就是,可以限定范围什么的ElementwiseProduct
就是向量乘法mport org.apache.spark.ml.feature.ElementwiseProduct import org.apache.spark.mllib.linalg.Vectors // Create some vector data; also works for sparse vectors val dataFrame = sqlContext.createDataFrame(Seq( ("a", Vectors.dense(1.0, 2.0, 3.0)), ("b", Vectors.dense(4.0, 5.0, 6.0)))).toDF("id", "vector") val transformingVector = Vectors.dense(0.0, 1.0, 2.0) val transformer = new ElementwiseProduct() .setScalingVec(transformingVector) .setInputCol("vector") .setOutputCol("transformedVector") // Batch transform the vectors to create new column: transformer.transform(dataFrame).show()
Bucketizer
对一个列的值就行分段,比如一个age,按照年龄划分区间import org.apache.spark.ml.feature.Bucketizer val splits = Array(Double.NegativeInfinity, -0.5, 0.0, 0.5, Double.PositiveInfinity) val data = Array(-0.5, -0.3, 0.0, 0.2) val dataFrame = sqlContext.createDataFrame(data.map(Tuple1.apply)).toDF("features") val bucketizer = new Bucketizer() .setInputCol("features") .setOutputCol("bucketedFeatures") .setSplits(splits) // Transform original data into its bucket index. val bucketedData = bucketizer.transform(dataFrame) bucketedData.show()
SQLTransformer
Assume that we have the following DataFrame with columns id
, v1
and v2
:
id | v1 | v2
----|-----|-----
0 | 1.0 | 3.0
2 | 2.0 | 5.0
This is the output of the SQLTransformer
with statement "SELECT *, (v1 + v2) AS v3, (v1 * v2) AS v4 FROM __THIS__"
:
id | v1 | v2 | v3 | v4
----|-----|-----|-----|-----
0 | 1.0 | 3.0 | 4.0 | 3.0
2 | 2.0 | 5.0 | 7.0 |10.0
Refer to the SQLTransformer Scala docs for more details on the API.
import org.apache.spark.ml.feature.SQLTransformer
val df = sqlContext.createDataFrame(
Seq((0, 1.0, 3.0), (2, 2.0, 5.0))).toDF("id", "v1", "v2")
val sqlTrans = new SQLTransformer().setStatement(
"SELECT *, (v1 + v2) AS v3, (v1 * v2) AS v4 FROM __THIS__")
sqlTrans.transform(df).show()
VectorAssembler
QuantileDiscretizer
分位树为数离散化,和Bucketizer(分箱处理)一样也是:将连续数值特征转换为离散类别特征。实际上Class QuantileDiscretizer extends (继承自) Class(Bucketizer)。
参数1:不同的是这里不再自己定义splits(分类标准),而是定义分几箱(段)就可以了。QuantileDiscretizer自己调用函数计算分位数,并完成离散化。
-参数2: 另外一个参数是精度,如果设置为0,则计算最精确的分位数,这是一个高时间代价的操作。另外上下边界将设置为正负无穷,覆盖所有实数范围。
Feature Selectors
VectorSlicer
就是从原向量列中提取子向量
RFormula
线性预测,将多个column变成向量,如果colum的值是string,会被one-hot-encoder