ALS行列因数分解
スコアリング行列Aは、多くの場合、近似の人の好みを記述している抽象と二つの小さな行列の積を持つ低次元空間上で実行することができ、それが記載されているお気に入りである必要はありません。次に抽象的に、人の好みや映画の特徴は、低次元空間に投資されている、人の好みは、低次元のベクトル、ベクターへの同じ緯度の長編映画にマッピングされ、この映画の後、人々類似性は、2つのベクトル間の積として表すことができます。
我々は、次に、 "スコアリング行列A(M×n個)の" "ユーザ選好特性行列U(m個* kの)"および製品"製品機能行列V(N * K)"とすることができる、類似性スコアを理解しました。
クロス最小二乗法(代替的最小二乗)と確率的勾配降下法(確率的勾配降下法)の2つのカテゴリに分解プロセスにおいて使用されるマトリックスの最適化。
損失関数は正則化項(setRegParam)を備えます。
パラメータ選択
ブロック番号:並列コンピューティングのためのブロッキング、デフォルトは10です。正則化パラメータ:デフォルトは1です。ランク:隠された情報の表示設定が-false因子のモデル番号、暗黙的嗜好情報-true、偽(ディスプレイ)アルファデフォルト:のみ暗黙嗜好データ、ベースラインの信頼性優先値。非負定義さnumBlocksユーザーとアイテムがされるブロックの数であり、
計算(デフォルトは並列化するために、INTOをパーティション
10)。ランクがモデルにおける潜在的要因(10デフォルトは)の数です。MaxIter可能での最大数です(10デフォルト)を実行するための反復。regparamは、ALS(1.0デフォルト)に正則化パラメータを指定します。implicitPrefsは、明示的なフィードバックALS変異体または暗黙のフィードバックデータ(へのデフォルトはfalseのために適合された1つを使用するかどうかを指定します
使用して明示的なフィードバックを意味します)。アルファは、暗黙的に適用可能なパラメータである嗜好のベースラインの信頼を支配ALSのフィードバック変異
観測(1.0デフォルト)。非負最小二乗(デフォルトはfalse)用の非負制約を使用するかどうかを指定します。
ALSは、ALS = 新しい新しいALS() .setMaxIter( 10)// 反復の最大数を、セットには、あまりにもjava.lang.StackOverflowErrorを発生 .setRegParam(0.16)// 正則化パラメータ .setAlpha(1.0 ) .setImplicitPrefs(falseに) .setNonnegative(偽の) .setNumBlocks( 10 ) .setRank( 10 ) .setUserCol( "はuserId" ) .setItemCol( "MOVIEID" ) .setRatingCol( "評価")。
:問題があることに注意してください
ユーザーと記事アイテムID、ベースのデータフレームのAPIは、整数で定義された範囲の最大値を整数のみをサポートしています。
ALSのためのデータフレームベースのAPIは、現在だけのための整数サポートし
、ユーザとアイテムのIDを。他の数値型は、ユーザとのためにサポートされている
アイテムIDの列が、IDSは、整数値の範囲内でなければなりません。
// ループ正則化パラメータは、各評価者RMSErrorによって与えられた リストRMSE = 新しい新しいのArrayList(); //は、すべてのRMSE保存リストを構築 するために(int型 {;;私は20 <I ++はI = 0)// 20回ループ ダブルラムダ=(I * + 1.5)* 0.01; // に従ってregparam 0.05増加 ALS ALS = 新しい新しいALS() .setMaxIter( 5)// 最大反復回数 .setRegParam(ラムダ)// 正則化パラメータ .setUserCol( "はuserId" ) .setItemCol( "MOVIEID" ) .setRatingCol( "評価" ); ALSModelモデル= als.fit(トレーニング)。 // テストデータにRMSEを計算することによってモデルを評価する データセットの予測= model.transform(テスト)。 // RegressionEvaluator.setMetricName可以定义四种评估器 // "RMSE"(デフォルト):根平均二乗誤差 // "MSE":平均は、二乗誤差 // R ^ 2 ^メトリック: "R2" // "メイ"を:絶対誤差の平均 RegressionEvaluator評価= 新しい()RegressionEvaluatorを .setMetricName( "RMSE")// RMSエラー .setLabelCol( "評価" .setPredictionCol( "予測" )。 ダブルRMSE = evaluator.evaluate(予測)。 RMSE.add(RMSE)。 System.out.println( "RegParam "+ 0.01 * I +" RMSE" + RMSE + "\ n"は); } // 输出所有结果 ため(INT J = 0; J <RMSE.size(); J ++ ){ ダブルラムダ =(J * 5 + 1)* 0.01 。 System.out.println( "RegParam = "+ラムダ+" RMSE =" + RMSE.get(J)+ "\ n" ); }
ループを設計することにより、最適なパラメータを研究することができる、いくつかの結果を次のように RMSEをregparam = 1.956 = 0.01 regparam RMSE = 1.166 = 0.06 regparam RMSE = 0.977 = 0.11 regparam RMSE = 0.962 = 0.16 //はRMSEの最小値、最も適切なパラメータを含みます RMSE = 0.985 = 0.21 regparamの regparam RMSE = 1.021 = 0.26 regparam RMSE = 1.061 = 0.31 regparam RMSE = 1.102 = 0.36 regparam RMSE = 1.144 = 0.41 regparam RMSE = 1.228 = 0.51 regparam RMSE = 1.267 = 0.56 regparam RMSE = 1.300 = 0.61 // 0.16に固定RegParamは、反復回数が与える影響の研究を続けて スタンドアロン環境での次の出力結果を、反復数が多すぎる、java.lang.StackOverflowErrorを例外が存在します。現在のスレッドのスタックによるものがいっぱいです。 RMSE = 1.7325。1 = numMaxIteration numMaxIteration RMSE = 1.0695。4 = numMaxIteration。7 RMSE = 1.0563 = numMaxIteration = 10 RMSE = 1.055 numMaxIteration = 13 RMSE = 1.053 numMaxIteration = 16 RMSE = 1.053 //测试ランク隐含语义个数 ランク= 1 RMSErr = 1.1584 ランク= 3 RMSErr = 1.1067 ランク= 5 RMSErr = 0.9366 ランク= 7 RMSErr = 0.9745 ランク= 9 RMSErr = 0.9440 ランク= 11 RMSErr = 0.9458 ランク= 13 RMSErr = 0.9466 ランク= 15 RMSErr = 0.9443 ランク= 17 RMSErr = 0.9543
//は、(平均絶対誤差演算処理して、以下に定義されるように)自分のSPARK-SQLの評価アルゴリズムを定義することができます // 登録ザ・DATAFRAME一時ビューAS SQL predictions.createOrReplaceTempView(「tmp_predictionsを」); データセットabsDiff = spark.sql( "AS差分tmp_predictionsからABS(予測評価)を選択" ); absDiff.createOrReplaceTempView( "tmp_absDiff" ); spark.sql( "平均(差分SELECT)tmp_absDiff absMeanDiff ASから")を表示();
完全なコード
パブリッククラス評価はSerializable {...}が実装 http://spark.apache.org/docs/latest/ml-collaborative-filtering.htmlで見つけることができます:
パッケージmy.spark.ml.practice.classification。 輸入org.apache.spark.api.java.function.Function。 輸入org.apache.spark.ml.evaluation.RegressionEvaluator。 輸入org.apache.spark.ml.recommendation.ALS。 輸入org.apache.spark.ml.recommendation.ALSModel。 輸入org.apache.log4j.Level。 輸入org.apache.log4j.Logger。 輸入org.apache.spark.api.java.JavaRDD; 輸入org.apache.spark.sql.Dataset; 輸入org.apache.spark.sql.Row。 輸入org.apache.spark.sql.SparkSession。 パブリック クラスmyCollabFilter2 { 公共 静的 ボイドメイン(文字列[]引数){ SparkSessionスパーク = SparkSession .builder() .appName( "CoFilter" ) 管理組織のビー玉( "ローカル[4]" ) の.config( "spark.sql.warehouse.dir"、「ファイル///:G:/プロジェクト/ジャワ/スパーク/スパーク倉庫」) .getOrCreate(); ストリングパス = "G:/Projects/CgyWin64/home/pengjy3/softwate/spark-2.0.0-bin-hadoop2.6/" + "データ/ mllib / ALS / sample_movielens_ratings.txt" 。 // 屏蔽日志 Logger.getLogger( "org.apache。).setLevel(Level.WARN); Logger.getLogger( "org.eclipse.jetty.server" ).setLevel(Level.OFF); // ----------------- 1.0 ---------------------------- --------------準備DATAFRAME // ..javaRDDデータフレームRDD変換する()関数 // [マップRDD各行のストリング]>評価 JavaRDD ratingRDD = spark.read()。テキストファイル(パス).javaRDD() .MAP(新しい新しい関数(){ @Override 公共の評価コール(文字列STR)をスロー例外{ 戻りRating.parseRating(STR)を; } )}。 // のSystem.out.println(ratingRDD.take(10)に.get(0).getMovieId()); // データフレームを作成JavaRDD(各行はインスタンス化されたオブジェクトの評価)で評価し、クラス データセット= spark.createDataFrame評価(ratingRDD、採点クラス); // ratings.show(30); // データをランダムに訓練および試験に分けた設定 ダブル [] =重みを新しい新しい ダブル [] {0.8、0.2 }; ロング = 1234 SEED ; データセット[]スプリット = ratings.randomSplit(重み、SEED); データセットトレーニング =スプリット[0 ]; データセットテスト =分割[1 ]; //------------------------------ 2.0 ALSアルゴリズムおよび推奨モデルを生成するために、トレーニングデータセット--------- ---- ため(INTランク= 1;ランクは<20であり、ランク++ ) { // アルゴリズムが定義 ALS ALS = 新しい新しいALS() .setMaxIter( 5)//// 反復の最大数を設定もjava.langで起こります。 StackOverflowErrorが .setRegParam(0.16 ) .setUserCol( "userIdを" ) .setRank(ランク) .setItemCol( "MOVIEID" ) .setRatingCol( "評価" ); //训练模型 ALSModelモデル= als.fit(トレーニング)。 // --------------------------- 3.0模型评估:计算RMSE、均方根误差---------- ----------- データセットの予測= model.transform(テスト)。 // predictions.show(); RegressionEvaluator評価= 新しいRegressionEvaluator() .setMetricName( "RMSE" ) .setLabelCol( "評価" ) .setPredictionCol( "予測" ); ダブルRMSE = evaluator.evaluate(予測)。 System.out.printlnは("ランク=" +ランク+ "RMSErr =" + RMSE)。 } } }