|
68 | 68 | "source": [ |
69 | 69 | "### Descriptors\n", |
70 | 70 | "\n", |
71 | | - "**Descriptors** are sets of physicochemical properties of molecule, e.g. number of heavy atoms (non-hydrogens), number of rings, estimated solubility, distributions of inter-atomic distances, and more. Those are typically floating point numbers or counts of simple topology features (graph structure). They are often very interpretable, as each feature has a certain chemical meaning. Those are e.g. [Mordred](https://scikit-fingerprints.github.io/scikit-fingerprints/modules/generated/skfp.fingerprints.MordredFingerprint.html) and [VSA](https://scikit-fingerprints.github.io/scikit-fingerprints/modules/generated/skfp.fingerprints.VSAFingerprint.html).\n", |
| 71 | + "**Descriptors** are sets of physicochemical properties of molecule, e.g. number of heavy atoms (non-hydrogens), number of rings, estimated solubility, distributions of inter-atomic distances, and more. Those are typically floating point numbers or counts of simple topology features (graph structure). They are often very interpretable, as each feature has a certain chemical meaning. Those are e.g. [Mordred](https://scikit-fingerprints.readthedocs.io/latest/modules/generated/skfp.fingerprints.MordredFingerprint.html) and [VSA](https://scikit-fingerprints.readthedocs.io/latest/modules/generated/skfp.fingerprints.VSAFingerprint.html).\n", |
72 | 72 | "\n", |
73 | 73 | "**Pros:**\n", |
74 | 74 | "- well-correlated with many global properties of molecule\n", |
|
81 | 81 | "- typically don't benefit from sparse arrays\n", |
82 | 82 | "- some are very slow to compute\n", |
83 | 83 | "\n", |
84 | | - "Let's compute two descriptor fingerprints: [Mordred](https://scikit-fingerprints.github.io/scikit-fingerprints/modules/generated/skfp.fingerprints.MordredFingerprint.html) and [RDKit2DDescriptorsFingerprint](https://scikit-fingerprints.github.io/scikit-fingerprints/modules/generated/skfp.fingerprints.RDKit2DDescriptorsFingerprint.html). Mordred is a set of descriptors proposed in the [Mordred software publication](https://doi.org/10.1186/s13321-018-0258-y), and the RDKit2DDescriptorsFingerprint is simply the collection of all topological descriptors available in RDKit.\n", |
| 84 | + "Let's compute two descriptor fingerprints: [Mordred](https://scikit-fingerprints.readthedocs.io/latest/modules/generated/skfp.fingerprints.MordredFingerprint.html) and [RDKit2DDescriptorsFingerprint](https://scikit-fingerprints.readthedocs.io/latest/modules/generated/skfp.fingerprints.RDKit2DDescriptorsFingerprint.html). Mordred is a set of descriptors proposed in the [Mordred software publication](https://doi.org/10.1186/s13321-018-0258-y), and the RDKit2DDescriptorsFingerprint is simply the collection of all topological descriptors available in RDKit.\n", |
85 | 85 | "\n", |
86 | 86 | "We will set a few options: `n_jobs=-1, batch_size=1, verbose=1`. Fingerprints can be computed for all molecules independently, so parallelism with multiple cores is very efficient. Setting `n_jobs=-1` by default uses all available N cores, dividing the dataset into N equal-sized batches. `batch_size` gives us more fine-grained control, and combined with `verbose=True`, it will show a nice progress bar, allowing us to check the progress molecule by molecule.\n", |
87 | 87 | "\n", |
|
569 | 569 | "source": [ |
570 | 570 | "### Substructure fingerprints\n", |
571 | 571 | "\n", |
572 | | - "**Substructure fingerprints** check for existence of selected substructures (subgraphs, patterns) in a molecule, such as functional groups, rings of given size, or counts of atoms of particular element. They are often hand-crafted and selected by domain experts, reflecting which parts of molecule is typically interesting to e.g. medicinal chemists. Substructures are typically described using [SMARTS patterns](https://www.daylight.com/dayhtml/doc/theory/theory.smarts.html), which can be though of as a kind of \"regular expressions\" for molecule structures. Examples include [MACCS fingerprint](https://scikit-fingerprints.github.io/scikit-fingerprints/modules/generated/skfp.fingerprints.MACCSFingerprint.html) and [PubChem fingerprint](https://scikit-fingerprints.github.io/scikit-fingerprints/modules/generated/skfp.fingerprints.PubChemFingerprint.html).\n", |
| 572 | + "**Substructure fingerprints** check for existence of selected substructures (subgraphs, patterns) in a molecule, such as functional groups, rings of given size, or counts of atoms of particular element. They are often hand-crafted and selected by domain experts, reflecting which parts of molecule is typically interesting to e.g. medicinal chemists. Substructures are typically described using [SMARTS patterns](https://www.daylight.com/dayhtml/doc/theory/theory.smarts.html), which can be though of as a kind of \"regular expressions\" for molecule structures. Examples include [MACCS fingerprint](https://scikit-fingerprints.readthedocs.io/latest/modules/generated/skfp.fingerprints.MACCSFingerprint.html) and [PubChem fingerprint](https://scikit-fingerprints.readthedocs.io/latest/modules/generated/skfp.fingerprints.PubChemFingerprint.html).\n", |
573 | 573 | "\n", |
574 | 574 | "Like descriptors, they have a constant length, but they result in integer-valued vectors. We can distinguish **binary** and **count** variants of those fingerprints. Binary ones only check for existence of a given pattern, and often are created as if/else conditions, e.g. \"number of oxygens >= 4\" or \"is there a ring of size 6?\". Count variants instead use the number of occurrences of a substructure, e.g. \"number of oxygens\" or \"number of rings of size 6\". Due to this difference, the count version may have less features. Most of those are scikit-fingerprints novel propositions.\n", |
575 | 575 | "\n", |
|
582 | 582 | "- don't generalize well outside the chemical space they've been designed for\n", |
583 | 583 | "- longer ones are quite slow\n", |
584 | 584 | "\n", |
585 | | - "We'll compute [MACCS fingerprint](https://scikit-fingerprints.github.io/scikit-fingerprints/modules/generated/skfp.fingerprints.MACCSFingerprint.html) and [PubChem fingerprint](https://scikit-fingerprints.github.io/scikit-fingerprints/modules/generated/skfp.fingerprints.PubChemFingerprint.html), in both binary and count versions. SMARTS pattern matching can be quite slow, so those fingerprints often benefit from parallelism, similarly to descriptors." |
| 585 | + "We'll compute [MACCS fingerprint](https://scikit-fingerprints.readthedocs.io/latest/modules/generated/skfp.fingerprints.MACCSFingerprint.html) and [PubChem fingerprint](https://scikit-fingerprints.readthedocs.io/latest/modules/generated/skfp.fingerprints.PubChemFingerprint.html), in both binary and count versions. SMARTS pattern matching can be quite slow, so those fingerprints often benefit from parallelism, similarly to descriptors." |
586 | 586 | ] |
587 | 587 | }, |
588 | 588 | { |
|
678 | 678 | "source": [ |
679 | 679 | "### Hashed fingerprints\n", |
680 | 680 | "\n", |
681 | | - "**Hashed fingerprints** extract all subgraphs of general shape, such as shortest paths between pairs of atoms (linear subgraphs) or neighborhoods of bonded atoms (circular fingerprints). From each substructure, an integer identifier is then computed. Then we use the hashing function (hence the name), which translates the identifier into an index in the final vector, where we put information that subgraph was detected. Those are e.g. [ECFP fingerprint](https://scikit-fingerprints.github.io/scikit-fingerprints/modules/generated/skfp.fingerprints.ECFPFingerprint.html) and [Atom Pair fingerprint](https://scikit-fingerprints.github.io/scikit-fingerprints/modules/generated/skfp.fingerprints.AtomPairFingerprint.html).\n", |
| 681 | + "**Hashed fingerprints** extract all subgraphs of general shape, such as shortest paths between pairs of atoms (linear subgraphs) or neighborhoods of bonded atoms (circular fingerprints). From each substructure, an integer identifier is then computed. Then we use the hashing function (hence the name), which translates the identifier into an index in the final vector, where we put information that subgraph was detected. Those are e.g. [ECFP fingerprint](https://scikit-fingerprints.readthedocs.io/latest/modules/generated/skfp.fingerprints.ECFPFingerprint.html) and [Atom Pair fingerprint](https://scikit-fingerprints.readthedocs.io/latest/modules/generated/skfp.fingerprints.AtomPairFingerprint.html).\n", |
682 | 682 | "\n", |
683 | 683 | "Initially, each atom gets assigned a numerical identifier, called atom invariant. It combines a few basic properties like e.g. atomic number, charge, and atomic mass, into a single integer value (typically with XOR function). This allows us to distinguish e.g. carbon in different contexts.\n", |
684 | 684 | "\n", |
685 | | - "Then, subgraphs are computed, with their shape depending on a fingerprint. For example, [ECFP](https://scikit-fingerprints.github.io/scikit-fingerprints/modules/generated/skfp.fingerprints.ECFPFingerprint.html) uses circular neighborhood, e.g. atom with neighbors (bonded atoms), then with their neighbors (radius 2 neighborhood), up to a given radius (by default 2). The identifiers of atoms and bonds in the subgraph are combined into a single identifier of a whole substructure.\n", |
| 685 | + "Then, subgraphs are computed, with their shape depending on a fingerprint. For example, [ECFP](https://scikit-fingerprints.readthedocs.io/latest/modules/generated/skfp.fingerprints.ECFPFingerprint.html) uses circular neighborhood, e.g. atom with neighbors (bonded atoms), then with their neighbors (radius 2 neighborhood), up to a given radius (by default 2). The identifiers of atoms and bonds in the subgraph are combined into a single identifier of a whole substructure.\n", |
686 | 686 | "\n", |
687 | 687 | "Output vector starts with only zeros. It has a given length (also called \"number of bits\"), which is a common hyperparameter of all hashed fingerprints. Subgraph identifiers are hashed into it, translating subgraph identifier into index of a vector, e.g. with a [modulo function](https://en.wikipedia.org/wiki/Modulo). Hashing collisions may occur, when two distinct substructures get the same index, but this is typically not a big problem. Binary variant ignores such collisions (just marks 1 at a given position), and count version sums up all occurrences at each index.\n", |
688 | 688 | "\n", |
|
695 | 695 | "**Cons:**\n", |
696 | 696 | "- not interpretable\n", |
697 | 697 | "\n", |
698 | | - "Let's check out [ECFP fingerprint](https://scikit-fingerprints.github.io/scikit-fingerprints/modules/generated/skfp.fingerprints.ECFPFingerprint.html) and [Atom Pair fingerprint](https://scikit-fingerprints.github.io/scikit-fingerprints/modules/generated/skfp.fingerprints.AtomPairFingerprint.html). We will create default versions with length 2048, and short ones with 1024. Those fingerprints are often so fast to compute they don't benefit from parallelism at all." |
| 698 | + "Let's check out [ECFP fingerprint](https://scikit-fingerprints.readthedocs.io/latest/modules/generated/skfp.fingerprints.ECFPFingerprint.html) and [Atom Pair fingerprint](https://scikit-fingerprints.readthedocs.io/latest/modules/generated/skfp.fingerprints.AtomPairFingerprint.html). We will create default versions with length 2048, and short ones with 1024. Those fingerprints are often so fast to compute they don't benefit from parallelism at all." |
699 | 699 | ] |
700 | 700 | }, |
701 | 701 | { |
|
919 | 919 | "cell_type": "markdown", |
920 | 920 | "id": "a2fd6d70-1479-46e0-81bd-5b6f146f7db2", |
921 | 921 | "metadata": {}, |
922 | | - "source": [ |
923 | | - "For evaluating the efficiency of downstream ML models, we'll train a Random Forest classifier and check its AUROC. Both this model type and metric are commonly used in chemoinformatics. For train-test splitting, we use [scaffold split](https://scikit-fingerprints.github.io/scikit-fingerprints/modules/generated/skfp.model_selection.scaffold_train_test_split.html), which typically gives better estimation than overly optimistic random split." |
924 | | - ] |
| 922 | + "source": "For evaluating the efficiency of downstream ML models, we'll train a Random Forest classifier and check its AUROC. Both this model type and metric are commonly used in chemoinformatics. For train-test splitting, we use [scaffold split](https://scikit-fingerprints.readthedocs.io/latest/modules/generated/skfp.model_selection.scaffold_train_test_split.html), which typically gives better estimation than overly optimistic random split." |
925 | 923 | }, |
926 | 924 | { |
927 | 925 | "cell_type": "code", |
|
0 commit comments