{"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":"import numpy as np \nimport pandas as pd \nimport os\nimport pickle as pkl\nfrom collections import defaultdict\nimport matplotlib.pyplot as plt\nimport catboost as cb","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-12-19T23:42:42.659826Z","iopub.execute_input":"2022-12-19T23:42:42.660751Z","iopub.status.idle":"2022-12-19T23:42:44.709703Z","shell.execute_reply.started":"2022-12-19T23:42:42.660705Z","shell.execute_reply":"2022-12-19T23:42:44.708288Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def open_pkl(path):\n    with open(path, \"rb\") as file:\n        return pkl.load(file)","metadata":{"execution":{"iopub.status.busy":"2022-12-19T23:42:44.712253Z","iopub.execute_input":"2022-12-19T23:42:44.713272Z","iopub.status.idle":"2022-12-19T23:42:44.720344Z","shell.execute_reply.started":"2022-12-19T23:42:44.713227Z","shell.execute_reply":"2022-12-19T23:42:44.719345Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def intersaction_coeff(list1, list2):\n    return len(set(list1).intersection(set(list2)))","metadata":{"execution":{"iopub.status.busy":"2022-12-19T23:46:07.971926Z","iopub.execute_input":"2022-12-19T23:46:07.972922Z","iopub.status.idle":"2022-12-19T23:46:07.978912Z","shell.execute_reply.started":"2022-12-19T23:46:07.972864Z","shell.execute_reply":"2022-12-19T23:46:07.977705Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def cos_sim(a, b):\n    cos_sim = np.dot(a, b)/(np.linalg.norm(a)*np.linalg.norm(b))\n    return cos_sim","metadata":{"execution":{"iopub.status.busy":"2022-12-19T23:46:19.547870Z","iopub.execute_input":"2022-12-19T23:46:19.549908Z","iopub.status.idle":"2022-12-19T23:46:19.557191Z","shell.execute_reply.started":"2022-12-19T23:46:19.549849Z","shell.execute_reply":"2022-12-19T23:46:19.555097Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Введение \n\nМы пытаемся предсказать значения ~140 белков по значениям ~22K РНК использую датасет из ~70K клеток. Так как тестовый датасет от нас скрыт, мы будем испльзовать исходный набор для тестирования и тренировки, используя различные разбиения. \n\nМы сконцентрируемся на ~15 белоков: **CD44**, **CD41**, **CD36**, **CD32**, **CD88**, **CD48**, **CD62L**, **CD49b**, **CD45RA**, **CD82**, **CD38**, **CD71**, **CD115**, **CD11a**, **CD244**, **CD45**.\n\nПредсказывать их на имеющихся данных, удается лучше всего. Для каждого белка мы тренируем отдельную модель. \n\nВ качестве базовых моделей мы используем градиентный бустинг, состоящий из множества решающих деревьев, в узлах которых значения разных РНК, а в листах дерева - значения белка, который мы пытемся предсказать данной моделью.\n\n#### Пример решающего дерева:\n![Пример решающего дерева](https://scikit-learn.org/stable/_images/sphx_glr_plot_iris_dtc_002.png)","metadata":{}},{"cell_type":"markdown","source":"## Feature importance (FI)\n\nПосле того как мы построили модель (для какого-то конкретного белка), мы можем получить для каждого входного РНК некоторый \"коэффициент важности\" - числа, которое описывает насколько значение этого РНК существенно для расчета белка. Такую характеристку можно получить разными способами (например сколько раз данное РНК участвовало в узлах решающего дерева). \n\nДля **catboost**-а: показывает, насколько в среднем изменяется прогноз при изменении входного значения. Чем больше значение важности, тем больше в среднем будет изменение значения прогноза, если этот признак изменится. \n\nТаким образом тренирую предсказывать один белок мы так же получем на выходе вектор из коэффициентов важности размерность 22K, по кол-ву входных РНК","metadata":{}},{"cell_type":"markdown","source":"## Тест 4го дня\n\nВначале мы обучили модели использую разбиение по дням: в качестве тесты мы взяли все данные 4го дня всех доноров, в качестве трейна - все остальное. \n\nПолученные модели лежат в: [cite-catboost-v5/models/YOUR_CD](cite-catboost-v5/models/YOUR_CD)\n\n**FI** и результаты теста (корреляция с истинным значением белка): [cite-catboost-v5/models/catboost_feature_importances_v5.pkl](cite-catboost-v5/models/catboost_feature_importances_v5.pkl) \n\nСо стуктурой: \n\n```python\n{\n    \"CDXXX\": {\n        \"scores\": array([...]), # FI \n        \"columns\": [...], # список РНК для FI,\n        \"corr_score\": ..., # корреляция на тесте\n        \"best_100\": [...] # список 100 наиболее значимых РНК по FI\n    }\n}\n```","metadata":{}},{"cell_type":"code","source":"!ls /kaggle/input/cite-catboost-v5/models/CD115","metadata":{"execution":{"iopub.status.busy":"2022-12-19T20:59:06.048842Z","iopub.execute_input":"2022-12-19T20:59:06.049237Z","iopub.status.idle":"2022-12-19T20:59:07.146626Z","shell.execute_reply.started":"2022-12-19T20:59:06.049207Z","shell.execute_reply":"2022-12-19T20:59:07.144822Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Отрисовка первого дерева (из 1000) для модели предсказания CD36","metadata":{}},{"cell_type":"code","source":"train_cite_input_df = pd.read_hdf(\"/kaggle/input/open-problems-multimodal/train_cite_inputs.h5\")\ntrain_cite_target_df = pd.read_hdf(\"/kaggle/input/open-problems-multimodal/train_cite_targets.h5\")","metadata":{"execution":{"iopub.status.busy":"2022-12-19T21:48:57.458093Z","iopub.execute_input":"2022-12-19T21:48:57.458592Z","iopub.status.idle":"2022-12-19T21:49:51.308352Z","shell.execute_reply.started":"2022-12-19T21:48:57.458551Z","shell.execute_reply":"2022-12-19T21:49:51.307387Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_cd36 = cb.CatBoostRegressor()\nmodel_cd36.load_model(\"/kaggle/input/cite-catboost-v5/models/CD115/model.cbm\")","metadata":{"execution":{"iopub.status.busy":"2022-12-19T21:47:48.572594Z","iopub.execute_input":"2022-12-19T21:47:48.572950Z","iopub.status.idle":"2022-12-19T21:47:48.632723Z","shell.execute_reply.started":"2022-12-19T21:47:48.572921Z","shell.execute_reply":"2022-12-19T21:47:48.631920Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pool = cb.Pool(\n    train_cite_input_df, \n    train_cite_target_df[\"CD36\"],\n    feature_names=list(train_cite_input_df.columns)\n)","metadata":{"execution":{"iopub.status.busy":"2022-12-19T21:49:51.310632Z","iopub.execute_input":"2022-12-19T21:49:51.311061Z","iopub.status.idle":"2022-12-19T21:49:53.052423Z","shell.execute_reply.started":"2022-12-19T21:49:51.311018Z","shell.execute_reply":"2022-12-19T21:49:53.051488Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_cd36.plot_tree(tree_idx=0, pool=pool)","metadata":{"execution":{"iopub.status.busy":"2022-12-19T21:50:14.929450Z","iopub.execute_input":"2022-12-19T21:50:14.929887Z","iopub.status.idle":"2022-12-19T21:50:15.984452Z","shell.execute_reply.started":"2022-12-19T21:50:14.929846Z","shell.execute_reply":"2022-12-19T21:50:15.982842Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Представим данные в ввиде датафрейма","metadata":{}},{"cell_type":"code","source":"catboost_fi = open_pkl(\"/kaggle/input/cite-catboost-v5/models/catboost_feature_importances_v5.pkl\")\n\ncatboost_fi_df = defaultdict(list)\nfor k,v in catboost_fi.items():\n    catboost_fi_df[\"CD\"].append(k)\n    catboost_fi_df[\"corr\"].append(v[\"corr_score\"])\n    \n    best_scores_idx = np.flip(np.argsort(v[\"scores\"]))\n    best_100_idx = best_scores_idx[:100] \n    best_100_scores = v[\"scores\"][best_100_idx]\n    best_100_names = [v[\"columns\"][it] for it in best_100_idx]\n    assert best_100_names == v[\"best_100\"]\n    \n    for i in range(len(best_100_names)):\n        catboost_fi_df[f\"FI_{i}\"].append(best_100_names[i])\n        catboost_fi_df[f\"FI_{i}_score\"].append(best_100_scores[i])\n    \ncatboost_fi_df = pd.DataFrame(catboost_fi_df)","metadata":{"execution":{"iopub.status.busy":"2022-12-19T23:45:37.852311Z","iopub.execute_input":"2022-12-19T23:45:37.852879Z","iopub.status.idle":"2022-12-19T23:45:37.961436Z","shell.execute_reply.started":"2022-12-19T23:45:37.852838Z","shell.execute_reply":"2022-12-19T23:45:37.960276Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"В этой таблицы мы видим значения корреляции предсказания каждого белка на тесте и 100 наиболее важных РНК (и значения важности) для каждого белка","metadata":{}},{"cell_type":"code","source":"pd.set_option('display.max_columns', None)\ncatboost_fi_df","metadata":{"execution":{"iopub.status.busy":"2022-12-19T21:13:30.555415Z","iopub.execute_input":"2022-12-19T21:13:30.555832Z","iopub.status.idle":"2022-12-19T21:13:30.784088Z","shell.execute_reply.started":"2022-12-19T21:13:30.555802Z","shell.execute_reply":"2022-12-19T21:13:30.783041Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Пример графика 10 наиболее важных РНК для предсказания **CD36**","metadata":{}},{"cell_type":"code","source":"best_scores_idx = np.flip(np.argsort(catboost_fi[\"CD36\"][\"scores\"]))\nbest_scores_10 = catboost_fi[\"CD36\"][\"scores\"][best_scores_idx[:10]]\nbest_names_10 = [catboost_fi[\"CD36\"][\"columns\"][i] for i in best_scores_idx[:10]]\n\nplt.figure(figsize=(10, 5), dpi=80)\nplt.bar(\n    best_names_10, \n    best_scores_10\n)\n_ = plt.xticks(rotation = 80)\n_ = plt.title(\"CD36 FI\")","metadata":{"execution":{"iopub.status.busy":"2022-12-19T21:32:35.186755Z","iopub.execute_input":"2022-12-19T21:32:35.187329Z","iopub.status.idle":"2022-12-19T21:32:35.682694Z","shell.execute_reply.started":"2022-12-19T21:32:35.187286Z","shell.execute_reply":"2022-12-19T21:32:35.681622Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Сравнение белков на основе FI\n\nТак как FI это с одной стороны вектор, а с другой множесто РНК, то можно сравнить разные белка на основе двух подходов:\n- кол-во пересекающихся РНК в первой сотне наиболее важных \n- косинусное расстояние между полными векторами **FI** т.е $ \\frac{\\vec{fi_1} \\cdot \\vec{fi_2}}{norm(\\vec{fi_1}) \\cdot norm(\\vec{fi_2})} $","metadata":{}},{"cell_type":"markdown","source":"","metadata":{}},{"cell_type":"markdown","source":"## Тест 4го дня по отдельным типам клеток \n\nТеперь возьмем в качестве теста так же данные 4го дня, но зафиксируем клеточный тип т.е для трейна/теста мы будем использовать только клетки с одним и тем же клеточным типом. \n\nМодели: [cite-catboost-v5/models/CD32_EryP](cite-catboost-v5/models/CD32_EryP)\n\nКорреляции/тесты: [cite-catboost-v5/models/cell_type_feature_importances_v5.pkl](cite-catboost-v5/models/cell_type_feature_importances_v5.pkl)","metadata":{}},{"cell_type":"code","source":"cell_type_catboost_fi = open_pkl(\n    \"/kaggle/input/cite-catboost-v5/models/cell_type_feature_importances_v5.pkl\"\n)","metadata":{"execution":{"iopub.status.busy":"2022-12-19T23:42:51.147914Z","iopub.execute_input":"2022-12-19T23:42:51.148634Z","iopub.status.idle":"2022-12-19T23:42:51.437386Z","shell.execute_reply.started":"2022-12-19T23:42:51.148591Z","shell.execute_reply":"2022-12-19T23:42:51.435879Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cell_type_catboost_fi_df = defaultdict(list)\nfor k, v in cell_type_catboost_fi.items():\n    cell_type_catboost_fi_df[\"CD\"].append(v[\"cd\"])\n    cell_type_catboost_fi_df[\"cell_type\"].append(v[\"cell_type\"])\n    cell_type_catboost_fi_df[\"corr\"].append(v[\"corr_score\"])\n    cell_type_catboost_fi_df[\"Intersetion\"].append(\n        intersaction_coeff(\n            v[\"best_100\"], \n            catboost_fi[v[\"cd\"]][\"best_100\"]\n        )\n    )\n    cell_type_catboost_fi_df[\"Cos_sim\"].append(\n        cos_sim(\n            v[\"scores\"], \n            catboost_fi[v[\"cd\"]][\"scores\"]\n        )\n    )    \ncell_type_catboost_fi_df = pd.DataFrame(cell_type_catboost_fi_df)\ncell_type_catboost_fi_df.sort_values(\"CD\", inplace=True, ascending=False)","metadata":{"execution":{"iopub.status.busy":"2022-12-20T00:04:43.063302Z","iopub.execute_input":"2022-12-20T00:04:43.064787Z","iopub.status.idle":"2022-12-20T00:04:43.099869Z","shell.execute_reply.started":"2022-12-20T00:04:43.064721Z","shell.execute_reply":"2022-12-20T00:04:43.098115Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"В этой таблице приведенны данные моделей по предсказанию белков обученныех на данных от зафиксированных клеточных типов (колонка **cell_type**). \n\n- corr - корреляция на тесте\n- Intersetion - размер пересечения лучших 100 РНК с моделью, обученной на всех клеточных типах\n- Cos_sim - косинусная близость FI","metadata":{}},{"cell_type":"code","source":"pd.set_option('display.max_rows', 100)\ncell_type_catboost_fi_df","metadata":{"execution":{"iopub.status.busy":"2022-12-20T00:04:44.246628Z","iopub.execute_input":"2022-12-20T00:04:44.247067Z","iopub.status.idle":"2022-12-20T00:04:44.272173Z","shell.execute_reply.started":"2022-12-20T00:04:44.247036Z","shell.execute_reply":"2022-12-20T00:04:44.270615Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}