Scalaの-MLlib公式文書--- spark.mllibパッケージ次元性の減少+特徴抽出と変換

六、次元削減

次元削減は、プロセスで考慮変数の数を減らすことです。それは維持しながら、元の潜在的にノイズの多い特徴から抽出機能を使用するか、またはデータ構造を圧縮することができます。spark.mllibはRowMatrixクラス次元削減のためのサポートを提供します

特異値分解(SVD)

3つの行列に行列の特異値分解(SVD):U、Σ及びV、その結果、
A =UΣVT、
前記

  • Uは、その列の左特異ベクトルと呼ばれる直交行列です。
  • Σは非負対角下降対角行列であり、対角特異値と呼ばれます。
  • Vは、その列の右特異ベクトルと呼ばれる直交行列です。

大きな行列のために、通常は完全な因数分解を必要とせず、特異値は、それらに関連する特異ベクトルの先頭にのみ必要です。これは、記憶空間を節約する、ノイズ低減及び下位行列の構造を復元します。

我々はk個の特異値を保持する場合、マトリックスの結果として得られる低いランクの寸法であろう:
U-:M×K、
[シグマ:K×K、
V :. K×N
1)を示した
私たちが想定N未満m以下です。特異値と右特異ベクトルは、ATAグラミアン行列の固有値と固有ベクトルから誘導されます。ComputeUパラメータユーザー要求した場合、Uは、U = A(VS-1)として算出される左特異行列乗算メモリマトリクスベクターを介し 。方法が自動的に決定され算出される実際のコストに基づいています。

  • nは(N小さい場合<N-Kと比較して100)または大(K> N / 2)、我々は最初のグラム行列を計算し、運転者のローカル最大固有値と固有ベクトルを計算します。これにより、ドライバの各アクチュエータやドライバ、およびO(N2K)処理時間の蓄積動作の時間O(N2)を必要とします。
  • そうでなければ、我々は、分散的(ATA)を算出し、ノードのドライバ(ATA)最大固有値と固有ベクトルを計算する、ARPACK Vに送られます。これは、各ドライバに、O(NK)O上に格納された(n)を通過したO(k)の時間を必要とし、記憶されたプログラムを実行します。

2)実施例SVD
spark.mllib SVD機能はRowMatrixが設けられマトリクス行指向のクラスを提供します。

import org.apache.spark.mllib.linalg.Matrix
import org.apache.spark.mllib.linalg.SingularValueDecomposition
import org.apache.spark.mllib.linalg.Vector
import org.apache.spark.mllib.linalg.Vectors
import org.apache.spark.mllib.linalg.distributed.RowMatrix

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 rows = sc.parallelize(data)

val mat: RowMatrix = new RowMatrix(rows)

// Compute the top 5 singular values and corresponding singular vectors.
val svd: SingularValueDecomposition[RowMatrix, Matrix] = mat.computeSVD(5, computeU = true)
val U: RowMatrix = svd.U  // The U factor is a RowMatrix.
val s: Vector = svd.s     // The singular values are stored in a local dense vector.
val V: Matrix = svd.V     // The V factor is a local dense matrix.

主成分分析(PCA)

主成分分析(PCA)は、最初の最大の分散、および後続の各座標を有し、最大の分散を有する座標ように、回転を見つけるための統計的手法です。回転行列の列は、主成分と呼ばれます。PCAは、広く次元縮小のために使用されています。
任意のベクターの高ライン指向の形式とストレージをサポートし、薄いPCAをマトリックスにspark.mllib。
サンプルコード
どの主成分を計算するとRowMatrixベクトルの次のコードが示すように低次元空間に射影しました。
APIの詳細については、RowMatrix Scalaのドキュメントを参照してください。

import org.apache.spark.mllib.linalg.Matrix
import org.apache.spark.mllib.linalg.Vectors
import org.apache.spark.mllib.linalg.distributed.RowMatrix

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 rows = sc.parallelize(data)

val mat: RowMatrix = new RowMatrix(rows)

// Compute the top 4 principal components.
// Principal components are stored in a local dense matrix.
val pc: Matrix = mat.computePrincipalComponents(4)

// Project the rows to the linear space spanned by the top 4 principal components.
val projected: RowMatrix = mat.multiply(pc)

APIの詳細については、PCA Scalaのドキュメントを参照してください。

import org.apache.spark.mllib.feature.PCA
import org.apache.spark.mllib.linalg.Vectors
import org.apache.spark.mllib.regression.LabeledPoint
import org.apache.spark.rdd.RDD

val data: RDD[LabeledPoint] = sc.parallelize(Seq(
  new LabeledPoint(0, Vectors.dense(1, 0, 0, 0, 1)),
  new LabeledPoint(1, Vectors.dense(1, 1, 0, 1, 0)),
  new LabeledPoint(1, Vectors.dense(1, 1, 0, 0, 0)),
  new LabeledPoint(0, Vectors.dense(1, 0, 0, 0, 0)),
  new LabeledPoint(1, Vectors.dense(1, 1, 0, 0, 0))))

// Compute the top 5 principal components.
val pca = new PCA(5).fit(data.map(_.features))

// Project vectors to the linear space spanned by the top 5 principal
// components, keeping the label
val projected = data.map(p => p.copy(features = pca.transform(p.features)))

七、特徴抽出と変換

TF-IDF

私たちは、あなたがTF-IDF ML・ユーザーズ・ガイドの中で詳述されているデータフレームAPIを使用することをお勧めします。
用語頻度逆文書頻度(TF-IDF)は、量子化方法の特徴は、広く文書コーパスにおける用語の重要性を反映するために、テキストマイニングのために使用されます。トンに代表される項目は、文書がdで表され、コーパスはD.によって表されます 用語頻度TF(T、d)は文書dに出現T用語の数であり、文書頻度DF(T、D)は、用語tを含むデジタル文書です。我々は唯一の周波数の重要性を測定するための用語を使用している場合、それは簡単にそれらの用語を強調過剰にあることが多い文書についてはほとんど情報は、「」、「」および「所属しています。」と、そこにあります 用語は、多くの場合、全体のコーパス中に存在している場合、それは用語は、特定の文書についての具体的な情報が含まれていないことを意味します。逆文書頻度はどのくらいのデジタル情報の尺度を提供するために使用される用語である:
ここに画像を挿入説明
| D |コーパス内のドキュメントの合計数です。対数ので、もしそうであれば全ての用語は、IDF値が0となる文書に現れます。外側本体のゼロ用語によって平滑用語分割の適用を回避するために、ことに留意されたいです。TFとIDFのTF-IDFメトリック単に製品:
ここに画像を挿入説明
用語頻度及び文書頻度の定義はいくつかのバリエーションがあります。spark.mllibでは、我々は柔軟性を持っているTFとIDFを分離します。私たちは、単語の頻度を達成するために、ハッシュ技術を使用しています。元の特性マップインデックス(項目)にハッシュ関数を適用することによって。単語頻度指標は、その後、マッピングに従って計算されます。このアプローチは、大規模コーパスのために高価になることができ、グローバルアイテムインデックス画像、計算する必要性を回避するが、元のハッシュ異なる特徴が同じ用語になるかもしれ後は、ハッシュ衝突の可能性、すなわちを受けます。競合の可能性を減らすために、我々は客観的要因、ハッシュテーブル保存された樽の、すなわち数の次元を追加することができます。2 ^ 20 = 1,048,576のデフォルトの機能のサイズ。
注:spark.mllibは、テキスト分割ツールを提供していません。私たちは、スタンフォードNLPグループへのユーザおよびscalanlp /チョークをお勧めします。
サンプルコード

import org.apache.spark.mllib.feature.{HashingTF, IDF}
import org.apache.spark.mllib.linalg.Vector
import org.apache.spark.rdd.RDD

// Load documents (one per line).
val documents: RDD[Seq[String]] = sc.textFile("data/mllib/kmeans_data.txt")
  .map(_.split(" ").toSeq)

val hashingTF = new HashingTF()
val tf: RDD[Vector] = hashingTF.transform(documents)

// While applying HashingTF only needs a single pass to the data, applying IDF needs two passes:
// First to compute the IDF vector and second to scale the term frequencies by IDF.
tf.cache()
val idf = new IDF().fit(tf)
val tfidf: RDD[Vector] = idf.transform(tf)

// spark.mllib IDF implementation provides an option for ignoring terms which occur in less than
// a minimum number of documents. In such cases, the IDF for these terms is set to 0.
// This feature can be used by passing the minDocFreq value to the IDF constructor.
val idfIgnore = new IDF(minDocFreq = 2).fit(tf)
val tfidfIgnore: RDD[Vector] = idfIgnore.transform(tf)

Word2Vec

Word2Vecワードベクトル表現を計算分散しました。分散表現の主な利点は、ベクトル空間内の単語に似ている新しいモデルの一般化より簡単で信頼性の高いモデルの推定を行っている、非常に近いです。分散型ベクターは、多くの自然言語処理アプリケーションで実証されて表すことは例えば、固有表現認識、一義化、解析、およびマーキング機械翻訳、便利です。
1)モデル
の実装Word2Vecで、我々は、スキップ文法モデルを使用しました。スキップ訓練目標は、文法がよく同じ文の文脈語ベクトル表現を予測することができます学ぶことです。数学的に重量が目的が文法モデルをスキップし、...、トレーニング語の系列は、W2をW1与え、言えば、平均対数尤度最大化することである
ここに画像を挿入説明
サンプルコード
次の例をテキストファイルを読み込む方法を示し、としてそれを解析配列[文字列] RDD、Word2Vec構成例、及びWord2VecModelをフィッティング入力データを使用して。最後に、我々は最初の40の同義語は単語を指定示しています。サンプルを実行するには、まずダウンロードtext8データを喜ばとお好みのディレクトリに展開します。ここでは、抽出されたファイルがtext8であると仮定し、とあなたは同じディレクトリにスパークシェルを実行したとき。

import org.apache.spark.mllib.feature.{Word2Vec, Word2VecModel}

val input = sc.textFile("data/mllib/sample_lda_data.txt").map(line => line.split(" ").toSeq)

val word2vec = new Word2Vec()

val model = word2vec.fit(input)

val synonyms = model.findSynonyms("1", 5)

for((synonym, cosineSimilarity) <- synonyms) {
  println(s"$synonym $cosineSimilarity")
}

// Save and load model
model.save(sc, "myModelPath")
val sameModel = Word2VecModel.load(sc, "myModelPath")

StandardScaler

標本平均の除去に単位分散および/またはトレーニングセットコラム要約統計の使用にスケーリングすることを特徴と正規化します。これは非常に一般的な前処理工程です。
例えば、モデルの線形単位分散、および/またはゼロ平均RBFカーネルSVM又はL1及びL2正則化は、典型的には、すべての機能している場合よりよく働きます。標準化は、最適化プロセスの収束をスピードアップすることができ、あなたは、モデルのトレーニング中にあまりにも多くの影響力を持っている特性の違いの多くを防ぐことができます。
1)モデルフィッティング
StandardScalerは、コンストラクタで、次のパラメータがあります。

  • withMean:デフォルトはFalseです。スケーリングの前に、平均へのデータセンター。注意しなければスパース入力に適用されるとき、それはそう、集中的な出力を生成します。
  • withStd:デフォルトはTrueです。単位標準偏差にスケーリングされたデータ。

我们在StandardScaler中提供了一个拟合方法,该方法可以获取RDD [Vector]的输入,学习汇总统计信息,然后返回一个模型,该模型可以将输入数据集转换为单位标准差和/或零均值特征,具体取决于我们如何配置StandardScaler 。
此模型实现VectorTransformer,可以将标准化应用到Vector上以生成转换后的Vector或在RDD [Vector]上生成转换的RDD [Vector]。
请注意,如果要素的方差为零,它将在向量中返回该要素的默认0.0值。
示例代码

import org.apache.spark.mllib.feature.{StandardScaler, StandardScalerModel}
import org.apache.spark.mllib.linalg.Vectors
import org.apache.spark.mllib.util.MLUtils

val data = MLUtils.loadLibSVMFile(sc, "data/mllib/sample_libsvm_data.txt")

val scaler1 = new StandardScaler().fit(data.map(x => x.features))
val scaler2 = new StandardScaler(withMean = true, withStd = true).fit(data.map(x => x.features))
// scaler3 is an identical model to scaler2, and will produce identical transformations
val scaler3 = new StandardScalerModel(scaler2.std, scaler2.mean)

// data1 will be unit variance.
val data1 = data.map(x => (x.label, scaler1.transform(x.features)))

// data2 will be unit variance and zero mean.
val data2 = data.map(x => (x.label, scaler2.transform(Vectors.dense(x.features.toArray))))

Normalizer

归一化器将单个样本缩放为单位Lp范数。这是文本分类或聚类的常用操作。例如,两个L2归一化TF-IDF向量的点积是向量的余弦相似度。
规范化器在构造函数中具有以下参数:

  • p Lp空间中的归一化,默认情况下p = 2。

规范化器实现了VectorTransformer,可以将规范化应用到Vector上以生成转换后的Vector或在RDD [Vector]上生成转换后的RDD [Vector]。
请注意,如果输入范数为零,则它将返回输入向量。
示例代码

import org.apache.spark.mllib.feature.Normalizer
import org.apache.spark.mllib.util.MLUtils

val data = MLUtils.loadLibSVMFile(sc, "data/mllib/sample_libsvm_data.txt")

val normalizer1 = new Normalizer()
val normalizer2 = new Normalizer(p = Double.PositiveInfinity)

// Each sample in data1 will be normalized using $L^2$ norm.
val data1 = data.map(x => (x.label, normalizer1.transform(x.features)))

// Each sample in data2 will be normalized using $L^\infty$ norm.
val data2 = data.map(x => (x.label, normalizer2.transform(x.features)))

ChiSqSelector

特征选择试图识别用于模型构建的相关特征。它减小了特征空间的大小,从而可以提高速度和统计学习行为。
ChiSqSelector实现Chi-Squared特征选择。它对具有分类特征的标记数据进行操作。 ChiSqSelector使用卡方独立性检验来决定选择哪些功能。它支持五种选择方法:numTopFeatures,percentile,fpr,fdr,fwe:

  • numTopFeatures 根据卡方检验选择固定数量的顶部特征。这类似于产生具有最大预测能力的特征。
  • percentile 与numTopFeatures相似,但是选择所有功能的一部分而不是固定数量。
  • fpr 选择p值低于阈值的所有特征,从而控制选择的误报率。
  • fdr 使用Benjamini-Hochberg过程选择错误发现率低于阈值的所有特征。
  • fwe 选择p值低于阈值的所有特征。阈值按1 / numFeatures缩放,从而控制族的选择错误率。

默认情况下,选择方法为numTopFeatures,顶部要素的默认数量设置为50。用户可以使用setSelectorType选择选择方法。可以使用保留的验证集来调整要选择的功能的数量。
1)模型拟合
fit方法采用具有分类特征的RDD [LabeledPoint]输入,学习摘要统计信息,然后返回ChiSqSelectorModel,它可以将输入数据集转换为精简特征空间。 ChiSqSelectorModel既可以应用于向量以生成简化的矢量,也可以应用于RDD [Vector]以生成简化的RDD [Vector]。
请注意,用户还可以通过提供一组选定要素索引(必须按升序排序)来手动构建ChiSqSelectorModel。
code example

import org.apache.spark.mllib.feature.ChiSqSelector
import org.apache.spark.mllib.linalg.Vectors
import org.apache.spark.mllib.regression.LabeledPoint
import org.apache.spark.mllib.util.MLUtils

// Load some data in libsvm format
val data = MLUtils.loadLibSVMFile(sc, "data/mllib/sample_libsvm_data.txt")
// Discretize data in 16 equal bins since ChiSqSelector requires categorical features
// Even though features are doubles, the ChiSqSelector treats each unique value as a category
val discretizedData = data.map { lp =>
  LabeledPoint(lp.label, Vectors.dense(lp.features.toArray.map { x => (x / 16).floor }))
}
// Create ChiSqSelector that will select top 50 of 692 features
val selector = new ChiSqSelector(50)
// Create ChiSqSelector model (selecting features)
val transformer = selector.fit(discretizedData)
// Filter the top 50 features from each feature vector
val filteredData = discretizedData.map { lp =>
  LabeledPoint(lp.label, transformer.transform(lp.features))
}

ElementwiseProduct

ElementwiseProduct使用逐元素乘法将每个输入向量乘以提供的“权重”向量。换句话说,它通过标量乘法器缩放数据集的每一列。这表示输入向量v和转换向量scaleVec之间的Hadamard乘积,以产生结果向量。
将scalingVec表示为“ w”,此转换可以写为:
ここに画像を挿入説明
ElementwiseProduct在构造函数中具有以下参数:

  • scalingVec: 转换向量

VectorTransformerを達成ElementwiseProduct、ベクトルベクトルはRDDはRDD [ベクター]の[ベクター]変換変換または生成量生成に適用されてもよいです。

import org.apache.spark.mllib.feature.ElementwiseProduct
import org.apache.spark.mllib.linalg.Vectors

// Create some vector data; also works for sparse vectors
val data = sc.parallelize(Array(Vectors.dense(1.0, 2.0, 3.0), Vectors.dense(4.0, 5.0, 6.0)))

val transformingVector = Vectors.dense(0.0, 1.0, 2.0)
val transformer = new ElementwiseProduct(transformingVector)

// Batch transform and per-row transform give the same results:
val transformedData = transformer.transform(data)
val transformedData2 = data.map(x => transformer.transform(x))

PCA

コンバータの低次元空間への投影特徴ベクトルにPCAを使用します。あなたは、次元削減の時に詳細情報を読むことができます。
コード例

import org.apache.spark.mllib.feature.PCA
import org.apache.spark.mllib.linalg.Vectors
import org.apache.spark.mllib.regression.{LabeledPoint, LinearRegressionWithSGD}

val data = sc.textFile("data/mllib/ridge-data/lpsa.data").map { line =>
  val parts = line.split(',')
  LabeledPoint(parts(0).toDouble, Vectors.dense(parts(1).split(' ').map(_.toDouble)))
}.cache()

val splits = data.randomSplit(Array(0.6, 0.4), seed = 11L)
val training = splits(0).cache()
val test = splits(1)

val pca = new PCA(training.first().features.size / 2).fit(data.map(_.features))
val training_pca = training.map(p => p.copy(features = pca.transform(p.features)))
val test_pca = test.map(p => p.copy(features = pca.transform(p.features)))

val numIterations = 100
val model = LinearRegressionWithSGD.train(training, numIterations)
val model_pca = LinearRegressionWithSGD.train(training_pca, numIterations)

val valuesAndPreds = test.map { point =>
  val score = model.predict(point.features)
  (score, point.label)
}

val valuesAndPreds_pca = test_pca.map { point =>
  val score = model_pca.predict(point.features)
  (score, point.label)
}

val MSE = valuesAndPreds.map { case (v, p) => math.pow((v - p), 2) }.mean()
val MSE_pca = valuesAndPreds_pca.map { case (v, p) => math.pow((v - p), 2) }.mean()

println(s"Mean Squared Error = $MSE")
println(s"PCA Mean Squared Error = $MSE_pca")
リリース元の2件の記事 ウォンの賞賛0 ビュー626

おすすめ

転載: blog.csdn.net/pt798633929/article/details/103850213