ClojureからJubatusのRecommender(推薦)を使ってみるサンプルです。
公式サイトの http://jubat.us/ja/tutorial/recommender.html のClojure版です。
プロ野球の野手成績を学習し、似た成績の野手を3人推薦するプログラムになっています。
動作に必要なnpb_similar_player.jsonとbaseball.csvは上記リンク先からどうぞ。
jubarecommender -f npb_similar_player.json
でJubatusサーバを起動しておけば以下のサンプルを実行できます。
recommender.clj
(ns jubatus-sample.recommender
(:require [clojure.java.io :as io]
[clojure.string :as s])
(:import [us.jubat.recommender RecommenderClient]
[us.jubat.common Datum]))
(defn map->datum [hmap]
(let [d (Datum.)]
(doseq [[k v] hmap]
(condp instance? v
String (.addString d k v)
Number (.addNumber d k v)
(.addBinary d k v)))
d))
(defn- datum [values]
(let [ks ["チーム" "打率" "試合数" "打席" "打数" "安打" "本塁打" "打点" "盗塁" "四球"
"死球" "三振" "犠打" "併殺打" "長打率" "出塁率" "OPS" "RC27" "XR27"]
vs (cons (first values) (map #(Double/parseDouble %) (rest values)))]
(map->datum (zipmap ks vs))))
(def ids (atom []))
(defn update [client]
(reset! ids [])
(with-open [r (io/reader "baseball.csv")]
(doseq [line (line-seq r)]
(let [values (s/split line #",")
id (first values)]
(swap! ids conj id)
(.updateRow client id (datum (rest values)))))))
(defn analyze [client]
(doseq [id @ids]
(let [result (rest (.similarRowFromId client id 4))]
(println "player" id "is similar to :" (s/join "," (map #(.-id %) result))))))
(def client (RecommenderClient. "127.0.0.1" 9199 "recommender_baseball" 1))
(update client)
(analyze client)
map->datum
は引数のMapのvalueの型を見て適切にDatumオブジェクトを構築する関数です。
datum
はCSVファイルの2カラム目以降のデータをもらってそれをDatumに変換しています。
update
はCSVファイルを読み込んで1行ずつ学習を行っています。後で使うためにid
も保存しています。
analyze
はそれぞれのid
ごとに(野手ごとに)似た野手を取得してプリントしています。