{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"_kg_hide-input":true,"_kg_hide-output":true},"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load in \nimport os\nimport sys\nimport itertools\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the \"../input/\" directory.\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Read Class Map"},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"class_map = pd.read_csv('/kaggle/input/bengaliai-cv19/class_map.csv')\ntrain_dataset = pd.read_csv('/kaggle/input/bengaliai-cv19/train.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_dataset.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class_map.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Unicode Components of Grapheme"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Breaking down a grapheme\n# Result corresponds to individual components\n\nprint(list('র্যো'))\n\nprint(list('র্অ্য')) \n\nprint(list('ত্ব'))\n\n# Character '্' acts as a binder to join root with consonant/vowel","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Rules discovered with manual observation from this [Kernel](https://www.kaggle.com/jamesmcguigan/unicode-visualization-of-the-bengali-alphabet) \n\n### 1. Consonant Label-1 has highest priority on right and preceeds vowel position.\n### 2. Consonant Label-2 has highest priority on left and preceeds root and grapheme position.\n### 3. Consonant Label-3 has two components that wraps around root with vowel taking highest priority on left.\n### 4. Consonant Label-4,5,6 has right priority with highest priority given to vowel if any.\n\n### This rules covers all the Graphemes from training data except one."},{"metadata":{},"cell_type":"markdown","source":"## Ultimate Magic"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Collecting mappings of components\nbinder = '্'\nroot_mapper = dict(zip(class_map[class_map.component_type=='grapheme_root'].label.to_list(), class_map[class_map.component_type=='grapheme_root'].component.to_list()))\nvowel_mapper = dict(zip(class_map[class_map.component_type=='vowel_diacritic'].label.to_list(), class_map[class_map.component_type=='vowel_diacritic'].component.to_list()))\nconsonant_mapper = dict(zip(class_map[class_map.component_type=='consonant_diacritic'].label.to_list(), class_map[class_map.component_type=='consonant_diacritic'].component.to_list()))\ncover_edge_cases = True","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Abra Kadabra\nfinal_output = []\nfor combination in list(itertools.product(range(168),range(11), range(7))): # create tuple of every combinations and iterate over\n    output = ''\n    root = combination[0]\n    vowel = combination[1]\n    consonant = combination[2]\n    \n    root_label = root_mapper[root]\n    vowel_label = vowel_mapper[vowel]\n    consonant_label = consonant_mapper[consonant]\n    \n    # Ignore root with label 0 and 1\n    if root in [0, 1] and vowel==0 and consonant==0:\n        output = root_label\n        \n    elif root in [0, 1] and (vowel!=0 or consonant!=0):\n        pass\n    \n    elif root != 0:\n        if consonant == 0 and vowel==0:\n            output = list(root_label)\n            output = ''.join(output)\n            \n        elif consonant ==  0 and vowel!=0:\n            output = list(root_label) + list(vowel_label)\n            output = ''.join(output)\n            \n        elif consonant in [1,2,3]:   \n            if consonant==1 and vowel==0:  #High priority on right. preceedes vowel position\n                output = list(root_label) + list(consonant_label)\n                output = ''.join(output)\n            elif consonant==1 and vowel!=0:  #High priority on right. preceedes vowel position\n                output = list(root_label)+ list(vowel_label) + list(consonant_label)\n                output = ''.join(output)\n\n            elif consonant==2 and vowel==0: #High priority on left.\n                output = list(consonant_label) + list(root_label)\n                output = ''.join(output)\n                \n                #Edge Case Handling regarding consonant==2 র‍্যা র্দ্র র্ত্রী র্ত্রে\n                if cover_edge_cases:\n                    final_output.append([root, vowel, consonant, output])\n                    output = list(consonant_label) + list(root_label) + [binder] + list(consonant_label[0])\n                    output = ''.join(output)\n                \n\n            elif consonant==2 and vowel!=0: #High priority on left.\n                output = list(consonant_label) + list(root_label) + list(vowel_label)\n                output = ''.join(output)\n                \n                #Edge Case Handling regarding consonant==2 র‍্যা র্দ্র র্ত্রী র্ত্রে\n                if cover_edge_cases:\n                    final_output.append([root, vowel, consonant, output])\n                    output = list(consonant_label) + list(root_label) + [binder] + list(consonant_label[0]) + list(vowel_label)\n                    output = ''.join(output)\n\n            elif consonant==3 and vowel==0: #Split priority Left and Right rest in middle.\n                output = list(consonant_label[0])+ [binder] + list(root_label) + [binder] + list(consonant_label[-1])\n                output = ''.join(output)    \n\n            elif consonant==3 and vowel!=0: #Split priority Left and Right rest in middle.\n                output = list(consonant_label[0])+ [binder] + list(root_label) + [binder] + list(consonant_label[-1]) + list(vowel_label)\n                output = ''.join(output)\n                \n        elif consonant in [4,5,6]:  \n            if consonant in [4, 5, 6] and vowel==0: #Soft Right priority\n                output = list(root_label) + list(consonant_label)\n                output = ''.join(output) \n\n            elif consonant in [4, 5, 6] and vowel!=0: #Soft Right priority\n                output = list(root_label) + list(consonant_label) + list(vowel_label)\n                output = ''.join(output) \n            \n    else:\n        print(combination)\n        break\n        \n    if output:\n        final_output.append([root, vowel, consonant, output])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"full_dataset = pd.DataFrame(final_output, columns=['grapheme_root', 'vowel_diacritic', 'consonant_diacritic', 'grapheme'])\nfull_dataset['image_id'] = full_dataset.index\nfull_dataset['image_id'] = 'Train_' + full_dataset['image_id'].astype(str)\ncols = full_dataset.columns.tolist()\ncols = cols[-1:] + cols[:-1]\nfull_dataset = full_dataset[cols]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"full_dataset.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"len(full_dataset) # 168 x 11 x 7 = 12784 + 1826 (Edge Cases)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for char in train_dataset.grapheme.unique():\n    if char not in full_dataset.grapheme.tolist():\n        print('Missing Grapheme: ', char)\n        print('Unicode Components: ',list(char))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"full_dataset.to_csv('BengaliAllCombinationsGrapheme.csv', index=None)","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":4}