LoginSignup
3
3

はじめに

今回はサンプルとして適当に作った10個の化合物に対してMorganフィンガープリントを作成していきます。また、作ったデータセットに対して機械学習のインプットデータにすることを念頭に置いて全てが0の列の削除などのデータの前処理を行っていきます。

環境

  • rdkit 2022.3.4
  • pandas 1.2.5
  • ipython 7.31.1

データの読み込み

# ライブラリーのインポート
import pandas as pd
import numpy as np
from IPython.display import SVG
from rdkit.Chem import AllChem, Draw, Descriptors, PandasTools
from rdkit.Chem import AllChem
from rdkit import Chem

以下のような化合物のSMILESが10個記載されたcsvファイルを今回はデータとして読み込みます。
image.png

# データ読み込み
df = pd.read_csv("sample_data.csv", index_col=0)
df

image.png

SMILESからMolオブジェクトを生成します(分子式の描画)

# SMILES→構造可視化
PandasTools.AddMoleculeColumnToFrame(df, "SMILES")
df

image.png

# エクセルに保存(エラー回避のため欠損値は0埋めしておく)
PandasTools.SaveXlsxFromFrame(df.fillna(0), "sample_data_withMol.xlsx", size=(150, 150))

Morganフィンガープリントの確認

どのようにMorganフィンガープリントが生成されるのか、ここではデータフレームの4番目の分子を例にとって確認してみましょう。

# 検討する分子の表示
m = Chem.MolFromSmiles(df["SMILES"][3])
m

image.png

# ビット数を定義
nBits=2048
# ビット情報を保持するための空の辞書を作っておく
bi = {} 
# 半径2, ビット数2048(デフォルト)でフィンガープリントを作成
fp = AllChem.GetMorganFingerprintAsBitVect(m,2,nBits=nBits, bitInfo=bi)
# フィンガープリントの表示
list(fp.GetOnBits())
出力
[1,
 69,
 204,
 228,
 268,
 273,
 283,
 304,
 389,
 486,
 650,
 658,
 695,
 745,
 807,
 874,
 940,
 1057,
 1088,
 1152,
 1199,
 1380,
 1385,
 1423,
 1665,
 1750,
 1873,
 1917,
 1985]

ここでフィンガープリントを1つ可視化してみましょう。

# リストの3番目のフィンガープリントを可視化する
img = Draw.DrawMorganBit(m, list(fp.GetOnBits())[2], bi)
img

image.png

複数の分子に対してMorganフィンガープリントを作成していく

# ビットを表現するデータフレームの作成
df_bits = pd.DataFrame(index = df.index, columns=np.arange(1,nBits+1))
df_bits

for i in range(len(df)): 
    m = Chem.MolFromSmiles(df["SMILES"][i])
    fp = AllChem.GetMorganFingerprintAsBitVect(m,2,nBits=nBits)
    # フィンガープリントが存在するビット数を"1"で埋める
    for j in list(fp.GetOnBits()):
        df_bits.iloc[i,j-1] = 1
    
df_bits

image.png

# NaNを0に変換する
df_bits = df_bits.fillna(0)
df_bits

image.png

# もともとのデータフレームとフィンガープリントの情報が入ったデータフレームを結合する
# 最初に読み込んだデータフレームには分子式が描画されているので、もう一度データを読み込み
df = pd.read_csv("sample_data.csv", index_col=0)
df_add = pd.concat([df, df_bits], axis=1)
df_add

image.png

# データの保存
df_add.to_csv("sample_data_withfp.csv")

データフレームの前処理

機械学習の用いるデータセットは一般的に前処理の段階で全て0や1もしくは同じ数値を持った列を除きます。そのような操作を実行していきます。

# 全て0の列を削除
def remove_all_zero_col(df):
    df = df.copy()
    for col in df.columns:
        if (df[col] == 0).all():
            df.drop(col, axis=1, inplace=True)
    return df

df2 = remove_all_zero_col(df_add)
df2

image.png

# 全ての化合物に共通するビット数1873のフィンガープリントを確認
img_1873 = Draw.DrawMorganBit(m, 1873, bi)
img_1873

image.png

# 全て1の列を削除
def remove_all_one_col(df):
    df = df.copy()
    for col in df.columns:
        if (df[col] == 1).all():
            df.drop(col, axis=1, inplace=True)
    return df

df3 = remove_all_one_col(df2)
df3

image.png

# この段階で保存
df3.to_csv("before.csv")

また機械学習では全て同じ値の説明変数は1つしか要らないので、説明変数が全て重複している列を取り除いていく。(行の重複を削除する方法を参考にする。列の重複を削除する方法は分かりませんでした。どなたかご存じであればコメントいただければ幸いです。)

まずは転置して行と列を入れ替えます。

df3.T

image.png

重複している行を確認します。

df3.T.duplicated()
出力
df3.T.duplicated()

重複している行を削除します。

df4 = df3.T.drop_duplicates()
df4

image.png

再度転置して、もともと行だったデータを行に、もともと列だったデータを列に変換します。

new_df = df4.T
new_df

image.png

これにてデータの前処理は終了です。このデータフレームを用いて機械学習の予測モデルの構築などが出来そうです。

# 最終的なデータセットを保存
new_df.to_csv("after.csv")

参考

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3