{"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.10.0"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":53666,"databundleVersionId":6589269,"sourceType":"competition"}],"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true},"papermill":{"default_parameters":{},"duration":4426.523986,"end_time":"2024-08-21T15:32:55.865671","environment_variables":{},"exception":null,"input_path":"__notebook__.ipynb","output_path":"__notebook__.ipynb","parameters":{},"start_time":"2024-08-21T14:19:09.341685","version":"2.4.0"},"widgets":{"application/vnd.jupyter.widget-state+json":{"state":{"04a02fa7eb134b8ba71bfb7ac786a296":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"066742cb687d47e5951ef8dca76dba9c":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"140168e7812240ba9466d1dda5eed8ba":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_d40a783824ec4c95a57c0dbb91062a70","placeholder":"​","style":"IPY_MODEL_53a87c03b90b44c9bf4b20eab4f9a7c6","value":"100%"}},"243288b9694c4515a07c9ae094a94025":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"292ed40f89474a808b713abd79c6faa5":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"2afbc94ce7c34e6cbddebc58ebc22c09":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"2da40a6bf2734162b22cda62145810a6":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"2e040b55749b4f87a3519dbdaba56c93":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"35856dd8abe54eaead0873b8b0c7f7df":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"38080ba4a8334c0b92780141c9fc50df":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"3ab5075b918b4f188e9df820982a7962":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"FloatProgressModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"FloatProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"ProgressView","bar_style":"success","description":"","description_tooltip":null,"layout":"IPY_MODEL_2afbc94ce7c34e6cbddebc58ebc22c09","max":5380,"min":0,"orientation":"horizontal","style":"IPY_MODEL_49dc7d146f844409b47cbc8a6dc83463","value":5380}},"3edf82cd2f6a4defbd50ab7bd5776819":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"495920747ef94e84890690c6ceeae1ec":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"FloatProgressModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"FloatProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"ProgressView","bar_style":"success","description":"","description_tooltip":null,"layout":"IPY_MODEL_68318c5fbcb9489289a905fd475d55e6","max":277,"min":0,"orientation":"horizontal","style":"IPY_MODEL_7b6f47188862495f8c1aebf24531bac5","value":277}},"49dc7d146f844409b47cbc8a6dc83463":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"ProgressStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","bar_color":null,"description_width":""}},"4d30e4538e964eb7b2e13cd30718bba9":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"4f40895e3e1b4c3cab6fcec8b5086463":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"53a87c03b90b44c9bf4b20eab4f9a7c6":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"55205f7d637d44c898a95be214832267":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"5d5b3c57aec143929451c45e44970aac":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HBoxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_837ca76e99cc451299eec274752bd94a","IPY_MODEL_7082d34f610641e4923c1789e598e4e6","IPY_MODEL_c7faee4ac907404e81ae906f4987d374"],"layout":"IPY_MODEL_292ed40f89474a808b713abd79c6faa5"}},"5dbc007ba2e14736a9a2a4858be7af06":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"627492dde2a44f7ba9e1a44089922c4b":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"68318c5fbcb9489289a905fd475d55e6":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"68cfde5646ad48c1b7785b8b6f55c37a":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"7082d34f610641e4923c1789e598e4e6":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"FloatProgressModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"FloatProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"ProgressView","bar_style":"success","description":"","description_tooltip":null,"layout":"IPY_MODEL_68cfde5646ad48c1b7785b8b6f55c37a","max":5380,"min":0,"orientation":"horizontal","style":"IPY_MODEL_9484b0e8f7ab44b3b986016dab5d5bdb","value":5380}},"791d37aa0c0f431a8ec6fa9c7823ae49":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"7b6f47188862495f8c1aebf24531bac5":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"ProgressStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","bar_color":null,"description_width":""}},"7cd92a9c06bd48e5bf2e86f2a9071b4d":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_55205f7d637d44c898a95be214832267","placeholder":"​","style":"IPY_MODEL_c9abb62330a14c0b9b550d0b6b53913d","value":" 5380/5380 [00:55&lt;00:00, 114.29it/s]"}},"837ca76e99cc451299eec274752bd94a":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_4d30e4538e964eb7b2e13cd30718bba9","placeholder":"​","style":"IPY_MODEL_d75102dd68c84d71be16ba8d7a9b5d1e","value":"Matching detections: 100%"}},"88535c5987db4e82abb7794108718f0b":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"8e8cc658c17e4b86a3c60d7f553d8738":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"8f79fe67eb4d49689b322d9a59e4e11a":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"9484b0e8f7ab44b3b986016dab5d5bdb":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"ProgressStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","bar_color":null,"description_width":""}},"98cdfcf52b884bda8e8234292d784180":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"98ffd4cba55a496e97279af4151313d1":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_35856dd8abe54eaead0873b8b0c7f7df","placeholder":"​","style":"IPY_MODEL_5dbc007ba2e14736a9a2a4858be7af06","value":" 277/277 [00:13&lt;00:00, 19.53it/s]"}},"9e02d692f7264dae8afec2a4a714deaa":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"a585bccf3fe74604b82e7d83420953e9":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_2da40a6bf2734162b22cda62145810a6","placeholder":"​","style":"IPY_MODEL_04a02fa7eb134b8ba71bfb7ac786a296","value":"100%"}},"aa27b554f6f1490e9efd393807cb6ca7":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"b2728370d395459ebe1f9f8d7a6a3f5f":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"ProgressStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","bar_color":null,"description_width":""}},"b39322f78b6149a8b277109225ae2043":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HBoxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_c828a1930fbb4d3fa71fdf786bf1cda4","IPY_MODEL_d877370e4c42444d9a88460e06578634","IPY_MODEL_e0311a664a8443ebbbb6f56e1430fe8c"],"layout":"IPY_MODEL_4f40895e3e1b4c3cab6fcec8b5086463"}},"b3ad5f497ac54938b558e0096c65a591":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HBoxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_fb8134f9ce764b2cbef172eb22fb8945","IPY_MODEL_3ab5075b918b4f188e9df820982a7962","IPY_MODEL_7cd92a9c06bd48e5bf2e86f2a9071b4d"],"layout":"IPY_MODEL_98cdfcf52b884bda8e8234292d784180"}},"b716677406d1410d86e0b4ff47eaa85d":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"bd0b5e7fd7bf4f72aabf65817884f130":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HBoxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_140168e7812240ba9466d1dda5eed8ba","IPY_MODEL_d810e1e659c24ead83e521e83594b87d","IPY_MODEL_ed85114c140c42f78ca717e87979a99d"],"layout":"IPY_MODEL_8f79fe67eb4d49689b322d9a59e4e11a"}},"c7528fffe082477e8fd074e4ce9a1621":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"c7faee4ac907404e81ae906f4987d374":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_38080ba4a8334c0b92780141c9fc50df","placeholder":"​","style":"IPY_MODEL_243288b9694c4515a07c9ae094a94025","value":" 5380/5380 [00:54&lt;00:00, 108.91it/s]"}},"c828a1930fbb4d3fa71fdf786bf1cda4":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_8e8cc658c17e4b86a3c60d7f553d8738","placeholder":"​","style":"IPY_MODEL_791d37aa0c0f431a8ec6fa9c7823ae49","value":"100%"}},"c9abb62330a14c0b9b550d0b6b53913d":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"d40a783824ec4c95a57c0dbb91062a70":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"d75102dd68c84d71be16ba8d7a9b5d1e":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"d810e1e659c24ead83e521e83594b87d":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"FloatProgressModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"FloatProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"ProgressView","bar_style":"success","description":"","description_tooltip":null,"layout":"IPY_MODEL_c7528fffe082477e8fd074e4ce9a1621","max":277,"min":0,"orientation":"horizontal","style":"IPY_MODEL_b2728370d395459ebe1f9f8d7a6a3f5f","value":277}},"d877370e4c42444d9a88460e06578634":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"FloatProgressModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"FloatProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"ProgressView","bar_style":"success","description":"","description_tooltip":null,"layout":"IPY_MODEL_88535c5987db4e82abb7794108718f0b","max":277,"min":0,"orientation":"horizontal","style":"IPY_MODEL_ebb8342a7db943aa9def8c73d4e11688","value":277}},"dc60f6755f0d4ab2bb67dcbff4ad18b0":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HBoxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_a585bccf3fe74604b82e7d83420953e9","IPY_MODEL_495920747ef94e84890690c6ceeae1ec","IPY_MODEL_98ffd4cba55a496e97279af4151313d1"],"layout":"IPY_MODEL_9e02d692f7264dae8afec2a4a714deaa"}},"e0311a664a8443ebbbb6f56e1430fe8c":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_627492dde2a44f7ba9e1a44089922c4b","placeholder":"​","style":"IPY_MODEL_066742cb687d47e5951ef8dca76dba9c","value":" 277/277 [07:22&lt;00:00,  1.96s/it]"}},"ebb8342a7db943aa9def8c73d4e11688":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"ProgressStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","bar_color":null,"description_width":""}},"ed85114c140c42f78ca717e87979a99d":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_3edf82cd2f6a4defbd50ab7bd5776819","placeholder":"​","style":"IPY_MODEL_2e040b55749b4f87a3519dbdaba56c93","value":" 277/277 [00:01&lt;00:00, 252.17it/s]"}},"fb8134f9ce764b2cbef172eb22fb8945":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_b716677406d1410d86e0b4ff47eaa85d","placeholder":"​","style":"IPY_MODEL_aa27b554f6f1490e9efd393807cb6ca7","value":"Matching detections: 100%"}}},"version_major":2,"version_minor":0}}},"nbformat_minor":4,"nbformat":4,"cells":[{"id":"e111e100","cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport polars as pl\nfrom tqdm.auto import tqdm\nfrom matplotlib import pyplot as plt\nfrom sklearn.model_selection import GroupKFold\nfrom sklearn.metrics import mean_squared_error\nfrom scipy.signal import find_peaks\nimport gc\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport torch.nn.functional as F\nfrom torch.utils.data import Dataset, DataLoader\nfrom torch.optim.lr_scheduler import CosineAnnealingLR\nfrom torchinfo import summary","metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","execution":{"iopub.execute_input":"2024-08-21T14:19:12.919125Z","iopub.status.busy":"2024-08-21T14:19:12.918416Z","iopub.status.idle":"2024-08-21T14:19:18.459395Z","shell.execute_reply":"2024-08-21T14:19:18.458526Z"},"papermill":{"duration":5.553023,"end_time":"2024-08-21T14:19:18.461807","exception":false,"start_time":"2024-08-21T14:19:12.908784","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"32685bac","cell_type":"code","source":"df_series = pl.read_parquet(\"train_series.parquet\")\ndf_events = pl.read_csv(\"train_events.csv\")\ndf_events = df_events.with_columns(pl.col(\"event\").map_dict({\"wakeup\": 1.0, \"onset\": -1.0}, return_dtype=pl.Float32))\ndf_groupby = df_series.group_by(\"series_id\", maintain_order=True)","metadata":{"execution":{"iopub.execute_input":"2024-08-21T14:19:18.479982Z","iopub.status.busy":"2024-08-21T14:19:18.479147Z","iopub.status.idle":"2024-08-21T14:19:33.571363Z","shell.execute_reply":"2024-08-21T14:19:33.57048Z"},"papermill":{"duration":15.103638,"end_time":"2024-08-21T14:19:33.573719","exception":false,"start_time":"2024-08-21T14:19:18.470081","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"999fbf8c","cell_type":"code","source":"dict_valid_ratio = dict()\nlist_feature_array = []\nlist_df_1min = []\n\nfor series_id, df in tqdm(df_groupby, total=df_series.get_column(\"series_id\").n_unique()):\n    df = (\n        df.join(\n            df_events.filter(pl.col(\"series_id\") == series_id).select(\"timestamp\", \"event\"),\n            on=\"timestamp\", how=\"left\"\n        ).with_columns(\n            pl.col(\"timestamp\").str.to_datetime(),\n            pl.col(\"event\").fill_null(0.0),\n        ).with_columns(\n            pl.col(\"timestamp\").dt.date().cast(str).alias(\"date\"),\n            pl.col(\"timestamp\").dt.time().cast(str).alias(\"time\"),\n        )\n    ).to_pandas()\n    \n    #  Handle duplicate data and calculate validity flag\n    df[\"timestamp\"] = df[\"timestamp\"].dt.tz_localize(None)\n    dup_count = df.groupby([\"anglez\", \"enmo\", \"time\"])[\"step\"].transform(\"count\")\n    df[\"valid_flag\"] = (dup_count == 1).astype(\"float32\")\n    dict_valid_ratio[series_id] = df[\"valid_flag\"].mean()\n    \n    #     Calculate rolling features and pivot the data\n    list_feature_array_tmp = []\n    df[\"log_anglez_std\"] = np.log(df[\"anglez\"].rolling(12, min_periods=1, center=True).std() + 1).astype(\"float32\")\n    df[\"log_enmo\"] = np.log(df[\"enmo\"] + 0.01).astype(\"float32\")\n    for feature in [\"log_anglez_std\", \"log_enmo\", \"valid_flag\"]:\n        df_pivot = df.pivot(index=[\"series_id\", \"date\"], columns=\"time\", values=feature)\n        feature_array = df_pivot.fillna(0).values\n        feature_array_1day_bedore = df_pivot.shift(1).fillna(0).values\n        feature_array_1day_after = df_pivot.shift(-1).fillna(0).values\n        feature_array = np.concatenate([feature_array_1day_bedore[:, -180*12:], feature_array, feature_array_1day_after[:, :180*12]], axis=1)\n        list_feature_array_tmp.append(feature_array)\n    list_feature_array.append(np.stack(list_feature_array_tmp, axis=1))\n    \n    #     Resample data to 1 minute intervals\n    dict_agg = {\"series_id\": \"first\", \"date\": \"first\", \"time\": \"first\", \"step\": \"mean\", \"event\": \"sum\", \"valid_flag\": \"max\"}\n    df_1min = df.resample(\"1min\", on=\"timestamp\").agg(dict_agg).reset_index()\n    df_1min[\"step\"] = df_1min[\"step\"].astype(\"int32\")\n    \n    #     Compute target values for events\n    values_event = df_1min[\"event\"].values\n    values_target = values_event.copy()\n    \n    #     window of 30 minutes (or steps) in both backward and forward directions\n    for j in range(30):\n        weight = np.exp(-j/2.8)\n        values_target[:-(j+1)] += weight*values_event[(j+1):]  # shift backward\n        if j > 0:\n            values_target[j:] += weight*values_event[:-j]  # shift forward\n    \n    df_1min[\"target\"] = values_target\n    list_df_1min.append(df_1min)","metadata":{"execution":{"iopub.execute_input":"2024-08-21T14:19:33.591209Z","iopub.status.busy":"2024-08-21T14:19:33.590846Z","iopub.status.idle":"2024-08-21T14:26:58.293991Z","shell.execute_reply":"2024-08-21T14:26:58.293005Z"},"papermill":{"duration":444.71461,"end_time":"2024-08-21T14:26:58.296295","exception":false,"start_time":"2024-08-21T14:19:33.581685","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"0cf6b008","cell_type":"code","source":"del df_series, df_groupby\ngc.collect()","metadata":{"execution":{"iopub.execute_input":"2024-08-21T14:26:58.314336Z","iopub.status.busy":"2024-08-21T14:26:58.313993Z","iopub.status.idle":"2024-08-21T14:26:58.976879Z","shell.execute_reply":"2024-08-21T14:26:58.975988Z"},"papermill":{"duration":0.674343,"end_time":"2024-08-21T14:26:58.978941","exception":false,"start_time":"2024-08-21T14:26:58.304598","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"45f0941d","cell_type":"code","source":"# Normalizing the Array\n# This operation standardizes each feature's values across all timesteps and samples to be between 0 and 1\n\nX = np.concatenate(list_feature_array)\nX = (X - X.min(axis=(0, 2), keepdims=True)) / (X.max(axis=(0, 2), keepdims=True) - X.min(axis=(0, 2), keepdims=True))","metadata":{"execution":{"iopub.execute_input":"2024-08-21T14:26:58.997269Z","iopub.status.busy":"2024-08-21T14:26:58.996935Z","iopub.status.idle":"2024-08-21T14:27:01.353492Z","shell.execute_reply":"2024-08-21T14:27:01.352662Z"},"papermill":{"duration":2.368456,"end_time":"2024-08-21T14:27:01.355923","exception":false,"start_time":"2024-08-21T14:26:58.987467","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"2b2dbf73","cell_type":"code","source":"X.shape","metadata":{"execution":{"iopub.execute_input":"2024-08-21T14:27:01.374689Z","iopub.status.busy":"2024-08-21T14:27:01.374014Z","iopub.status.idle":"2024-08-21T14:27:01.380315Z","shell.execute_reply":"2024-08-21T14:27:01.379403Z"},"papermill":{"duration":0.017749,"end_time":"2024-08-21T14:27:01.382216","exception":false,"start_time":"2024-08-21T14:27:01.364467","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"ca99bafe","cell_type":"code","source":"df_1min = pd.concat(list_df_1min)\ndf_1min","metadata":{"execution":{"iopub.execute_input":"2024-08-21T14:27:01.401335Z","iopub.status.busy":"2024-08-21T14:27:01.400362Z","iopub.status.idle":"2024-08-21T14:27:01.986239Z","shell.execute_reply":"2024-08-21T14:27:01.985312Z"},"papermill":{"duration":0.597679,"end_time":"2024-08-21T14:27:01.988375","exception":false,"start_time":"2024-08-21T14:27:01.390696","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"d7da65bf","cell_type":"code","source":"del list_df_1min\ndel list_feature_array\ngc.collect()","metadata":{"execution":{"iopub.execute_input":"2024-08-21T14:27:02.007875Z","iopub.status.busy":"2024-08-21T14:27:02.007501Z","iopub.status.idle":"2024-08-21T14:27:02.241693Z","shell.execute_reply":"2024-08-21T14:27:02.240818Z"},"papermill":{"duration":0.246181,"end_time":"2024-08-21T14:27:02.243681","exception":false,"start_time":"2024-08-21T14:27:01.9975","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"6ca74186","cell_type":"code","source":"# reshape df_1min from a long format to a wide format \n\ndf_y = df_1min.pivot(index=[\"series_id\", \"date\"], columns=\"time\", values=\"target\").fillna(0)\ndf_mask = df_1min.pivot(index=[\"series_id\", \"date\"], columns=\"time\", values=\"valid_flag\").fillna(0)\ndf_mask.to_parquet(\"df_mask.parquet\")\n\ndf_y","metadata":{"execution":{"iopub.execute_input":"2024-08-21T14:27:02.263471Z","iopub.status.busy":"2024-08-21T14:27:02.263123Z","iopub.status.idle":"2024-08-21T14:27:10.821568Z","shell.execute_reply":"2024-08-21T14:27:10.820566Z"},"papermill":{"duration":8.570878,"end_time":"2024-08-21T14:27:10.823729","exception":false,"start_time":"2024-08-21T14:27:02.252851","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"7f013fd2","cell_type":"code","source":"class MyDataset(Dataset):\n    def __init__(self, X, Y, flag):\n        self.X = torch.FloatTensor(X)\n        if Y is not None:\n            self.Y = torch.FloatTensor(Y)\n        self.flag = torch.FloatTensor(flag)\n    \n    def __len__(self):\n        return self.X.shape[0]\n    \n    def __getitem__(self, idx):\n        if \"Y\" in dir(self):\n            return (self.X[idx], self.Y[idx], self.flag[idx])\n        else:\n            return (self.X[idx], torch.Tensor(), self.flag[idx])","metadata":{"execution":{"iopub.execute_input":"2024-08-21T14:27:10.845841Z","iopub.status.busy":"2024-08-21T14:27:10.845073Z","iopub.status.idle":"2024-08-21T14:27:10.853452Z","shell.execute_reply":"2024-08-21T14:27:10.852474Z"},"papermill":{"duration":0.021822,"end_time":"2024-08-21T14:27:10.855422","exception":false,"start_time":"2024-08-21T14:27:10.8336","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"185a87f1","cell_type":"markdown","source":"Regression Model (1D-CNN UNet) https://www.kaggle.com/code/kmat2019/u-net-1d-cnn-with-keras","metadata":{"papermill":{"duration":0.00961,"end_time":"2024-08-21T14:27:10.874941","exception":false,"start_time":"2024-08-21T14:27:10.865331","status":"completed"},"tags":[]}},{"id":"ac399645","cell_type":"code","source":"# 1D convolutional layer,\n# batch normalization, \n# a ReLU activation function\n\nclass ConvBNReLU(nn.Module):\n    def __init__(self, in_channels, out_channels, kernel_size, stride, groups=1):\n        super().__init__()\n        \n        if stride == 1:\n            padding = \"same\"\n        else:\n            padding = (kernel_size - stride) // 2\n        self.layers = nn.Sequential(\n            nn.Conv1d(in_channels, out_channels, kernel_size=kernel_size, stride=stride, padding=padding, groups=groups),\n            nn.BatchNorm1d(out_channels),\n            nn.ReLU()\n        )\n    \n    def forward(self, x):\n        x_out = self.layers(x)\n        return x_out","metadata":{"execution":{"iopub.execute_input":"2024-08-21T14:27:10.896464Z","iopub.status.busy":"2024-08-21T14:27:10.895801Z","iopub.status.idle":"2024-08-21T14:27:10.902928Z","shell.execute_reply":"2024-08-21T14:27:10.901997Z"},"papermill":{"duration":0.020015,"end_time":"2024-08-21T14:27:10.904858","exception":false,"start_time":"2024-08-21T14:27:10.884843","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"f2870a43","cell_type":"code","source":"# Squeeze-and-Excitation (SE) block\n\nclass SEBlock(nn.Module):\n    def __init__(self, n_channels, se_ratio):\n        super().__init__()\n        \n        self.layers = nn.Sequential(\n            nn.AdaptiveAvgPool1d(output_size=1),  #  Global Average Pooling\n            nn.Conv1d(n_channels, n_channels//se_ratio, kernel_size=1),\n            nn.ReLU(),\n            nn.Conv1d(n_channels//se_ratio, n_channels, kernel_size=1),\n            nn.Sigmoid()\n        )\n\n    def forward(self, x):\n        x_out = torch.mul(x, self.layers(x))\n        return x_out\n","metadata":{"execution":{"iopub.execute_input":"2024-08-21T14:27:10.926656Z","iopub.status.busy":"2024-08-21T14:27:10.925811Z","iopub.status.idle":"2024-08-21T14:27:10.932387Z","shell.execute_reply":"2024-08-21T14:27:10.931495Z"},"papermill":{"duration":0.019427,"end_time":"2024-08-21T14:27:10.934355","exception":false,"start_time":"2024-08-21T14:27:10.914928","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"5285896f","cell_type":"code","source":"# residual block\n\nclass ResBlock(nn.Module):\n    def __init__(self, n_channels, kernel_size, se_ratio):\n        super().__init__()\n        \n        self.layers = nn.Sequential(\n            ConvBNReLU(n_channels, n_channels, kernel_size, stride=1),\n            ConvBNReLU(n_channels, n_channels, kernel_size, stride=1),\n            SEBlock(n_channels, se_ratio)\n        )\n    \n    def forward(self, x):\n        x_re = self.layers(x)\n        x_out = x + x_re\n        return x_out\n    ","metadata":{"execution":{"iopub.execute_input":"2024-08-21T14:27:10.955544Z","iopub.status.busy":"2024-08-21T14:27:10.95518Z","iopub.status.idle":"2024-08-21T14:27:10.961436Z","shell.execute_reply":"2024-08-21T14:27:10.960552Z"},"papermill":{"duration":0.019264,"end_time":"2024-08-21T14:27:10.963522","exception":false,"start_time":"2024-08-21T14:27:10.944258","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"86ce22ee","cell_type":"code","source":"# U-Net model adapted for 1-dimensional data\n\nclass UNet1d(nn.Module):\n    def __init__(self, input_channels, initial_channels, initial_kernel_size,\n                 down_channels, down_kernel_size, down_stride, res_depth, res_kernel_size, se_ratio, out_kernel_size):\n        super().__init__()\n        self.down_kernel_size = down_kernel_size\n        self.down_stride = down_stride\n        \n        self.initial_layers = ConvBNReLU(input_channels, initial_channels, initial_kernel_size, stride=1, groups=input_channels)\n        \n        self.down_layers = nn.ModuleList()\n        for i in range(len(down_channels)):\n            if i == 0:\n                in_channels = initial_channels\n            else:\n                in_channels = down_channels[i-1] + input_channels\n            out_channels = down_channels[i]\n            kernel_size = down_kernel_size[i]\n            stride = down_stride[i]\n            \n            block = []\n            block.append(ConvBNReLU(in_channels, out_channels, kernel_size, stride))\n            for j in range(res_depth):\n                block.append(ResBlock(out_channels, res_kernel_size, se_ratio))\n            self.down_layers.append(nn.Sequential(*block))\n        \n        self.up_layers = nn.ModuleList()\n        for i in range(len(down_channels)-1, 0, -1):\n            in_channels = out_channels + down_channels[i]\n            out_channels = down_channels[i]\n            kernel_size = down_kernel_size[i]\n            self.up_layers.append(ConvBNReLU(in_channels, out_channels, kernel_size, stride=1))\n        \n        self.out_layers = nn.Conv1d(down_channels[1], 1, out_kernel_size, padding=\"same\")\n    \n    def forward(self, x):\n        outs = []\n        x_avg = x\n        x = self.initial_layers(x)\n        \n        for i in range(len(self.down_layers)):\n            x_out = self.down_layers[i](x)\n            if i == len(self.down_layers) - 1:\n                x = x_out\n            else:\n                outs.append(x_out)\n                kernel_size = self.down_kernel_size[i]\n                stride = self.down_stride[i]\n                padding = (kernel_size - stride) // 2\n                x_avg = F.avg_pool1d(x_avg, kernel_size, stride, padding)\n                x = torch.cat([x_out, x_avg], dim=1)\n        \n        for i in range(len(self.up_layers)):\n            scale_factor = self.down_stride[-i-1]\n            x = F.interpolate(x, scale_factor=scale_factor, mode=\"linear\")\n            x = torch.cat([x, outs[-i-1]], dim=1)\n            x = self.up_layers[i](x)\n        \n        x_out = self.out_layers(x)\n        x_out = x_out[:, 0, 180:-180]\n        \n        return x_out","metadata":{"execution":{"iopub.execute_input":"2024-08-21T14:27:10.98515Z","iopub.status.busy":"2024-08-21T14:27:10.984811Z","iopub.status.idle":"2024-08-21T14:27:11.000737Z","shell.execute_reply":"2024-08-21T14:27:10.999802Z"},"papermill":{"duration":0.029138,"end_time":"2024-08-21T14:27:11.002757","exception":false,"start_time":"2024-08-21T14:27:10.973619","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"8e63aa41","cell_type":"code","source":"def train(model, data_loader, optimizer, criterion, device):\n    model.train()\n    for batch in data_loader:\n        X = batch[0].to(device)\n        Y = batch[1].to(device)\n        mask = batch[2].to(device)\n        preds = model(X) * mask\n        loss = criterion(preds, Y)\n\n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()","metadata":{"execution":{"iopub.execute_input":"2024-08-21T14:27:11.024551Z","iopub.status.busy":"2024-08-21T14:27:11.024197Z","iopub.status.idle":"2024-08-21T14:27:11.030124Z","shell.execute_reply":"2024-08-21T14:27:11.029172Z"},"papermill":{"duration":0.019011,"end_time":"2024-08-21T14:27:11.032099","exception":false,"start_time":"2024-08-21T14:27:11.013088","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"309ad4a0","cell_type":"code","source":"def evaluate(model, data_loader, criterion, device):\n    model.eval()\n    n = 0\n    total_loss = 0.0\n    for batch in data_loader:\n        X = batch[0].to(device)\n        Y = batch[1].to(device)\n        mask = batch[2].to(device)\n        \n        with torch.no_grad():\n            preds = model(X) * mask\n        \n        loss = criterion(preds, Y)\n        total_loss += loss.item() * X.shape[0]\n        n += X.shape[0]\n    \n    avg_loss = total_loss / n\n    \n    return avg_loss","metadata":{"execution":{"iopub.execute_input":"2024-08-21T14:27:11.053656Z","iopub.status.busy":"2024-08-21T14:27:11.053303Z","iopub.status.idle":"2024-08-21T14:27:11.059878Z","shell.execute_reply":"2024-08-21T14:27:11.058991Z"},"papermill":{"duration":0.019486,"end_time":"2024-08-21T14:27:11.061762","exception":false,"start_time":"2024-08-21T14:27:11.042276","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"f99ebff6","cell_type":"code","source":"def predict(model, data_loader, device):\n    model.eval()\n    preds_all = []\n    for batch in data_loader:\n        X = batch[0].to(device)\n        mask = batch[2].to(device)\n        \n        with torch.no_grad():\n            preds = model(X) * mask\n            \n        preds = preds.cpu().numpy()\n        preds_all.append(preds)\n    \n    preds_all = np.concatenate(preds_all)\n        \n    return preds_all","metadata":{"execution":{"iopub.execute_input":"2024-08-21T14:27:11.083691Z","iopub.status.busy":"2024-08-21T14:27:11.083101Z","iopub.status.idle":"2024-08-21T14:27:11.089159Z","shell.execute_reply":"2024-08-21T14:27:11.088274Z"},"papermill":{"duration":0.01902,"end_time":"2024-08-21T14:27:11.090992","exception":false,"start_time":"2024-08-21T14:27:11.071972","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"c53c1441","cell_type":"code","source":"n_splits = 10\nn_epochs = 15\nbatch_size = 16\n    \nY = df_y.values\nmask = df_mask.values\ngroups = df_y.index.get_level_values(\"series_id\").tolist()","metadata":{"execution":{"iopub.execute_input":"2024-08-21T14:27:11.168453Z","iopub.status.busy":"2024-08-21T14:27:11.167595Z","iopub.status.idle":"2024-08-21T14:27:11.172932Z","shell.execute_reply":"2024-08-21T14:27:11.171997Z"},"papermill":{"duration":0.073803,"end_time":"2024-08-21T14:27:11.174854","exception":false,"start_time":"2024-08-21T14:27:11.101051","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"81f4cc55","cell_type":"code","source":"preds_valid = np.zeros_like(Y)\ngkf = GroupKFold(n_splits=n_splits)\nfor fold, (idx_train, idx_valid) in enumerate(gkf.split(X, Y, groups=groups)):   \n    print(f\"fold: {fold}\")\n    X_train = X[idx_train]\n    Y_train = Y[idx_train]\n    mask_train = mask[idx_train]\n\n    X_valid = X[idx_valid]\n    Y_valid = Y[idx_valid]\n    mask_valid = mask[idx_valid]\n\n    # dataset\n    ds_train = MyDataset(X_train, Y_train, mask_train)\n    ds_valid = MyDataset(X_valid, Y_valid, mask_valid)\n\n    # dataloader\n    dl_train = DataLoader(\n        ds_train, \n        batch_size=batch_size,\n        shuffle=True, \n        num_workers=0, \n        pin_memory=True,\n        drop_last=True\n    )\n    dl_valid = DataLoader(\n        ds_valid,\n        batch_size=batch_size,\n        shuffle=False, \n        num_workers=0, \n        pin_memory=True, \n        drop_last=False\n    )\n\n    # build model\n    torch.manual_seed(0)\n    device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n    model = UNet1d(\n        input_channels=X.shape[1],\n        initial_channels=72,\n        initial_kernel_size=15,\n        down_channels=(72, 72, 72),\n        down_kernel_size=(12, 15, 15),\n        down_stride=(12, 9, 5),  # first element must be 12\n        res_depth=3,\n        res_kernel_size=15,\n        se_ratio=4,\n        out_kernel_size=21,\n    )\n    \n    if fold == 0:\n        print(summary(\n            model=model,\n            input_size=(batch_size, X.shape[1], X.shape[2]),\n            col_names=[\"input_size\", \"output_size\", \"num_params\"],\n            col_width=20\n        ))\n        \n    model.to(device)\n    optimizer = optim.Adam(model.parameters(), lr=1e-3)\n    scheduler = CosineAnnealingLR(optimizer, T_max=n_epochs)\n    criterion = nn.MSELoss()\n\n    best_loss = np.inf\n    for epoch in range(n_epochs):\n        train(model, dl_train, optimizer, criterion, device)\n        loss = evaluate(model, dl_valid, criterion, device)\n        scheduler.step()\n        if loss < best_loss:\n            best_loss = loss\n            torch.save(model.state_dict(), f\"model_{fold}.pth\")\n            print(f\"epoch: {epoch}\\tValid-Loss: {loss}\\tBEST\")\n        else:\n            print(f\"epoch: {epoch}\\tValid-Loss: {loss}\")\n\n    with torch.no_grad():\n        model.load_state_dict(torch.load(f\"model_{fold}.pth\"))\n        preds_valid[idx_valid] = predict(model, dl_valid, device)\n        \n    print(f\"Best_Loss: {best_loss}\")","metadata":{"execution":{"iopub.execute_input":"2024-08-21T14:27:11.197566Z","iopub.status.busy":"2024-08-21T14:27:11.196853Z","iopub.status.idle":"2024-08-21T15:30:14.16784Z","shell.execute_reply":"2024-08-21T15:30:14.166724Z"},"papermill":{"duration":3782.984964,"end_time":"2024-08-21T15:30:14.170083","exception":false,"start_time":"2024-08-21T14:27:11.185119","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"411e270e","cell_type":"code","source":"rmse = mean_squared_error(Y, preds_valid, squared=False)\nprint(f\"RMSE: {rmse:.5f}\")","metadata":{"execution":{"iopub.execute_input":"2024-08-21T15:30:14.216987Z","iopub.status.busy":"2024-08-21T15:30:14.216632Z","iopub.status.idle":"2024-08-21T15:30:14.250048Z","shell.execute_reply":"2024-08-21T15:30:14.248676Z"},"papermill":{"duration":0.059351,"end_time":"2024-08-21T15:30:14.252144","exception":false,"start_time":"2024-08-21T15:30:14.192793","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"c38eb3da","cell_type":"code","source":"plt.figure(figsize=(12, 3))\nplt.plot(np.linspace(0, 24, 60*24), preds_valid.mean(axis=0), label=\"Mean of Prediction\")\nplt.plot(np.linspace(0, 24, 60*24), df_y.mean().values, label=\"Mean of Target\")\nplt.xlim(0, 24)\nplt.xlabel(\"Hour(UTC)\")\nplt.legend()\nplt.show()","metadata":{"execution":{"iopub.execute_input":"2024-08-21T15:30:14.299715Z","iopub.status.busy":"2024-08-21T15:30:14.299339Z","iopub.status.idle":"2024-08-21T15:30:14.536535Z","shell.execute_reply":"2024-08-21T15:30:14.535564Z"},"papermill":{"duration":0.263608,"end_time":"2024-08-21T15:30:14.538637","exception":false,"start_time":"2024-08-21T15:30:14.275029","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"af35898f","cell_type":"code","source":"df_pred = pd.DataFrame(preds_valid, index=df_y.index, columns=df_y.columns)\ndf_pred = df_pred.stack().reset_index(name=\"score\")\ndf_pred = pd.merge(\n    df_1min[[\"series_id\", \"date\", \"time\", \"step\", \"event\"]],\n    df_pred,\n    on=[\"series_id\", \"date\", \"time\"],\n    how=\"inner\"\n)\n\ndf_pred","metadata":{"execution":{"iopub.execute_input":"2024-08-21T15:30:14.58745Z","iopub.status.busy":"2024-08-21T15:30:14.587085Z","iopub.status.idle":"2024-08-21T15:30:29.288306Z","shell.execute_reply":"2024-08-21T15:30:29.287401Z"},"papermill":{"duration":14.728301,"end_time":"2024-08-21T15:30:29.29062","exception":false,"start_time":"2024-08-21T15:30:14.562319","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"67f902c1","cell_type":"code","source":"list_df = []\nfor series_id, df in tqdm(df_pred.groupby(\"series_id\")):\n    for event in [\"onset\", \"wakeup\"]:\n        values_step = df[\"step\"].values\n        if event == \"onset\":\n            values_score = -df[\"score\"].values\n        else:\n            values_score = df[\"score\"].values\n\n        peak_idx = find_peaks(values_score, height=0.0, distance=8)[0]\n        df_peak = pd.DataFrame(values_step[peak_idx], columns=[\"step\"])\n        df_peak[\"series_id\"] = series_id\n        df_peak[\"event\"] = event\n        df_peak[\"score\"] = values_score[peak_idx]\n        list_df.append(df_peak)\n\n        \ndf_sub = pd.concat(list_df)\ndf_sub = df_sub.sort_values(\"score\", ascending=False).groupby(\"event\").head(100000)  # avoid Submission Scoring Error\ndf_sub = df_sub.sort_values([\"series_id\", \"step\"]).reset_index(drop=True)\ndf_sub = df_sub[[\"series_id\", \"step\", \"event\", \"score\"]].reset_index(names=\"row_id\")\ndf_sub.to_csv(\"df_sub.csv\", index=False)\ndf_sub","metadata":{"execution":{"iopub.execute_input":"2024-08-21T15:30:29.340455Z","iopub.status.busy":"2024-08-21T15:30:29.340099Z","iopub.status.idle":"2024-08-21T15:30:33.54185Z","shell.execute_reply":"2024-08-21T15:30:33.540976Z"},"papermill":{"duration":4.228805,"end_time":"2024-08-21T15:30:33.543977","exception":false,"start_time":"2024-08-21T15:30:29.315172","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"efaa0e2a","cell_type":"markdown","source":"post processing","metadata":{"papermill":{"duration":0.024628,"end_time":"2024-08-21T15:30:33.593252","exception":false,"start_time":"2024-08-21T15:30:33.568624","status":"completed"},"tags":[]}},{"id":"bd4999c9","cell_type":"code","source":"df_events = pd.read_csv(\"/kaggle/input/child-mind-institute-detect-sleep-states/train_events.csv\").dropna()\ndf_events[\"timestamp\"] = pd.to_datetime(df_events[\"timestamp\"], utc=True).dt.tz_localize(None)\ndf_events[\"time\"] = df_events[\"timestamp\"].dt.time.astype(str)\ndf_events[\"minute_mod15\"] = df_events[\"timestamp\"].dt.minute % 15\n\ndf_agg = df_events.groupby([\"time\", \"event\"], as_index=False).size()\ndf_agg[\"rate\"] = df_agg[\"size\"] / df_agg.groupby(\"event\")[\"size\"].transform(\"sum\") * (60*24)\ndf_time = df_agg.pivot(index=\"time\", columns=\"event\", values=\"rate\").fillna(0).reset_index()\ndf_time = df_time.merge(df_pred[[\"time\"]].drop_duplicates(), how=\"right\").fillna(0)\ndf_time = pd.concat([df_time]*3, ignore_index=True)\ndf_time[\"onset\"] = df_time[\"onset\"].rolling(60, center=True).mean()\ndf_time[\"wakeup\"] = df_time[\"wakeup\"].rolling(60, center=True).mean()\ndf_time = df_time.iloc[60*24:-60*24].reset_index(drop=True)\n\ndf_agg = df_events.groupby([\"minute_mod15\", \"event\"], as_index=False).size()\ndf_agg[\"rate\"] = df_agg[\"size\"] / df_agg.groupby(\"event\")[\"size\"].transform(\"sum\") * 15\ndf_minute = df_agg.pivot(index=\"minute_mod15\", columns=\"event\", values=\"rate\").reset_index()\n\ndf_time[[\"onset\", \"wakeup\"]] = df_time[[\"onset\", \"wakeup\"]].clip(0.1, 1.1) ** 0.13\ndf_minute[[\"onset\", \"wakeup\"]] = df_minute[[\"onset\", \"wakeup\"]].clip(0.5, 1.3) ** 0.06\n","metadata":{"execution":{"iopub.execute_input":"2024-08-21T15:30:33.643743Z","iopub.status.busy":"2024-08-21T15:30:33.643139Z","iopub.status.idle":"2024-08-21T15:30:34.639151Z","shell.execute_reply":"2024-08-21T15:30:34.638249Z"},"papermill":{"duration":1.024043,"end_time":"2024-08-21T15:30:34.641475","exception":false,"start_time":"2024-08-21T15:30:33.617432","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"b0cfba1e","cell_type":"code","source":"df_pred[\"minute_mod15\"] = df_pred[\"time\"].str[3:5].astype(int) % 15","metadata":{"execution":{"iopub.execute_input":"2024-08-21T15:30:34.693118Z","iopub.status.busy":"2024-08-21T15:30:34.692262Z","iopub.status.idle":"2024-08-21T15:30:41.042092Z","shell.execute_reply":"2024-08-21T15:30:41.041214Z"},"papermill":{"duration":6.377582,"end_time":"2024-08-21T15:30:41.044308","exception":false,"start_time":"2024-08-21T15:30:34.666726","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"25d46552","cell_type":"code","source":"list_df = []\nfor series_id, df in tqdm(df_pred.groupby(\"series_id\")):\n    df = df.merge(df_time, how=\"left\", on=\"time\")\n    df = df.merge(df_minute, how=\"left\", on=\"minute_mod15\")\n    \n    df_tmp = df.copy()\n    df_tmp[\"score\"] = df_tmp[\"score\"].replace(0.0, np.nan)\n    df_tmp = df_tmp.groupby(\"time\")[\"score\"].mean()\n    df_tmp = pd.concat([df_tmp]*3).rolling(90, center=True, min_periods=1).mean()\n    df_tmp = df_tmp.iloc[60*24:-60*24].reset_index().rename({\"score\": \"score_mean\"}, axis=1)\n    df = df.merge(df_tmp, on=\"time\", how=\"left\")\n    \n    df[\"score\"] = 0.9*df[\"score\"] + 0.1*df[\"score_mean\"]\n    df[\"score\"] *= np.where(df[\"score\"]>0, df[\"wakeup_x\"], df[\"onset_x\"])\n    df[\"score\"] *= np.where(df[\"score\"]>0, df[\"wakeup_y\"], df[\"onset_y\"])\n    valid_ratio = dict_valid_ratio[series_id]\n    \n    for event in [\"onset\", \"wakeup\"]:\n        values_step = df[\"step\"].values\n        if event == \"onset\":\n            values_score = -df[\"score\"].values\n        else:\n            values_score = df[\"score\"].values\n        \n        # measure peaks\n        peak_idx = find_peaks(values_score, height=0.04, distance=60*16)[0]  # at least 16 hours interval\n        df_measure_peak = pd.DataFrame(values_step[peak_idx], columns=[\"step\"])\n        df_measure_peak[\"series_id\"] = series_id\n        df_measure_peak[\"event\"] = event\n        df_measure_peak[\"score\"] = values_score[peak_idx] * 4 * valid_ratio**0.15\n        \n        # minor peaks\n        peak_idx = find_peaks(values_score, height=0.0, distance=6)[0]\n        df_minor_peak = pd.DataFrame(values_step[peak_idx], columns=[\"step\"])\n        df_minor_peak[\"series_id\"] = series_id\n        df_minor_peak[\"event\"] = event\n        df_minor_peak[\"score\"] = values_score[peak_idx]\n        \n        df_peak = pd.concat([df_measure_peak, df_minor_peak]).drop_duplicates(subset=[\"step\"])\n        list_df.append(df_peak)\n        \n        \ndf_sub = pd.concat(list_df)\ndf_sub = df_sub.sort_values(\"score\", ascending=False).groupby(\"event\").head(100000)  # avoid Submission Scoring Error\ndf_sub = df_sub.sort_values([\"series_id\", \"step\"]).reset_index(drop=True)\ndf_sub = df_sub[[\"series_id\", \"step\", \"event\", \"score\"]].reset_index(names=\"row_id\")\ndf_sub.to_csv(\"df_sub_with_postprocess.csv\", index=False)\ndf_sub\n","metadata":{"execution":{"iopub.execute_input":"2024-08-21T15:30:41.094573Z","iopub.status.busy":"2024-08-21T15:30:41.094246Z","iopub.status.idle":"2024-08-21T15:30:58.088191Z","shell.execute_reply":"2024-08-21T15:30:58.087211Z"},"papermill":{"duration":17.021486,"end_time":"2024-08-21T15:30:58.090308","exception":false,"start_time":"2024-08-21T15:30:41.068822","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"8fc11e5c","cell_type":"markdown","source":"Evaluation Function https://github.com/tubo213/kaggle-child-mind-institute-detect-sleep-states/blob/main/src/utils/metrics.py","metadata":{"papermill":{"duration":0.024634,"end_time":"2024-08-21T15:30:58.140812","exception":false,"start_time":"2024-08-21T15:30:58.116178","status":"completed"},"tags":[]}},{"id":"a74da6ff","cell_type":"code","source":"from bisect import bisect_left\nfrom typing import Dict, List, Tuple","metadata":{"execution":{"iopub.execute_input":"2024-08-21T15:30:58.193029Z","iopub.status.busy":"2024-08-21T15:30:58.192346Z","iopub.status.idle":"2024-08-21T15:30:58.19686Z","shell.execute_reply":"2024-08-21T15:30:58.195973Z"},"papermill":{"duration":0.032903,"end_time":"2024-08-21T15:30:58.198765","exception":false,"start_time":"2024-08-21T15:30:58.165862","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"c9b3bb04","cell_type":"code","source":"class ParticipantVisibleError(Exception):\n    pass\n\n# Set some placeholders for global parameters\nseries_id_column_name = \"series_id\"\ntime_column_name = \"step\"\nevent_column_name = \"event\"\nscore_column_name = \"score\"\nuse_scoring_intervals = False\ntolerances = {\n    \"onset\": [12, 36, 60, 90, 120, 150, 180, 240, 300, 360],\n    \"wakeup\": [12, 36, 60, 90, 120, 150, 180, 240, 300, 360],\n}\n\n\ndef score(\n    solution: pd.DataFrame,\n    submission: pd.DataFrame,\n    tolerances: Dict[str, List[float]],\n    series_id_column_name: str,\n    time_column_name: str,\n    event_column_name: str,\n    score_column_name: str,\n    use_scoring_intervals: bool = False,\n    verbose: bool = True,\n) -> Tuple[float, pd.DataFrame, pd.DataFrame]:\n    # Validate metric parameters\n    assert len(tolerances) > 0, \"Events must have defined tolerances.\"\n    assert set(tolerances.keys()) == set(solution[event_column_name]).difference(\n        {\"start\", \"end\"}\n    ), (\n        f\"Solution column {event_column_name} must contain the same events \"\n        \"as defined in tolerances.\"\n    )\n    assert pd.api.types.is_numeric_dtype(\n        solution[time_column_name]\n    ), f\"Solution column {time_column_name} must be of numeric type.\"\n\n    # Validate submission format\n    for column_name in [\n        series_id_column_name,\n        time_column_name,\n        event_column_name,\n        score_column_name,\n    ]:\n        if column_name not in submission.columns:\n            raise ParticipantVisibleError(\n                f\"Submission must have column '{column_name}'.\"\n            )\n\n    if not pd.api.types.is_numeric_dtype(submission[time_column_name]):\n        raise ParticipantVisibleError(\n            f\"Submission column '{time_column_name}' must be of numeric type.\"\n        )\n    if not pd.api.types.is_numeric_dtype(submission[score_column_name]):\n        raise ParticipantVisibleError(\n            f\"Submission column '{score_column_name}' must be of numeric type.\"\n        )\n\n    # Set these globally to avoid passing around a bunch of arguments\n    globals()[\"series_id_column_name\"] = series_id_column_name\n    globals()[\"time_column_name\"] = time_column_name\n    globals()[\"event_column_name\"] = event_column_name\n    globals()[\"score_column_name\"] = score_column_name\n    globals()[\"use_scoring_intervals\"] = use_scoring_intervals\n\n    return event_detection_ap(solution, submission, tolerances, verbose=verbose)\n\n\ndef find_nearest(xs: np.ndarray, value):\n    \"\"\"\n    Find the index of the closest value to x in the array xs.\n    \"\"\"\n    idx = np.searchsorted(xs, value, side=\"left\")\n    best_idx = None\n    best_error = float(\"inf\")\n    best_diff = float(\"inf\")\n\n    range_min = max(0, idx - 1)\n    range_max = min(len(xs), idx + 2)\n    for check_idx in range(\n        range_min, range_max\n    ):  # Check the exact, one before, and one after\n        error = abs(xs[check_idx] - value)\n        if error < best_error:\n            best_error = error\n            best_idx = check_idx\n            best_diff = xs[check_idx] - value\n\n    return best_idx, best_error, best_diff\n\n\ndef find_nearest_time_idx(sorted_gt_times, det_time, excluded_indices: set):\n    \"\"\"\n    search index of gt_times closest to det_time.\n\n    assumes gt_times is sorted in ascending order.\n    \"\"\"\n    # e.g. if gt_times = [0, 1, 2, 3, 4, 5] and det_time = 2.5, then idx = 3\n    sorted_gt_times = np.asarray(sorted_gt_times)\n    available_indices = np.asarray(\n        sorted(set(range(len(sorted_gt_times))) - excluded_indices), dtype=int\n    )\n    sorted_gt_times = sorted_gt_times[available_indices]\n    idx, error, diff = find_nearest(sorted_gt_times, det_time)\n    best_idx = available_indices[idx] if idx is not None else None\n\n    return best_idx, error, diff\n\n\ndef match_detections(\n    tolerance: float, ground_truths: pd.DataFrame, detections: pd.DataFrame\n) -> pd.DataFrame:\n    detections_sorted = detections.sort_values(\n        score_column_name, ascending=False\n    ).dropna()\n    is_matched = np.full_like(detections_sorted[event_column_name], False, dtype=bool)\n    diffs = np.full_like(\n        detections_sorted[event_column_name], float(\"inf\"), dtype=float\n    )\n    ground_truths_times = ground_truths.sort_values(time_column_name)[\n        time_column_name\n    ].to_list()\n    matched_gt_indices: set[int] = set()\n\n    for i, det in enumerate(detections_sorted.itertuples(index=False)):\n        det_time = getattr(det, time_column_name)\n\n        best_idx, best_error, best_diff = find_nearest_time_idx(\n            ground_truths_times, det_time, matched_gt_indices\n        )\n\n        if (best_idx is not None) and (best_error < tolerance):\n            is_matched[i] = True\n            diffs[i] = best_diff\n            matched_gt_indices.add(best_idx)\n\n    detections_sorted[\"matched\"] = is_matched\n    detections_sorted[\"diff\"] = diffs\n    return detections_sorted\n\n\ndef precision_recall_curve(\n    matches: np.ndarray, scores: np.ndarray, p: int\n) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:\n    if len(matches) == 0:\n        return [1], [0], []\n\n    # Sort matches by decreasing confidence\n    idxs = np.argsort(scores, kind=\"stable\")[::-1]\n    scores = scores[idxs]\n    matches = matches[idxs]\n\n    distinct_value_indices = np.where(np.diff(scores))[0]\n    threshold_idxs = np.r_[distinct_value_indices, matches.size - 1]\n    thresholds = scores[threshold_idxs]\n\n    # Matches become TPs and non-matches FPs as confidence threshold decreases\n    tps = np.cumsum(matches)[threshold_idxs]\n    fps = np.cumsum(~matches)[threshold_idxs]\n\n    precision = tps / (tps + fps)\n    precision[np.isnan(precision)] = 0\n    recall = (\n        tps / p\n    )  # total number of ground truths might be different than total number of matches\n\n    # Stop when full recall attained and reverse the outputs so recall is non-increasing.\n    last_ind = tps.searchsorted(tps[-1])\n    sl = slice(last_ind, None, -1)\n\n    # Final precision is 1 and final recall is 0\n    return np.r_[precision[sl], 1], np.r_[recall[sl], 0], thresholds[sl]\n\n\ndef average_precision_score(matches: np.ndarray, scores: np.ndarray, p: int) -> float:\n    precision, recall, _ = precision_recall_curve(matches, scores, p)\n    # Compute step integral\n    return -np.sum(np.diff(recall) * np.array(precision)[:-1])\n\n\ndef event_detection_ap(\n    solution: pd.DataFrame,\n    submission: pd.DataFrame,\n    tolerances: Dict[str, List[float]] = tolerances,\n    progress_bar: bool = True,\n    verbose: bool = True,\n) -> Tuple[float, pd.DataFrame, pd.DataFrame]:\n    # Ensure solution and submission are sorted properly\n    solution = solution.sort_values([series_id_column_name, time_column_name])\n    submission = submission.sort_values([series_id_column_name, time_column_name])\n\n    # Extract scoring intervals.\n    if use_scoring_intervals:\n        raise NotImplementedError(\"Scoring intervals not implemented.\")\n\n    # Extract ground-truth events.\n    ground_truths = solution.query(\"event not in ['start', 'end']\").reset_index(\n        drop=True\n    )\n\n    # Map each event class to its prevalence (needed for recall calculation)\n    class_counts = ground_truths.value_counts(event_column_name).to_dict()\n\n    # Create table for detections with a column indicating a match to a ground-truth event\n    detections = submission.assign(matched=False)\n\n    # Remove detections outside of scoring intervals\n    if use_scoring_intervals:\n        raise NotImplementedError(\"Scoring intervals not implemented.\")\n    else:\n        detections_filtered = detections\n\n    # Create table of event-class x tolerance x series_id values\n    aggregation_keys = pd.DataFrame(\n        [\n            (ev, tol, vid)\n            for ev in tolerances.keys()\n            for tol in tolerances[ev]\n            for vid in ground_truths[series_id_column_name].unique()\n        ],\n        columns=[event_column_name, \"tolerance\", series_id_column_name],\n    )\n\n    # Create match evaluation groups: event-class x tolerance x series_id\n    detections_grouped = aggregation_keys.merge(\n        detections_filtered, on=[event_column_name, series_id_column_name], how=\"left\"\n    ).groupby([event_column_name, \"tolerance\", series_id_column_name])\n    ground_truths_grouped = aggregation_keys.merge(\n        ground_truths, on=[event_column_name, series_id_column_name], how=\"left\"\n    ).groupby([event_column_name, \"tolerance\", series_id_column_name])\n\n    # Match detections to ground truth events by evaluation group\n    pbars = aggregation_keys.itertuples(index=False)\n    if progress_bar:\n        pbars = tqdm(pbars, total=len(aggregation_keys), desc=\"Matching detections\")\n        \n    detections_matched = []\n    for key in pbars:\n        dets = detections_grouped.get_group(key)\n        gts = ground_truths_grouped.get_group(key)\n        detections_matched.append(\n            match_detections(dets[\"tolerance\"].iloc[0], gts, dets)\n        )\n        \n    detections_matched = pd.concat(detections_matched)\n\n    # Compute AP per event x tolerance group\n    event_classes = ground_truths[event_column_name].unique()\n    ap_table = (\n        detections_matched.query(\"event in @event_classes\")\n        .groupby([event_column_name, \"tolerance\"])\n        .apply(\n            lambda group: average_precision_score(\n                group[\"matched\"].to_numpy(),\n                group[score_column_name].to_numpy(),\n                class_counts[group[event_column_name].iat[0]],\n            )\n        )\n        .reset_index()\n        .pivot(index=\"tolerance\", columns=\"event\", values=0)\n    )\n    \n    if verbose:\n        display(ap_table)\n        \n    # Average over tolerances, then over event classes\n    mean_ap = ap_table.mean().mean()\n\n    return mean_ap, ap_table, detections_matched","metadata":{"execution":{"iopub.execute_input":"2024-08-21T15:30:58.249806Z","iopub.status.busy":"2024-08-21T15:30:58.249493Z","iopub.status.idle":"2024-08-21T15:30:58.288001Z","shell.execute_reply":"2024-08-21T15:30:58.287087Z"},"papermill":{"duration":0.066643,"end_time":"2024-08-21T15:30:58.289984","exception":false,"start_time":"2024-08-21T15:30:58.223341","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"a5ca12b5","cell_type":"code","source":"df_sub = pd.read_csv(\"df_sub.csv\")\nscore_all, df_score, df_result = score(\n    solution=df_events,\n    submission=df_sub,\n    tolerances=tolerances,\n    series_id_column_name=series_id_column_name,\n    time_column_name=time_column_name,\n    event_column_name=event_column_name,\n    score_column_name=score_column_name\n)\n\nprint(score_all)","metadata":{"execution":{"iopub.execute_input":"2024-08-21T15:30:58.34263Z","iopub.status.busy":"2024-08-21T15:30:58.341662Z","iopub.status.idle":"2024-08-21T15:31:55.889382Z","shell.execute_reply":"2024-08-21T15:31:55.888165Z"},"papermill":{"duration":57.576458,"end_time":"2024-08-21T15:31:55.891432","exception":false,"start_time":"2024-08-21T15:30:58.314974","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"c087174c","cell_type":"code","source":"df_sub = pd.read_csv(\"df_sub_with_postprocess.csv\")\nscore_all, df_score, df_result = score(\n    solution=df_events,\n    submission=df_sub,\n    tolerances=tolerances,\n    series_id_column_name=series_id_column_name,\n    time_column_name=time_column_name,\n    event_column_name=event_column_name,\n    score_column_name=score_column_name\n)\n\nprint(score_all)","metadata":{"execution":{"iopub.execute_input":"2024-08-21T15:31:55.944851Z","iopub.status.busy":"2024-08-21T15:31:55.944098Z","iopub.status.idle":"2024-08-21T15:32:53.057391Z","shell.execute_reply":"2024-08-21T15:32:53.056441Z"},"papermill":{"duration":57.142888,"end_time":"2024-08-21T15:32:53.05999","exception":false,"start_time":"2024-08-21T15:31:55.917102","status":"completed"},"tags":[]},"outputs":[],"execution_count":null}]}