Weitere ähnliche Inhalte
Ähnlich wie AI入門「第2回:Scala/Spark/Mahoutでレコメンドエンジンを作る」 (20)
AI入門「第2回:Scala/Spark/Mahoutでレコメンドエンジンを作る」
- 15. 「おすすめ」を ”機械学習” で自動生成
• 商品属性相関
(こんなもの買った人は、
こんなもの買ってま
す)
• 顧客属性相関
(あなたに似た人は
こんなもの買ってま
す)
• 売上ランキング
などなど
レコメンド情報
(機械学習で生成)
エンドユーザー
- 25. 通常ScalaコードとSparkコードの差
val file = scala.io.Source.fromFile( "/tmp/log.txt" )
val lines = file.getLines
val error = lines.filter( _.contains( "ERROR" ) ).size
通常のScalaコードを書くのと、ほぼ変わら
ないコードで、複数クラスタでの分散処理
が実現されてしまうのが、Sparkの凄さ
通常のScalaコード
val lines = sc.textFile( "/tmp/log.txt" )
val error = lines.filter( _.contains( "ERROR" ) ).count
Spark呼出を利用したScalaコード(裏では、複数のクラスタに分散されている)
Spark 2.x系 (初回リリースは2016/7/26) だとメソッド
セットが変わる (RDD※/DataFrameもDatasetに変更)
※Resilient Distributed Dataset: 不変で並列実行可能な分割コレクション
- 31. ScalaからSpark呼出で商品別集計
2017-06-01T00:00:27Z activities.xxxxxxxxxx
{"ts":1496275227402,"account":"xxxxxxxxxx","vt":"wKPoI.lNwXiTH","cid":"","ctype":"1","act_type":"bdr_detail","act_params":[{"product_id":"HNHYA-367693-
04"}]}
2017-06-01T00:00:57Z activities.xxxxxxxxxx
{"ts":1496275257338,"account":"xxxxxxxxxx","vt":"16fHvG.lMYDCZ7","cid":"","ctype":"1","act_type":"bdr_detail","act_params":[{"product_id":"HNKYA-364957-
04"}]}
2017-06-01T00:01:48Z activities.xxxxxxxxxx
{"ts":1496275308434,"account":"xxxxxxxxxx","vt":"3%2BsMkQ.lN4P72N","cid":"","ctype":"1","act_type":"bdr_detail","act_params":[{"product_id":"HNRYB-
360844-04"}]}
2017-06-01T00:02:52Z activities.xxxxxxxxxx
{"ts":1496275372269,"account":"xxxxxxxxxx","vt":"6TxF1.lLWEepM","cid":"","ctype":"1","act_type":"bdr_detail","act_params":[{"product_id":"HNHJB-357844-
03"}]}
2017-06-01T00:03:45Z activities.xxxxxxxxxx
{"ts":1496275425990,"account":"xxxxxxxxxx","vt":"Y9hcv.lFgztJ0","cid":"","ctype":"1","act_type":"bdr_detail","act_params":[{"product_id":"FKMYA-368333-
03"}]}
2017-06-01T00:05:14Z activities.xxxxxxxxxx
{"ts":1496275514546,"account":"xxxxxxxxxx","vt":"1jrjda.lNhpu8E","cid":"","ctype":"1","act_type":"bdr_detail","act_params":[{"product_id":"OSHGF-363474-
02"}]}
2017-06-01T00:05:24Z activities.xxxxxxxxxx {"ts":1496275524952,"account":"xxxxxxxxxx","vt":"3%2525252525252525252520il-
g.lzgfvlh","cid":"","ctype":"1","act_type":"bdr_detail","act_params":[{"product_id":"CTRJA-362952-05"}]}
2017-06-01T00:06:43Z activities.xxxxxxxxxx
{"ts":1496275603657,"account":"xxxxxxxxxx","vt":"2LXKDi.lBqDjmb","cid":"","ctype":"1","act_type":"bdr_detail","act_params":[{"product_id":"CTJJK-265962-
03"}]}
2017-06-01T00:07:36Z activities.xxxxxxxxxx
{"ts":1496275656723,"account":"xxxxxxxxxx","vt":"6TxF1.lLWEepM","cid":"","ctype":"1","act_type":"bdr_detail","act_params":[{"product_id":"HNHJB-357841-
03"}]}
2017-06-01T00:08:10Z activities.xxxxxxxxxx
{"ts":1496275690808,"account":"xxxxxxxxxx","vt":"28Y4OC.lwdLlM4","cid":"","ctype":"1","act_type":"bdr_detail","act_params":[{"product_id":"FUJJK-368890-
03"}]}
…
商品IDとユーザIDの入ったユーザ行動
(Webアクセス)ログを商品別に集計する
※集計後のデータは、公開控えさせてください
- 32. ScalaからSpark呼出で商品別集計
// Sparkの初期化
val conf = new SparkConf().setAppName( "mario-opt-mapred/ActivitiesItemCorrCalculation" )
conf.set( "spark.hadoop.validateOutputSpecs", "false" )
val sc = new SparkContext( conf )
val hadoopConf = sc.hadoopConfiguration
hadoopConf.set( "fs.s3a.impl", "org.apache.hadoop.fs.s3native.NativeS3FileSystem" )
hadoopConf.set( "fs.s3a.awsAccessKeyId", configs.getOrElse( "AWS_ACCESS_KEY_ID", "" ) )
hadoopConf.set( "fs.s3a.awsSecretAccessKey", configs.getOrElse( "AWS_SECRET_ACCESS_KEY", "" ) )
…
// 入力ファイルからRDDを作り集計
val inputAct = sc.textFile( actFile )
q.sourceAggregateType match {
case SOURCE_AGGREGATE_TYPE_COUNT =>
val rddAct = inputAct.filter( x => x.nonEmpty && x.contains( schemaName ) ).map { x =>
val json = gson.fromJson[ AggregateBehavior ]( x, classOf[ AggregateBehavior ] )
val id = if ( json.params.get( q.sourceAttribute ) != null && json.params.get( q.sourceAttribute ).length > 128 )
json.params.get( q.sourceAttribute ).substring( 0, 128 ) else json.params.get( q.sourceAttribute )
( id, ( json.vt.hashCode, json.count ) )
}.filter( x => x._1 != null && x._1.nonempty )
val rddActAndItem = rddAct.join( rddItem )
val csv = rddActAndItem.map( x => { Array( x._2._1._1, x._2._2, x._2._1._2 ).mkString( "," ) } )
csv.repartition( 1 ).saveAsTextFile( outputFile )
Sparkを呼び出すバッチをScalaで作成
- 35. Mahoutで商品閲覧の相関を計算
3 69 0.9577542080518994
3 482 0.9091600912310319
3 601 0.8981679030325392
3 909 0.9038946377087511
3 1161 0.9474190693417451
3 1532 0.9026751528181597
3 2533 0.9007963954721725
3 2561 0.8957260345613678
3 2568 0.8964474529800505
3 2575 0.8990213228483238
…
前述の「商品別閲覧集計」で作った結果
の相関をMahoutで算出すると、以下の
ような、商品間の相関係数が取得でき、
相関係数が高いものをレコメンドする