はじめに
レコメンダーシステムは、さまざまな要素に基づいてユーザーにアイテムを推薦するために設計されたシステムです。このシステムは、ユーザーが最も興味を持ちそうなものを推薦します。Netflixは、レコメンダーシステムを利用して、ユーザーに映画を推薦しています。Amazonは、購入する商品をユーザーに勧めるためにレコメンダーシステムを使用しています。
レコメンダーシステムは、デジタル世界では非常に重要なシステムです。これにより、顧客はよりハッピーになり、より多くの売り上げに繋がります。今回は、JavaとGridDBを使ってレコメンダーシステムを構築する方法について説明します。
Javaによるレコメンダーシステムの実装方法
ここでは、Apache Mahoutを使用して、Javaでレコメンダーシステムを構築します。Apache Mahoutは、機械学習アルゴリズムを作成するために使用されるオープンソースプロジェクトです。これを使用して、分類、クラスタリング、および推薦などの機械学習技術を実装することができます。
レコメンダーシステムの仕事は、ユーザーにアイテムを推薦することです。使用するデータセットは、UserID, Item Number, Ratingの3つのカラムで構成されます。したがって、「4, 12, 3.0」という値を持つ列は、IDが4のユーザがアイテム12を星3つで評価したことを意味しています。データセットは.CSVファイルに保存されていますが、レコメンダーシステムを構築するために、GridDBに移動して、そこからデータを取り出します。
Mavenプロジェクトの作成
Java IDE を起動し、Maven プロジェクトを新規に作成します。pom.xml
ファイルを開き、以下のように修正します。
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>Add your Group Id</groupId>
<artifactId>Add your Artifact Id</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Add the name of your Project</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.mahout</groupId>
<artifactId>mahout-mr</artifactId>
<version>0.10.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
プロジェクトの設定にしたがって、上記ファイルに正しい内容を入力していることを確認してください。
データをGridDBに書き込む
次に、CSVファイルからGridDBにデータを書き込む必要があります。まず、使用するライブラリをインポートしましょう。
import java.io.IOException;
import java.util.Collection;
import java.util.Properties;
import java.util.Scanner;
import com.toshiba.mwcloud.gs.Collection;
import com.toshiba.mwcloud.gs.GSException;
import com.toshiba.mwcloud.gs.GridStore;
import com.toshiba.mwcloud.gs.GridStoreFactory;
import com.toshiba.mwcloud.gs.Query;
import com.toshiba.mwcloud.gs.RowKey;
import com.toshiba.mwcloud.gs.RowSet;
データは data.csv
という名前の CSV ファイルに保存されています。このデータをGridDBコンテナに格納することが目的です。まず、コンテナスキーマを静的クラスとして作成します。
public static class Ratings{
@RowKey String userid;
String item;
String rating;
}
上記のクラスはGridDBコンテナを表しており、これは3つのカラムを持つSQLテーブルに相当します。
では、GridDBへの接続を確立してみましょう。接続先のクラスタ名、接続するユーザ名、パスワードなど、GridDBをインストールした際の情報を入力してPropertiesインスタンスを作成します。以下のコードを使用します。
Properties props = new Properties();
props.setProperty("notificationAddress", "239.0.0.1");
props.setProperty("notificationPort", "31999");
props.setProperty("clusterName", "defaultCluster");
props.setProperty("user", "admin");
props.setProperty("password", "admin");
GridStore store = GridStoreFactory.getInstance().getGridStore(props);
上記の内容は、GridDBをインストールした際の認証情報に合わせて変更してください。
データを Ratings
コンテナに書き込みたいので、それを選択します。
Collection<String, Ratings> coll = store.putCollection("col01", Ratings.class);
collは
Ratings` コンテナのインスタンスであるため、このコンテナを参照するために使用します。
それでは、data.csv
ファイルからデータを読み込んで、GridDB コンテナに書き込んでみましょう。
File file1 = new File("data.csv");
Scanner sc = new Scanner(file1);
String data = sc.next();
while (sc.hasNext()){
String scData = sc.next();
String dataList[] = scData.split(",");
String userid = dataList[0];
String item = dataList[1];
String rating = dataList[2];
Ratings ratings = new Ratings();
ratings.userid = userid;
ratings.item = item;
ratings.rating = rating;
coll.append(ratings);
}
上記のコードは data.csv
ファイルからデータを読み込み、ratings
オブジェクトを作成します。このオブジェクトは、GridDB コンテナに追加されます。データのカラムはカンマで区切られているので、デリミターとしてカンマ(,)を設定する必要がありました。
GridDB からデータを取得する
それでは、GridDBからデータを取り出し、それを使ってレコメンダーシステムを構築してみましょう。以下のコードで、GridDBからデータを取り出します。
Query<ratings> query = coll.query("select *");
RowSet<ratings> rs = query.fetch(false);
RowSet res = query.fetch();
select *
クエリは、GridDBコンテナからすべてのデータを引き出すのに役立ちます。
レコメンダーシステムを構築する
いよいよApache Mahoutを使って、データからレコメンダーシステムを構築します。まず、必要なライブラリをApache Mahoutからインポートしましょう。
import java.io.File;
import java.util.List;
import org.apache.mahout.cf.taste.impl.neighborhood.ThresholdUserNeighborhood;
import org.apache.mahout.cf.taste.impl.model.file.FileDataModel;
import org.apache.mahout.cf.taste.impl.recommender.GenericUserBasedRecommender;
import org.apache.mahout.cf.taste.model.DataModel;
import org.apache.mahout.cf.taste.impl.similarity.CityBlockSimilarity;
import org.apache.mahout.cf.taste.neighborhood.UserNeighborhood;
import org.apache.mahout.cf.taste.recommender.UserBasedRecommender;
import org.apache.mahout.cf.taste.recommender.RecommendedItem;
目標は、n
個のアイテムをユーザに推薦することです。アイテムのクラスタリングには、類似度指標を用います。類似度指標は、異なるアイテム間のマンハッタン距離を使って計算されます。また、このコードは try
と catch
ブロックで囲まれており、発生しうる例外をキャッチするようになっています。以下は、レコメンダーシステムを構築するためのコードです。
try {
CityBlockSimilarity similarity = new CityBlockSimilarity(res);
UserNeighborhood neighborhood = new ThresholdUserNeighborhood(0.1,similarity, res);
UserBasedRecommender recommender = new GenericUserBasedRecommender(res, neighborhood, similarity);
// UserID and number of items to be recommended
List<recommendeditem> recommended_items = recommender.recommend(2, 2);
for (RecommendedItem r : recommended_items) {
System.out.println(r);
}
} catch (Exception ex) {
System.out.println("An exception occured!");
}
上記のコードで最も重要なのは、類似度の閾値です。これは、同じクラスタに属する2つのデータ項目間の類似度の下限値です。例えば類似度閾値を0.5とした場合、フィールド値が50%似ているアイテムは、同じクラスタに割り当てられる可能性が高くなります。類似度のしきい値を 1.0 にすると、アイテムが一緒にクラスタ化されるためには、それらのアイテムが類似した特性を有していなければならないことを意味します。
上記のコードでは、IDが2のユーザーに対して2つのレコメンデーションを算出しています。
コードのコンパイルと実行
コードを実行するために、gsadm
ユーザでログインします。プロジェクトファイルを、GridDBの bin
フォルダに移動します。
/griddb_4.6.0-1_amd64/usr/griddb-4.6.0/bin
Linux端末で以下のコマンドを実行し、gridstore.jarファイルのパスを設定します。
export CLASSPATH=$CLASSPATH:/home/osboxes/Downloads/griddb_4.6.0-1_amd64/usr/griddb-4.6.0/bin/gridstore.jar
次に、以下のコマンドを実行して、.java
ファイルをコンパイルします。
javac RecommenderSystemClass.java
以下のコマンドを実行して生成された .class ファイルを実行します。
java RecommenderSystemClass
以下のように、2つの項目を降順に推薦します。
Recommended Item[item:12, value:4.857143]
Recommended Item[item:14, value:3.357143]
おめでとうございます。
以上、JavaとGridDBを使ったレコメンダーシステムの構築方法でした。
ブログの内容について疑問や質問がある場合は Q&A サイトである Stack Overflow に質問を投稿しましょう。 GridDB 開発者やエンジニアから速やかな回答が得られるようにするためにも "griddb" タグをつけることをお忘れなく。 https://stackoverflow.com/questions/ask?tags=griddb