<jupyter_start><jupyter_text>Food embeddings made using ingredients>"Visualize food recipes based on their clustering as per ingredients"- toc:true- badges: true- comments: true- author: <NAME>- categories: [python, exploratory-data-analysis, data-visualization, web-scrapping]  Get data for food items and recipes I use a Kaggle dataset containing 6000+ recipes from https://www.archanaskitchen.com/. Using this data as base collection of recipes representing most of the indian food, I analyze which spices occur most freqeuntly and which spices are most connected to each other. * Dataset for Indian recipe: This dataset 6000+ recipe scrapped from  | [Link to the dataset](https://www.kaggle.com/kanishk307/6000-indian-food-recipes-dataset)<jupyter_code>import pandas as pd 
import numpy as np 
#----- PLOTTING PARAMS ----# 
import matplotlib.pyplot as plt
from matplotlib.pyplot import cm
import seaborn as sns
%config InlineBackend.figure_format = 'retina'
%config InlineBackend.print_figure_kwargs={'facecolor' : "w"}

plot_params = {
'font.size' : 22,
'axes.titlesize' : 24,
'axes.labelsize' : 20,
'xtick.labelsize' : 16,
'ytick.labelsize' : 16,
}
 
plt.rcParams.update(plot_params)
# Functions for PMF and CDF, we will come to those later in the notebook 
def pmf(pandas_series):
    value, counts = np.unique(pandas_series, return_counts=True)
    pmf = np.c_[ value, counts / sum(counts) ]
    return pmf 

def cdf(pandas_series):
    pmf_data = pmf(pandas_series)
    cdf = np.zeros(shape=pmf_data.shape)
    
    for i in range(0, cdf.shape[0]):
        cdf[i] = [ pmf_data[i][0], np.sum(pmf_data[0:i][:,1]) ]
    return cdf<jupyter_output><empty_output><jupyter_text>Read the dataset<jupyter_code>food_df = pd.read_csv('./IndianFoodDatasetCSV.csv')
food_df.columns
food_df.shape
food_df.sample(4)
food_df.info()
# dropping miscellaneous columns and NaN entries
columns_to_drop = ['Srno', 'RecipeName', 'CookTimeInMins', 'TotalTimeInMins', 'Servings', 'Instructions', 'TranslatedInstructions', 'Ingredients', 'URL']
food_df = food_df.drop(columns=columns_to_drop)
food_df.shape<jupyter_output><empty_output><jupyter_text>Check out null entries<jupyter_code>food_df.columns[food_df.isnull().any()]
food_df.iloc[ np.where(food_df.isnull().any())[0] ]<jupyter_output><empty_output><jupyter_text>Column-wise view of number of null entries in the dataframe<jupyter_code>null_columns=food_df.columns[food_df.isnull().any()]
food_df[null_columns].isnull().sum()<jupyter_output><empty_output><jupyter_text>Views columns with atleast 1 null entry<jupyter_code>is_NaN = food_df.isnull()
row_has_NaN = is_NaN.any(axis=1)
food_df[row_has_NaN]
food_df = food_df.dropna()
print(food_df.shape)
# data has indian-inspired international cuisines which are not what we are interested in
cuisin_counts = food_df['Cuisine'].value_counts()
cuisin_counts_more_than_50 = cuisin_counts.iloc[np.where(cuisin_counts > 50)]
food_df_top_cuisine = food_df.loc[ food_df['Cuisine'].isin(list(cuisin_counts_more_than_50.index))  ] #Dropping entries in `food_df` which have non-ind
food_df_top_cuisine.shape
food_df_top_cuisine['Cuisine'].value_counts()
south_indian_tag = ['Chettinad', 'Andhra', 'Karnataka', 'Tamil Nadu', 'Kerala Recipes', 'South Indian Recipes']
central_indian_tag = ['Gujarati Recipes', 'Goan Recipes', 'Rajasthani', 'Maharashtrian Recipes']
north_indian_tag = ['North Indian Recipes', 'Punjabi', 'Kashmiri']
food_df_top_cuisine
food_df_top_cuisine.loc[food_df_top_cuisine['Cuisine'].isin(south_indian_tag), 'Combined_cuisine'] = 'South Indian'
food_df_top_cuisine.loc[food_df_top_cuisine['Cuisine'].isin(central_indian_tag), 'Combined_cuisine'] = 'Central Indian'
food_df_top_cuisine.loc[food_df_top_cuisine['Cuisine'].isin(north_indian_tag), 'Combined_cuisine'] = 'North Indian'
food_df_top_cuisine.loc[ ~food_df_top_cuisine['Combined_cuisine'].isnull() ]['Combined_cuisine'].value_counts()
food_df_top_cuisine.head(5)
food_df_top_cuisine['Course'].value_counts()
breakfast_tag = ['South Indian Breakfast', 'North Indian Breakfast', 'Indian Breakfast', 'World Breakfast']
food_df_top_cuisine['Combined_Course'] = food_df_top_cuisine['Course'].copy()
food_df_top_cuisine.loc[ food_df_top_cuisine['Course'].isin(breakfast_tag), 'Combined_Course'] = 'Breakfast'
food_df_top_cuisine = food_df_top_cuisine.reset_index(drop=True)<jupyter_output><empty_output><jupyter_text>Drop non-english entries for consistency<jupyter_code># Some entries in the `TranslatedIngredients` have non-english entries 
def filter_english(string):
    try:
        string.encode('utf-8').decode('ascii')
        out = True
    except UnicodeDecodeError: 
        out = False
    return out
# Droping columns in the dataset having ingredients in language other than english 
df = food_df_top_cuisine.loc[ food_df_top_cuisine['TranslatedIngredients'].apply(filter_english) ]
df.shape
df = df.reset_index(drop=True)
df.head(10)
string_words_common = ['to taste', 'as required', 'tablespoon', 'teaspoon', 'cup', 'cups']
# Text cleaning function 
import re
def clean_symbols(row_entry):
    return re.sub(r'\W+|[0-9,]+', ' ', row_entry).strip().lower().replace('  ','')
clean_symbols(df['TranslatedIngredients'][0])
df['TranslatedIngredients'].map(clean_symbols)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.12561763587989358, 'fraction_numerical': 0.008931965032307108, 'mean_word_length': 6.998480243161095, 'pattern_counts': {'":': 0, '<': 26, '<?xml version=': 0, '>': 28, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '555476', 'license': 'Apache-2.0', 'n_tokens_mistral': 1974, 'n_tokens_neox': 1864, 'n_words': 380, 'path': '_notebooks/data/.ipynb_checkpoints/2021-05-20-Food_embeddings-checkpoint.ipynb', 'repo_name': 'pgg1610/blog_fastpages', 'size': '5275'}