복붙노트

[SCALA] 멀티 클래스 분류 예 불꽃

SCALA

멀티 클래스 분류 예 불꽃

너희들은 내가 스파크에서 멀티 클래스 분류의 예를 찾을 수있는 위치를 알고있다. 나는 책과 웹에서 시간 검색을 많이 소비하고, 지금까지 난 그냥 최신 버전의 문서를 따라하기 때문에 그것이 가능하다는 것을 알고있다.

해결법

  1. ==============================

    1.ML

    ML

    (2.0 스파크에 권장)

    우리는 아래의 MLlib에서와 동일한 데이터를 사용합니다. 두 가지 기본 옵션이 있습니다. 견적이 multilclass 분류를 지원하는 경우 아웃 오브 더 박스 (예 : 임의 숲에 대한) 당신은 그것을 직접 사용할 수 있습니다 :

    val trainRawDf = trainRaw.toDF
    
    import org.apache.spark.ml.feature.{Tokenizer, CountVectorizer, StringIndexer}
    import org.apache.spark.ml.Pipeline
    
    import org.apache.spark.ml.classification.RandomForestClassifier
    
    val transformers = Array(
      new StringIndexer().setInputCol("group").setOutputCol("label"),
      new Tokenizer().setInputCol("text").setOutputCol("tokens"),
      new CountVectorizer().setInputCol("tokens").setOutputCol("features")
    )
    
    
    val rf = new RandomForestClassifier() 
      .setLabelCol("label")
      .setFeaturesCol("features")
    
    val model = new Pipeline().setStages(transformers :+ rf).fit(trainRawDf)
    
    model.transform(trainRawDf)
    

    모델 지원 이진 분류 (로지스틱 회귀) 및 o.a.s.ml.classification.Classifier를 확장하는 경우는 한 대 받침대 전략을 사용할 수 있습니다 :

    import org.apache.spark.ml.classification.OneVsRest
    import org.apache.spark.ml.classification.LogisticRegression
    
    val lr = new LogisticRegression() 
      .setLabelCol("label")
      .setFeaturesCol("features")
    
    val ovr = new OneVsRest().setClassifier(lr)
    
    val ovrModel = new Pipeline().setStages(transformers :+ ovr).fit(trainRawDf)
    

    MLLib

    이 순간 (MLlib 1.6.0)의 공식 문서에 따르면 다음과 같은 방법은 멀티 클래스 분류를 지원합니다

    적어도 예제 중 일부는 멀티 클래스 분류를 사용 :

    일반 프레임 워크는 방법의 특정 인수를 무시하고, 거의 MLlib의 다른 모든 방법과 동일합니다. 당신은 라벨과 기능을 나타내는 열 중 하나의 데이터 프레임을 만들-사전 처리 입력을해야합니다 :

    root
     |-- label: double (nullable = true)
     |-- features: vector (nullable = true)
    

    또는 EET [LabeledPoint].

    스파크는 특징 추출기 및 기능 변압기 및 파이프 라인을 포함하여이 과정을 촉진하기위한 유용한 도구의 넓은 범위를 제공합니다.

    당신은 아래 임의의 숲을 사용하는 다소 순진 예를 찾을 수 있습니다.

    먼저 가져 오기 패키지를 요구하고 더미 데이터를 생성 할 수 있습니다 :

    import sqlContext.implicits._
    import org.apache.spark.ml.feature.{HashingTF, Tokenizer} 
    import org.apache.spark.mllib.regression.LabeledPoint
    import org.apache.spark.ml.feature.StringIndexer
    import org.apache.spark.mllib.tree.RandomForest
    import org.apache.spark.mllib.tree.model.RandomForestModel
    import org.apache.spark.mllib.linalg.{Vectors, Vector}
    import org.apache.spark.mllib.evaluation.MulticlassMetrics
    import org.apache.spark.sql.Row
    import org.apache.spark.rdd.RDD
    
    case class LabeledRecord(group: String, text: String)
    
    val trainRaw = sc.parallelize(
        LabeledRecord("foo", "foo v a y b  foo") ::
        LabeledRecord("bar", "x bar y bar v") ::
        LabeledRecord("bar", "x a y bar z") ::
        LabeledRecord("foobar", "foo v b bar z") ::
        LabeledRecord("foo", "foo x") ::
        LabeledRecord("foobar", "z y x foo a b bar v") ::
        Nil
    )
    

    이제 필요한 변압기 및 공정 기차 데이터 집합을 정의 할 수 있습니다 :

    // Tokenizer to process text fields
    val tokenizer = new Tokenizer()
        .setInputCol("text")
        .setOutputCol("words")
    
    // HashingTF to convert tokens to the feature vector
    val hashingTF = new HashingTF()
        .setInputCol("words")
        .setOutputCol("features")
        .setNumFeatures(10)
    
    // Indexer to convert String labels to Double
    val indexer = new StringIndexer()
        .setInputCol("group")
        .setOutputCol("label")
        .fit(trainRaw.toDF)
    
    
    def transfom(rdd: RDD[LabeledRecord]) = {
        val tokenized = tokenizer.transform(rdd.toDF)
        val hashed = hashingTF.transform(tokenized)
        val indexed = indexer.transform(hashed)
        indexed
            .select($"label", $"features")
            .map{case Row(label: Double, features: Vector) =>
                LabeledPoint(label, features)}
    }
    
    val train: RDD[LabeledPoint] = transfom(trainRaw)
    

    그 인덱서가 기차 데이터에 "적합"되어 있습니다. 그것은 단순히 레이블로 사용 범주 값이 더블로 변환하는 것을 의미한다. 먼저이 인덱서를 사용하여 변환 당신이 새로운 데이터에 대한 분류를 사용합니다.

    우리는 RF 모델을 훈련 할 수 다음 :

    val numClasses = 3
    val categoricalFeaturesInfo = Map[Int, Int]()
    val numTrees = 10
    val featureSubsetStrategy = "auto"
    val impurity = "gini"
    val maxDepth = 4
    val maxBins = 16
    
    val model = RandomForest.trainClassifier(
        train, numClasses, categoricalFeaturesInfo, 
        numTrees, featureSubsetStrategy, impurity,
        maxDepth, maxBins
    )
    

    마지막으로 테스트 :

    val testRaw = sc.parallelize(
        LabeledRecord("foo", "foo  foo z z z") ::
        LabeledRecord("bar", "z bar y y v") ::
        LabeledRecord("bar", "a a  bar a z") ::
        LabeledRecord("foobar", "foo v b bar z") ::
        LabeledRecord("foobar", "a foo a bar") ::
        Nil
    )
    
    val test: RDD[LabeledPoint] = transfom(testRaw)
    
    val predsAndLabs = test.map(lp => (model.predict(lp.features), lp.label))
    val metrics = new MulticlassMetrics(predsAndLabs)
    
    metrics.precision
    metrics.recall
    
  2. ==============================

    2.당신은 오히려 스파크 2.1보다 스파크 1.6를 사용하고 있습니까? I 문제가 스파크 2.1 메소드 리턴 내재적 그 이전과 같이,이 데이터 프레임 또는 행을 반환하는 입력 RDD로 변환 될 수있는 데이터 세트를 변환하는 것이 생각.

    당신은 오히려 스파크 2.1보다 스파크 1.6를 사용하고 있습니까? I 문제가 스파크 2.1 메소드 리턴 내재적 그 이전과 같이,이 데이터 프레임 또는 행을 반환하는 입력 RDD로 변환 될 수있는 데이터 세트를 변환하는 것이 생각.

    RDD [LabeledPoint]로 변환 함수의 반환 형식을 지정하는 진단으로 시도하고 같은 오류가 있는지 확인합니다.

  3. from https://stackoverflow.com/questions/32029314/spark-multiclass-classification-example by cc-by-sa and MIT license