การออกแบบโครงข่ายประสาทเทียมสำหรับแมชชีนเลิร์นนิงของกัญชา ตอนที่ 1
เช้าวันอาทิตย์ที่ดีและสดใสในการออกแบบ 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)