File size: 6,256 Bytes
2de4987
bba1512
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2de4987
bba1512
 
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
import streamlit as st
import pandas as pd
import numpy as np
import plotly.graph_objects as go
from plotly.subplots import make_subplots
from sklearn.ensemble import RandomForestRegressor
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import StandardScaler
import xgboost as xgb
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv1D, Dense, Flatten, Input
import multiprocessing
import joblib

# Page configuration
st.set_page_config(page_title="Well Log Analysis", layout="wide")

# Sidebar for file upload
uploaded_file = st.sidebar.file_uploader("Upload your log.csv file", type=["csv"])

if uploaded_file is not None:
    data = pd.read_csv(uploaded_file).dropna().reset_index(drop=True)
    st.sidebar.success("File uploaded successfully!")
else:
    st.sidebar.warning("Please upload a CSV file.")
    st.stop()

# Page 1: Visualizer
def page_visualizer(data):
    st.title("Well Log Visualizer")
    curve_columns = st.multiselect("Select columns to plot", data.columns, default=data.columns.tolist())
    depth_column = st.selectbox("Select depth column", data.columns, index=0)

    if curve_columns:
        fig = make_subplots(rows=1, cols=len(curve_columns), shared_yaxes=True, subplot_titles=curve_columns)
        for i, col in enumerate(curve_columns, start=1):
            fig.add_trace(go.Scatter(x=data[col], y=data[depth_column], mode='lines', name=col), row=1, col=i)
            fig.update_xaxes(title_text=col, row=1, col=i)
        fig.update_yaxes(autorange='reversed', title_text=depth_column, row=1, col=1)
        fig.update_layout(height=800, width=2000, showlegend=False)
        st.plotly_chart(fig, use_container_width=True)

# Page 2: Trainer
def page_trainer(data):
    st.title("Model Trainer")
    target_column = st.selectbox("Select target column", data.columns, index=0)
    model_type = st.selectbox("Select model type", ["Random Forest", "XGBoost", "Linear Regression", "1D CNN"])

    # Prepare data
    df = data.dropna().reset_index(drop=True)
    features = df.drop(columns=[target_column])
    target = df[target_column].values

    # Train/test split
    split_idx = int(0.8 * len(df))
    X_train, X_test = features.iloc[:split_idx], features.iloc[split_idx:]
    y_train, y_test = target[:split_idx], target[split_idx:]

    if model_type in ["Random Forest", "XGBoost", "Linear Regression"]:
        if model_type == "Random Forest":
            model = RandomForestRegressor(n_estimators=500, n_jobs=-1, random_state=42)
        elif model_type == "XGBoost":
            model = xgb.XGBRegressor(n_estimators=200, n_jobs=-1, random_state=42)
        elif model_type == "Linear Regression":
            model = LinearRegression()

        model.fit(X_train, y_train)
        score = model.score(X_test, y_test)
        st.success(f"{model_type} R^2 Score: {score:.4f}")

        # Save model
        st.session_state.model = model
        st.session_state.is_cnn = False
        st.session_state.features = features
        st.session_state.target_column = target_column

    elif model_type == "1D CNN":
        scaler = StandardScaler()
        X_scaled = scaler.fit_transform(features)
        X = X_scaled.reshape((X_scaled.shape[0], X_scaled.shape[1], 1))

        X_train, X_test = X[:split_idx], X[split_idx:]
        y_train, y_test = y_train, y_test

        model = Sequential([
            Input(shape=(X.shape[1], 1)),
            Conv1D(32, 3, activation='relu'),
            Flatten(),
            Dense(64, activation='relu'),
            Dense(1)
        ])
        model.compile(optimizer='adam', loss='mse', metrics=['mae'])
        model.fit(X_train, y_train, epochs=30, batch_size=16, verbose=0)

        loss, mae = model.evaluate(X_test, y_test, verbose=0)
        st.success(f"1D CNN MAE: {mae:.4f}")

        st.session_state.model = model
        st.session_state.scaler = scaler
        st.session_state.is_cnn = True
        st.session_state.features = features
        st.session_state.target_column = target_column

    # Download model
    if st.button("Download Trained Model"):
        if not st.session_state.get("is_cnn", False):
            joblib.dump(st.session_state.model, "trained_model.pkl")
            with open("trained_model.pkl", "rb") as f:
                st.download_button("Download sklearn model", f, file_name="trained_model.pkl")
        else:
            model.save("cnn_model.h5")
            with open("cnn_model.h5", "rb") as f:
                st.download_button("Download CNN model", f, file_name="cnn_model.h5")

# Page 3: Prediction

def page_prediction(data):
    st.title("Prediction Comparison")
    if 'model' not in st.session_state:
        st.warning("Please train a model first.")
        return

    features = st.session_state.features
    target_column = st.session_state.target_column

    if st.session_state.get("is_cnn", False):
        scaler = st.session_state.scaler
        X_scaled = scaler.transform(features)
        X_input = X_scaled.reshape((X_scaled.shape[0], X_scaled.shape[1], 1))
        predicted = st.session_state.model.predict(X_input).flatten()
    else:
        predicted = st.session_state.model.predict(features)

    data_plot = data.copy()
    data_plot['Predicted'] = predicted
    depth_column = st.selectbox("Select depth column", data.columns, index=0)

    fig = go.Figure()
    fig.add_trace(go.Scatter(x=data_plot[target_column], y=data_plot[depth_column],
                             mode='lines+markers', name='Original'))
    fig.add_trace(go.Scatter(x=data_plot['Predicted'], y=data_plot[depth_column],
                             mode='lines+markers', name='Predicted'))
    fig.update_yaxes(autorange='reversed', title_text=depth_column)
    fig.update_layout(height=600, width=800, title="Original vs Predicted")
    st.plotly_chart(fig, use_container_width=True)

# Main navigation

def main():
    st.sidebar.title("Navigation")
    page = st.sidebar.radio("Go to", ["Visualizer", "Trainer", "Prediction"])

    if page == "Visualizer":
        page_visualizer(data)
    elif page == "Trainer":
        page_trainer(data)
    elif page == "Prediction":
        page_prediction(data)

if __name__ == "__main__":
    main()