👌

分子表現SELFIESの紹介

2023/04/20に公開

SELFIESとは

[https://iopscience.iop.org/article/10.1088/2632-2153/aba947]で発表された分子表現であるSELFIESを紹介します。
日本語の解説資料としてはかなり丁寧な
[https://blacktanktop.hatenablog.com/entry/2021/08/12/115613#Atomic-Symbols:title]
があるのでここでは使い方のメモだけ残します。
本当にやりたいSELFIESを使用した構造生成である
[https://github.com/aspuru-guzik-group/stoned-selfies:title]

[https://github.com/aspuru-guzik-group/JANUS:title]
を次回以降紹介します。

インストール方法

pip install selfies

実行方法

smilesからSELFIESヘの変換

import selfies as sf

# smiles
benzene = "c1ccccc1"

# SMILES -> SELFIES
try:
    benzene_sf = sf.encoder(benzene) 
except sf.EncoderError:
    pass  # sf.encoder error!

print(benzene_sf)

SELFIESからsmilesへの変換

# SELFIES -> SMILES translation
try:
    benzene_smi = sf.decoder(benzene_sf)
except sf.DecoderError:
    pass  # sf.decoder error!

print(benzene_smi)

SELFIESの文字の数を返す

# number of selfies
len_benzene = sf.len_selfies(benzene_sf) 
print(len_benzene)

SELFIESを単語毎に分割する

# split
symbols_benzene = list(sf.split_selfies(benzene_sf))
print(symbols_benzene)

価数が通常より大きいSMILESに対して実施する。strict=Falseの場合はエラー出ない。

hypervalent_smiles = 'O=I(O)(O)(O)(O)O'

hypervalent_sf = sf.encoder(hypervalent_smiles, strict=False)  # orthoperiodic acid
print(hypervalent_sf)

strict=Trueの場合はエラーが出る。

hypervalent_sf = sf.encoder(hypervalent_smiles, strict=True)  # orthoperiodic acid
print(hypervalent_sf)

価数が満たされるように出力される。

# decoder時に価数が満たされるように変換する
standard_derived_smi = sf.decoder(hypervalent_sf)
print(standard_derived_smi)

価数の修正なしで変換される。

# 制約条件を緩和する
sf.set_semantic_constraints("hypervalent")
relaxed_derived_smi = sf.decoder(hypervalent_sf)
print(relaxed_derived_smi)

One-Hot Encodingへの変換

import selfies as sf

dataset = ["[C][O][C]", "[F][C][F]", "[O][=O]", "[C][C][O][C][C]"]
alphabet = sf.get_alphabet_from_selfies(dataset)
alphabet.add("[nop]")  # [nop] is a special padding symbol
alphabet = list(sorted(alphabet))

pad_to_len = max(sf.len_selfies(s) for s in dataset) 
symbol_to_idx = {s: i for i, s in enumerate(alphabet)}

dimethyl_ether = dataset[0] 

label, one_hot = sf.selfies_to_encoding(
   selfies=dimethyl_ether,
   vocab_stoi=symbol_to_idx,
   pad_to_len=pad_to_len,
   enc_type="both"
)

One-HotからSMILESへの変換

idx_to_symbol = {i: s for i, s in enumerate(alphabet)}
sf.encoding_to_selfies(one_hot, idx_to_symbol, enc_type="one_hot")

最後に

今回は簡単な使い方の説明だけ行いました。
次回はSTONEDアルゴリズムを見ていきたいと思います。

Discussion