# Products classification by name

I am a beginner with machine learning, and I'm trying to build a model to classify products by category according to the words present in the product name. My goal is to predict the category of some new product, just by observing the categories for existing products.
For example, having the following products:

PRODUCT                                     CATEGORY
soap bar johnsons green leaves              bath
strawberry soap soft                        bath
spoon hercules medium                       kitchen
soap dish plastic medium                    bath
[...]


My first thought is to group the words (tokens) present in each product, indicating the designated category and the occurrences count (to be used as a weight). So, for this sample, I have:

WORD           CATEGORY         COUNT
soap           bath             3
medium         bath             1
medium         kitchen          1
bar            bath             1
johnsons       bath             1


Having this, I could be able to train a model, and use it to classify a new product.

For example, having a new product hands liquid soap 120oz, it could be classified as bath, because it contains the word soap, which have a strong weight for the bath category.

In other case, the new product medium hammer could be classified as bath or kitchen , according the occurrence of the word medium in the training set.

So, my doubts are:

• Am I going to the correct approach?
• What is the best algorithm to be used in this case?
• How can I apply this using Weka?
• Do you know anything about zero-shot learning and word embedding algorithms? – Alireza Zolanvari Mar 15 '19 at 7:59
• @alirezazolanvari no, but I'll search for. – elias Mar 15 '19 at 13:25
• @elias how many CATEGORY do you have ? – mujjiga Mar 17 '19 at 20:52
• @mujjiga about 3.000 – elias Mar 18 '19 at 16:43
• @elias do you mean 3 or 3000 ? :) – mujjiga Mar 18 '19 at 17:51

I think, and have done similar problem too, that this problem can be solved in this way:
1. Generate NGrams
2. Create 1 hot encoding matrix
3. Pass to Naive Bayes or Random forest

It would automatically count the words count (you can apply TFIDF too) and based on that weightage will be calculated.
Examples:

If you have enough data and reasonable number of classes, you can definitely train your model. The grouping of words that you have done is similar to an approach called bag-of-words model. You can use that to build a classifier using Naive Bayes or SVM etc. On a different note, you can also look at the KNN algorithm because it looks fit for your use case. You can have a look at this paper

You can also try Tfidf Vectorizer from Sklearn which would be helpful in your case, As Tfidf vectorization inherently is able to learn and differentiate between the frequently occurring words and rarely occurring words by calculating the product of term frequency and inverse document frequency. Check here for more details. On top of this featurization, You can try Naive Bayes as it's pretty fast and seems to work well for text data as it uses with conditional probabilities. Use performance metrics such as confusion matrix to get a better sense of what is happening as accuracy is not a good measure when your data is imbalance. Hope it helps

This should be doable with pre-trained word vectors + document/sentence vectors. Tutorial : https://medium.com/scaleabout/a-gentle-introduction-to-doc2vec-db3e8c0cce5e

All Product labels with "similar meanings" should cluster in a short distance.

After product name ha been transformed into a vector, vector can be fed into a logistic regression classifier (Or a shallow neural network).

The steps are the following:

1. Prepare your dataset. Put everything in a dataframe. Divide it in train and test (or even train, cv and test). Use of the order of 10k samples for the test set, or 10-20%, whatever is smaller. Consider using https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html
2. Encode your input. You can convert the input, which is a string, to a bag of words, or to a TFIDF. Consider using https://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.text.TfidfVectorizer.html.
3. Instantiate and train your model. You can use for example a simple logistic regression model, for example https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html.
4. Test the performance of the model. Use the test set to understand how well your model is doing. You can use for example the accuracy (https://scikit-learn.org/stable/modules/generated/sklearn.metrics.accuracy_score.html) or the precision and recall for each class (https://scikit-learn.org/stable/modules/generated/sklearn.metrics.precision_score.html and https://scikit-learn.org/stable/modules/generated/sklearn.metrics.recall_score.html). Understand well what they mean (https://en.wikipedia.org/wiki/Precision_and_recall).

Your pseudocode should be something like:

-> Divide train and test set. Output: X_train, y_train, X_test, y_test
-> Instantiate tfidf and the desired model (e.g. logistic regression).
-> Fit tfidf with X_train (e.g. use .fit_transform) and get the X_train_transformed
-> Fit the model (e.g. using .fit) with X_train_transformed and y_train
-> Use X_test to get a prediction y_pred of the model (first pass it through tfidf and then through the model object, e.g. using .predict)
-> Use y_pred and y_test to get some metrics to understand the performance of the model.


Hope this works for you.