Blogs

Creating a simple recommendation engine using Apache Mahout in Grails app

November 27, 2012 by arun kumar

I have integrated mahout in one of my projects in grails so I wanted to share some thoughts on how we can create recommendation engine using Apache Mahout.

First of all What is Apache Mahout ?

The Apache Mahout is an open source machine learning library from Apache. It's goal is to build scalable machine learning libraries. The Algorithms Mahout implements fall under of machine learning or collective intelligence. Mahout has Collaborative Filtering, User and Item based recommender

In This blog i am sharing thoughts about Mahout recommendations and various recommendation Algorithm.

What is recommendation engine ?

Recommender engines are the most recognizable machine learning technique used today. you have seen various services or sites that attempt to recommend Books or Movies based on your past actions. They try to infer tastes and preferences and identify unknown items that are of interest.

Mahout provides various Algorithms to give better item recommendation to various user according to their taste.

  • 1. User-based recommender
  • 2. Item-based recommender
  • 3. Slope-one recommander

The brief description about these algorithms are as follows-

User-based recommender algorithm-

The user-based recommender algorithm comes out of this intuition .It's a process of recommending items to some user, denoted by u, as seen below:

for every item i that u has no preference for yet
    for every other user v that has a preference for i
    compute a similarity s between u and v
      incorporate v's preference for i, weighted by s, into a running average
return the top items, ranked by weighted average.

it would be terribly slow to examine every item. In reality a neighborhood of most similar users to computed first, and only items known to those users are considered:

for every other user w
   compute a similarity s between u and w
  retain the top users , ranked by similarity , as a neighborhood n
     for every item i that some user in n has a preference for i
   compute a similarity s between u and v
     incorporate v's preference for i ,weighed by s, into a running average.

The primary difference is that similar users are found first ,before seeing what those most-similar users are interested in.Those items becomes the candidates for recommendation. the rest are same.

This is the standard user-based recommender algorithm and the way it's implemented in Mahout.

Item-based recommender algorithm-

Item-based recommendation is derived from how similar items are to items . instead of users to users.In Mahout this means they are based on an ItemSimilarity implemeention instead of UserSimilarity

for every item i that u has no preference for yet
   for every item j that u has a preference for
  compute a similarity s between i and j
  add u's preference for j , weighted by s, to a running average
  return the top items ,ranked by weighted average.

The third line in above algorithms shows how it's based on item-item similarities,not user-user similarities as before.

Slope-one recommender algorithm-

The Slope-one name comes from the fact that the recommender algorithm starts with the assumption that there's some linear relationship between preference values for one item and another,that it's valid to estimate the preferences for some item Y based on the preferences for item X ,via some linear function like Y=mX+b. Then the slope-one recommender makes the additional simplifying assumption that m=1 : slope one .It just remains to find b=Y-X, the (average) difference in preference value , for every pair of items.

This means the algorithm consists of a significant preprocessing phase, in which all item-item preference value differences are computed:

for every item i
  for every other item j
    for every user u expressing preference for both i and j
  add the difference in u's preference for i and j to an average.

And then ,the recommendation algorithm looks like this:

for every item i the user u expresses no preference for
   for every item j that user u expresses a preference for
  find the average preference difference between j and i
     add this diff to u's preference value for j
     add this to a running average
  return the top items ranked by these averages.

Its performance does not depend upon the number of users in the data model. So Slope one is attractive and fast like an Item-based recommender.

Now i am using Mahout-recommender plugin in grails to create a recommender.

Hope you have integrated mahout in grails if not please follow steps from Mahout Integration with Grails

After integrating mahout recommender plugin in grails app and configure data model with mysql using

     mahout.recommender.data.model='mysql'
	

in config.groovy

Then create a TastePreferences domain class in your mysql database with userId , itemId and preference field something like that

package mahoutrecommander
import org.apache.commons.lang.builder.HashCodeBuilder

class TastePreferences implements Serializable {
  long userId
  long itemId
  float preference
  static constraints = {
  	userId()
  	itemId()
 	preference range: 0.0f..5.0f
  }

  boolean equals(other) {
      if(!(other instanceof TastePreferences)) {
         return false
      }
      log.debug "other"
  	other.userId == userId && other.itemId == itemId
  }

  int hashCode() {
      def builder = new HashCodeBuilder()
      builder.append userId
      builder.append itemId
      builder.toHashCode()
  }

  static mapping = {
     id composite: ['userId', 'itemId']
     version false
  }
}
    

Bydefault plugin uses TastePreferences named domain class if you want to use any other table for mahout recommender you can configure it in config.groovy

mahout.recommender.preference.table='tableName'
mahout.recommender.preference.userIdColumn='userIdColumn'
mahout.recommender.preference.itemIdColumn='itemIdColumn'
mahout.recommender.preference.valueColumn='preference value'
    

you can use mahout-recommender plugin via three mode

  • 1 input
  • 2 config
  • 3 class
mahout.recommender.mode = 'input'  // 'input', 'config' or 'class' in config.groovy
	

if mode is 'input' then user can pass parameters to recommender controller something as follows-

params.userID-user id of that user whom we are providing recommendation

params.howMany- how many recommendation we want to show to the user otherwise it takes default value.

params.hasPreference-it is boolean value it can be true or false.

params.r- recommender selected like user-based recommender ,item-based recommender or slope-one recommender.

params.s- similarity that can be pearson correlation, Euclidian distance ,Log-likelihood ,Tanimoto coefficient these are different approach to find out similarity.

params.n-it contains neighborhood.

params.w- it is a boolean value that give withWeighting or not.

You can provide these values from config.groovy also as follows:

mahout.recommender.mode="config" //in config of project. give these values in config.groovy.
mahout.recommender.selected=' '
mahout.recommender.hasPreference=' '
mahout.recommender.similarity=' '
mahout.recommender.withWeighting=' '
mahout.recommender.neighborhood=' '
    

and just pass userId and howMany in parameters to recommender controller all other recommender configuration it will pick from config file.

And now last is class mode ,it is used to create custom recommender if you want to use this part then change

mahout.recommander.mode="class"

and also give name of that class in which you are building recommender.

mahout.recommender.builderClass='className'
    

You can use test data in TastePreferences table as follows to check recommender engine working.

+---------+---------+------------+
| user_id | item_id | preference |
+---------+---------+------------+
|       1 |     101 |          5 |
|       1 |     102 |          3 |
|       1 |     103 |          2 |
|       2 |     101 |          2 |
|       2 |     102 |        2.5 |
|       2 |     103 |          5 |
|       2 |     104 |          2 |
|       3 |     101 |        2.5 |
|       3 |     104 |          4 |
|       3 |     105 |        4.5 |
|       3 |     107 |          5 |
|       4 |     101 |          5 |
|       4 |     103 |          3 |
|       4 |     104 |        4.5 |
|       4 |     106 |          4 |
|       5 |     101 |          4 |
|       5 |     102 |          3 |
|       5 |     103 |          2 |
|       5 |     104 |          4 |
|       5 |     105 |        3.5 |
|       5 |     106 |          0 |
+---------+---------+------------+

Suppose our recommender mode is input in config when we start our project in grails it will show recommender controller in home page select that it will show an input form in which you can pass parameters as discussed above and click on submit button.

Suppose we are using userId 1 in input field and want to give recommendation to user 1 then it will show result

 

Now you are getting recommendation. Well that working fine.

hope it helps ! to create recommendation in grails app.

Arun kumar

Mahout Integration with Grails

June 19, 2012 by Varun Sharma

I have integrated mahout in one of my projects in grails so I wanted to share some thoughts on how Apache Mahout might be integrated with grails.


First of all What is Apache Mahout ?

The Apache Mahout™ machine learning library's goal is to build scalable machine learning libraries. Mahout has Collaborative Filtering, User and Item based recommenders. 

To start working with Mahout you will need to install Mahout on your system 


Installing Mahout, the Ubuntu edition

For Mahout installation you need 3 things:

1. Install JDK 1.6 or higher

2. Install Maven

3. Install Mahout

After successful Mahout installation you have to add Mahout Recommender plugin for grails.


What Mahout Recommender plugin is all about ?

The Mahout Recommender plugin enabled you to use Apache Mahout recommendation algorithms in your Grails project. With the plugin, you can find an effective recommender, evaluating precision and recall, and evaluating the performance of the selected recommender without writing single line of code.

There are two ways to install Mahout Recommender Plugin in grails:

1. You can use the command grails install-plugin mahout-recommender in grails command prompt. or

2. Use the right click option on plugins (under your project) select the plugin from the window & select install then OK.

After the plugin installed into your project, the following configurations will be appended to your project's Config.groovy file:

// Added by the Mahout Recommender plugin:
mahout.recommender.mode = 'input'  // 'input', 'config' or 'class'

The plugin support both the file data model and MySQL data model.

For file data model, no additional configuration is required to make use of command line tool of the plugin, but the data file must be located in classpath such asgrails-app/conf and data file name must be specified in mahout.recommender.data.file for web-based tools such as recommenders' evaluator and recommender.

For MySQL data model, change mahout.recommender.data.model from 'file' to 'mysql' and configure the DataSource.groovy properly.

For Basic Configurations(refer)

ttp://limcheekin.github.com/mahout-recommender/docs/manual/guide/configuration.html


Steps to Setup Mahout Recommendation Plugin with MySQL:

The plugin is using file data model by default, this section will described step-by-step of how to setup your project to use MySQL data model with assumption that MySQL database is pre-installed and started in your development workstation.

Simple steps to work with MySQL:

1. Login to MySQL using command:  mysql -u root

2. Create recommender database using command:  create database recommender

3. You should have MySQL Connector/J plugin installed in grails.

4. Update mahout.recommender.data.model in grails-app/conf/Config.groovy from 'file' to 'mysql'.

5. Update database configurations in grails-app/conf/DataSource.groovy from HSQL or H2 to MySQL.

mahout.recommender.data.model = 'mysql' // 'file' or 'mysql'
dataSource {

    pooled = true
    driverClassName = "com.mysql.jdbc.Driver"
    username = "root"
    password = ""
}
hibernate {
    cache.use_second_level_cache = true
    cache.use_query_cache = true
    cache.provider_class = 'net.sf.ehcache.hibernate.EhCacheProvider'
}
// environment specific settings
environments {
    development {
        dataSource {
            dbCreate = "create-drop" // one of 'create', 'create-drop','update'
            url = "jdbc:mysql://localhost:3306/recommender"
        }
    }
    test {
        dataSource {
            dbCreate = "create-drop"          
            url = "jdbc:mysql://localhost:3306/recommender"
        }
    }
    production {
        dataSource {
            dbCreate = "update"
            url = "jdbc:mysql://localhost:3306/recommender"
        }
    }
}

Other Useful Links: 

1. http://girlgeekintraining.com/?p=51

2. https://ccp.cloudera.com/display/CDHDOC/Mahout+Installation


>Hope it helps !

Varun Sharma
varun.sharma@oodlestechnologies.com

http://oodlestechnologies.com/

Powered byApache Solr

Follow Us

Recent Entries