2024-07-08
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
# Perkemahan Musim Panas AI # Datawhale # Perkemahan Musim Panas
Selain validasi silang pada Baseline asli, terdapat juga metode optimasi utama yaitu rekayasa fitur.
Cara mengoptimalkan fitur berkaitan dengan cara kami meningkatkan akurasi prediksi model. Rekayasa fitur sering kali merupakan bagian yang dapat dilakukan dengan baik oleh orang-orang yang memiliki pemahaman mendalam tentang domain masalah, karena kita harus memikirkan transformasinya.
Selain fitur Smiles, terdapat banyak fitur yang dapat mengekstrak informasi berharga. Misalnya, InChI terdiri dari serangkaian bagian dan memberikan informasi detail tentang struktur molekul.MisalnyaIdentifikasi awal, rumus molekul, tabel koneksi, jumlah atom hidrogen, jumlah ikatan multi-rotasi, informasi stereokimia, informasi isomer, informasi campuran atau tautomer, informasi multiplisitas muatan dan putaran, dll.
Selain itu, jika ingin meningkatkan akurasi model, ada baiknya untuk mengubah model.
Dari string InChI kita dapat melihat bahwa rumus molekul diberikan secara langsung/C47H61N7O6S
bagian. Artinya molekul tersebut tersusun atas 47 atom karbon, 61 atom hidrogen, 7 atom nitrogen, 6 atom oksigen, dan 1 atom belerang;
Berat molekul dapat ditemukan dengan mengalikan massa atom setiap atom dengan nomornya, lalu menjumlahkannya.
menyukai
Massa atom karbon (C) kira-kira 12,01 g/mol
Massa atom hidrogen (H) kira-kira 1,008 g/mol
Massa atom nitrogen (N) kira-kira 14,01 g/mol
Massa atom oksigen (O) kira-kira 16,00 g/mol
Massa atom belerang (S) kira-kira 32,07 g/mol
Dikalikan dengan jumlah dan dijumlahkan, kita mendapatkan berat molekul.
Hitung langsung jumlah atom yang berbeda dan kembangkan.
import pandas as pd
import re
atomic_masses = {
'H': 1.008, 'He': 4.002602, 'Li': 6.94, 'Be': 9.0122, 'B': 10.81, 'C': 12.01,
'N': 14.01, 'O': 16.00, 'F': 19.00, 'Ne': 20.180, 'Na': 22.990, 'Mg': 24.305,
'Al': 26.982, 'Si': 28.085, 'P': 30.97, 'S': 32.07, 'Cl': 35.45, 'Ar': 39.95,
'K': 39.10, 'Ca': 40.08, 'Sc': 44.956, 'Ti': 47.867, 'V': 50.942, 'Cr': 52.00,
'Mn': 54.938, 'Fe': 55.845, 'Co': 58.933, 'Ni': 58.69, 'Cu': 63.55, 'Zn': 65.38
}
# 函数用于解析单个InChI字符串
def parse_inchi(row):
inchi_str = row['InChI']
formula = ''
molecular_weight = 0
element_counts = {}
# 提取分子式
formula_match = re.search(r"InChI=1S/([^/] )/c", inchi_str)
if formula_match:
formula = formula_match.group(1)
# 计算分子量和原子计数
for element, count in re.findall(r"([A-Z][a-z]*)([0-9]*)", formula):
count = int(count) if count else 1
element_mass = atomic_masses.get(element.upper(), 0)
molecular_weight = element_mass * count
element_counts[element.upper()] = count
return pd.Series({
'Formula': formula,
'MolecularWeight': molecular_weight,
'ElementCounts': element_counts
})
# 应用函数到DataFrame的每一行
train[['Formula', 'MolecularWeight', 'ElementCounts']] = train.apply(parse_inchi, axis=1)
# 定义存在的key
keys = ['H', 'He', 'Li', 'Be', 'B', 'C', 'N', 'O', 'F', 'Ne', 'Na', 'Mg', 'Al', 'Si', 'P', 'S', 'Cl', 'Ar', 'K', 'Ca', 'Sc', 'Ti', 'V', 'Cr', 'Mn', 'Fe', 'Co', 'Ni', 'Cu', 'Zn']
# 创建一个空的DataFrame,列名为keys
df_expanded = pd.DataFrame({key: pd.Series() for key in keys})
# 遍历数据,填充DataFrame
for index, item in enumerate(train['ElementCounts'].values):
for key in keys:
# 将字典中的值填充到相应的列中
df_expanded.at[index, key] = item.get(key, 0)
df_expanded = pd.DataFrame(df_expanded)
Seperti disebutkan terakhir kali, kami menggunakan model catboost. Kami belum mencoba lightgbm dan xgboost. Anda dapat menjalankan ketiga model ini secara berurutan, lalu rata-rata hasil ketiga model untuk fusi (ini juga merupakan area yang dapat ditingkatkan). ).
def cv_model(clf, train_x, train_y, test_x, clf_name, seed = 2023):
folds = 5
kf = KFold(n_splits=folds, shuffle=True, random_state=seed)
oof = np.zeros(train_x.shape[0])
test_predict = np.zeros(test_x.shape[0])
cv_scores = []
for i, (train_index, valid_index) in enumerate(kf.split(train_x, train_y)):
print('************************************ {} ************************************'.format(str(i 1)))
trn_x, trn_y, val_x, val_y = train_x.iloc[train_index], train_y[train_index], train_x.iloc[valid_index], train_y[valid_index]
if clf_name == "lgb":
train_matrix = clf.Dataset(trn_x, label=trn_y)
valid_matrix = clf.Dataset(val_x, label=val_y)
params = {
'boosting_type': 'gbdt',
'objective': 'binary',
'min_child_weight': 6,
'num_leaves': 2 ** 6,
'lambda_l2': 10,
'feature_fraction': 0.8,
'bagging_fraction': 0.8,
'bagging_freq': 4,
'learning_rate': 0.35,
'seed': 2024,
'nthread' : 16,
'verbose' : -1,
}
model = clf.train(params, train_matrix, 2000, valid_sets=[train_matrix, valid_matrix],
categorical_feature=[], verbose_eval=1000, early_stopping_rounds=100)
val_pred = model.predict(val_x, num_iteration=model.best_iteration)
test_pred = model.predict(test_x, num_iteration=model.best_iteration)
if clf_name == "xgb":
xgb_params = {
'booster': 'gbtree',
'objective': 'binary:logistic',
'num_class':3,
'max_depth': 5,
'lambda': 10,
'subsample': 0.7,
'colsample_bytree': 0.7,
'colsample_bylevel': 0.7,
'eta': 0.35,
'tree_method': 'hist',
'seed': 520,
'nthread': 16
}
train_matrix = clf.DMatrix(trn_x , label=trn_y)
valid_matrix = clf.DMatrix(val_x , label=val_y)
test_matrix = clf.DMatrix(test_x)
watchlist = [(train_matrix, 'train'),(valid_matrix, 'eval')]
model = clf.train(xgb_params, train_matrix, num_boost_round=2000, evals=watchlist, verbose_eval=1000, early_stopping_rounds=100)
val_pred = model.predict(valid_matrix)
test_pred = model.predict(test_matrix)
if clf_name == "cat":
params = {'learning_rate': 0.35, 'depth': 5, 'bootstrap_type':'Bernoulli','random_seed':2024,
'od_type': 'Iter', 'od_wait': 100, 'random_seed': 11, 'allow_writing_files': False}
model = clf(iterations=2000, **params)
model.fit(trn_x, trn_y, eval_set=(val_x, val_y),
metric_period=1000,
use_best_model=True,
cat_features=[],
verbose=1)
val_pred = model.predict_proba(val_x)
test_pred = model.predict_proba(test_x)
oof[valid_index] = val_pred
test_predict = test_pred / kf.n_splits
F1_score = f1_score(val_y, np.where(val_pred