การออกแบบโครงข่ายประสาทเทียมสำหรับแมชชีนเลิร์นนิงของกัญชา ตอนที่ 1

May 01 2023
เช้าวันอาทิตย์ที่ดีและสดใสในการออกแบบ Convolutional Neural Networks CNN คือโครงข่ายประสาทเทียมที่ได้รับการฝึกอบรมเกี่ยวกับการใช้รูปภาพและส่งผ่านชุดตัวกรองเพื่อกำหนดคุณลักษณะต่างๆ

เช้าวันอาทิตย์ที่ดีและสดใสในการออกแบบ Convolutional Neural Networks CNN คือโครงข่ายประสาทเทียมที่ได้รับการฝึกอบรมเกี่ยวกับการใช้รูปภาพและส่งผ่านชุดตัวกรองเพื่อกำหนดคุณลักษณะต่างๆ ในฐานะนักเคมีอินทรีย์ เราใช้สายตาในการออกแบบโครงสร้าง ดังนั้นนี่อาจเป็นแนวทางการเรียนรู้ของเครื่องที่ใช้งานง่ายและแยกส่วนโมเลกุลโดยใช้ตัวกรองภายในของเราเอง มันดูเป็นธรรมชาติที่จะลองดู

เป้าหมายของเราสำหรับเครือข่ายนี้คือเราต้องการทราบว่าโมเลกุลจะทำงานเหมือนกัญชาหรือไม่โดยพิจารณาจากค่าคงที่ในการจับตัวของมัน (ลิแกนด์จับตัวกันแรงแค่ไหน) เข้ากับตัวรับเอนโดแคนนาบินอยด์ทั่วไป CB1 ซึ่งเป็นเป้าหมายหลักสำหรับ THC โครงสร้างผลึกได้มาจาก Hua et al

โครงสร้างเป็นชุดของเอนริเก้อัลฟ่าในรูปทรงรองเท้าที่มีกระเป๋าผูกอยู่ลึกมากภายในตัวรับ

ค่าของ THC ต่อตัวรับ CB1 สามารถวัดได้ด้วยค่าคงที่การยับยั้ง Ki ซึ่งเป็นตัวบ่งชี้ว่าตัวยับยั้งมีศักยภาพเพียงใด ค่า Ki ขนาดเล็ก 100 ไมโครโมลาร์ถือว่ามีศักยภาพ

หากเรานำรายการสารยับยั้งสำหรับ CB1 และค่าคงที่การยับยั้งตามที่บันทึกเป็น nM จากบทความนี้:

เราสามารถทำนายได้หรือไม่ว่าสารประกอบ cannabinoid ใหม่จะทำงานคล้ายกับ terpene เช่น THC โดยพิจารณาจากค่าคงที่ของการยับยั้ง นี่คือข้อมูลบางส่วนที่สรุปมาจากกระดาษ อย่าลังเลที่จะคว้าเพิ่มเติม

compounds = {
    'CCCCC1=CC(=C2C3C=C(CCC3C(OC2=C1)(C)C)C)O': 36,
    'CCCC1=CC(=C2C3C=C(CCC3C(OC2=C1)(C)C)C)O': 22,
    'CCCCCC1=CC2=C(C3C=C(CCC3C(O2)(C)C)C)C(=C1C(=O)O)O': 620,
    'CCCCCC1=CC(=C(C(=C1)O)C/C=C(\C)/CCC=C(C)C)O': 1045,
    'CCCC1=CC(=C(C(=C1)O)C/C=C(\C)/CCC=C(C)C)O': 2865,
    'CCCCCC1=CC(=C(C(=C1C(=O)O)O)C/C=C(\C)/CCC=C(C)C)O': 13116,
    'COC1=C(C/C=C(CC/C=C(C)\C)\C)C(O)=CC(CCCCC)=C1': 10000,
    'CCCCCC1=CC(=C(C(=C1)O)C2C=C(CCC2C(=C)C)C)O': 1690,
    'CCCC1=CC(=C(C(=C1)O)C2C=C(CCC2C(=C)C)C)O': 14445,
    'CCCCCC1=CC(=C(C(=C1C(=O)O)O)C2C=C(CCC2C(=C)C)C)O': 626,
}

มาเริ่มนำเข้ากันเถอะ:


import rdkit
import numpy as np
import pandas as pd

from rdkit import Chem
from rdkit.Chem import AllChem

from matplotlib import pyplot as plt

df = pd.DataFrame()
df['smiles'] = list(compounds.keys())
df['ki'] = list(compounds.values())
df["mol"] = df["smiles"].apply(Chem.MolFromSmiles)

ผลกระทบของความละเอียดบนภาพอาจทำให้พื้นที่ที่ถูกครอบครองโดยข้อมูลที่แตกต่างกันสามารถครอบงำได้

การฝังและความละเอียดของรูปภาพของคุณมีความสำคัญมาก เนื่องจากจะช่วยให้โครงข่ายประสาทเทียมสามารถแสดงคุณลักษณะเชิงนามธรรมได้อย่างมีประสิทธิภาพมากขึ้น ดังนั้นเราจึงคำนวณขนาดและพิกัด 2 มิติ และตั้งค่าศูนย์ว่าง 4 ตัวที่จะทำหน้าที่เป็นที่เก็บเมตาสำหรับข้อมูลต่างๆ เช่น เลขอะตอม

def chemcepterize_mol(mol, embed=10.0, res=0.2):

    dimensions = int(embed*2/res)
    chempcepterized_molecule = Chem.Mol(mol.ToBinary())
    chempcepterized_molecule.ComputeGasteigerCharges()
    AllChem.Compute2DCoords(chempcepterized_molecule)
    coords = chempcepterized_molecule.GetConformer(0).GetPositions()
    vector = np.zeros((dims,dims,4))

[[[0. 0. 0. 0.]
  [0. 0. 0. 0.]
  [0. 0. 0. 0.]
  ...
  [0. 0. 0. 0.]
  [0. 0. 0. 0.]
  [0. 0. 0. 0.]]

 [[0. 0. 0. 0.]
  [0. 0. 0. 0.]
  [0. 0. 0. 0.]
  ...
  [0. 0. 0. 0.]
  [0. 0. 0. 0.]
  [0. 0. 0. 0.]]

 [[0. 0. 0. 0.]
  [0. 0. 0. 0.]
  [0. 0. 0. 0.]
  ...
  [0. 0. 0. 0.]
  [0. 0. 0. 0.]
  [0. 0. 0. 0.]]

for i,bond in enumerate(mol.GetBonds()):

    bond_order = bond.GetBondTypeAsDouble()
    start_atom_index = bond.GetBeginAtomIdx()
    end_atom_index = bond.GetEndAtomIdx()
    start_coordinates = coords[start_atom_index]
    end_coordinates = coords[end_atom_index]

fractional_space = np.linspace(0,1,int(1/res*2))

for fraction in fractional_space:
    coordinates = (fraction*start_coordinates + (1-fraction)*end_coordinates)
    x = int(round((coordinates[0] + embed)/res))
    y = int(round((coordinates[1]+ embed)/res))
    vector[ x, y, 0] = bond_order

for i,atom in enumerate(cmol.GetAtoms()):
   x = int(round((coords[i][0] + embed)/res))
   y = int(round((coords[i][1]+ embed)/res))
   
   vector[ x , y, 1] = atom.GetAtomicNum()
   
   hyptype = atom.GetHybridization().real
   vector[ x , y, 2] = hyptype

   charge = atom.GetProp("_GasteigerCharge")
   vector[ x , y, 3] = charge

return vect

def chemcepterize_mol(mol, embed=10.0, res=0.2):

    dimensions = int(embed*2/res)
    chempcepterized_molecule = Chem.Mol(mol.ToBinary())
    chempcepterized_molecule.ComputeGasteigerCharges()
    AllChem.Compute2DCoords(chempcepterized_molecule)
    coords = chempcepterized_molecule.GetConformer(0).GetPositions()
    vector = np.zeros((dims,dims,4))
    
    # Bonds

    for i,bond in enumerate(mol.GetBonds()):
    
        bond_order = bond.GetBondTypeAsDouble()
        start_atom_index = bond.GetBeginAtomIdx()
        end_atom_index = bond.GetEndAtomIdx()
        start_coordinates = coords[start_atom_index]
        end_coordinates = coords[end_atom_index]
        
        # Draw Bond A long Vector 

        fractional_space = np.linspace(0,1,int(1/res*2))

        for fraction in fractional_space:
            coordinates = (fraction*start_coordinates + (1-fraction)*end_coordinates)
            x = int(round((coordinates[0] + embed)/res))
            y = int(round((coordinates[1]+ embed)/res))
            vector[ x, y, 0] = bond_order
    
    # Atoms

    for i,atom in enumerate(cmol.GetAtoms()):
       x = int(round((coords[i][0] + embed)/res))
       y = int(round((coords[i][1]+ embed)/res))
       
       vector[ x , y, 1] = atom.GetAtomicNum()
       
       hyptype = atom.GetHybridization().real
       vector[ x , y, 2] = hyptype
    
       charge = atom.GetProp("_GasteigerCharge")
       vector[ x , y, 3] = charge
    
    return vect

def vectorize(mol):
    return chemcepterize_mol(mol, embed=12)

df["mol_image"] = df["mol"].apply(vectorize)