Berbagi teknologi

[Pertempuran Praktis Pembelajaran Mesin] Perkemahan Musim Panas Datawhale: Catatan Bacaan Intensif Dasar 2

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.

Pengoptimalan fitur

Ekstrak rumus molekul

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;

Hitung berat molekul

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.

Hitungan Atom

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)

Penggabungan model

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