|
a |
|
b/transfer-learning.ipynb |
|
|
1 |
{ |
|
|
2 |
"cells": [ |
|
|
3 |
{ |
|
|
4 |
"cell_type": "code", |
|
|
5 |
"execution_count": 1, |
|
|
6 |
"id": "d3426c73-9556-4223-a0f4-afdd5edbd911", |
|
|
7 |
"metadata": {}, |
|
|
8 |
"outputs": [], |
|
|
9 |
"source": [ |
|
|
10 |
"import matplotlib.pyplot as plt\n", |
|
|
11 |
"import numpy as np\n", |
|
|
12 |
"import pandas as pd\n", |
|
|
13 |
"import torch\n", |
|
|
14 |
"import xgboost as xgb\n", |
|
|
15 |
"from scipy.stats import spearmanr\n", |
|
|
16 |
"from sklearn.model_selection import train_test_split, GridSearchCV, KFold\n", |
|
|
17 |
"from sklearn.metrics import mean_squared_error\n", |
|
|
18 |
"from transformers import AutoTokenizer, AutoModel" |
|
|
19 |
] |
|
|
20 |
}, |
|
|
21 |
{ |
|
|
22 |
"cell_type": "code", |
|
|
23 |
"execution_count": 2, |
|
|
24 |
"id": "cc1849cc-efb9-4eb9-946e-3ce2a0480fee", |
|
|
25 |
"metadata": {}, |
|
|
26 |
"outputs": [ |
|
|
27 |
{ |
|
|
28 |
"name": "stdout", |
|
|
29 |
"output_type": "stream", |
|
|
30 |
"text": [ |
|
|
31 |
"Number of examples is: 560\n" |
|
|
32 |
] |
|
|
33 |
}, |
|
|
34 |
{ |
|
|
35 |
"data": { |
|
|
36 |
"text/html": [ |
|
|
37 |
"<div>\n", |
|
|
38 |
"<style scoped>\n", |
|
|
39 |
" .dataframe tbody tr th:only-of-type {\n", |
|
|
40 |
" vertical-align: middle;\n", |
|
|
41 |
" }\n", |
|
|
42 |
"\n", |
|
|
43 |
" .dataframe tbody tr th {\n", |
|
|
44 |
" vertical-align: top;\n", |
|
|
45 |
" }\n", |
|
|
46 |
"\n", |
|
|
47 |
" .dataframe thead th {\n", |
|
|
48 |
" text-align: right;\n", |
|
|
49 |
" }\n", |
|
|
50 |
"</style>\n", |
|
|
51 |
"<table border=\"1\" class=\"dataframe\">\n", |
|
|
52 |
" <thead>\n", |
|
|
53 |
" <tr style=\"text-align: right;\">\n", |
|
|
54 |
" <th></th>\n", |
|
|
55 |
" <th>CANONICAL_SMILES</th>\n", |
|
|
56 |
" <th>pIC50</th>\n", |
|
|
57 |
" </tr>\n", |
|
|
58 |
" </thead>\n", |
|
|
59 |
" <tbody>\n", |
|
|
60 |
" <tr>\n", |
|
|
61 |
" <th>0</th>\n", |
|
|
62 |
" <td>Nc1nc(N)c2c(Sc3ccccc3)cccc2n1</td>\n", |
|
|
63 |
" <td>6.21</td>\n", |
|
|
64 |
" </tr>\n", |
|
|
65 |
" <tr>\n", |
|
|
66 |
" <th>1</th>\n", |
|
|
67 |
" <td>COc1ccc(OC)c(Cc2sc3nc(N)nc(N)c3c2C)c1</td>\n", |
|
|
68 |
" <td>6.14</td>\n", |
|
|
69 |
" </tr>\n", |
|
|
70 |
" <tr>\n", |
|
|
71 |
" <th>2</th>\n", |
|
|
72 |
" <td>CN(Cc1coc2nc(N)nc(N)c12)c3ccc(cc3)C(=O)N[C@@H]...</td>\n", |
|
|
73 |
" <td>6.66</td>\n", |
|
|
74 |
" </tr>\n", |
|
|
75 |
" <tr>\n", |
|
|
76 |
" <th>3</th>\n", |
|
|
77 |
" <td>Nc1nc(N)c2nc(CSc3ccc(cc3)C(=O)NC(CCC(=O)O)C(=O...</td>\n", |
|
|
78 |
" <td>5.57</td>\n", |
|
|
79 |
" </tr>\n", |
|
|
80 |
" <tr>\n", |
|
|
81 |
" <th>4</th>\n", |
|
|
82 |
" <td>Nc1nc(N)c2nc(CCSc3ccc(cc3)C(=O)NC(CCC(=O)O)C(=...</td>\n", |
|
|
83 |
" <td>4.60</td>\n", |
|
|
84 |
" </tr>\n", |
|
|
85 |
" </tbody>\n", |
|
|
86 |
"</table>\n", |
|
|
87 |
"</div>" |
|
|
88 |
], |
|
|
89 |
"text/plain": [ |
|
|
90 |
" CANONICAL_SMILES pIC50\n", |
|
|
91 |
"0 Nc1nc(N)c2c(Sc3ccccc3)cccc2n1 6.21\n", |
|
|
92 |
"1 COc1ccc(OC)c(Cc2sc3nc(N)nc(N)c3c2C)c1 6.14\n", |
|
|
93 |
"2 CN(Cc1coc2nc(N)nc(N)c12)c3ccc(cc3)C(=O)N[C@@H]... 6.66\n", |
|
|
94 |
"3 Nc1nc(N)c2nc(CSc3ccc(cc3)C(=O)NC(CCC(=O)O)C(=O... 5.57\n", |
|
|
95 |
"4 Nc1nc(N)c2nc(CCSc3ccc(cc3)C(=O)NC(CCC(=O)O)C(=... 4.60" |
|
|
96 |
] |
|
|
97 |
}, |
|
|
98 |
"execution_count": 2, |
|
|
99 |
"metadata": {}, |
|
|
100 |
"output_type": "execute_result" |
|
|
101 |
} |
|
|
102 |
], |
|
|
103 |
"source": [ |
|
|
104 |
"# Load the relevant columns of the dataset\n", |
|
|
105 |
"df = pd.read_csv(\"data/hDHFR_pIC50_data.csv\")[[\"CANONICAL_SMILES\", \"pIC50\"]]\n", |
|
|
106 |
"print(f'Number of examples is: {len(df)}')\n", |
|
|
107 |
"df.head()" |
|
|
108 |
] |
|
|
109 |
}, |
|
|
110 |
{ |
|
|
111 |
"cell_type": "code", |
|
|
112 |
"execution_count": 3, |
|
|
113 |
"id": "005b3f00-7291-4ea0-9726-18a8217d5a22", |
|
|
114 |
"metadata": {}, |
|
|
115 |
"outputs": [ |
|
|
116 |
{ |
|
|
117 |
"name": "stderr", |
|
|
118 |
"output_type": "stream", |
|
|
119 |
"text": [ |
|
|
120 |
"Some weights of RobertaModel were not initialized from the model checkpoint at DeepChem/ChemBERTa-77M-MLM and are newly initialized: ['roberta.pooler.dense.bias', 'roberta.pooler.dense.weight']\n", |
|
|
121 |
"You should probably TRAIN this model on a down-stream task to be able to use it for predictions and inference.\n" |
|
|
122 |
] |
|
|
123 |
} |
|
|
124 |
], |
|
|
125 |
"source": [ |
|
|
126 |
"# Load pre-trained model and tokenizer\n", |
|
|
127 |
"model_name = \"DeepChem/ChemBERTa-77M-MLM\"\n", |
|
|
128 |
"tokenizer = AutoTokenizer.from_pretrained(model_name)\n", |
|
|
129 |
"model = AutoModel.from_pretrained(model_name)\n", |
|
|
130 |
"\n", |
|
|
131 |
"# Tokenize the input data\n", |
|
|
132 |
"input_texts = list(df[\"CANONICAL_SMILES\"])\n", |
|
|
133 |
"input_ids = tokenizer(input_texts, padding=True, truncation=True, return_tensors=\"pt\")\n", |
|
|
134 |
"\n", |
|
|
135 |
"# Pass tokenized input through the model to obtain embeddings\n", |
|
|
136 |
"with torch.no_grad():\n", |
|
|
137 |
" outputs = model(**input_ids)\n", |
|
|
138 |
" embeddings = outputs.last_hidden_state" |
|
|
139 |
] |
|
|
140 |
}, |
|
|
141 |
{ |
|
|
142 |
"cell_type": "code", |
|
|
143 |
"execution_count": 4, |
|
|
144 |
"id": "2157c60e-ff96-44c8-8938-8b2e1773d55d", |
|
|
145 |
"metadata": {}, |
|
|
146 |
"outputs": [ |
|
|
147 |
{ |
|
|
148 |
"data": { |
|
|
149 |
"text/plain": [ |
|
|
150 |
"torch.Size([560, 166, 384])" |
|
|
151 |
] |
|
|
152 |
}, |
|
|
153 |
"execution_count": 4, |
|
|
154 |
"metadata": {}, |
|
|
155 |
"output_type": "execute_result" |
|
|
156 |
} |
|
|
157 |
], |
|
|
158 |
"source": [ |
|
|
159 |
"# (number_of_examples, max_length, hidden_dimentions)\n", |
|
|
160 |
"embeddings.shape" |
|
|
161 |
] |
|
|
162 |
}, |
|
|
163 |
{ |
|
|
164 |
"cell_type": "code", |
|
|
165 |
"execution_count": 5, |
|
|
166 |
"id": "f2f0def2-3c37-46c1-a335-90c70eb7a1a9", |
|
|
167 |
"metadata": {}, |
|
|
168 |
"outputs": [ |
|
|
169 |
{ |
|
|
170 |
"data": { |
|
|
171 |
"text/plain": [ |
|
|
172 |
"torch.Size([560, 384])" |
|
|
173 |
] |
|
|
174 |
}, |
|
|
175 |
"execution_count": 5, |
|
|
176 |
"metadata": {}, |
|
|
177 |
"output_type": "execute_result" |
|
|
178 |
} |
|
|
179 |
], |
|
|
180 |
"source": [ |
|
|
181 |
"# Flatten embeddings by pooling across the sequence dimension\n", |
|
|
182 |
"pooled_embeddings = torch.mean(embeddings, dim=1) # use mean; other pooling methods can be used\n", |
|
|
183 |
"pooled_embeddings.shape" |
|
|
184 |
] |
|
|
185 |
}, |
|
|
186 |
{ |
|
|
187 |
"cell_type": "code", |
|
|
188 |
"execution_count": 6, |
|
|
189 |
"id": "8250d5d7-fe14-40a5-ad50-0368ab2b39d8", |
|
|
190 |
"metadata": {}, |
|
|
191 |
"outputs": [], |
|
|
192 |
"source": [ |
|
|
193 |
"# Concatenate the embeddings with the dataset\n", |
|
|
194 |
"column_names = ['x' + str(i) for i in range(pooled_embeddings.shape[1])]\n", |
|
|
195 |
"pooled_embeddings_df = pd.DataFrame(data=pooled_embeddings, columns=column_names)\n", |
|
|
196 |
"data = pd.concat([df, pooled_embeddings_df], axis=1)" |
|
|
197 |
] |
|
|
198 |
}, |
|
|
199 |
{ |
|
|
200 |
"cell_type": "code", |
|
|
201 |
"execution_count": 7, |
|
|
202 |
"id": "d9efd79f-ddbc-4941-86c1-c782203fa850", |
|
|
203 |
"metadata": {}, |
|
|
204 |
"outputs": [ |
|
|
205 |
{ |
|
|
206 |
"name": "stdout", |
|
|
207 |
"output_type": "stream", |
|
|
208 |
"text": [ |
|
|
209 |
"There are 448 molecules in Train df.\n", |
|
|
210 |
"There are 56 molecules in Val df.\n", |
|
|
211 |
"There are 56 molecules in Test df.\n" |
|
|
212 |
] |
|
|
213 |
} |
|
|
214 |
], |
|
|
215 |
"source": [ |
|
|
216 |
"# Split the dataset into train, validation, and test sets\n", |
|
|
217 |
"train_df, temp_df = train_test_split(data, test_size=0.2, random_state=21)\n", |
|
|
218 |
"val_df, test_df = train_test_split(temp_df, test_size=0.5, random_state=21)\n", |
|
|
219 |
"print(f\"There are {len(train_df)} molecules in Train df.\")\n", |
|
|
220 |
"print(f\"There are {len(val_df)} molecules in Val df.\")\n", |
|
|
221 |
"print(f\"There are {len(test_df)} molecules in Test df.\")" |
|
|
222 |
] |
|
|
223 |
}, |
|
|
224 |
{ |
|
|
225 |
"cell_type": "code", |
|
|
226 |
"execution_count": 8, |
|
|
227 |
"id": "8681a83d-124f-48a2-a904-403bb18785e7", |
|
|
228 |
"metadata": {}, |
|
|
229 |
"outputs": [ |
|
|
230 |
{ |
|
|
231 |
"data": { |
|
|
232 |
"text/html": [ |
|
|
233 |
"<style>#sk-container-id-1 {color: black;}#sk-container-id-1 pre{padding: 0;}#sk-container-id-1 div.sk-toggleable {background-color: white;}#sk-container-id-1 label.sk-toggleable__label {cursor: pointer;display: block;width: 100%;margin-bottom: 0;padding: 0.3em;box-sizing: border-box;text-align: center;}#sk-container-id-1 label.sk-toggleable__label-arrow:before {content: \"▸\";float: left;margin-right: 0.25em;color: #696969;}#sk-container-id-1 label.sk-toggleable__label-arrow:hover:before {color: black;}#sk-container-id-1 div.sk-estimator:hover label.sk-toggleable__label-arrow:before {color: black;}#sk-container-id-1 div.sk-toggleable__content {max-height: 0;max-width: 0;overflow: hidden;text-align: left;background-color: #f0f8ff;}#sk-container-id-1 div.sk-toggleable__content pre {margin: 0.2em;color: black;border-radius: 0.25em;background-color: #f0f8ff;}#sk-container-id-1 input.sk-toggleable__control:checked~div.sk-toggleable__content {max-height: 200px;max-width: 100%;overflow: auto;}#sk-container-id-1 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {content: \"▾\";}#sk-container-id-1 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-1 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-1 input.sk-hidden--visually {border: 0;clip: rect(1px 1px 1px 1px);clip: rect(1px, 1px, 1px, 1px);height: 1px;margin: -1px;overflow: hidden;padding: 0;position: absolute;width: 1px;}#sk-container-id-1 div.sk-estimator {font-family: monospace;background-color: #f0f8ff;border: 1px dotted black;border-radius: 0.25em;box-sizing: border-box;margin-bottom: 0.5em;}#sk-container-id-1 div.sk-estimator:hover {background-color: #d4ebff;}#sk-container-id-1 div.sk-parallel-item::after {content: \"\";width: 100%;border-bottom: 1px solid gray;flex-grow: 1;}#sk-container-id-1 div.sk-label:hover label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-1 div.sk-serial::before {content: \"\";position: absolute;border-left: 1px solid gray;box-sizing: border-box;top: 0;bottom: 0;left: 50%;z-index: 0;}#sk-container-id-1 div.sk-serial {display: flex;flex-direction: column;align-items: center;background-color: white;padding-right: 0.2em;padding-left: 0.2em;position: relative;}#sk-container-id-1 div.sk-item {position: relative;z-index: 1;}#sk-container-id-1 div.sk-parallel {display: flex;align-items: stretch;justify-content: center;background-color: white;position: relative;}#sk-container-id-1 div.sk-item::before, #sk-container-id-1 div.sk-parallel-item::before {content: \"\";position: absolute;border-left: 1px solid gray;box-sizing: border-box;top: 0;bottom: 0;left: 50%;z-index: -1;}#sk-container-id-1 div.sk-parallel-item {display: flex;flex-direction: column;z-index: 1;position: relative;background-color: white;}#sk-container-id-1 div.sk-parallel-item:first-child::after {align-self: flex-end;width: 50%;}#sk-container-id-1 div.sk-parallel-item:last-child::after {align-self: flex-start;width: 50%;}#sk-container-id-1 div.sk-parallel-item:only-child::after {width: 0;}#sk-container-id-1 div.sk-dashed-wrapped {border: 1px dashed gray;margin: 0 0.4em 0.5em 0.4em;box-sizing: border-box;padding-bottom: 0.4em;background-color: white;}#sk-container-id-1 div.sk-label label {font-family: monospace;font-weight: bold;display: inline-block;line-height: 1.2em;}#sk-container-id-1 div.sk-label-container {text-align: center;}#sk-container-id-1 div.sk-container {/* jupyter's `normalize.less` sets `[hidden] { display: none; }` but bootstrap.min.css set `[hidden] { display: none !important; }` so we also need the `!important` here to be able to override the default hidden behavior on the sphinx rendered scikit-learn.org. See: https://github.com/scikit-learn/scikit-learn/issues/21755 */display: inline-block !important;position: relative;}#sk-container-id-1 div.sk-text-repr-fallback {display: none;}</style><div id=\"sk-container-id-1\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>XGBRegressor(base_score=None, booster=None, callbacks=None,\n", |
|
|
234 |
" colsample_bylevel=None, colsample_bynode=None,\n", |
|
|
235 |
" colsample_bytree=0.9, device=None, early_stopping_rounds=None,\n", |
|
|
236 |
" enable_categorical=False, eval_metric=None, feature_types=None,\n", |
|
|
237 |
" gamma=None, grow_policy=None, importance_type=None,\n", |
|
|
238 |
" interaction_constraints=None, learning_rate=0.1, max_bin=None,\n", |
|
|
239 |
" max_cat_threshold=None, max_cat_to_onehot=None,\n", |
|
|
240 |
" max_delta_step=None, max_depth=4, max_leaves=None,\n", |
|
|
241 |
" min_child_weight=None, missing=nan, monotone_constraints=None,\n", |
|
|
242 |
" multi_strategy=None, n_estimators=200, n_jobs=None,\n", |
|
|
243 |
" num_parallel_tree=None, random_state=42, ...)</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-1\" type=\"checkbox\" checked><label for=\"sk-estimator-id-1\" class=\"sk-toggleable__label sk-toggleable__label-arrow\">XGBRegressor</label><div class=\"sk-toggleable__content\"><pre>XGBRegressor(base_score=None, booster=None, callbacks=None,\n", |
|
|
244 |
" colsample_bylevel=None, colsample_bynode=None,\n", |
|
|
245 |
" colsample_bytree=0.9, device=None, early_stopping_rounds=None,\n", |
|
|
246 |
" enable_categorical=False, eval_metric=None, feature_types=None,\n", |
|
|
247 |
" gamma=None, grow_policy=None, importance_type=None,\n", |
|
|
248 |
" interaction_constraints=None, learning_rate=0.1, max_bin=None,\n", |
|
|
249 |
" max_cat_threshold=None, max_cat_to_onehot=None,\n", |
|
|
250 |
" max_delta_step=None, max_depth=4, max_leaves=None,\n", |
|
|
251 |
" min_child_weight=None, missing=nan, monotone_constraints=None,\n", |
|
|
252 |
" multi_strategy=None, n_estimators=200, n_jobs=None,\n", |
|
|
253 |
" num_parallel_tree=None, random_state=42, ...)</pre></div></div></div></div></div>" |
|
|
254 |
], |
|
|
255 |
"text/plain": [ |
|
|
256 |
"XGBRegressor(base_score=None, booster=None, callbacks=None,\n", |
|
|
257 |
" colsample_bylevel=None, colsample_bynode=None,\n", |
|
|
258 |
" colsample_bytree=0.9, device=None, early_stopping_rounds=None,\n", |
|
|
259 |
" enable_categorical=False, eval_metric=None, feature_types=None,\n", |
|
|
260 |
" gamma=None, grow_policy=None, importance_type=None,\n", |
|
|
261 |
" interaction_constraints=None, learning_rate=0.1, max_bin=None,\n", |
|
|
262 |
" max_cat_threshold=None, max_cat_to_onehot=None,\n", |
|
|
263 |
" max_delta_step=None, max_depth=4, max_leaves=None,\n", |
|
|
264 |
" min_child_weight=None, missing=nan, monotone_constraints=None,\n", |
|
|
265 |
" multi_strategy=None, n_estimators=200, n_jobs=None,\n", |
|
|
266 |
" num_parallel_tree=None, random_state=42, ...)" |
|
|
267 |
] |
|
|
268 |
}, |
|
|
269 |
"execution_count": 8, |
|
|
270 |
"metadata": {}, |
|
|
271 |
"output_type": "execute_result" |
|
|
272 |
} |
|
|
273 |
], |
|
|
274 |
"source": [ |
|
|
275 |
"# Create an XGBoost regressor with the specified parameters; TODO: hyperparameter-tuning\n", |
|
|
276 |
"xgb_model = xgb.XGBRegressor(\n", |
|
|
277 |
" objective='reg:squarederror',\n", |
|
|
278 |
" colsample_bytree=0.9,\n", |
|
|
279 |
" learning_rate=0.1,\n", |
|
|
280 |
" max_depth=4,\n", |
|
|
281 |
" n_estimators=200,\n", |
|
|
282 |
" subsample=0.8,\n", |
|
|
283 |
" random_state=42 \n", |
|
|
284 |
")\n", |
|
|
285 |
"\n", |
|
|
286 |
"# Fit the model to the data\n", |
|
|
287 |
"xgb_model.fit(train_df[column_names], train_df[\"pIC50\"])" |
|
|
288 |
] |
|
|
289 |
}, |
|
|
290 |
{ |
|
|
291 |
"cell_type": "code", |
|
|
292 |
"execution_count": 9, |
|
|
293 |
"id": "4086aff3-6eea-4c1e-8698-5cf7383f24bf", |
|
|
294 |
"metadata": {}, |
|
|
295 |
"outputs": [ |
|
|
296 |
{ |
|
|
297 |
"name": "stdout", |
|
|
298 |
"output_type": "stream", |
|
|
299 |
"text": [ |
|
|
300 |
"Train Mean Squared Error: 0.0011\n", |
|
|
301 |
"Train Spearman Correlation: 0.9995\n", |
|
|
302 |
"Val Mean Squared Error: 0.5986\n", |
|
|
303 |
"Val Spearman Correlation: 0.7224\n", |
|
|
304 |
"Test Mean Squared Error: 0.6954\n", |
|
|
305 |
"Test Spearman Correlation: 0.6968\n" |
|
|
306 |
] |
|
|
307 |
} |
|
|
308 |
], |
|
|
309 |
"source": [ |
|
|
310 |
"# Calculate and print Mean Squared Error (MSE) and Spearman Correlation\n", |
|
|
311 |
"def get_metrics(X_, y_, model, option='Train'):\n", |
|
|
312 |
" # Get training predictions\n", |
|
|
313 |
" y_pred = xgb_model.predict(X_)\n", |
|
|
314 |
" \n", |
|
|
315 |
" # Calculate Mean Squared Error\n", |
|
|
316 |
" mse = np.round(mean_squared_error(y_, y_pred), 4)\n", |
|
|
317 |
" print(f\"{option} Mean Squared Error:\", mse)\n", |
|
|
318 |
"\n", |
|
|
319 |
" # Calculate Spearman Correlation\n", |
|
|
320 |
" spearman_corr, _ = np.round(spearmanr(y_, y_pred), 4)\n", |
|
|
321 |
" print(f\"{option} Spearman Correlation:\", spearman_corr)\n", |
|
|
322 |
"\n", |
|
|
323 |
"# Get metrics for train, validation, and test sets\n", |
|
|
324 |
"get_metrics(train_df[column_names], train_df[\"pIC50\"], xgb_model, option='Train')\n", |
|
|
325 |
"get_metrics(val_df[column_names], val_df[\"pIC50\"], xgb_model, option='Val')\n", |
|
|
326 |
"get_metrics(test_df[column_names], test_df[\"pIC50\"], xgb_model, option='Test')" |
|
|
327 |
] |
|
|
328 |
}, |
|
|
329 |
{ |
|
|
330 |
"cell_type": "code", |
|
|
331 |
"execution_count": 10, |
|
|
332 |
"id": "8332903c-8d23-4517-9177-940025fd7ae3", |
|
|
333 |
"metadata": {}, |
|
|
334 |
"outputs": [], |
|
|
335 |
"source": [ |
|
|
336 |
"# Calculate the predictions for the test set\n", |
|
|
337 |
"pred = xgb_model.predict(test_df[column_names])\n", |
|
|
338 |
"actual = test_df['pIC50']" |
|
|
339 |
] |
|
|
340 |
}, |
|
|
341 |
{ |
|
|
342 |
"cell_type": "code", |
|
|
343 |
"execution_count": 11, |
|
|
344 |
"id": "117d1b8e-bd88-49ea-8545-7f6e0ff2e997", |
|
|
345 |
"metadata": {}, |
|
|
346 |
"outputs": [ |
|
|
347 |
{ |
|
|
348 |
"data": { |
|
|
349 |
"image/png": "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", |
|
|
350 |
"text/plain": [ |
|
|
351 |
"<Figure size 640x480 with 1 Axes>" |
|
|
352 |
] |
|
|
353 |
}, |
|
|
354 |
"metadata": {}, |
|
|
355 |
"output_type": "display_data" |
|
|
356 |
} |
|
|
357 |
], |
|
|
358 |
"source": [ |
|
|
359 |
"# Scatterplot of predicted vs. actual values \n", |
|
|
360 |
"plt.scatter(pred, actual)\n", |
|
|
361 |
"plt.plot([min(actual), max(actual)], [min(actual), max(actual)], 'k--')\n", |
|
|
362 |
"plt.xlabel('Predicted')\n", |
|
|
363 |
"plt.ylabel('Actual')\n", |
|
|
364 |
"plt.grid();" |
|
|
365 |
] |
|
|
366 |
} |
|
|
367 |
], |
|
|
368 |
"metadata": { |
|
|
369 |
"kernelspec": { |
|
|
370 |
"display_name": "Python 3 (ipykernel)", |
|
|
371 |
"language": "python", |
|
|
372 |
"name": "python3" |
|
|
373 |
}, |
|
|
374 |
"language_info": { |
|
|
375 |
"codemirror_mode": { |
|
|
376 |
"name": "ipython", |
|
|
377 |
"version": 3 |
|
|
378 |
}, |
|
|
379 |
"file_extension": ".py", |
|
|
380 |
"mimetype": "text/x-python", |
|
|
381 |
"name": "python", |
|
|
382 |
"nbconvert_exporter": "python", |
|
|
383 |
"pygments_lexer": "ipython3", |
|
|
384 |
"version": "3.9.18" |
|
|
385 |
} |
|
|
386 |
}, |
|
|
387 |
"nbformat": 4, |
|
|
388 |
"nbformat_minor": 5 |
|
|
389 |
} |