# 42nd Solution, explanations and apologies

Fisrt of all, I'd like to apologize for what happened last week, the leaked -2.163 submission ... also thank my mates and
[@inversion](/inversion)
for understanding the situation and reacting quickly.
It's surreal, I know, days later I read the posts and many people didn't understand why it had happened or what reasons I would have to do it. It's very surrealistic, I am sure the first kaggler that filters a top50 solution while in the bathroom pooping (not a joke). Now when I remember it I laugh, but at that moment I felt really really bad. I submit, go to the bathroom, come back and see my teammates are calling me desperate...
I write this post in order to prove our solution is legit, explain it and show our code.
I didn't hide my mistake and communicated it as quickly as I could to the community and administrators, and I pointed out who had used it and forked it.
I don't know what happened that night, I think I edited a kernel that was already public, or because I am used to sharing kernels I didn't read the message when I invited my mates and clicked to accept... I don't know.
A lot of people shared different opinions, and I tought about it... I remember the post
[Disallow Deleting Topics](https://www.kaggle.com/product-feedback/83351)
by
[@brandenkmurray](/brandenkmurray)
, there are a lot of deleted posts in these forums and using posts you can share almost the same information as kernels (code, pictures, descriptions etc) ... (it's just a opinion, I think it's also a big problem and I thought about it after reading all the messages).
I resent the fact that many people think I leaked it on purpose or that it's a case of private sharing, because I hate private sharing and believe in fair competitions, but at the same time I understand those persons because this is surreal.
I just wanted to apologize with the community, hosts and my mates... and share my point of view.
I hope you have obtained great results, or at least according to the time you have dedicated to the competition, and I also hope that you have not been affected by the leak.
best,
Marcos.
Base
The -2.163 submission was a simple median of 4 files, the names of the files were self-descriptive, like
lgbm1945.csv
, the models were :
|  model  | LB  | 
|---|---|
|lgbm   |  -1.945 |   |
| mpnn  |  -1.884  |   |
| semGCN  | -1.830  |   |
why didn't we open sourced the solution?
Team decision, I would like but we had 3 big problems:
1. We couldn't reproduce results
![](assets/813227b608143691b5e7ad7f.png)
The people who forked the kernel can check that we used those subs for stacking, but we did those subs 1 month ago... (I wasn't even member of the team) we couldn't reproduce those results, semgcn is a python script (no checkpoints, no github, just a local run).
2. I read about that idea on Friday (next day afternoon) and I was very busy, I couldn't prepare all the code + continue competition... and then all the problems with kaggle kernels +  we couldn't reproduce results.
3. If we open sourced the solution, people would use the submission without running the code and using the excuse: nono, we generated this file using the open source solution (at least that what we tought)
Features
![](assets/ad8cb8edd83454162146aebf.png)
I read the posts and papers, watched some youtube videos and my knowledge in biochemistry and bioinformatics.
- Distances and Angles (bond angles and dihedral angles). The distance between C-C bond is very important.
- Bond type
- Number of atoms, number of neighbors of each ...
- Hybridization (aromatization, atom__type, electronegativity, valences) in the theory are equivalent.
> C3 = carbon sp3 = more electronegative than carbon2
Important
[Is 1JHC really one class](https://www.kaggle.com/c/champs-scalar-coupling/discussion/104241#latest-606224)
> Giba: The two groups are easily splited setting a threshold in 1J coupling distance to 1.065.
The reason is this:
![](assets/d8117ea8a26db04569460b07.png)
So we started to count those substituents using this
[rdkit.Chem.Fragments](http://rdkit.org/docs_temp/source/rdkit.Chem.Fragments.html)
(Number of aromatic nitrogens, Number of carboxylic acids etc)
Things that didn't work
SchNet
I improved this amazing baseline and we could get -1.61 with only 25 epochs, but we faced 2 problems:
Time, needs loong epochs, and we only had 1 kaggle gpu (MPNN was running on GCP already)
Initialization, random_state, nobbie error... the results vary greatly depending on the initial configuration and we forgot to set random seed.
Karplus Ecuation
Bothner-By equation
JHH = 7 -cos Θ + 5 cos 2Θ
where Θ is the torsion angle ... the problem wasn't obtain those angles, the problem was that I checked openbabel and RDKit and were not well calculated! For example we have CH4 (1st molecule)
Even the bond angles, I tried with water H20 and insted of 104.5 I obtained random results like: 122, 97...
I read about it
[here](https://www.rdkit.org/docs/GettingStartedInPython.html)
and in the case of RDKit, it uses an algorithm based on distance geometry for conorming molecules from 3D (xyz), probably that's the reason :(
> Note that the conformations that result from this procedure tend to be fairly ugly. They should be cleaned up using a force field. This can be done within the RDKit using its implementation of the Universal Force Field (UFF).
Final submission and postprocessing
|  model  | LB  | 
|---|---|
|lgbm   |  -2.103 |   |
| mpnn  |  -2.24  |   |
| NN  | -2.11  |   |
btw, we just realized about this (private scores):
|  single model  | LB private | 
|---|---|
|lgbm   |  -2.252 |   |
| NN  | -2.134  |   |
Median stacking +
Lasso
regression in order to smooth/round the predictions
![](assets/f3961abafcc4b0d75bd31cbe.png)
Models and Code
We used the thread
[Which graph CNN is the best (with starter kit at LB -1.469)?](https://www.kaggle.com/c/champs-scalar-coupling/discussion/93972#latest-602628)
as baseline for the GNN, all credits to
[@hengck23](/hengck23)
(
note:
we did several changes).
NN based on
[Keras Neural Net and Distance Features](https://www.kaggle.com/xwxw2929/keras-neural-net-and-distance-features)
by
[@xwxw2929](/xwxw2929)
LGBM based on
[Distance - is all you need. LB -1.481](https://www.kaggle.com/criskiev/distance-is-all-you-need-lb-1-481)
by
[@criskiev](/criskiev)
other important kernels:
-
[SchNet Starter Kit](https://www.kaggle.com/toshik/schnet-starter-kit)
by
[@toshik](/toshik)
-
[Using RDKit for Atomic Feature and Visualization](https://www.kaggle.com/sunhwan/using-rdkit-for-atomic-feature-and-visualization)
by
[@sunhwan](/sunhwan)
-
[Molecule with OpenBabel](https://www.kaggle.com/jmtest/molecule-with-openbabel)
by
[@jmtest](/jmtest)
Code and datasets
[github](https://github.com/mv-lab/CHAMPS-Kaggle19)
Our single model LGBM has private score -2.242
[Single LGBM -2.242 = Top54](https://www.kaggle.com/jesucristo/single-lgbm-2-242-top54)
[dataset with features](https://www.kaggle.com/jesucristo/mol-features)
[dataset with submissions](https://www.kaggle.com/jesucristo/molsubs)