{"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":"code","source":"!pip install nb-black > /dev/null","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-05-12T05:57:52.187255Z","iopub.execute_input":"2022-05-12T05:57:52.187725Z","iopub.status.idle":"2022-05-12T05:58:06.616947Z","shell.execute_reply.started":"2022-05-12T05:57:52.187688Z","shell.execute_reply":"2022-05-12T05:58:06.615893Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport librosa\nimport matplotlib.pyplot as plt\nimport seaborn as sns\n\nplt.style.use(\"ggplot\")\n\n%load_ext lab_black","metadata":{"execution":{"iopub.status.busy":"2022-05-12T05:58:14.902157Z","iopub.execute_input":"2022-05-12T05:58:14.902463Z","iopub.status.idle":"2022-05-12T05:58:14.914814Z","shell.execute_reply.started":"2022-05-12T05:58:14.902420Z","shell.execute_reply":"2022-05-12T05:58:14.913878Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from types import SimpleNamespace\n\ncfg = SimpleNamespace(subclip_len_sec=60, n_splits=3, random_seed=135)","metadata":{"execution":{"iopub.status.busy":"2022-05-12T05:58:15.257516Z","iopub.execute_input":"2022-05-12T05:58:15.257850Z","iopub.status.idle":"2022-05-12T05:58:15.268742Z","shell.execute_reply.started":"2022-05-12T05:58:15.257814Z","shell.execute_reply":"2022-05-12T05:58:15.267720Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_meta = pd.read_csv(\"../input/birdclef-2022/train_metadata.csv\")\nsubclip_meta = pd.read_csv(\"../input/birdclef-2022-subclip-60-sec/subclip_meta.csv\")\ntrain_meta.rename({\"filename\": \"original_filename\"}, axis=1, inplace=True)\nscored_birds = pd.read_json(\"../input/birdclef-2022/scored_birds.json\")[0].tolist()\ntrain_meta[\"is_scored\"] = train_meta.primary_label.apply(lambda x: x in scored_birds)\ntrain_meta[\"in_hawaii\"] = (\n    (train_meta[\"longitude\"] >= -161)\n    & (train_meta[\"longitude\"] < -153)\n    & (train_meta[\"latitude\"] >= 18)\n    & (train_meta[\"latitude\"] < 24)\n)","metadata":{"execution":{"iopub.status.busy":"2022-05-12T05:58:15.354225Z","iopub.execute_input":"2022-05-12T05:58:15.355089Z","iopub.status.idle":"2022-05-12T05:58:15.496708Z","shell.execute_reply.started":"2022-05-12T05:58:15.355045Z","shell.execute_reply":"2022-05-12T05:58:15.495787Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, ax = plt.subplots()\nsns.countplot(x=\"in_hawaii\", data=train_meta, ax=ax)\nax.set(title=\"Sample Counts\")\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-05-12T05:58:15.652384Z","iopub.execute_input":"2022-05-12T05:58:15.653201Z","iopub.status.idle":"2022-05-12T05:58:15.829597Z","shell.execute_reply.started":"2022-05-12T05:58:15.653156Z","shell.execute_reply":"2022-05-12T05:58:15.828598Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, ax = plt.subplots()\nsns.countplot(x=\"is_scored\", data=train_meta, ax=ax)\nax.set(title=\"Sample Counts\")\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-05-12T05:58:15.831269Z","iopub.execute_input":"2022-05-12T05:58:15.831541Z","iopub.status.idle":"2022-05-12T05:58:16.006900Z","shell.execute_reply.started":"2022-05-12T05:58:15.831510Z","shell.execute_reply":"2022-05-12T05:58:16.005882Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"meta_merged = pd.merge(train_meta, subclip_meta, on=\"original_filename\", how=\"right\")","metadata":{"execution":{"iopub.status.busy":"2022-05-12T05:58:16.008501Z","iopub.execute_input":"2022-05-12T05:58:16.008718Z","iopub.status.idle":"2022-05-12T05:58:16.046350Z","shell.execute_reply.started":"2022-05-12T05:58:16.008691Z","shell.execute_reply":"2022-05-12T05:58:16.045572Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"meta_merged.head().T","metadata":{"execution":{"iopub.status.busy":"2022-05-12T05:58:16.304921Z","iopub.execute_input":"2022-05-12T05:58:16.305626Z","iopub.status.idle":"2022-05-12T05:58:16.326275Z","shell.execute_reply.started":"2022-05-12T05:58:16.305581Z","shell.execute_reply":"2022-05-12T05:58:16.325224Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Define Label order","metadata":{}},{"cell_type":"markdown","source":"* 元のmetadataにおいて\n    * scored 21 species: primary_labelのサンプル数が多い順\n    * unscored 131 species: primary_labelのサンプル数が多い順","metadata":{}},{"cell_type":"code","source":"all_set = set(meta_merged.primary_label.unique())\nscored_set = set(scored_birds)\nunscored_set = all_set.difference(scored_set)\nlen(all_set), len(scored_set), len(unscored_set)","metadata":{"execution":{"iopub.status.busy":"2022-05-12T05:58:17.363527Z","iopub.execute_input":"2022-05-12T05:58:17.363944Z","iopub.status.idle":"2022-05-12T05:58:17.378639Z","shell.execute_reply.started":"2022-05-12T05:58:17.363898Z","shell.execute_reply":"2022-05-12T05:58:17.377497Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"label_counts = meta_merged.value_counts(\"primary_label\")\nlabel_counts = pd.DataFrame({\"num_samples\": label_counts}).reset_index()\nlabel_counts[\"is_scored\"] = label_counts[\"primary_label\"].apply(\n    lambda s: s in scored_birds\n)\nlabel_counts.sort_values([\"is_scored\", \"num_samples\"])\nlabel_counts","metadata":{"execution":{"iopub.status.busy":"2022-05-12T05:58:17.538954Z","iopub.execute_input":"2022-05-12T05:58:17.540000Z","iopub.status.idle":"2022-05-12T05:58:17.572213Z","shell.execute_reply.started":"2022-05-12T05:58:17.539956Z","shell.execute_reply":"2022-05-12T05:58:17.571093Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def create_scored_org():\n    train_org = pd.read_csv(\"../input/birdclef-2022/train_metadata.csv\")\n    scored_org = train_org.query(\"primary_label in @scored_birds\")\n    df = (\n        scored_org.groupby(\"primary_label\")\n        .agg(num_samples=(\"filename\", \"count\"))\n        .sort_values(\"num_samples\", ascending=False)\n    )\n    df[\"group\"] = [\"top5\"] * 5 + [\"mid_top5\"] * 5 + [\"mid_low5\"] * 5 + [\"low6\"] * 6\n    groups = df[\"group\"].unique()\n    group2id = {g: i for i, g in enumerate(groups)}\n    df[\"group_id\"] = df[\"group\"].apply(lambda g: group2id[g])\n    df = df.reset_index()\n    df = df.rename({\"num_samples\": \"num_samples_org\"}, axis=1)\n    return df","metadata":{"execution":{"iopub.status.busy":"2022-05-12T05:58:17.879147Z","iopub.execute_input":"2022-05-12T05:58:17.879465Z","iopub.status.idle":"2022-05-12T05:58:17.904961Z","shell.execute_reply.started":"2022-05-12T05:58:17.879420Z","shell.execute_reply":"2022-05-12T05:58:17.903892Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def create_unscored_org():\n    train_org = pd.read_csv(\"../input/birdclef-2022/train_metadata.csv\")\n    unscored_org = train_org.query(\"primary_label not in @scored_birds\")\n    df = (\n        unscored_org.groupby(\"primary_label\")\n        .agg(num_samples=(\"filename\", \"count\"))\n        .sort_values(\"num_samples\", ascending=False)\n    )\n    df = df.reset_index()\n    df = df.rename({\"num_samples\": \"num_samples_org\"}, axis=1)\n    return df","metadata":{"execution":{"iopub.status.busy":"2022-05-12T05:58:18.410428Z","iopub.execute_input":"2022-05-12T05:58:18.410735Z","iopub.status.idle":"2022-05-12T05:58:18.428604Z","shell.execute_reply.started":"2022-05-12T05:58:18.410705Z","shell.execute_reply":"2022-05-12T05:58:18.427726Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"create_scored_org()","metadata":{"execution":{"iopub.status.busy":"2022-05-12T05:58:18.953029Z","iopub.execute_input":"2022-05-12T05:58:18.953887Z","iopub.status.idle":"2022-05-12T05:58:19.057851Z","shell.execute_reply.started":"2022-05-12T05:58:18.953834Z","shell.execute_reply":"2022-05-12T05:58:19.057159Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"create_unscored_org()","metadata":{"execution":{"iopub.status.busy":"2022-05-12T05:58:19.982742Z","iopub.execute_input":"2022-05-12T05:58:19.983316Z","iopub.status.idle":"2022-05-12T05:58:20.094699Z","shell.execute_reply.started":"2022-05-12T05:58:19.983270Z","shell.execute_reply":"2022-05-12T05:58:20.093732Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ordered_species = np.concatenate(\n    [\n        create_scored_org().primary_label.tolist(),\n        create_unscored_org().primary_label.tolist(),\n    ]\n)\nassert len(ordered_species) == 152\nordered_species","metadata":{"execution":{"iopub.status.busy":"2022-05-12T05:58:20.550170Z","iopub.execute_input":"2022-05-12T05:58:20.550879Z","iopub.status.idle":"2022-05-12T05:58:20.743957Z","shell.execute_reply.started":"2022-05-12T05:58:20.550836Z","shell.execute_reply":"2022-05-12T05:58:20.742979Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"label2id = {l: i for i, l in enumerate(ordered_species)}\nmeta_merged[\"target\"] = meta_merged.primary_label.apply(lambda l: label2id[l])\nmeta_merged[\"target2\"] = meta_merged.secondary_labels.apply(\n    lambda ls: \" \".join([str(label2id[l]) for l in eval(ls)])\n)","metadata":{"execution":{"iopub.status.busy":"2022-05-12T05:58:21.050734Z","iopub.execute_input":"2022-05-12T05:58:21.051049Z","iopub.status.idle":"2022-05-12T05:58:21.189034Z","shell.execute_reply.started":"2022-05-12T05:58:21.051019Z","shell.execute_reply":"2022-05-12T05:58:21.188213Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"meta_merged[meta_merged.target2.apply(lambda x: len(x)) > 0].head().T","metadata":{"execution":{"iopub.status.busy":"2022-05-12T05:58:21.546679Z","iopub.execute_input":"2022-05-12T05:58:21.546956Z","iopub.status.idle":"2022-05-12T05:58:21.589528Z","shell.execute_reply.started":"2022-05-12T05:58:21.546927Z","shell.execute_reply":"2022-05-12T05:58:21.588686Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Split into folds","metadata":{}},{"cell_type":"code","source":"from sklearn.model_selection import StratifiedGroupKFold","metadata":{"execution":{"iopub.status.busy":"2022-05-12T05:58:29.112043Z","iopub.execute_input":"2022-05-12T05:58:29.112550Z","iopub.status.idle":"2022-05-12T05:58:29.118203Z","shell.execute_reply.started":"2022-05-12T05:58:29.112493Z","shell.execute_reply":"2022-05-12T05:58:29.117128Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def split_group_by(df, group_key, cfg):\n    df = df.copy()\n    skf = StratifiedGroupKFold(\n        n_splits=cfg.n_splits, shuffle=True, random_state=cfg.random_seed\n    )\n\n    df[\"fold\"] = -1\n    for n, (trn_index, val_index) in enumerate(\n        skf.split(\n            df,\n            df.primary_label,\n            df[group_key],\n        )\n    ):\n        df.loc[val_index, \"fold\"] = int(n)\n    return df","metadata":{"execution":{"iopub.status.busy":"2022-05-12T05:58:29.945824Z","iopub.execute_input":"2022-05-12T05:58:29.946556Z","iopub.status.idle":"2022-05-12T05:58:29.966879Z","shell.execute_reply.started":"2022-05-12T05:58:29.946507Z","shell.execute_reply":"2022-05-12T05:58:29.965724Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def create_metadata(df, group_key, cfg):\n    df = df.copy()\n    scored_df = df.query(\"is_scored == True\").reset_index(drop=True)\n    unscored_df = df.query(\"is_scored == False\").reset_index(drop=True)\n    scored_df = split_group_by(scored_df, group_key, cfg)\n    unscored_df[\"fold\"] = -2\n    merged_df = pd.concat([scored_df, unscored_df]).reset_index(drop=True)\n    merged_df.to_csv(\n        f\"birdclef2022_metadata_v2_subclip_{cfg.subclip_len_sec}_sec_group_key_{group_key}_{cfg.n_splits}_fold_seed_{cfg.random_seed}.csv\",\n        index=False,\n    )\n    return merged_df","metadata":{"execution":{"iopub.status.busy":"2022-05-12T06:02:09.287164Z","iopub.execute_input":"2022-05-12T06:02:09.287740Z","iopub.status.idle":"2022-05-12T06:02:09.316904Z","shell.execute_reply.started":"2022-05-12T06:02:09.287703Z","shell.execute_reply":"2022-05-12T06:02:09.315948Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df = create_metadata(meta_merged, \"original_filename\", cfg)\ndf = df.query(\"fold >= 0\")\n\nfig, ax = plt.subplots(figsize=(8, 8))\nsns.countplot(\n    y=\"primary_label\",\n    data=df,\n    hue=\"fold\",\n    order=ordered_species[:21],\n    ax=ax,\n)\nax.set(xscale=\"log\", title=\"sample count per fold\")\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-05-12T06:05:11.245623Z","iopub.execute_input":"2022-05-12T06:05:11.245910Z","iopub.status.idle":"2022-05-12T06:05:12.934007Z","shell.execute_reply.started":"2022-05-12T06:05:11.245882Z","shell.execute_reply":"2022-05-12T06:05:12.933329Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df = create_metadata(meta_merged, \"author\", cfg)\ndf = df.query(\"fold >= 0\")\n\nfig, ax = plt.subplots(figsize=(8, 8))\nsns.countplot(\n    y=\"primary_label\",\n    data=df,\n    hue=\"fold\",\n    order=ordered_species[:21],\n    ax=ax,\n)\nax.set(xscale=\"log\", title=\"sample count per fold\")\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-05-12T06:05:02.806837Z","iopub.execute_input":"2022-05-12T06:05:02.807761Z","iopub.status.idle":"2022-05-12T06:05:03.987898Z","shell.execute_reply.started":"2022-05-12T06:05:02.807701Z","shell.execute_reply":"2022-05-12T06:05:03.986721Z"},"trusted":true},"execution_count":null,"outputs":[]}]}