2017-05-17 1 views
0

私はScala-Sparkで初めてですが、私はこれで最終プロジェクトの学士号を開発する必要があります。RDD [Row] .map内のgetIntが "error:value getIntはAnyのメンバーではありません"と表示されるのはなぜですか?

私はK平均アルゴリズムを構築するためのデータから試しています。 データはkaggleからです:https://www.kaggle.com/murderaccountability/homicide-reports

私はデータを使ってファイルを読みました。 ケースクラスを次のように作成します。

case class CrimeReport (Record_ID: String, Agency_Name: String, 
City: String, State: String, Year: Int, Month: Int, Crime_Type: String, 
Crime_Solved: String, Victim_Sex: String, Victim_Age: Int, Victim_Race: String, 
Perpetrator_Sex: String, Perpetrator_Age: String, Perpetrator_Race: String, Relationship: String, Victim_Count: String) 

データをケースクラスにマップします。例えば、月は文字列であり、私はこの解析する関数を定義するのIntを(私の特徴ベクトルの後に作成する)必要がある、として:

//Parsear Month: String ===> Int 
    def parseMonthToNumber(month: String) : Int = { 
     var result = 0 
     month match { 
      case "January" => result = 1 
      case "February" => result = 2 
      case "March" => result = 3 
      case "April" => result = 4 
      case "May" => result = 5 
      case "June" => result = 6 
      case "July" => result = 7 
      case "August" => result = 8 
      case "September" => result = 9 
      case "October" => result = 10 
      case "November" => result = 11 
      case _ => result = 12 
     } 
     result 
    } 

    data = sc.textFile (... .csv) 
    val data_split = data.map(line => line.split(",")) 

    val allData = data_split.map(p => CrimeReport(p(0).toString, 
    p(1).toString, p(2).toString, p(3).toString, parseInt(p(4)), 
    parseMonthToNumber(p(5)), p(6).toString, p(7).toString, p(8).toString, 
    parseInt(p(9)), p(10).toString, p(11).toString, p(12).toString, 
    p(13).toString, p(14).toString, p(15).toString)) 
//DataFrame 
val allDF = allData.toDF() 

//convert data to RDD which will be passed to KMeans 
val rowsRDD = allDF.rdd.map(x => 

       (x(0).getString, x.getString(1), x.getString(2), x.getString(3), x(4).getInt, x(5).getInt, x.getString(6), x.getString(7), x.getString(8), x(9).getInt, x.getString(10), x.getString(11), x.getString(12), x.getString(13), x.getString(14), x.getString(15)) 
       ) 

をしかし、私はこのエラーを取得する:

error: value getInt is not a member of Any 
         (x(0).getString, x.getString(1), x.getString(2), x.getString(3), x(4).getInt, x(5).getInt, x.getString(6), x.getString(7), x.getString(8), x(9).getInt, x.getString(10), x.getString(11), x.getString(12), x.getString(13), x.getString(14), x.getString(15)) 
                             ^

なぜ?

答えて

2

Spark 2.1.1の最新バージョンを想定しています。

DataFrame-based KMeans implementation in Sparkがあるため、DataFrameをRDD[Row]に変換してKMeansを実行する理由について質問してみましょう。

KMeans in Spark MLlibを読んでください。私はSpark MLlib's RDD-based API is deprecatedので、これをしないだろう

:それと

This page documents sections of the MLlib guide for the RDD-based API (the spark.mllib package). Please see the MLlib Main Guide for the DataFrame-based API (the spark.ml package), which is now the primary API for MLlib.


は、あなたが直面しているどのような問題を見てみましょう、と述べました。

私があなただっ(とMLlibのデータフレームベースのAPIをスパークするために固執するアドバイスを無視)した場合、私は、次の操作を行いたい:ずっとあるDataset[CrimeReport]を持っていると思います上記で

を純粋なよりも仕事が楽しいです。

あなたが変換を行ってきた後、あなたはxがあなたのタイプCrimeReportのものであり、あなたはそれをどうするか知っているだろうと確信して

val rowsRDD = allDF.rdd.map { x => ... } 

を行うことができます。


直接あなたの質問に答えるために、エラーの原因:

​​

x(5)(と他の人が)タイプAnyであるので、あなたは自分の型にキャストする必要があるか、単にx(5)を交換することですx.getInt(5)となります。

スカラドックRowを参照してください。

+1

感謝そんなに! :)あなたの助けを借りて、私はどこでエラーが発生したかを知ることができました。 2つありました。まず、DataFrameをDataSetに置き換えます。もう一つはval rowsRDD = allDF.rdd.map {x => ...}にありました。私は列の名前で属性を呼び出す必要がありました。つまり、私のケースクラスで定義した名前で呼び出しを行いました。 no(x(5)、x(6)、...)のような位置はありません。 – Borja

0

caseクラスのdouble型ではなくString型のデータ型を扱うときに、kmeansを使用するにはどうすればよいですか?私が持っているこのコードは、vectorがdoubleを期待しているので動作しません。

// Passing in Crime_Type, Crime_Solved, Perpetrator_Race to KMeans as 
the attributes we want to use to assign the instance to a cluster. 

val vectors = allDF.rdd.map(r => Vectors.dense(r.Crime_Type, r.Crime_Solved, r.Perpetrator_Race)) 

//KMeans model with 2 clusters and 10 iterations 

val kMeansModel = KMeans.train(vectors, 2, 10) 
+0

私は新しい形式であなたに答えるだけで、形式をはっきりと見ることができました。 – Borja

0

あなたはメソッドVector.denseに使いたいint型/ダブル属性として定義する必要があります。

その後、ファイル内のデータを使用してケースクラスをマッピングするときは、前に定義した関数を呼び出す必要があります。あなたがここに見ることができるように:

val data_split = data.map(line => line.split(",")) 

val allData = data_split.map(p => 
           CrimeReport(p(0).toString, p(1).toString, p(2).toString, p(3).toString, parseInt(p(4)), parseMonthToNumber(p(5)), p(6).toString, parseSolved(p(7)), parseSex(p(8)), parseInt(p(9)), parseRaceToNumber(p(10)), p(11).toString, p(12).toString, p(13).toString, p(14).toString, p(15).toString)) 

アンの機能は以下のとおりです。

//Filter and Cleaning data  => Crime Solved 
def parseSolved (solved: String): Int = { 
    var result = 0 
    solved match { 
     case "Yes" => result = 1 
     case _ => result = 0 
    } 
    result 
} 

または:

//Parsear Victim_Race: String ===> Int 
def parseRaceToNumber (crType : String) : Int = { 
    var result = 0 
    val race = crType.split("/") 
    race(0) match { 
     case "White" => result = 1 
     case "Black" => result = 2 
     case "Asian" => result = 3 
     case "Native American" => result = 4 
     case _ => result = 0 
    } 
    result 
} 
関連する問題