Monthly Archives: 7月 2015

KNIME: Wekaノードを用いた機械学習


今回は、Wekaノードを用いた機械学習を行ってみます。
ここでは例として、Adaboost M1、Naive Bayes、Multilayer Perceptron、K Star、Best-first decision tree、5つの機械学習アルゴリズムを用いました。

訓練用データ、テストデータは、以下のサイトにある化合物のlogS値(Huuskonen dataset)を利用しています。
入手先:
https://github.com/rdkit/rdkit-orig/tree/master/Docs/Book/data
ファイル名: solubility.train.sdf, solubility.test.sdf

knime_weka_01b

各ノードの設定方法を説明します。
各ノードを配置、接続した後、ノードをダブルクリックするとConfigureが開き、設定を行うことができます

訓練データの入力

SDFの読み込みには、SDF Readerノードを使います。
File selectionタブでSDFファイルの場所を指定します。

knime_weka_02

クラスデータの加工

SDFのタグには、logS値が、low、medium、highの3つのカテゴリーで表現されています。Rule Engineノードを使って、lowは0、mediumは1、そしてhighは2と変更します。

knime_weka_03

ワークフロー上には2つ”クラスデータの加工”ノードがありますが、設定は同じです。

RDMol変換

SDFからRDKitのMol形式(RDMol)にRDKit From Moleculeノードを用いて変換します。

knime_weka_04

ワークフロー上には2つ”RDMol変換”ノードがありますが、設定は同じです。

記述子計算

RDKit Descriptor Calculationノードを使って、記述子の計算を行います。

knime_weka_05

ワークフロー上には2つ”記述子計算”ノードがありますが、設定は同じです。

正規化1

Normalizerノードを使って、記述子の正規化を行います。
ここでは、Min-Max Normalizationにより、0から1の範囲で記述子を表現するように設定します。

knime_weka_06

テストデータの入力

SDFの読み込みには、SDF Readerノードを使います。
File selectionタブでSDFファイルの場所を指定します。

knime_weka_07

正規化2

Normalizer (Apply)ノードを使って、テストデータの正規化を行います。
特に設定はしません。

列の抽出

Column Filterを用いて、学習に必要な列だけ抽出します。

knime_weka_08

学習

本ワークフローでは、Wekaに実装されている機械学習アルゴリズムのうち、Adaboost M1、Naive Bayes、Multilayer Perceptron、K Star、Best-first decision treeの5つのノードを使って、機械学習を行います。
例として、AdaBoostM1 (3.7)の設定方法を示したいと思います。
classifierとしてBFTreeを、numIterationsを20とし、そしてSelct target columnは、SOL_classificationを選択します。

knime_weka_09a

その他4つの機械学習ノードの設定は、デフォルト値を利用していますが、Select target columnは、SOL_classificationを選択します。

予測

訓練データにより学習したモデルを使って、テストデータの評価を行います。
Weka Predictorノードにより実施することができます。

knime_weka_10

ワークフロー上には5つ”予測”ノードがありますが、設定は同じです。

スコア

Scorerノードを使って、予測結果の評価を行います。

knime_weka_11

ワークフロー上には5つ”スコア”ノードがありますが、設定は同じです。

以上で設定は終わりです。
ワークフローを実行し、ScorerノードのView: Confusion Matrixを選択すると結果を見ることができます。

AdaBoostM1による予測結果

knime_weka_12

NaiveBayesによる予測結果

knime_weka_13

MultilayerPerceptronによる予測結果

knime_weka_14

KStarによる予測結果

knime_weka_15

BFTreeによる予測結果

knime_weka_16

ノードを配置するだけで、様々な機械学習アルゴリズムを利用できるところもKNIMEのいいところだと思います。


利用したソフトウェア:
KNIME 2.11.3

Chainer: クラス分類による溶解度の予測 (2)


今回は、scikit-chainerの作法に従って、先日の溶解度の予測プログラムを書き換えてみました。

クラス分類による溶解度の予測

活性化関数をReLuからsigmoidに変更しています。

chainer_02.py

from rdkit import Chem
from rdkit.Chem import AllChem
from rdkit.Chem import Descriptors
from rdkit import DataStructs
from rdkit.ML.Descriptors import MoleculeDescriptors
from rdkit import rdBase
print 'RDKit version ',rdBase.rdkitVersion

from chainer import FunctionSet, Variable, optimizers
from chainer import functions as F
from chainer import cuda
from chainer import __version__ as chainer_version
print 'Chainer version ',chainer_version

from sklearn import datasets
from sklearn import base
from sklearn.preprocessing import MinMaxScaler
from sklearn import metrics
from sklearn import __version__ as sklean_version
print 'sklearn version',sklean_version

from abc import ABCMeta, abstractmethod
import numpy as np
import sys
import six

class BaseChainerEstimator(base.BaseEstimator):
    __metaclass__= ABCMeta  # python 2.x
    def __init__(self, optimizer=optimizers.SGD(), n_iter=10000, eps=1e-5, report=100,
                 **params):
        self.network = self._setup_network(**params)
        self.optimizer = optimizer
        self.optimizer.setup(self.network.collect_parameters())
        self.n_iter = n_iter
        self.eps = eps
        self.report = report

    @abstractmethod
    def _setup_network(self, **params):
        return FunctionSet(l1=F.Linear(1, 1))

    @abstractmethod
    def forward(self, x, train=True):
        y = self.network.l1(x)
        return y

    @abstractmethod
    def loss_func(self, y, t):
        return F.mean_squared_error(y, t)

    @abstractmethod
    def output_func(self, h):
        return F.identity(h)

    def fit(self, x_data, y_data):
        batchsize = 100
        N = len(y_data)
        for loop in range(self.n_iter):
            perm = np.random.permutation(N)
            sum_accuracy = 0
            sum_loss = 0
            for i in six.moves.range(0, N, batchsize):
                x_batch = x_data[perm[i:i + batchsize]]
                y_batch = y_data[perm[i:i + batchsize]]
                x = Variable(x_batch)
                y = Variable(y_batch)
                self.optimizer.zero_grads()
                loss = self.loss_func(self.forward(x),y)
                loss.backward()
                self.optimizer.update()
                sum_loss += loss.data * len(y_batch)
            if self.report > 0 and loop % self.report == 0:
                print('loop={}, train mean loss={}'.format(loop, sum_loss / N))

        return self

    def predict(self, x_data):
        x = Variable(x_data)
        y = self.forward(x,train=False)
        return self.output_func(y).data


class ChainerClassifier(BaseChainerEstimator, base.ClassifierMixin):
    def predict(self, x_data):
        return BaseChainerEstimator.predict(self, x_data).argmax(1)


class MultiLayerPerceptron(ChainerClassifier):
    def _setup_network(self, **params):
        print(params)
        network = FunctionSet(
            l1=F.Linear(params["input_dim"], params["hidden_dim"]),
            l2=F.Linear(params["hidden_dim"], params["hidden_dim"]),
            l3=F.Linear(params["hidden_dim"], params["n_classes"])
        )
        return network

    def forward(self, x, train=True):
        h1 = F.dropout(F.sigmoid(self.network.l1(x)),train=train)
        h2 = F.dropout(F.sigmoid(self.network.l2(h1)),train=train)
        y = self.network.l3(h2)
        return y

    def loss_func(self, y, t):
        return F.softmax_cross_entropy(y, t)

    def output_func(self, h):
        return F.softmax(h)


if __name__ == "__main__":
    # 記述子の準備
    act_classes={'(A) low':0,'(B) medium':1,'(C) high':2}
    descList = [x[0] for x in Descriptors._descList]
    calc = MoleculeDescriptors.MolecularDescriptorCalculator(descList)

    # 訓練データの読み込み
    # データセットは、以下のサイトにある化合物のlogS値(Huuskonen dataset)を利用しました。
    # 入手先: http://sourceforge.net/p/rdkit/code/HEAD/tree/trunk/Docs/Book/data/
    # ファイル名: solubility.train.sdf, solubility.test.sdf
    #  solubility.train.sdfに含まれるCyhexatinは、一部の記述子が計算できなかったので、除外しています。
    m_train = [m for m in Chem.SDMolSupplier('solubility.train.sdf') if m is not None]
    x_train = [calc.CalcDescriptors(m) for m in m_train]
    x_train = np.array(x_train,dtype=np.float32)
    y_train = [act_classes[m.GetProp('SOL_classification')] for m in m_train]
    y_train = np.array(y_train,dtype=np.int32)

    # テストデータの読み込み
    m_test = [m for m in Chem.SDMolSupplier('solubility.test.sdf') if m is not None]
    x_test = [calc.CalcDescriptors(m) for m in m_test]
    x_test = np.array(x_test,dtype=np.float32)
    y_test = [act_classes[m.GetProp('SOL_classification')] for m in m_test]
    y_test = np.array(y_test,dtype=np.int32)

    # 訓練データ、テストデータのスケーリング
    scaler = MinMaxScaler()
    scaler.fit(x_train)
    x_train = scaler.transform(x_train)
    x_test  = scaler.transform(x_test)

    # パラメータ設定
    n_epoch = 30                # 学習の繰り返し回数
    n_units = 1000              # 中間層のユニット数
    input_dim = len(descList)   # 入力層のユニット数(記述子の数)
    n_classes = 3               # 出力層のユニット数(クラスの数)

    # 学習
    model = MultiLayerPerceptron(optimizer=optimizers.Adam(),n_iter=n_epoch,
        input_dim=input_dim, hidden_dim=n_units, n_classes=n_classes, report=5)
    model.fit(x_train, y_train)

     # テストデータの評価 (Confusion matrixの計算)
    yh = model.predict(x_test)
    confmat = metrics.confusion_matrix(y_test,yh)
    print confmat
    print model.score(x_test,y_test)

実行結果

RDKit version  2014.09.2
Chainer version  1.1.0
sklearn version 0.15.2
{'n_classes': 3, 'hidden_dim': 1000, 'input_dim': 196}
loop=0, train mean loss=1.41157905944
loop=5, train mean loss=0.897083431482
loop=10, train mean loss=0.669134197058
loop=15, train mean loss=0.543652085355
loop=20, train mean loss=0.487358732615
loop=25, train mean loss=0.461836358882
[[90 12  0]
 [14 96  5]
 [ 0  7 33]]
0.852140077821

scikit-learnのように使えるので、便利だと思います。

KNIME: 互変異性体を考慮した部分構造検索


今回は、Indigoノードを使って、互変異性体を考慮した部分構造検索を行ってみます。

knime_tauto_01

各ノードの設定方法を説明します。
各ノードを配置、接続した後、ノードをダブルクリックするとConfigureが開き、設定を行うことができます。

分子の入力

MarvinSketchノードを使って、化学構造を描きます。

knime_tauto_02

Output optionsタグで、Structure typeをSdfCellとします。

knime_tauto_03

Indigo形式変換

Molecule to Indigoノードを使って、化学構造をIndigo形式に変換します。

knime_tauto_04

1クエリー構造の入力

MarvinSketchノードを使って、クエリーとする化学構造を描きます。

knime_tauto_05

Output optionsタグで、Structure typeをSdfCellとします。

knime_tauto_06

クエリー構造のIndigo形式変換

Query Molecule to Indigoノードを使って、クエリーの化学構造をIndigo形式に変換します。

knime_tauto_07

部分構造検索

Substructure Matcherノードを使って、互変異性体を考慮した部分構造検索を行います。
Substructure SettingsのMode:をTautomerとします。

knime_tauto_08

以上で設定は、終わりです。
ワークフローを実行し、Substructure Matcherノードで右クリックをし、Matchedを選択します。
ハイライトされた部分がクエリー構造と一致した構造となります。
互変異性体が考慮されていることが確認できます。

knime_tauto_09


利用したソフトウェア:
KNIME 2.11.3

Chainer: クラス分類による溶解度の予測


今回は、Deep Learningの新しいフレームワークであるChainerを使って、クラス分類による溶解度の予測を行いたいと思います。

Chainer 公式サイト

業務では主にPythonを使うことが多いので、Chainerは、本当に有難いフレームワークだと思っています。

インストール

インストールは本当に簡単です!

> pip install chainer

クラス分類による溶解度の予測

Chainerのサンプルプログラムにあるtrain_mnist.pyを参考にして、以下のプログラムを書いてみました。

chainer_01.py:

from rdkit import Chem
from rdkit.Chem import AllChem
from rdkit.Chem import Descriptors
from rdkit import DataStructs
from rdkit.ML.Descriptors import MoleculeDescriptors
from rdkit import rdBase
print 'RDKit version ',rdBase.rdkitVersion

import chainer
from chainer import computational_graph as c
import chainer.functions as F
from chainer import cuda
from chainer import optimizers
print 'Chainer version ',chainer.__version__

import six
import numpy as np
import sys

from sklearn.preprocessing import MinMaxScaler
from sklearn import metrics

# 記述子の準備
act_classes={'(A) low':0,'(B) medium':1,'(C) high':2}
descList = [x[0] for x in Descriptors._descList]
calc = MoleculeDescriptors.MolecularDescriptorCalculator(descList)

# 訓練データの読み込み
# 訓練データの読み込み
# データセットは、以下のサイトにある化合物のlogS値(Huuskonen dataset)を利用しました。
# 入手先:http://sourceforge.net/p/rdkit/code/HEAD/tree/trunk/Docs/Book/data/
# ファイル名: solubility.train.sdf, solubility.test.sdf
#  solubility.train.sdfに含まれるCyhexatinは、一部の記述子が計算できなかったので、除外しています。
m_train = [m for m in Chem.SDMolSupplier('solubility.train.sdf') if m is not None]
x_train = [calc.CalcDescriptors(m) for m in m_train]
x_train = np.array(x_train,dtype=np.float32)
y_train = [act_classes[m.GetProp('SOL_classification')] for m in m_train]
y_train = np.array(y_train,dtype=np.int32)

# テストデータの読み込み
m_test = [m for m in Chem.SDMolSupplier('solubility.test.sdf') if m is not None]
x_test = [calc.CalcDescriptors(m) for m in m_test]
x_test = np.array(x_test,dtype=np.float32)
y_test = [act_classes[m.GetProp('SOL_classification')] for m in m_test]
y_test = np.array(y_test,dtype=np.int32)

# 訓練データ、テストデータのスケーリング
scaler = MinMaxScaler()
scaler.fit(x_train)
x_train = scaler.transform(x_train)
x_test  = scaler.transform(x_test)

# パラメータ設定
batchsize = 100         # 確率的勾配降下法で学習させるバッチサイズ
n_epoch = 30            # 学習の繰り返し回数
n_units = 1000          # 中間層のユニット数
Ndesc = len(descList)   # 入力層のユニット数(記述子の数)
Nout = 3                # 出力層のユニット数(クラス数)
N = y_train.size        # 訓練データ数
N_test = y_test.size    # テストデータ数


# Prepare multi-layer perceptron model
# 入力:記述子の数(196) 出力:クラスの数(3)
model = chainer.FunctionSet(l1=F.Linear(Ndesc, n_units),
                            l2=F.Linear(n_units, n_units),
                            l3=F.Linear(n_units, Nout))

# Neural net architecture
def forward(x_data, y_data, train=True):
    x, t = chainer.Variable(x_data), chainer.Variable(y_data)
    h1 = F.dropout(F.relu(model.l1(x)),  train=train)
    h2 = F.dropout(F.relu(model.l2(h1)), train=train)
    y = model.l3(h2)
    return F.softmax_cross_entropy(y, t), F.accuracy(y, t)

# Setup optimizer
optimizer = optimizers.Adam()
optimizer.setup(model.collect_parameters())

# Learning loop
for epoch in six.moves.range(1, n_epoch + 1):

    perm = np.random.permutation(N)
    sum_accuracy = 0
    sum_loss = 0

    for i in six.moves.range(0, N, batchsize):
        x_batch = x_train[perm[i:i + batchsize]]
        y_batch = y_train[perm[i:i + batchsize]]
        optimizer.zero_grads()
        loss, acc = forward(x_batch, y_batch)
        loss.backward()
        optimizer.update()
        sum_loss += float(cuda.to_cpu(loss.data)) * len(y_batch)
        sum_accuracy += float(cuda.to_cpu(acc.data)) * len(y_batch)

    print('epoch={}, train mean loss={}, accuracy={}'.format(
        epoch, sum_loss / N, sum_accuracy / N))

# テストデータのクラス予測
x, t = chainer.Variable(x_test), chainer.Variable(y_test)
h1 = F.relu(model.l1(x))
h2 = F.relu(model.l2(h1))
y = model.l3(h2)
loss = F.softmax_cross_entropy(y, t)
acc = F.accuracy(y, t)
print('test  mean loss={}, accuracy={}'.format(loss.data, acc.data))

# テストデータの評価 (Confusion matrixの計算)
prob = F.softmax(y).data
pred_y = []
for p,y in zip(prob,y_test):
    pre_y= np.argmax(p)
    #print pre_y,y
    pred_y.append(pre_y)
pred_y = np.array(pred_y)
confmat = metrics.confusion_matrix(y_test,pred_y)
print confmat

実行結果

RDKit version  2014.09.2
Chainer version  1.1.0
epoch=1, train mean loss=0.894346793881, accuracy=0.566406252095
epoch=2, train mean loss=0.645627270918, accuracy=0.691406251863
epoch=3, train mean loss=0.513133924454, accuracy=0.779296863126
epoch=4, train mean loss=0.435840750113, accuracy=0.811523431214
epoch=5, train mean loss=0.393394864397, accuracy=0.818359375233
epoch=6, train mean loss=0.388552646618, accuracy=0.832031250233
epoch=7, train mean loss=0.358083432424, accuracy=0.838867195882
epoch=8, train mean loss=0.352884827647, accuracy=0.847656235332
epoch=9, train mean loss=0.383986310917, accuracy=0.833984377794
epoch=10, train mean loss=0.343003616203, accuracy=0.851562500466
epoch=11, train mean loss=0.302874319255, accuracy=0.869140624767
epoch=12, train mean loss=0.268378470792, accuracy=0.883789068786
epoch=13, train mean loss=0.273156624346, accuracy=0.885742178652
epoch=14, train mean loss=0.250554838101, accuracy=0.889648437966
epoch=15, train mean loss=0.256678346079, accuracy=0.898437502328
epoch=16, train mean loss=0.220834126638, accuracy=0.916015628027
epoch=17, train mean loss=0.255951596599, accuracy=0.88769530924
epoch=18, train mean loss=0.212121372344, accuracy=0.914062497672
epoch=19, train mean loss=0.222044002789, accuracy=0.905273431912
epoch=20, train mean loss=0.234405800642, accuracy=0.905273449374
epoch=21, train mean loss=0.234147735522, accuracy=0.902343754424
epoch=22, train mean loss=0.206508405623, accuracy=0.91796874674
epoch=23, train mean loss=0.201678971905, accuracy=0.914062494645
epoch=24, train mean loss=0.180077250669, accuracy=0.92773438571
epoch=25, train mean loss=0.168802947854, accuracy=0.935546882683
epoch=26, train mean loss=0.167988513713, accuracy=0.931640626164
epoch=27, train mean loss=0.146641206753, accuracy=0.939453131985
epoch=28, train mean loss=0.162885584054, accuracy=0.931640614523
epoch=29, train mean loss=0.150213876128, accuracy=0.943359381054
epoch=30, train mean loss=0.142516513588, accuracy=0.941406241851
test  mean loss=0.423470169306, accuracy=0.859922170639
[[90 12  0]
 [12 96  7]
 [ 0  5 35]]

過去の記事と比較しても、非常に良好な結果だと思います。

利用したソフトウェア:
Chainer 1.1.0
RDKit_2014_09_2

KNIME: ChEMBLからのデータ取得とPAINSフィルターの適用


PAINS(Pan Assay Interference Compounds)*フィルターは、複数の評価系に対して、いつもヒットするような化合物(frequent hitters)を検出するためのフィルターです。
具体的には、PAINSのもつ部分構造をまとめたもので、全部で480の部分構造からなります。
今回は、ChEMBLからCDK2阻害剤の構造と活性値を取得し、PAINSフィルターを適用させるまでの工程をKNIMEのワークフローで作成してみます。

*Journal of Medicinal Chemistry,2010,53,2719

knime_pains_01

各ノードの設定方法を説明します。
各ノードを配置、接続した後、ノードをダブルクリックするとConfigureが開き、設定を行うことができます。

ChEMBLから活性値の取得

ChEMBLdb Connectorノードを使います。
CDK2のChEMBL IDであるCHEMBL301をChEMBL ID:に入力し、Search Type:はtargetとします。
また、Bioactivities:にチェックをいれます。

knime_pains_02

活性値を数値に変換

ChEMBLから取得したデータは全てString型ですので、String To Numberノードを使って、活性値(value)のみDouble型に変換します。

knime_pains_03

活性化合物の判定

ChEMBLから取得したCDK2の活性データには、Ki値、IC50値、%阻害等が混在しています。
ここでは、かなり大雑把ですが、operatorは”=”、 unitsは”nM”、valueは10,000以下の化合物を活性化合物(Active)とするルールをRule Engineノードを使って作成します。

knime_pains_04

活性化合物の選別

Row Splitterノードを使って、活性化合物の選別を行います。
Column to test:にActivity列を指定し、Matching criteriaでuse pattern matchingを選択し、Activeと入力します。

knime_pains_05

列の選別

Column Filterノードを使って、列の選別を行います。
ここでは、parent_cmpd_chemblid、bioactivity_type、units、value、Activityをinclude枠に加えます。

knime_pains_06

重複除去

GroupByノードを使って、化合物の重複を除去します。
ここでは、parent_cmpd_chemblidで重複を取ります。

knime_pains_07

重複があった場合、はじめに登録されている化合物情報を残すようにします。

knime_pains_08

ChEMBLからSMILESの取得

ChEMBLdb Connector Inputノードを使って、parent_cmpd_chemblidに対応するSMILESをChEMBLから取得します。
Look-upタブにおいて、ChEMBL ID:にparent_cmpd_chemblidを、Search Type:にcompoundを指定します。

knime_pains_09

SMILESの付加

Joinerノードを使って、ChEMBLdb Connector Inputノードで取得したSMILESをテーブルに付加します。
Joiner Settingsタブにおいて、Left Tableはparent_compd_chemblidとし、Right TableはchemblIdを指定します。

knime_pains_10

次に、Column Selectionにおいて、Left Tableでは、全ての列をInclude枠に加え、Right Tableでは、smilesのみをInclude枠に加えます。

knime_pains_11

活性化合物の保存

Table Writerノードを使って、ここまでのTableの状態を保存します。

knime_pains_12b

型変換1

Molecule Type Castを使って文字列として認識されているsmilesをSmiles形式に変換します。

knime_pains_13

RDMolに変換

SDFからRDKitのMol形式(RDMol)にRDKit From Moleculeノードを用いて変換します。

knime_pains_14

PAINSの入力

File Readerノードを使って、PAINSフィルターを入力します。
PAINSフィルターは以下のサイトのものを利用しました。
部分構造は、SMARTSで表現されています。

入手先:http://www.macinchem.org/reviews/pains/painsFilter.php
ファイル名:Archive.zip (PAINS.sieve)

入力の都合上、PAINS.sieveの中のコメント部分は削除し、FRAGMENT行のみ取り出したファイルを入力の対象としました。

knime_pains_15

型変換2

Molecule Type Castノードを使って、文字列として入力されたsmartsをSmarts形式に変換します。

knime_pains_16

部分構造検索1

RDKit Molecule Substructure Filterノードを使って、PAINSの検出を行います。
OptionsタブのMatchではAt leastを選択し、1とします。
これにより、少なくとも1つの部分構造が一致すれば、PAINSであることになります。

knime_pains_17

PAINS無の活性化合物の保存

Table Writerノードを使って、PAINSではない活性化合物のみ保存することにします。

knime_pains_18

ループ開始、ループ終了

PAINSフィルターでヒットした化合物に対して、化合物の中のどの部分構造が、PAINSの原因として認識されたのかを視覚的に確認したいと思います。
ここでは、PAINSフィルターを構成している全ての部分構造(SMARTS)を1つ1つループ内で取り出し、PAINSと判定された化合物に対しRDKit Substructure FilterとRDKit Molecule Highlightingノードを使うことで、視覚化を行います。
Table Row To Variable Loop StartとLoop Endノードを使いますが、特別な設定はしません。

部分構造検索2

RDKit Substructure Filterノードを使って、PAINSの原因として認識された部分構造の検出を行います。
OptionsタブのMatch handling:でAdd column with atom list of first matchを指定します。
この情報を利用して、後程マッチした部分構造をハイライト表示します。

knime_pains_19

Flow Variablesとして、PAINSフィルターを構成する部分構造(SMARTS)を利用します。
Flow Variablesタブのsmarts_valueにCol2を指定します。

knime_pains_21

ChEMBLIDでソート

Sorterノードを使って、ChEMBLIDでソートします。
化合物の中には、PAINSの原因となる部分構造を2つ以上もつ化合物がありますので、ChEMBLIDでソートすると、結果が見やすくなります。

knime_pains_20

PAINSのハイライト表示

RDKit Molecule Highlightingノードを使って、PAINSの原因となる部分構造をハイライト表示します。

knime_pains_22

RDKit Molecule Highlightingノードが無い場合は、以下のサイトから入手することができます。

http://update.knime.org/community-contributions/trunk

メニューから[Help]→[Install New Software]を選択し、Work with:に上記サイトを入力します。そうしますと、nightly buildとして更新されているCheminformaticsノードの一覧が表示され、RDKitが選択できます。

以上で設定は終わりです。
ワークフローを実行すると、CDK_ACTIVE.tableとCDK_ACTIVE_PASS.tableがファイル出力されます。
また、RDKit Molecule Highlightingノードで右クリックし、Highlighted Moleculesを選択すると、PAINSの原因となった部分構造を視覚的に確認することができます。

knime_pains_23


利用したソフトウェア:
KNIME 2.11.3

KNIME: パレートランキング


今回は、化合物のMwとSlogPを計算し、Mwが大きく、SlogPが小さい化合物を取得することを考えてみます。このように、2つ以上の値を用いて、化合物のランキングを行いたい場合、Pareto Rankingノード、またはDesirability Rankingノードを使うことで、実現することができます。
ここでは、ランキングの結果をScatter Plotに反映させて、視覚的に結果を確認したいと思います。

knime_pareto_01

各ノードの設定方法を説明します。
各ノードを配置、接続した後、ノードをダブルクリックするとConfigureが開き、設定を行うことができます。

化合物の入力

SDFの読み込みには、SDF Readerノードを使います。
File selectionタブでSDFファイルの場所を指定します。
また、ここで入力するSDFにおいては、各分子の1行目に分子IDを記載していますので、Extract molecule nameにチェックを入れて、分子IDを利用することにします。
入力ファイルは、DUDのace decoysの座標を2D化したファイルを使っています。

knime_pareto_02

記述子の計算

RDKit Descriptor Calculationノードを使って、MwとSlogPを計算します。

knime_pareto_03

パレートランキング

Pareto Rankingノードを使って、パレートランキングを行います。
ここでは、SlogPのOptimizationはMinimizeとし、ExactMwのOptimizationはMaximizeとします。これにより、Mwが大きく、SlogPの小さい化合物群をPareto Rankとして取得することができます。
結果は、後ほど視覚的に確認することにします。

knime_pareto_04

ソート1

Sorterノードを使って、パレートランクの昇順に並べ替えを行います。

knime_pareto_05

色の割り付け1

Color Managerノードを使って、パレートランクに色を割り付けます。
ここでは、Pareto Rankの最小値である1を赤に、最大値である70を青としています。

knime_pareto_06

散布図1

Scatter Plotノードを使って散布図を作成します。
特に設定はしません。

連動テーブル1

Interactive Tableノードを使って、散布図と連動したテーブルを作成します。
特に設定はしません。

Desirabilityランキング

Desirability Rankingノードを使って、ランキングを行います。
ここでは、SlogPをMinimiseとし、Weightを1.0とします。また、ExactMWは、Maximiseとし、Weightを1.0とします。本ノードでは、このWeight値の反映されたDesirability Scoreを得ることができます。

knime_pareto_07

ソート2

Sorterノードを使って、Desirability Scoreを降順にソートします。

knime_pareto_08

色の割り付け2

Color Managerノードを使って、Desirability Scoreに色の割り付けを行います。
ここでは、Desirability Scoreの最小値を青に、最大値を赤に設定しています。

knime_pareto_09

散布図2

Scatter Plotノードを使って散布図を作成します。
特に設定はしません。

連動テーブル2

Interactive Tableノードを使って、散布図と連動したテーブルを作成します。
特に設定はしません。

以上で設定は終わりです。
ワークフローを実行し、まずは、Pareto Rankingの結果から確認したいと思います。
Interactive Tableノードで右クリックし、View: Table Viewを選択します。
次に、Scatter Plotノードで右クリックし、View: Scatter Plotを選択します。
Table Viewで、Pareto Rankが1の行を全て選択した状態で、[Hilite]→[Hilite Selected]を選択すると、Scatter PlotにPareto Rankが1の化合物の点がハイライト表示されます。

knime_pareto_10

ハイライトされている点をパレート解と呼びます。

knime_pareto_11

Desirability Rankingの結果を確認したいと思います。
Pareto Rankingと同様に、Interactive Tableノードで右クリックし、View: Table Viewを選択します。
次に、Scatter Plotノードで右クリックし、View: Scatter Plotを選択します。
Table Viewで、Desirability Scoreの上位10化合物を選択した状態で、[Hilite]→[Hilite Selected]を選択すると、上位10化合物の点がハイライト表示されます。

knime_pareto_12

Desirability RankingとPareto Rankingの結果の違いが分かると思います。

knime_pareto_13


利用したソフトウェア:
KNIME 2.11.3

KNIME: Matched Molecular Pair Analysis


今回は、Matched Molecular Pair Analysisを行います。
解析対象となるデータセットは、以下のサイトにある化合物とそのlogS値(Huuskonen dataset)としました。
入手先: http://sourceforge.net/p/rdkit/code/HEAD/tree/trunk/Docs/Book/data/
ファイル名: solubility.train.sdf

knime_mmpa_01

分子の入力

SDFの読み込みには、SDF Readerノードを使います。
File selectionタブでSDFファイルの場所を指定します。

knime_mmpa_02

MMP

Matched Molecular Pairs (RDKit)ノードを使って、MMPを検出します。
分子のIDとして、SMILESを使いたいので、OptionタブのSelect Molecule IDs columnに、smilesを指定します。
Advanced Settingタブでは、MMPを検出するための設定値を指定できますが、ここでは、全てデフォルト値を用いています。

knime_mmpa_03

左辺の物性値付加

Joinerノードを使って、MMPの左辺にあたる化合物のlogS値を付加します。
ここでは、Left TableのID(Left)列とRight Tableのsmiles列をInner Joinで結合することにより、logS値を付加しています。

knime_mmpa_04

Left Tableの列は全て、Include枠に加えます。
Right Tableからは、SOL列(logS値)だけInclude枠に加えます。

knime_mmpa_05

右辺の物性値付加

Joinerノードを使って、MMPの右辺にあたる化合物のlogS値を付加します。
ここでは、Left TableのID(Right)列とRight Tableのsmiles列をInner Joinで結合することにより、logS値を付加しています。

knime_mmpa_06

Left Tableの列は全て、Include枠に加えます。
Right Tableからは、SOL列(logS値)だけInclude枠に加えます。

knime_mmpa_07

Δ物性値計算

Java Snippet(simple)ノードを使って、MMPの物性値の差(Δ物性値)を計算します。

knime_mmpa_08

頻度カウント値付加

MMPより得られる変換ルールの頻度を後で計算するために、MMP_count列を新たに作成し、1をセットしておきます。

knime_mmpa_09

Δ物性値の平均と頻度の計算

GroupByノードを使って、変換ルールのΔ物性値の平均と頻度を計算します。
Groupタブでは、Group column(s)枠に、Transformation、Left Fragment、Right Fragmentを加えます。

knime_mmpa_10

次に、Manual Aggregationタブにおいて、dPのAggregationをMeanとし、MMP_countのAggregationをSumとします。先程、MMP_countに1をセットしたのは、ここで利用するためです。

knime_mmpa_11

頻度フィルター

Rule-based Row Filterノードを使って、ある頻度の値でフィルタリングを行います。
ここでは、頻度が5以上ある変換ルールだけを取り出しています。

knime_mmpa_12

Δ物性値でソート

Sorterノードを使って、Δ物性値の平均でソートを行います。

knime_mmpa_13

PDFで出力

Table to PDFノードを使って、結果をPDFで出力します。

knime_mmpa_14

以上で設定は終わりです。
実行すると、以下の様なMMPAの結果がPDFで出力されます。

knime_mmpa_15


利用したソフトウェア:
KNIME 2.11.3

KNIME: k-Means法によるクラスタリング


今回は、k-Means法によるクラスタリングを行います。
ここでは、クラスタリングに用いていないデータ(Newデータ)は、Cluster Assignerノードを使って、最も近いクラスタへの割り当てを行います。
クラスタリングの結果は、視覚的に分かりやすいように、Color ManagerノードとShape Managerノードを使って加工し、散布図で表示しています。

knime_kms_01

各ノードの設定方法を説明します。
各ノードを配置、接続した後、ノードをダブルクリックするとConfigureが開き、設定を行うことができます。

分子の入力

SDFの読み込みには、SDF Readerノードを使います。
File selectionタブでSDFファイルの場所を指定します。
また、ここで入力するSDFにおいては、各分子の1行目に分子IDを記載していますので、Use molecule name as row IDにチェックをいれ、分子IDを行のIDとして使います。

knime_kms_02

RDMolに変換

SDFからRDKitのMol形式(RDMol)にRDKit From Moleculeノードを用いて変換します。

knime_kms_03

記述子の計算

RDKit Descriptor Calculationノードを使って、記述子の計算を行います。
ここでは、SlogPとTPSAのみInclude枠に加え、記述子として利用します。

knime_kms_04

データの分割

Partitioningノードを使って、データを2つに分割します。
1つは、k-Means法への入力データとし、もう1つは、後ほどCluster Assignerノードを使って、最も近いクラスタへの割り当てを行う際の入力データとして利用します。
ここでは、データの8割をk-Menas法への入力データとして利用したいので、Choose size of first partitionにあるRalative[%]を80とします。

knime_kms_05

クラスタリング

k-Meansノードを使って、クラスタリングを行います。
ここでは、number of clustersに3を指定し、Include枠にSlogPとTPSAを加えます。

knime_kms_06

最も近いクラスタへの割り当て

Cluster Assignerノードを用いて、Newデータのクラスタへの割り当てを行います。
特に設定は必要ありません。

データの加工

前のノードで、Newデータのクラスタへの割り当てが行われています。
ここでは、k-Meansノードの出力との区別を行うために、割り当てられたクラスタ名の前に文字列”Pre_”をJava Snippet(simple)ノードを使って加えます。

knime_kms_07

データの結合

k-Meansノードの出力と、Cluster Assignerノードの出力を結合します。
特に設定は必要ありません。

色の割り当て

Color Managerノードを使って、クラスタの種類ごとに色を指定します。
cluster_0とPre_cluster_0は赤、cluster_1とPre_cluster_1は緑、そしてcluster_2とPre_cluster2は、黄色を指定します。

knime_kms_08

形の割り当て

Shape Managerノードを使って形の割り当てを行います。
k-Meansノードの出力には●を、Cluster Assignerの出力には×を指定します。

knime_kms_09

散布図で確認

Scatter Plot(JFreeChart)ノードを使って、クラスタリングとクラスタの割り当ての結果を散布図で確認するための設定を行います。

knime_kms_10

以上で設定は終わりです。
ワークフローを実行します。
Scatter Plotノード上で右クリックし、View: Scatter Plotを選択します。
Newデータ(×)が、近傍のクラスタに適切に割り振られていることが、視覚的に確認できます。

knime_kms_11


利用したソフトウェア:
KNIME 2.11.3

KNIME: MCSを利用したクラスタリング (2)


前回の続きですが、今回は、距離行列を利用したクラスタリングを行います。
knime_mcs_clust2_01

各ノードの設定方法を説明します。
各ノードを配置、接続した後、ノードをダブルクリックするとConfigureが開き、設定を行うことができます。

MCSから算出された距離行列の読み込み

前回のワークフローで出力された距離行列ファイルをDistance Matrix Readerノードを使って、読み込みます。

knime_mcs_clust2_02

クラスタリング

k-Medoidsノードを使ってクラスタリングを行います。
Partion count (k)でクラスタの数を指定できます。ここでは、3を入力します。

knime_mcs_clust2_03

構造式を確認するためのSDFを読み込み

クラスタリングの結果を確認する際に、構造式があると便利です。
ここでは、SDF Readerノードを使って、SDFの読み込みを行います。
File selectionタブでSDFファイルの場所を指定します。
また、ここで入力するSDFにおいては、各分子の1行目に分子IDを記載していますので、Use molecule name as row IDにチェックを入れて、分子IDを利用することにします。

knime_mcs_clust2_04

RDMolに変換

SDFからRDKitのMol形式(RDMol)にRDKit From Moleculeノードを用いて変換します。

knime_mcs_clust2_05

構造式の付加1

Joinderノードを使って、クラスタリングに利用した全ての化合物に構造式を付加します。
Left Table、Right Table共にRow IDを指定します。

knime_mcs_clust2_06

構造式の付加2

各クラスタの代表となる化合物にもJoinerノードを使って構造式を付加します。
Left Tableには、ClusterをRight TableにはRow IDを指定します。

knime_mcs_clust2_07

ここまでの処理により、Tableの状態は以下の様になっています。
一番右が、各クラスタの代表となる化合物の構造式、その左が、各化合物の構造式となります。

knime_mcs_clust2_11

クラスタの色設定

Color Managerノードを使って、各クラスに色の割り当てを行います。

knime_mcs_clust2_08

散布図

Scatter Plotノードを使います。
特に設定はしません。

結果確認用テーブル

Interactive Tableノードを使って、散布上のプロットとテーブルの行を連動させることができます。
特に設定はしません。

以上で設定は終わりです。
実行し、Scatter PlotとInteractive Tableを表示させます。
まずは、Scatter Plotノードで右クリックをし、View: Scatter Plotを選択します。

knime_mcs_clust2_09

次に、Interactive Tableノードで右クリックをし、View: Table Viewを選択します。

knime_mcs_clust2_10

行を選択して、メニューバーから[Hilite]→[Hilite Selected]を選択すると、この行に対応する散布図上の点が、ハイライトされます。


利用したソフトウェア:
KNIME 2.11.3