File size: 1,560 Bytes
5ac1b4e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

import joblib, numpy as np
from pathlib import Path

def load_globalwellfm(model_dir="GlobalWellFM_v1"):
    p = Path(model_dir)
    model   = joblib.load(p / "xgb_model.joblib")
    imputer = joblib.load(p / "imputer.joblib")
    le      = joblib.load(p / "label_encoder.joblib")
    return model, imputer, le

def predict_lithofacies(df, model_dir="GlobalWellFM_v1"):
    """df: DataFrame with columns GR, RHOB, NPHI, RT (ohm.m)"""
    model, imputer, le = load_globalwellfm(model_dir)
    f = df.copy()
    f["GR_N"]   = f["GR"].clip(0,200)/200
    f["RHOB_N"] = (f["RHOB"].clip(1.5,3.0)-1.5)/1.5
    f["NPHI_N"] = f["NPHI"].clip(-0.1,0.6)
    f["RT_LOG"] = np.log10(f["RT"].clip(0.01,10000))
    f["VCL"]    = ((f["GR"].clip(0,200)-30)/(120-30)).clip(0,1)
    f["PHI_D"]  = ((2.65-f["RHOB"])/(2.65-1.0)).clip(0,0.45)
    f["PHI_N"]  = f["NPHI"].clip(0,0.45)
    f["PHI_AVG"]= (f["PHI_D"]+f["PHI_N"])/2
    f["PHI_EFF"]= (f["PHI_AVG"]*(1-f["VCL"])).clip(0,0.45)
    f["NPHI_RHOB_DIFF"] = f["NPHI_N"]-f["RHOB_N"]
    f["GR_RT_RATIO"]    = f["GR_N"]/(f["RT_LOG"]+2)
    import warnings; warnings.filterwarnings("ignore")
    Ro = 0.05/np.power(np.where(f["PHI_EFF"]>0,f["PHI_EFF"],np.nan),2)
    f["SW"] = np.clip(np.sqrt(Ro/f["RT"].clip(0.01)),0,1)
    FCOLS = ["GR_N","RHOB_N","NPHI_N","RT_LOG","VCL","PHI_D","PHI_N","PHI_AVG","PHI_EFF","NPHI_RHOB_DIFF","GR_RT_RATIO","SW"]
    X = imputer.transform(f[FCOLS].values)
    probs = model.predict_proba(X)
    preds = le.inverse_transform(model.predict(X))
    conf  = probs.max(axis=1)
    return preds, conf