LoginSignup
1
0

USPTO Dataset の中身を確認

Last updated at Posted at 2023-03-12

USPTOの中身の反応が見たいんじゃ

USPTO

Daniel Loweさんが公開してくれている、オリジナルのデータが以下

Reactions extracted by text-mining from United States patents published between 1976 and September 2016.

米国の特許のテキストデータから化学反応を抽出してきたヤツです。テキストマイニング自体が完璧ではないので、普通に間違っている反応や重複した反応がたくさんあります。

全部ダウンロードすると重いので、2001_Sep2016_USPTOapplications_smiles.7z (83.54 MB)だけダウンロードして解凍しましょう。このファイルの中身はreaction SMILES なので、拡張子がrsmiになっています。

ipynbで反応を表示

このデータと同じディレクトリにipynbを作ります。

スクリーンショット 2023-03-12 23.41.03.png

ipynbでファイルを読み込み、上からてきとうに見る

with open('./2001_Sep2016_USPTOapplications_smiles.rsmi', 'r') as f:
    lines = f.read().splitlines()
lines[:5]
['ReactionSmiles\tPatentNumber\tParagraphNum\tYear\tTextMinedYield\tCalculatedYield',
 '[C:1]([C:5]1[CH:10]=[CH:9][C:8]([OH:11])=[CH:7][CH:6]=1)([CH3:4])([CH3:3])[CH3:2]>[Ni]>[C:1]([CH:5]1[CH2:6][CH2:7][CH:8]([OH:11])[CH2:9][CH2:10]1)([CH3:4])([CH3:2])[CH3:3]\tUS20010000035A1\t0007\t2001\t\t',
 '[Cl-].[Al+3].[Cl-].[Cl-].[Cl:5][CH2:6][CH2:7][CH2:8][C:9](Cl)=[O:10].[C:12]1([CH:18]([CH3:20])[CH3:19])[CH:17]=[CH:16][CH:15]=[CH:14][CH:13]=1>C(Cl)Cl>[Cl:5][CH2:6][CH2:7][CH2:8][C:9]([C:15]1[CH:16]=[CH:17][C:12]([CH:18]([CH3:20])[CH3:19])=[CH:13][CH:14]=1)=[O:10] |f:0.1.2.3|\tUS20010000038A1\t0256\t2001\t86%\t86.9%',
 '[Al+3].[Cl-].[Cl-].[Cl-].[Cl:5][CH2:6][CH2:7][CH2:8][C:9](Cl)=[O:10].[C:12]1([CH3:18])[CH:17]=[CH:16][CH:15]=[CH:14][CH:13]=1>>[Cl:5][CH2:6][CH2:7][CH2:8][C:9]([C:15]1[CH:16]=[CH:17][C:12]([CH3:18])=[CH:13][CH:14]=1)=[O:10] |f:0.1.2.3|\tUS20010000038A1\t0259\t2001\t95%\t',
 '[Cl:1][CH2:2][CH2:3][CH2:4][C:5]([C:7]1[CH:12]=[CH:11][C:10]([CH:13]([CH3:15])[CH3:14])=[CH:9][CH:8]=1)=[O:6].[Br:16]N1C(=O)CCC1=O.C(OOC(=O)C1C=CC=CC=1)(=O)C1C=CC=CC=1>C(Cl)(Cl)(Cl)Cl>[Br:16][C:13]([C:10]1[CH:9]=[CH:8][C:7]([C:5](=[O:6])[CH2:4][CH2:3][CH2:2][Cl:1])=[CH:12][CH:11]=1)([CH3:15])[CH3:14]\tUS20010000038A1\t0285\t2001\t\t']

ReactionSmiles, PatentNumber, ..., Yieldがタブで区切られています

ReactionSmilesは'原料と試薬>触媒・溶媒>生成物'の形で反応式が入っています。このデータセットでは、反応前後で対応する原子に番号が振られています(Atom Mapping)。原料や生成物に化合物が2つ以上存在する場合はピリオドで区切られています。
Atom MappingはChemAxon社が提供しているツールをフリーのアカデミックライセンスで使えるのでやってみてください。

1行目のデータの説明は飛ばして、上から10個見てみます。
ReactionSmiles以外はいらないので、str.find('\t')でタブの位置のindexを取得し、このindexより後ろの文字は捨てます。

from rdkit.Chem import rdChemReactions as Reactions
from rdkit.Chem import Draw

data = lines[1:11]
rxns = []
for rxn in data:
    rxn = rxn[:rxn.find('\t')]
    rxns.append(Reactions.ReactionFromSmarts(rxn, useSmiles=True))

Reactions.RectionFromSmartsの中に反応のstrを入れてやれば、反応のデータに変換してくれます。これでrxnsリストの中に10個の反応が入っていることになります。Drawで表示します。

Draw.ReactionToImage(rxns[0])

output.png
Niで芳香環が還元されています。Reaction SMILESでは水素を明示的に扱わないので、矢印の左側に3H2が隠れている感じですかね。。原子の番号は回転しちゃってますが、合っています。

indexをずらして見ていきます。

Draw.ReactionToImage(rxns[1])

output1.png

表記がrdkitのキショスタイルですが我慢しましょう。

またindexをずらします。

Draw.ReactionToImage(rxns[2])

output2.png

rxns[1]の基質違い、かつ溶媒のジクロロメタンが消えているだけです。こんな感じで反応を見ることができました。

反応を大量に見ていくと分かるのですが、1段階の反応が多いです。中にはワンポットでできそうな2段階くらいの反応が一つの矢印にまとまっているものもあります。テキストマイニングなのでその辺はご愛嬌です。ケモインフォの論文では、USPTOに入っているmultistep reactionsガーと書いている人がいますが、私が見ていった限りでは10段階の反応が一つの矢印にまとまっていたりするようなことは無いです。ただし重複した反応はたくさん含まれています。

USPTO_MIT

このDaniel Loweさんのデータセットは、1976年〜2016年のデータを合わせると180万反応ほどあります(今回ダウンロードしたのは2001年〜2016年のモノ)。180万反応もあるとかスゲ〜と思っちゃいますが、テキストマイニングなので間違ったデータが含まれていたり、重複したデータが多いというのは冒頭で書いた通りです。これをキレイにしてくれた人たちがいます。

GitHubはコチラ

このキレイにしてくれたデータセットは全部で48万反応くらいになっていて、大体みんなtrain 41万、valid 3万、test 4万にして使っているようです。他の論文でもUSPTO_MIT datasetとしてめちゃめちゃ使われていてめちゃめちゃ引用されています。

nips17-rexgen/USPTO/data.zip がデータセットなので、ダウンロードして見てみます。手順は同じです。

with open('./data/train.txt', 'r') as f:
    lines = f.read().splitlines()
lines[:5]
['[CH2:15]([CH:16]([CH3:17])[CH3:18])[Mg+:19].[CH2:20]1[O:21][CH2:22][CH2:23][CH2:24]1.[Cl-:14].[OH:1][c:2]1[n:3][cH:4][c:5]([C:6](=[O:7])[N:8]([O:9][CH3:10])[CH3:11])[cH:12][cH:13]1>>[OH:1][c:2]1[n:3][cH:4][c:5]([C:6](=[O:7])[CH2:15][CH:16]([CH3:17])[CH3:18])[cH:12][cH:13]1 15-19;6-15;6-8',
 '[CH3:14][NH2:15].[N+:1](=[O:2])([O-:3])[c:4]1[cH:5][c:6]([C:7](=[O:8])[OH:9])[cH:10][cH:11][c:12]1[Cl:13].[OH2:16]>>[N+:1](=[O:2])([O-:3])[c:4]1[cH:5][c:6]([C:7](=[O:8])[OH:9])[cH:10][cH:11][c:12]1[NH:15][CH3:14] 12-13;12-15',
 '[CH2:1]([CH3:2])[n:3]1[cH:4][c:5]([C:22](=[O:23])[OH:24])[c:6](=[O:21])[c:7]2[cH:8][c:9]([F:20])[c:10](-[c:13]3[cH:14][cH:15][c:16]([NH2:19])[cH:17][cH:18]3)[cH:11][c:12]12.[CH:25](=[O:26])[OH:27]>>[CH2:1]([CH3:2])[n:3]1[cH:4][c:5]([C:22](=[O:23])[OH:24])[c:6](=[O:21])[c:7]2[cH:8][c:9]([F:20])[c:10](-[c:13]3[cH:14][cH:15][c:16]([NH:19][CH:25]=[O:26])[cH:17][cH:18]3)[cH:11][c:12]12 19-25;25-27',
 '[Cl:1][C:2]([N:3]([CH3:4])[CH3:5])=[C:6]([CH3:7])[CH3:8].[Cl:51][CH2:52][Cl:53].[N:9]1([C:13](=[O:14])[c:15]2[n:16][cH:17][c:18]([O:21][c:22]3[cH:23][c:24]([C:25](=[O:26])[OH:27])[cH:28][c:29]([O:31][CH:32]([CH2:33][O:34][CH3:35])[CH3:36])[cH:30]3)[n:19][cH:20]2)[CH2:10][CH2:11][CH2:12]1.[NH2:37][c:38]1[n:39][cH:40][c:41]([CH3:44])[n:42][cH:43]1.[cH:45]1[cH:46][cH:47][n:48][cH:49][cH:50]1>>[N:9]1([C:13](=[O:14])[c:15]2[n:16][cH:17][c:18]([O:21][c:22]3[cH:23][c:24]([C:25](=[O:27])[NH:37][c:38]4[n:39][cH:40][c:41]([CH3:44])[n:42][cH:43]4)[cH:28][c:29]([O:31][CH:32]([CH2:33][O:34][CH3:35])[CH3:36])[cH:30]3)[n:19][cH:20]2)[CH2:10][CH2:11][CH2:12]1 25-26;25-37;25-27',
 '[Cl:11][c:12]1[c:13]2[c:14]([n:15][c:16](-[c:18]3[cH:19][cH:20][n:21][cH:22][cH:23]3)[n:17]1)[s:24][c:25]([Cl:27])[cH:26]2.[Cl:1][c:2]1[cH:3][c:4]([CH2:5][NH2:6])[cH:7][cH:8][c:9]1[Cl:10]>>[Cl:1][c:2]1[cH:3][c:4]([CH2:5][NH:6][c:12]2[c:13]3[c:14]([n:15][c:16](-[c:18]4[cH:19][cH:20][n:21][cH:22][cH:23]4)[n:17]2)[s:24][c:25]([Cl:27])[cH:26]3)[cH:7][cH:8][c:9]1[Cl:10] 6-12;11-12']

この論文では、反応物において切断される結合と新しく接続される結合の情報を渡してモデルにreaction centerを学習させるので、結合の切断・接続位置がReaction SMILESの後ろに入っています。反応を表示するだけなら不要なので、' 'より後ろの文字を捨てて表示します。

data = lines[0:10]
rxns = []
for rxn in data:
    rxn = rxn[:rxn.find(' ')]
    rxns.append(Reactions.ReactionFromSmarts(rxn, useSmiles=True))
Draw.ReactionToImage(rxns[0])

output_WLN.png

生のテキストに書いてあった 15-19;6-15;6-8 という数字は、それぞれ切断されるグリニャーのC-Mg, 新しく結合ができるC-C, 窒素側が脱離して切断されるC-Nに対応していることが分かります。

反応を一気に表示

私の環境では以下のコードで複数の反応を表示できます。昔macbookでやった時にうまくいかなかったことがあるので動くかわかりませんがやってみてくだサイ

with open('./data/train.txt', 'r') as f:
    rxns = f.read().splitlines()
    f.close()

for i, rxn in enumerate(rxns):
    rxn = Reactions.ReactionFromSmarts(rxn,useSmiles=True)
    display(rxn)

これをipynbでやっちゃうと数万個の画像が出力されてカーネルが落ちてしまうので、

for i, rxn in enumerate(rxns):
    rxn = Reactions.ReactionFromSmarts(rxn,useSmiles=True)
    display(rxn)
    
    if i == 50:
        break

とかにしておくと良いと思います。以上

1
0
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
1
0