{"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_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Introduction","metadata":{}},{"cell_type":"markdown","source":"Welcome to the first of a series of notebooks on the TensorFlow Great Barrier Reef Competition. This first notebook will be an EDA with animations to get a better idea of how to process/display the data.","metadata":{}},{"cell_type":"markdown","source":"# Part 1. EDA","metadata":{}},{"cell_type":"code","source":"#Import libraries\nimport pandas as pd\nimport numpy as np\nimport os\nimport ast\nimport seaborn as sns\nimport cv2\nfrom matplotlib import animation, rc\nimport matplotlib.pyplot as plt\n%matplotlib inline\nrc('animation', html='jshtml')","metadata":{"execution":{"iopub.status.busy":"2022-01-01T15:57:39.688897Z","iopub.execute_input":"2022-01-01T15:57:39.689606Z","iopub.status.idle":"2022-01-01T15:57:40.917081Z","shell.execute_reply.started":"2022-01-01T15:57:39.689484Z","shell.execute_reply":"2022-01-01T15:57:40.916383Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train = pd.read_csv('../input/tensorflow-great-barrier-reef/train.csv')\ntest = pd.read_csv('../input/tensorflow-great-barrier-reef/test.csv')","metadata":{"execution":{"iopub.status.busy":"2022-01-01T15:57:40.918284Z","iopub.execute_input":"2022-01-01T15:57:40.918636Z","iopub.status.idle":"2022-01-01T15:57:40.984348Z","shell.execute_reply.started":"2022-01-01T15:57:40.918607Z","shell.execute_reply":"2022-01-01T15:57:40.98356Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.head()","metadata":{"execution":{"iopub.status.busy":"2022-01-01T15:57:40.985468Z","iopub.execute_input":"2022-01-01T15:57:40.985797Z","iopub.status.idle":"2022-01-01T15:57:41.006943Z","shell.execute_reply.started":"2022-01-01T15:57:40.985763Z","shell.execute_reply":"2022-01-01T15:57:41.006164Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.tail()","metadata":{"execution":{"iopub.status.busy":"2022-01-01T15:57:41.008552Z","iopub.execute_input":"2022-01-01T15:57:41.008758Z","iopub.status.idle":"2022-01-01T15:57:41.020235Z","shell.execute_reply.started":"2022-01-01T15:57:41.008732Z","shell.execute_reply":"2022-01-01T15:57:41.019259Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test.head()","metadata":{"execution":{"iopub.status.busy":"2022-01-01T15:57:41.023689Z","iopub.execute_input":"2022-01-01T15:57:41.023951Z","iopub.status.idle":"2022-01-01T15:57:41.035739Z","shell.execute_reply.started":"2022-01-01T15:57:41.023921Z","shell.execute_reply":"2022-01-01T15:57:41.034898Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test.tail()","metadata":{"execution":{"iopub.status.busy":"2022-01-01T15:57:41.037337Z","iopub.execute_input":"2022-01-01T15:57:41.037659Z","iopub.status.idle":"2022-01-01T15:57:41.053078Z","shell.execute_reply.started":"2022-01-01T15:57:41.037617Z","shell.execute_reply":"2022-01-01T15:57:41.052087Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.info()","metadata":{"execution":{"iopub.status.busy":"2022-01-01T15:57:41.054601Z","iopub.execute_input":"2022-01-01T15:57:41.054945Z","iopub.status.idle":"2022-01-01T15:57:41.084833Z","shell.execute_reply.started":"2022-01-01T15:57:41.054898Z","shell.execute_reply":"2022-01-01T15:57:41.084234Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test.info()","metadata":{"execution":{"iopub.status.busy":"2022-01-01T15:57:41.085744Z","iopub.execute_input":"2022-01-01T15:57:41.086596Z","iopub.status.idle":"2022-01-01T15:57:41.098882Z","shell.execute_reply.started":"2022-01-01T15:57:41.086549Z","shell.execute_reply":"2022-01-01T15:57:41.098007Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(train.duplicated().sum())\nprint(test.duplicated().sum())","metadata":{"execution":{"iopub.status.busy":"2022-01-01T15:57:41.10021Z","iopub.execute_input":"2022-01-01T15:57:41.101002Z","iopub.status.idle":"2022-01-01T15:57:41.123522Z","shell.execute_reply.started":"2022-01-01T15:57:41.100958Z","shell.execute_reply":"2022-01-01T15:57:41.12266Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We can see that all data is present and singular. However, note that the annotations are provided in string format. We need to use ast to convert to arrays.","metadata":{}},{"cell_type":"code","source":"train['annotations_list'] = train['annotations'].apply(lambda x: ast.literal_eval(x))","metadata":{"execution":{"iopub.status.busy":"2022-01-01T15:57:41.12563Z","iopub.execute_input":"2022-01-01T15:57:41.125851Z","iopub.status.idle":"2022-01-01T15:57:41.50585Z","shell.execute_reply.started":"2022-01-01T15:57:41.125824Z","shell.execute_reply":"2022-01-01T15:57:41.504941Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Displaying a few countplots to see distributions:","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(15, 15))\nplt.title(\"Number Of Frames Containing X Starfish\")\nstarfish_count = sns.countplot(x = train['annotations_list'].apply(lambda x: len(x)))\nstarfish_count.bar_label(starfish_count.containers[0])","metadata":{"execution":{"iopub.status.busy":"2022-01-01T15:57:41.507235Z","iopub.execute_input":"2022-01-01T15:57:41.507481Z","iopub.status.idle":"2022-01-01T15:57:42.049016Z","shell.execute_reply.started":"2022-01-01T15:57:41.50745Z","shell.execute_reply":"2022-01-01T15:57:42.048345Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We can see here that most entries are empty, but a few frames have 1 starfish, and potentially as much as 18. ","metadata":{}},{"cell_type":"code","source":"video_count = sns.countplot(x = train['video_id'])\nvideo_count.bar_label(video_count.containers[0])\nplt.title(\"Number Of Frames For Each Video ID\")","metadata":{"execution":{"iopub.status.busy":"2022-01-01T15:57:42.050227Z","iopub.execute_input":"2022-01-01T15:57:42.0505Z","iopub.status.idle":"2022-01-01T15:57:42.272038Z","shell.execute_reply.started":"2022-01-01T15:57:42.050469Z","shell.execute_reply":"2022-01-01T15:57:42.271272Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"It's roughly an equal distribution of frames between the videos, with video_id 2 earning the plurality of them.","metadata":{}},{"cell_type":"code","source":"for i in train['video_id'].unique():\n    plt.figure(figsize=(10, 10))\n    plt.title(\"Number of Starfish In Each Frame of Video \" + str(i))\n    temp = train[train['video_id'] == i]\n    starfish_count_vid = sns.countplot(x = temp['annotations_list'].apply(lambda x: len(x)))\n    starfish_count_vid.bar_label(starfish_count_vid.containers[0])\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2022-01-01T15:57:42.273191Z","iopub.execute_input":"2022-01-01T15:57:42.273415Z","iopub.status.idle":"2022-01-01T15:57:43.372713Z","shell.execute_reply.started":"2022-01-01T15:57:42.273387Z","shell.execute_reply":"2022-01-01T15:57:43.371883Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We see here that video 0 doesn't contain that many starfish, while videos 1 and 2 contain significantly more. In addition, video 0 will have a starfish on screen for longer than videos 1 and 2.","metadata":{}},{"cell_type":"code","source":"train['temp'] = list(zip(train.video_id, train.sequence))\nsns.countplot(x = train['temp'])\nplt.xticks(rotation = 90)","metadata":{"execution":{"iopub.status.busy":"2022-01-01T16:01:19.396212Z","iopub.execute_input":"2022-01-01T16:01:19.396528Z","iopub.status.idle":"2022-01-01T16:01:19.7819Z","shell.execute_reply.started":"2022-01-01T16:01:19.396482Z","shell.execute_reply":"2022-01-01T16:01:19.780947Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Lastly, we can see that there are 20 different sequences of videos, with the most coming from sequences 8503, 29859, 37114, and 60754. Of special note is that those sequences are from video IDs 1 and 2, primarily; video 0 instead contains more evenly distributed sets of sequences. ","metadata":{}},{"cell_type":"markdown","source":"With this out of the way, we can proceed to head to the videos themselves.","metadata":{}},{"cell_type":"code","source":"def createVideo(video_id, num_frames, start_frame):\n    video = []\n    directory = ('../input/tensorflow-great-barrier-reef/train_images/video_' + str(video_id) + '/')\n    for i in range(num_frames):\n        image = cv2.imread(directory + str(start_frame + i) + '.jpg', 1)\n        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n        temp = train[(train['video_id'] == video_id) & (train['video_frame'] == start_frame + i)].iloc[0]\n        starfish_box = temp.annotations_list\n        for j in starfish_box:\n            x0, y0, x1, y1 = (j['x'], j['y'], j['x'] + j['width'], j['y'] + j['height'])\n            cv2.rectangle(image, (x0, y0), (x1, y1), (255,0,0), 3)\n        video.append(image)\n    return video","metadata":{"execution":{"iopub.status.busy":"2022-01-01T15:57:43.732619Z","iopub.execute_input":"2022-01-01T15:57:43.733055Z","iopub.status.idle":"2022-01-01T15:57:43.741992Z","shell.execute_reply.started":"2022-01-01T15:57:43.733013Z","shell.execute_reply":"2022-01-01T15:57:43.741306Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def showVideo(video_array):\n    fig = plt.figure(figsize=(9, 9))\n    plt.axis('off')\n    im = plt.imshow(video_array[0])\n    def animate_func(i):\n        im.set_array(video_array[i])\n        return [im]\n    return animation.FuncAnimation(fig, animate_func, frames = len(video_array), interval = 1000 // 24)","metadata":{"execution":{"iopub.status.busy":"2022-01-01T15:57:43.743044Z","iopub.execute_input":"2022-01-01T15:57:43.743239Z","iopub.status.idle":"2022-01-01T15:57:43.759007Z","shell.execute_reply.started":"2022-01-01T15:57:43.743214Z","shell.execute_reply":"2022-01-01T15:57:43.758222Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"video_array = createVideo(video_id = 0, num_frames = 100, start_frame = 0)\nshowVideo(video_array)","metadata":{"execution":{"iopub.status.busy":"2022-01-01T15:57:43.759867Z","iopub.execute_input":"2022-01-01T15:57:43.760616Z","iopub.status.idle":"2022-01-01T15:57:59.838241Z","shell.execute_reply.started":"2022-01-01T15:57:43.760581Z","shell.execute_reply":"2022-01-01T15:57:59.83747Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Credit to Diego Gomez for the inspiration: https://www.kaggle.com/diegoalejogm/great-barrier-reefs-eda-with-animations","metadata":{}},{"cell_type":"markdown","source":"Next time, we proceed with a baseline model. See you then!","metadata":{}},{"cell_type":"markdown","source":"UPDATE 1/1/22: Added in sequence countplot. ","metadata":{}}]}