# Getting interpretable chemical information from hashed molecular fingerprints

I have been using molecular fingerprints like ECFP (extended connectivity fingerprint), APFP (atom-pair fingerprint) etc. in my research to predict spectral properties of organic molecules with machine learning (basically a QSAR project). Now, I have got very good results from the machine learning models, but I want to understand what exactly the model is learning i.e. some kind of interpretable chemical information which can be understood by an organic chemist for example.

However, I am not sure how to do that, because from the trained model, all I can possibly get are importances or effects of each position of the fingerprint. But then I am lost because fingerprints like ECFP are hashed fingerprints, so I do not know what the number in each position actually means. Is there any way to link hashed fingerprints to some chemical structure or feature that is easy to understand?

I only found this one paper that attempts to reverse-engineer ECFP with neural networks, but I am looking for something simpler.

Using RDKit, it's fairly easy to depict bits on example molecules - it's even an example in the documentation "Generating Images of Fingerprint Bits")

from rdkit.Chem import Draw
mol = Chem.MolFromSmiles('c1ccccc1CC1CC1')
bi = {}
bi[872]
((6, 2),)
mfp2_svg = Draw.DrawMorganBit(mol, 872, bi, useSVG=True)


To quote the documentation:

The default highlight colors for the Morgan bits indicate:

• blue: the central atom in the environment
• yellow: aromatic atoms
• gray: aliphatic ring atoms

As an example from the documentation:

• No no, I wrote in the question that I was using the hashed fingerprints (GetHashedMorganFingerprint). You are using the unhashed fingerprint here, but I can't use that for machine learning as it has so many bits scikit learn can't handle that much data on my machine. Apr 13 at 22:30
• Okay, but you could keep the original bitvector and map the bits into the hash. So you'd know at least something. You're describing a scenario in which multiple bits go into one hash - if you don't track the mapping, there's no function which reverses the hash for you. Apr 13 at 23:44
• I forgot to come back to the question, but your answer actually solved my problem, so thanks! Jul 8 at 21:06

I don't know of any simpler methods. Heuristic methods such as Neural Networks are likely your better option if you wish to actually reconstruct the original molecule.

Keep in mind that an active bit in one position doesn't necessarily encode only one information. If you want that to happen in order to have a more easily interpretable model you should use something like structural key fingerprints or molecular descriptors. In hashed fingerprints you might have "bit collision", this means that two different structural features might activate the same bit. Moreover, one feature might activate more than one bit.

Since you just want to understand what one single bit represents, if you only need to do this on a few bits you could do the following: Take a few molecules that have that bit enabled and manually calculate the fingerprint identifiers up to the hashing point. Take note of which substructures are associated to each identifier. Follow the hashing algorithm and understand which bits get activated by each identifier. To simplify the decoding of the hashing, you could run the hashing function on the set of identifiers, removing one identifier at a time until you find the one that activates that particular bit. Since there could be bit collision you might have to remove couples of identifiers and so on.

You need to do this with several (or all) molecules with that bit active, in order to identify all substructures that activate it.