Showing posts with label text mining. Show all posts
Showing posts with label text mining. Show all posts

Day 4: PredictionIO--How to Build A Blog Recommender - OpenShift Blog



Day 4: PredictionIO--How to Build A Blog Recommender – OpenShift Blog
PredictionIO is an open source machine learning server application written in Scala. It provides an easy to use REST API to build recommendation engines. It also provides client SDKs, which wraps the REST API. The Client SDKs are available in Java, Python, Ruby, and PHP programming languages. PredictionIO core is using Apache Mahout. Apache Mahout is a scalable machine learning library which provides various clustering, classification, filtering algorithms. Apache Mahout can run these algorithms on distributed Hapoop cluster.
The usecase that we are solving is to recommend blogs to user depending on the blog he has viewed. In the code shown below, we are getting all similar items to blog1 for userId “shekhar”.
import io.prediction.Client;
 
import java.util.Arrays;
 
public class BlogrRecommender {
 
    public static void main(String[] args) throws Exception {
 
        Client client = new Client("wwoTLn0FR7vH6k51Op8KbU1z4tqeFGZyvBpSgafOaSSe40WqdMf90lEncOA0SB13");
        client.identify("shekhar");
        String[] recommendedItems = client.getItemSimTopN("engine1", "blog1", 5);
 
        System.out.println(String.format("User %s is recommended %s", "shekhar", Arrays.toString(recommendedItems)));
 
        client.close();
    }
}
Run the Java program and you will see result as “blog4″,”blog5″,”blog6″ , and “blog7″.
Read full article from Day 4: PredictionIO--How to Build A Blog Recommender – OpenShift Blog

NLP | Sergey Tihon's Blog



NLP | Sergey Tihon's Blog
Statistical Parsing and Linguistic Analysis Toolkit is a linguistic analysis toolkit. Its main goal is to allow easy access to the linguistic analysis tools produced by the Natural Language Processing group at Microsoft Research. The tools include both traditional linguistic analysis tools such as part-of-speech taggers and parsers, and more recent developments, such as sentiment analysis (identifying whether a particular of text has positive or negative sentiment towards its focus)

Read full article from NLP | Sergey Tihon's Blog

Recursive Deep Models for Semantic Compositionality Over a Sentiment Treebank



Recursive Deep Models for Semantic Compositionality Over a Sentiment Treebank
This website provides a live demo for predicting the sentiment of movie reviews. Most sentiment prediction systems work just by looking at words in isolation, giving positive points for positive words and negative points for negative words and then summing up these points. That way, the order of words is ignored and important information is lost. In constrast, our new deep learning model actually builds up a representation of whole sentences based on the sentence structure. It computes the sentiment based on how words compose the meaning of longer phrases. This way, the model is not as easily fooled as previous models. For example, our model learned that funny and witty are positive but the following sentence is still negative overall:

The underlying technology of this demo is based on a new type of Recursive Neural Network that builds on top of grammatical structures. You can also browse the Stanford Sentiment Treebank, the dataset on which this model was trained.

Read full article from Recursive Deep Models for Semantic Compositionality Over a Sentiment Treebank

UIMA PEAR packaging



 Read full article from UIMA PEAR packaging

The following two build plug-ins hooks into the build cycle of the PEAR project in order to make sure all dependencies end up being packaged into the final PEAR file.
The first uses the maven-dependency-plugin to resolve the runtime dependencies of the PEAR into the lib folder of the PEAR. They have to be there because the PEAR packaging plugin does not take care of packaging up the dependencies.
The second hooks into the clean phase of the build phase. It deletes the lib folder again.
Note: The lib folder is thus automatically filled and removed during the build process. Thus it should not go into the source control system and neither should you manually place any jars in there.

Read full article from UIMA PEAR packaging

Salmon Run: An UIMA Noun Phrase POS Annotator using OpenNLP



Salmon Run: An UIMA Noun Phrase POS Annotator using OpenNLP
I stumbled on these two posts in Davelog: Getting starting with OpenNLP 1.5.0 - Sentence Detection and Tokenizing and Part of Speech (POS) Tagging with OpenNLP 1.5.0.

 So I decided to replace my SentenceAnnotator (which annotated the text with sentence annotation markers) with a NounPhraseAnnotator. This one also first splits the input text into sentences using the SentenceDetector, then for each sentence it tokenizes it into words using the Tokenizer, then find POS tags for each token using the POSTagger. Now using the tokens and the associated tags, it uses the Chunker to break up the sentence into phrase chunks. For each chunk, it checks its type and only noun-phrases (NP) are annotated. The SentenceDetector, Tokenizer, POSTagger and Chunker are all OpenNLP components, each backed by their own maximum entropy based models. Pre-built versions of these models are available for download from here.


Sentiment Analysis using Solr



Linguistics module
Stems, Lemmas and Synonyms
multi language capability
CJKAnalyzer, UIMA Analyzers
UIMA integration
UpdateProcessorChain

Extract domain specific entities and concepts

Usecase
Consumer feedback about products
Which product features are more relevant Polarity

NLP+UIMA
Use POS in query understanding
boosting terms
Synonym expansion

Extract concepts/entities
Faceting using entities
Identify places in query and use spatial queries

Ideas: Sentiment Analysis App
Identify Subjective Sentences from text
Remove noisy sentences
– Regex, conditional probability
Graph min cut – LingPipe
Subjectivity Lexicons
Discard Facts and Objective Sentences

Ideas: Sentiment Analysis App
Sentiments Intensity - SentiWordNet
WordNet-Affect: WordNet + annotated concepts
Hybrid model with adding dictionary

http://ceur-ws.org/Vol-1038/paper_5.pdf
Sentiment Analysis
Social Media Monitoring, Reputation
Management, Opinion Mining, ...
“Who says what about what?”
or “What do people say about my product/brand?”

Objective: analysing customer opinion from unstructed product reviews
Approach:
detect Opinionated Units (Targets and
Cues) → UIMA
data mining / visualization of targetcue relations → Solr, Cluto, etc.

OU detection
combine statistical and rule-based approaches
reliably find known entities and opinion expressions
discover new entities and opinions

mark known Targets (e.g. brand /
product names, etc.) and known Cues
(e.g. polar words and expressions)
detect new Targets and Cues using statistical models
relate Targets and Cues through syntactic dependencies

flexible interactive querying/filtering
clustering using Carrot, Cluto, Solrbased kNN, etc.

UIMA components
OpenNLP (Apache)
JNET (JulieLabs)
Zanzibar (Tor Vergata University)
seems mostly abandoned (2011)

Lemmatizer (BM)
DeSR (University of Pisa, wrapper by BM)
DependencyTreeWalker (BM)
Weka Wrapper (based on MAWUI by Mayo Clinic)
upstream not updated since 2008
UIMA Collection Tools (BM)

Salmon Run: Using Lucene Similarity in Item-Item Recommenders



By default, Lucene stores document vectors keyed by terms, but can be configured to store term vectors by setting the field attribute TermVector.YES. In case of text documents, words (or terms) are the features which are used to compute similarity between documents. I am using the same dataset as last week, where movies (items) correspond to documents and movie tags correspond to the words. So we build a movie "document" by preprocessing the tags to form individual tokens and concatenating them into a tags field in the index.

Find Movies Similar to given Movie: This is just content based filtering and is implemented as a simple MLT query. Given the itemID, we lookup the docID of the source movie, then get the top N movies that are most like it. We then return a List of tuples of docIDs that are similar and their similarities (scores), except the original docID.

Predict a User's Rating for a Movie: This is the prediction functionality of an item-item CF recommender. The prediction is based on how the user has rated other movies similar to this one. Otherwise, we calculate the average weighted sum of the ratings of already rated items, where the weights are the similarities between the target item and this item. If the movie is already rated, we just return the rating. Similarity between two items are calculated using the MLT query using a simplifying assumption - a target item outside the item neighborhood has 0 similarity with the source item. If we did not use this assumption, we would have to use approaches such as the TermFreqVector API for Lucene 3.x or the Fields API for Lucene 4.x to compute individual doc-doc similarities.

Recommend Movies to a User: This is topN recommender functionality of an item-item CF. We recommend movies that are similar to ones the user has already rated, weighted by the similarity between this item and the rated item. We use the algorithm outlined in Mahout in Action, § 4.4.1, detailed below. The 3rd and 4th lines in the algorithm is essentially the rating prediction task we described above. Essentially, we calculate the prediction for all items not rated so far by the user, and return them sorted by descending order of predicted rating.

Read full article from Salmon Run: Using Lucene Similarity in Item-Item Recommenders

Comparing Document Classification Functions of Lucene and Mahout | soleami | Visualize the needs of your visitors.



Comparing Document Classification Functions of Lucene and Mahout | soleami | Visualize the needs of your visitors.
Lucene implements Naive Bayes and k-NN rule classifiers. The trunk equivalent to Lucene 5, the next major releases, implements boolean (2-class) classification perceptron in addition to these two. We use Lucene 4.6.1, the most recent version at the time of writing, to perform document classification with Naive Bayes and k-NN rule.
You need to have IndexReader with prepared index open and specify it as the first argument of the train() method because Classifier uses index as learning data. Also, set the Lucene field name that has text, which is tokenized and indexed, as the second argument of train() method. In addition, set the Lucene field that has document category as the third argument of train() method. In the same manner, set a Lucene Analyzer to the fourth argument and Query to the fifth argument. Analyzer then specifies Analyzer that is used to classify unknown document (In my personal opinion, this is a bit complicated and should use them as arguments for after-mentioned assignClass() method instead) . While Query is used to narrow down documents that are used for learning, null is used if there’s no need to do so. The train() method has 2 more varieties that have different arguments but I will skip the explanation for now.
Use unknown document in the String type as an argument to call the assignClass() method after you call train() of Classifier interface to obtain the result of classification. Classifier is an interface that uses Java Generics, and the ClassificationResult class that uses type variable T is the returned value of assignClass().
Calling the getAssignedClass() method of ClassificationResult gives you a classification result of the type T.
Note that Lucene’s classifier is unique in that the train() method does little work while the assignClass() does most of the work. This is where it is very different from the other commonly used machine learning software. In the learning phase of commonly used machine learning software, a model file is created by learning corpus according to a selected machine learning algorithm (This is where the most time/effort is put into. As Mahout is based on Hadoop, it uses MapReduce to try to reduce the time required here). And in the classification phase, an unknown document is classified by referring to a previously created model file. This phase usually requires little resource.
As Lucene uses an index as a model file, train() method, which is a learning phase, does almost nothing here (Its learning completes as soon as index is created). Lucene’s index, however, is optimized to perform high-speed keyword search and is not in an appropriate format for document classification model file. Therefore, here we do document classification by searching index with the assignClass() method that is a classification phase. Contrary to commonly used machine learning software, Lucene’s classifier requires very high computing power in the classification phase. For sites mainly focused on searching, this function that enables document classification should be appealing as they can create indexes without additional cost.

SimpleNaiveBayesClassifier is the first implement class of Classifier interface. As you can see from the name, it’s a Naive Bayes classifier. Naive Bayes classification finds c where conditional probability P(c|d), the probability of class being c in document d, becomes the highest. Here you use Bayes’ theorem to do deformation of P(c|d) but you need to find P(c)P(d|c) to calculate class c with the highest probability. While you usually calculate logarithm to avoid underflow, the assignClass() method of SimpleNaiveBayesClassifier repeats this calculation as many times as the number of classes to perform MLE (maximum likelihood estimation).
Using Lucene KNearestNeighborClassifier
Another implement class for Classifier is KNearestNeighborClassifier. KNearestNeighborClassifier specifies k, which is no less than 1, in an argument for constructor to create an instance. You can use the program exactly the same as one for SimpleNaiveBayesClassifier. Only you need to do is to replace the portion that is creating an instance for SimpleNaiveBayesClassifier with KNearestNeighborClassifier.
The assignClass() method does all the work for KNearestNeighborClassifier as well in the same manner described before but one interesting point is that it is using Lucene MoreLikeThis. MoreLikeThis is a tool that sees document to become criteria as a query and performs search. With this, you can find documents that are similar to the ones to be criteria. KNearestNeighborClassifier uses MoreLikeThis to “k” number of documents that are most similar to the unknown document passed to the assignClass() method. Then, the majority rule is applied to that k number of documents to determine the document category of unknown document.
Executing the same program as KNearestNeighborClassifier will display the following when k=1.

In this article, we used the same corpus to do document classification of the both Lucene and Mahout to compare their results. The accuracy rate seems to be higher for Mahout but, as already stated, its learning data classification use not all word but only top 2,000 important words in the body field. On the other hand, Lucene’s classifier, which accuracy rate was only 70%, uses the all words in body field. Lucene will be able to pass the 90% accuracy rate if you have a field to hold only the words reviewed specially for document classification. It may also be a good idea to create another Classifier implement class for train() method that has such function.
I should add that the accuracy rate goes down to around 80% when you do not use test data for learning but test it as real unknown data.
Read full article from Comparing Document Classification Functions of Lucene and Mahout | soleami | Visualize the needs of your visitors.

Lucene 4 is Super Convenient for Developing NLP Tools



Lucene 4 is Super Convenient for Developing NLP Tools
Lucene 4.0 classes that I used for developing this system are as follows:
  • IndexSearcher, TermQuery, TopDocs
    This system calculates similarities of synonym candidates that consist of nouns extracted from keywords and their descriptions. The system determines that the candidate is a synonym of keyword if similarity is bigger than a threshold value and output it to a CSV file.
    But how I calculate the similarity of a keyword and its synonym candidate. This system determines the similarity by calculating the similarity of keyword description Aa and dictionary entry description set {Ab} that are written using synonym candidates.
    Thus, I have to find {Ab} where I used classes such as IndexSearcher, TermQuery, and TopDocsto to search description field using synonym candidate.
  • PriorityQueue
    Next, I have to pick out “feature word” from Aa and {Ab} to calculate similarity of the two. In order to do so, I select N most important words to structure feature vector. Here, I use TF*IDF of the target word as their degree of importance. See the above SlideShare for the detail. Here, I use PriorityQueue to select “N most important words”
  • DocsEnum, TotalHitCountCollector
    I used TF*IDF to calculate weight to extract the above feature word and used DocsEnum.freq() to obtain TF. docFreq (number of articles including synonym candidate), which is a required parameter to obtain IDF, has been calculated by passing TotalHitCountCollector to the search() method of IndexSearcher.
  • Terms, TermsEnum
    I use these classes to search “description” field for synonym candidates.
These are usage examples for Lucene 4.0 on this system. I also believe Lucene will be a great help for NLP tool developers as well. For lexical knowledge obtention task using Bootstrap, for example, I can use a cycle (1: pattern extraction, 2: pattern selection, 3: instance extraction, 4: instance selection) to obtain knowledge from a small number of seed instances. I believe that you can replace pattern extraction and instance extraction with a simple search task if you use Lucene for these tasks.
Please read full article from Lucene 4 is Super Convenient for Developing NLP Tools

Text categorization with Lucene and Solr



Text categorization with Lucene and Solr
Let the algorithm assign one or more labels (classes) to some item given some previous knowledge
l Spam filter
l Tagging system
l Digit recognition system
l Text categorization 

l Lucene already has a lot of features for common information retrieval needs
l Postings
l Term vectors
l Statistics
l Positions
l TF / IDF
l maybe Payloads
l etc.
l We may avoid bringing in new components
to do classification just leveraging what we
get for free from Lucene

l Lucene has so many features stored you can take advantage of for free
l Therefore writing the classification algorithm is relatively simple
l In many cases you’re just not adding anything to the architecture
l Your Lucene index was already there for searching l Lucene index is, to some extent, already a model which we just need to “query” with the proper algorithm
l And it is fast enough 

Classifier API
l Training
l void train(atomicReader, contentField, classField, analyzer) throws IOException


K Nearest neighbor classifier
l Fairly simple classification algorithm
l Given some new unseen item
l I search in my knowledge base the k items which are nearer to the new one
l I get the k classes assigned to the k nearest items
l I assign to the new item the class that is most frequent in the k returned items 

K Nearest neighbor classifier
l How can we do this in Lucene?
l We have VSM for representing documents as
vectors and eventually find distances
l Lucene MoreLikeThis module can do a lot for it
l Given a new document
l It’s represented as a MoreLikeThisQuery which filters
out too frequent words and helps on keeping only the
relevant tokens for finding the neighbors
l The query is executed returning only the first k results
l The result is then browsed in order to find the most
frequent class and that is then assigned with a score
of classFreq / k 

Naïve Bayes classifier
l Slightly more complicated
l Based on probabilities
l C = argmax( P(d|c) * P(c) )
l P(d|c) : likelihood
l P(c) : prior
l With some assumptions:
l bag of words assumption: positions don't matter
l conditional independence: the feature probabilities
are independent given a class


Things to consider - bootstrapping
l How are your first documents classified?
l Manually
l Categories are already there in the documents
l Someone is explicitly charged to do that (e.g. article
authors) at some point in time
l (semi) automatically
l Using some existing service / library
l With or without human supervision
l In either case the classifier needs something to
be fed with to be effective 

As specific search services
l A classification based more like this
l While indexing
l For automatic text categorization

Automatic text categorization
l Once a doc reaches Solr
l We can use the Lucene classifiers to automate assigning document’s category
l We can leverage existing Solr facilites for enhancing the indexing pipeline
l An UpdateChain can be decorated with one or more UpdateRequestProcessors

CategorizationUpdateRequestProcessorFactory
CategorizationUpdateRequestProcessor
l void processAdd(AddUpdateCommand
cmd) throws IOException
l String text = solrInputDocument.getFieldValue(“text”);
l String class = classifier.assignClass(text);
l solrInputDocument.addField(“cat”, class);
l Every now and then need to retrain to get latest stuff in the current index, but that can be done in the background without affecting performances 

CategorizationUpdateRequestProcessor
l Finer grained control
l Use automatic text categorization only if a value
does not exist for the “cat” field
l Add the classifier output class to the “cat” field only if it’s above a certain score 

Implement a MaxEnt Lucene based classifier
l which takes into account words correlation 

Please read full article from Text categorization with Lucene and Solr

Getting Started with Topic Modeling and MALLET



Getting Started with Topic Modeling and MALLET
To create an environment variable in Windows 7, click on your Start Menu -> Control Panel -> System -> Advanced System Settings (Figures 1,2,3). Click new and type MALLET_HOME in the variable name box. It must be like this – all caps, with an underscore – since that is the shortcut that the programmer built into the program and all of its subroutines. Then type the exact path (location) of where you unzipped MALLET in the variable value, e.g., c:\mallet.

bin\mallet import-dir --help
To work with this corpus and find out what the topics are that compose these individual documents, we need to transform them from several individual text files into a single MALLET format file. MALLET can import more than one file at a time. We can import the entire directory of text files using the import command. The commands below import the directory, turn it into a MALLET file, keep the original texts in the order in which they were listed, and strip out the stop words (words such as andthebut, and if that occur in such frequencies that they obstruct analysis) using the default English stop-words dictionary. 

This file now contains all of your data, in a format that MALLET can work with.
bin\mallet train-topics --input tutorial.mallet

This command opens your tutorial.mallet file, and runs the topic model routine on it using only the default settings. As it iterates through the routine, trying to find the best division of words into topics.
MALLET includes an element of randomness, so the keyword lists will look different every time the program is run, even if on the same set of data.

bin\mallet train-topics --input tutorial.mallet --num-topics 20 --output-state topic-state.gz --output-topic-keys tutorial_keys.txt --output-doc-topics tutorial_compostion.txt

The second number in each paragraph is the Dirichlet parameter for the topic. This is related to an option which we did not run, and so its default value was used (this is why every topic in this file has the number 2.5).
If when you ran the topic model routine you had included
--optimize-interval 20
bin\mallet train-topics --input tutorial.mallet --num-topics 20 --optimize-interval 20 --output-state topic-state.gz --output-topic-keys tutorial_keys.txt --output-doc-topics tutorial_composition.txt

That is, the first number is the topic (topic 0), and the second number gives an indication of the weight of that topic. In general, including –optimize-interval leads to better topics.


What topics compose your documents? The answer is in thetutorial_composition.txt file. 

How do you know the number of topics to search for? Is there a natural number of topics? What we have found is that one has to run the train-topics with varying numbers of topics to see how the composition file breaks down. If we end up with the majority of our original texts all in a very limited number of topics, then we take that as a signal that we need to increase the number of topics; the settings were too coarse. There are computational ways of searching for this, including using MALLETs hlda command, but for the reader of this tutorial, it is probably just quicker to cycle through a number of iterations 

Read full article from Getting Started with Topic Modeling and MALLET

Text Analytics in Enterprise Search - Daniel Ling



Text Analytics in Enterprise Search - Daniel Ling
Document Categorization

 To assign a label to the document / content / data.
 Labels for the category or for the sentiment.
 Threshold values for matching a category before labeling.
 Statistics and “knowledge” from previous examples can be used.


 Mallet and the process of setup and train:
Training the component, Mallet (Machine Learning for Language Toolkit).
• Alternative components includes Lucene (TFIDF) index
(MoreLikeThis), OpenNLP, Textcat, Classifier4j.
 Running the new documents against the model/index of trained
documents.
 Training from interface, adhoc, or index pre-categorized

Document Summarization

Summarize a document, at index time or on-demand.
 Leverage from the knowledge and term statistics of the document
and the index.
 Picks the “most important” sentences based on the statistics and
displays those.

Example Solution: Document Summarization

Custom RequestHandler that receives document ID and field to summarize.
 Custom Search Component making the selection of top sentences.
 Selecting a subset of sentences and sends these back in a field.

Please read full article from Text Analytics in Enterprise Search - Daniel Ling

SolrPerformanceProblems - Solr Wiki




Java Heap

The java heap is the memory that Solr requires in order to actually run. Certain things will require a lot of heap memory. The following list is incomplete, but in no particular order, these include:

  • A large index.
  • Frequent updates.
  • Super large documents.
  • Extensive use of faceting with the default facet.method value.
  • Using a lot of different sort parameters.
  • Very large Solr caches
  • A large RAMBufferSizeMB.
  • Use of Lucene's RAMDirectoryFactory.

Reducing heap requirements

Here is an incomplete list, in no particular order, of how to reduce heap requirements, based on the list above for things that require a lot of heap:

  • Take a large index and make it distributed - shard your index onto multiple servers.
    • One very easy way to do this is to switch to SolrCloud.
    • This doesn't actually reduce the overall memory requirement for a large index (it may actually increase it slightly), but spreads it across multiple servers, so each server will have lower memory requirements.
  • Don't store all your fields, especially the really big ones.
    • Instead, have your application retrieve detail data from the original data source, not Solr.
    • Note that doing this will mean that you cannot use Atomic Updates.
  • Use facet.method=enum for your facets.
  • Reduce the number of different sort parameters.
  • Reduce the size of your Solr caches.
  • Reduce RAMBufferSizeMB. The default in recent Solr versions is 100.
    • This value can be particularly important if you have a lot of cores, because a buffer will be used for each core.
  • Don't use RAMDirectoryFactory - instead, use the default and install enough system RAM so the OS can cache your entire index as discussed above.
  • Try Heliosearch, a Solr fork that features Off-Heap Filters and an Off-Heap FieldCache

Read full article from SolrPerformanceProblems - Solr Wiki

Apache Mahout: Scalable machine learning and data mining



Apache Mahout: Scalable machine learning and data mining
Mahout's recommenders expect interactions between users and items as input. The easiest way to supply such data to Mahout is in the form of a textfile, where every line has the format userID,itemID,value. Here userID and itemID refer to a particular user and a particular item, and value denotes the strength of the interaction (e.g. the rating given to a movie).
1,10,1.0
1,11,2.0
1,12,5.0
https://github.com/jpatanooga/Caduceus/blob/master/src/tv/floe/caduceus/mahout/cf/taste/samples/SampleRecommender.java
public static void main(String[] args) throws IOException, TasteException {
DataModel model = new FileDataModel( new File( "data/mahout/cf/sample_recommender_data.csv" ) ); // load model
UserSimilarity similarity = new PearsonCorrelationSimilarity( model );
UserNeighborhood neighborhood = new NearestNUserNeighborhood(2, similarity, model );
Recommender recommender = new GenericUserBasedRecommender( model, neighborhood, similarity );
List<RecommendedItem> recommendations = recommender.recommend(1, 1);
for ( RecommendedItem recommendation : recommendations ) {
System.out.println( recommendation );
}
}

Creating a user-based recommender

Create a class called SampleRecommender with a main method.
The first thing we have to do is load the data from the file. Mahout's recommenders use an interface called DataModel to handle interaction data. You can load our made up interactions like this:
DataModel model = new FileDataModel(new File("/path/to/dataset.csv"));
In this example, we want to create a user-based recommender. The idea behind this approach is that when we want to compute recommendations for a particular users, we look for other users with a similar taste and pick the recommendations from their items. For finding similar users, we have to compare their interactions. There are several methods for doing this. One popular method is to compute the correlation coefficient between their interactions. In Mahout, you use this method as follows:
UserSimilarity similarity = new PearsonCorrelationSimilarity(model);
The next thing we have to do is to define which similar users we want to leverage for the recommender. For the sake of simplicity, we'll use all that have a similarity greater than 0.1. This is implemented via a ThresholdUserNeighborhood:
UserNeighborhood neighborhood = new ThresholdUserNeighborhood(0.1, similarity, model);
Now we have all the pieces to create our recommender:
UserBasedRecommender recommender = new GenericUserBasedRecommender(model, neighborhood, similarity);
We can easily ask the recommender for recommendations now. If we wanted to get three items recommended for the user withuserID 2, we would do it like this:
List recommendations = recommender.recommend(2, 3);
for (RecommendedItem recommendation : recommendations) {
  System.out.println(recommendation);
}

Evaluation

You might ask yourself, how to make sure that your recommender returns good results. Unfortunately, the only way to be really sure about the quality is by doing an A/B test with real users in a live system.
We can however try to get a feel of the quality, by statistical offline evaluation.
One way to check whether the recommender returns good results is by doing a hold-out test. We partition our dataset into two sets: a trainingset consisting of 90% of the data and a testset consisting of 10%. Then we train our recommender using the training set and look how well it predicts the unknown interactions in the testset.
To test our recommender, we create a class called EvaluateRecommender with a main method and add an inner class calledMyRecommenderBuilder that implements the RecommenderBuilder interface. We implement the buildRecommender method and make it setup our user-based recommender:
UserSimilarity similarity = new PearsonCorrelationSimilarity(dataModel);
UserNeighborhood neighborhood = new ThresholdUserNeighborhood(0.1, similarity, dataModel);
return new GenericUserBasedRecommender(dataModel, neighborhood, similarity);
Now we have to create the code for the test. We'll check how much the recommender misses the real interaction strength on average. We employ an AverageAbsoluteDifferenceRecommenderEvaluator for this. The following code shows how to put the pieces together and run a hold-out test:
DataModel model = new FileDataModel(new File("/path/to/dataset.csv"));
RecommenderEvaluator evaluator = new AverageAbsoluteDifferenceRecommenderEvaluator();
RecommenderBuilder builder = new MyRecommenderBuilder();
double result = evaluator.evaluate(builder, null, model, 0.9, 1.0);
System.out.println(result);
Note: if you run this test multiple times, you will get different results, because the splitting into trainingset and testset is done randomly.
Please read full article from Apache Mahout: Scalable machine learning and data mining
Read full article from Apache Mahout: Scalable machine learning and data mining

Playing with the Mahout recommendation engine on a Hadoop cluster | Chimpler



Playing with the Mahout recommendation engine on a Hadoop cluster | Chimpler
The GroupLens Movie DataSet provides the rating of movies in this format. You can download it: MovieLens 100k.
  • u.data: contains several tuples(user_id, movie_id, rating, timestamp)
  • hadoop jar <MAHOUT DIRECTORY>/mahout-core-0.7-job.jar org.apache.mahout.cf.taste.hadoop.item.RecommenderJob -s SIMILARITY_COOCCURRENCE --input u.data --output output
  • With the argument “-s SIMILARITY_COOCURRENCE”, we tell the recommender which item similary formula to use. With SIMILARITY COOCURRENCE, two items(movies) are very similar if they often appear together in users’ rating. So to find the movies to recommend to a user, we need to find the 10 movies most similar to the movies the user has rated. Or said differently, if a user A gives a good rating on movie X and other users gives a good rating on movie X and movie Y, then we can recommend the movie Y to the user A.
    Mahout computes the recommendations by running several Hadoop mapreduce jobs.
    After 30-50 minutes, the jobs are finished and each user will have the 10 movies that she might mostly like based on the co-occurrence of each movie in users’ reviews.
To copy and merge the files from HDFS to your local filesystem, type:
hadoop fs -getmerge output output.txt
1       [845:5.0,550:5.0,546:5.0,25:5.0,531:5.0,529:5.0,527:5.0,31:5.0,515:5.0,514:5.0] 
Each line represents the recommendation for a user. The first number is the user id and the 10 number pairs represents a movie id and a score.
If we are looking at the first line for example, it means that for the user 1, the 10 best recommendations are for the movies 845, 550, 546, 25 ,531, 529, 527, 31, 515, 514.
It’s not easy to see what those recommendation means so we wrote a small python program to show for a given user, the movies he has rated and the movies we recommend him.
The python program uses the file u.data for the list of rated movies, the file u.item to get the movie titles and output.txt to get the list of recommended movies for the user.

import sys
 
if len(sys.argv) != 5:
        print "Arguments: userId userDataFilename movieFilename recommendationFilename"
        sys.exit(1)
 
userId, userDataFilename, movieFilename, recommendationFilename = sys.argv[1:]
 
print "Reading Movies Descriptions"
movieFile = open(movieFilename)
movieById = {}
for line in movieFile:
        tokens = line.split("|")
        movieById[tokens[0]] = tokens[1:]
movieFile.close()
 
print "Reading Rated Movies"
userDataFile = open(userDataFilename)
ratedMovieIds = []
for line in userDataFile:
        tokens = line.split("\t")
        if tokens[0] == userId:
                ratedMovieIds.append((tokens[1],tokens[2]))
userDataFile.close()
 
print "Reading Recommendations"
recommendationFile = open(recommendationFilename)
recommendations = []
for line in recommendationFile:
        tokens = line.split("\t")
        if tokens[0] == userId:
                movieIdAndScores = tokens[1].strip("[]\n").split(",")
                recommendations = [ movieIdAndScore.split(":") for movieIdAndScore in movieIdAndScores ]
                break
recommendationFile.close()
 
print "Rated Movies"
print "------------------------"
for movieId, rating in ratedMovieIds:
        print "%s, rating=%s" % (movieById[movieId][0], rating)
print "------------------------"
 
print "Recommended Movies"
print "------------------------"
for movieId, score in recommendations:
        print "%s, score=%s" % (movieById[movieId][0], score)
print "------------------------"
Read full article from Playing with the Mahout recommendation engine on a Hadoop cluster | Chimpler

Labels

Algorithm (219) Lucene (130) LeetCode (97) Database (36) Data Structure (33) text mining (28) Solr (27) java (27) Mathematical Algorithm (26) Difficult Algorithm (25) Logic Thinking (23) Puzzles (23) Bit Algorithms (22) Math (21) List (20) Dynamic Programming (19) Linux (19) Tree (18) Machine Learning (15) EPI (11) Queue (11) Smart Algorithm (11) Operating System (9) Java Basic (8) Recursive Algorithm (8) Stack (8) Eclipse (7) Scala (7) Tika (7) J2EE (6) Monitoring (6) Trie (6) Concurrency (5) Geometry Algorithm (5) Greedy Algorithm (5) Mahout (5) MySQL (5) xpost (5) C (4) Interview (4) Vi (4) regular expression (4) to-do (4) C++ (3) Chrome (3) Divide and Conquer (3) Graph Algorithm (3) Permutation (3) Powershell (3) Random (3) Segment Tree (3) UIMA (3) Union-Find (3) Video (3) Virtualization (3) Windows (3) XML (3) Advanced Data Structure (2) Android (2) Bash (2) Classic Algorithm (2) Debugging (2) Design Pattern (2) Google (2) Hadoop (2) Java Collections (2) Markov Chains (2) Probabilities (2) Shell (2) Site (2) Web Development (2) Workplace (2) angularjs (2) .Net (1) Amazon Interview (1) Android Studio (1) Array (1) Boilerpipe (1) Book Notes (1) ChromeOS (1) Chromebook (1) Codility (1) Desgin (1) Design (1) Divide and Conqure (1) GAE (1) Google Interview (1) Great Stuff (1) Hash (1) High Tech Companies (1) Improving (1) LifeTips (1) Maven (1) Network (1) Performance (1) Programming (1) Resources (1) Sampling (1) Sed (1) Smart Thinking (1) Sort (1) Spark (1) Stanford NLP (1) System Design (1) Trove (1) VIP (1) tools (1)

Popular Posts