Setting up Taste v1.7.2 on a CentOS 4 x86_64 box.
Taste has merged with Mahout now, but I still want to do this standalone b/c I’m having trouble getting the JUnit tests to pass for Mahout. With that out of the way…
These are the shell commands I assembled after following the Taste Demo guide.
#make sure you have ant, and the JDK. I don't recommend the CentOS stock, get them from Sun/Apache #download necessary .jar files, sources, data files. unpack/move them to correct locations. wget http://internap.dl.sourceforge.net/sourceforge/taste/taste-1.7.2.zip wget http://internap.dl.sourceforge.net/sourceforge/proguard/proguard4.2.zip wget http://www.grouplens.org/system/files/million-ml-data.tar__0.gz wget http://www.hightechimpact.com/Apache/tomcat/tomcat-5/v5.5.26/bin/apache-tomcat-5.5.26.tar.gz unzip taste-1.7.2.zip unzip proguard4.2.zip tar -xvzf million-ml-data.tar__0.gz tar -xvzf apache-tomcat-5.5.26.tar.gz cp proguard4.2/lib/proguard.jar lib/ mv [mr]*.dat src/example/com/planetj/taste/example/grouplens/ #start up tomcat on port 8080 (default) JAVA_OPTS="-server -da -dsa -Xms1024m -Xmx1024m" JAVA_HOME=/usr/java/jdk1.6.0_02 sh apache-tomcat-5.5.26/bin/startup.sh #build taste.war, and inject it into tomcat JDK_HOME=/usr/java/jdk1.6.0_02 JAVA_HOME=/usr/java/jdk1.6.0_02 ant build-grouplens-example cp taste.war apache-tomcat-5.5.26/webapps/ #test the app. may take a minute or two on the first query. wget -O - -S 'http://localhost:8080/taste/RecommenderServlet?userID=1&debug=true'
Once you get that working, you can tweak the demo slightly to work on another data set. You just need to know the grouplens file format. ratings.dat is of the format:
UserID::MovieID::Rating::Timestamp
e.g.
1::1193::5::978300760
and movies.dat is of the format:
MovieID::Title::Genres
e.g.
1::Toy Story (1995)::Animation|Children's|Comedy
I wrote a script, let’s call it load_taste.pl, that can generate new movies.dat and ratings.dat files from an alternate data source. If I make these new files, I can drop them in place of the grouplens data, rebuild the .war files, and make recommendations on this other data set. Here’s how to do it:
#generate ratings.dat and movies.dat. move them to replace the grouplens data files. perl ./load_taste.pl mv [mr]*.dat src/example/com/planetj/taste/example/grouplens/ #get rid of stale .war and .jar files rm taste.war grouplens.jar #build the "quick" version of the example. see below for build.xml patch JDK_HOME=/usr/java/jdk1.6.0_02 JAVA_HOME=/usr/java/jdk1.6.0_02 ant build-grouplens-example-quick #inject the re-built .war file into tomcat. cp taste.war apache-tomcat-5.5.26/webapps/ #get rid of stale tomcat caches rm -rf apache-tomcat-5.5.26/webapps/taste apache-tomcat-5.5.26/temp/taste.*.txt
Note that I’ve defined a new ant build target called “build-grouplens-example-quick”. The purpose of this is that we only want to rebuild grouplens.jar and taste.war, not reoptimize/reverify/rebuild taste.jar, etc. The “build-grouplens-example” target takes ~55 seconds to complete on my machine, whereas the “build-grouplens-example-quick” target takes ~2 seconds. Here’s a diff to the original build.xml file:
--- /tmp/build.xml 2008-03-21 21:18:20.000000000 -0700 +++ ./build.xml 2008-06-30 11:46:18.000000000 -0700 @@ -161,6 +161,58 @@ <delete file="${my-web.xml}"/> </target> + <target depends="" name="build-taste-server-quick" description="Builds deployable web-based Taste server"> + <fail unless="my-recommender.jar" message="Please set -Dmy-recommender.jar=XXX"/> + <fail unless="my-recommender-class" message="Please set -Dmy-recommender-class=XXX"/> + <tempfile property="my-web.xml"/> + <copy file="src/main/com/planetj/taste/web/web.xml" tofile="${my-web.xml}"> + <filterset> + <filter token="RECOMMENDER_CLASS" value="${my-recommender-class}"/> + </filterset> + </copy> + <war destfile="${release-war}" webxml="${my-web.xml}"> + <lib dir="."> + <include name="${release-jar}"/> + <include name="${my-recommender.jar}"/> + </lib> + <lib dir="lib/axis"/> + <classes dir="build"> + <include name="com/planetj/taste/web/**"/> + </classes> + <fileset dir="src/main/com/planetj/taste/web"> + <include name="RecommenderService.jws"/> + </fileset> + </war> + <delete file="${my-web.xml}"/> + </target> + <target depends="" name="build-grouplens-example-quick" description="Builds deployable GroupLens example"> + <javac source="1.5" + target="1.5" + deprecation="true" + debug="true" + optimize="false" + destdir="build" + srcdir="src/example"> + <compilerarg value="-Xlint:all"/> + <classpath> + <pathelement location="${release-jar}"/> + <pathelement location="${annotations.jar}"/> + </classpath> + </javac> + <jar jarfile="grouplens.jar"> + <fileset dir="src/example"> + <include name="com/planetj/taste/example/grouplens/ratings.dat"/> + <include name="com/planetj/taste/example/grouplens/movies.dat"/> + </fileset> + <fileset dir="build"> + <include name="com/planetj/taste/example/grouplens/**"/> + </fileset> + </jar> + <property name="my-recommender.jar" value="grouplens.jar"/> + <property name="my-recommender-class" value="com.planetj.taste.example.grouplens.GroupLensRecommender"/> + <antcall target="build-taste-server-quick"/> + </target> + <target depends="build,optimize" name="build-grouplens-example" description="Builds deployable GroupLens example"> <javac source="1.5" target="1.5"


Sean Owen | 30-Jun-08 at 11:35 am | Permalink
Yep that is all right, thanks for posting the notes. This should all basically work with the new Mahout-ified version of the code too, which includes some small changes and improvements since 1.7.2. I think you would need to change step 2, where you need to download the Mahout source with SVN. Then the rest is about the same except you need to use the build script called taste-build.xml (ant -f taste-build.xml …).
This should all work with Tomcat 6 as well BTW.
allenday | 30-Jun-08 at 12:02 pm | Permalink
Thanks for the feedback Sean. Feel free to poach any of this for the main guide if you think it’s helpful.
I’m particularly interested to hear your thoughts on this alternate “quick” build target. As it is now users will have to wait until the next build, so no recommendations until then. I feel it’s a bit of a hack and that it would be better to implement an addUser() method added to the web service.