Migue1804 commited on
Commit
abb123d
·
verified ·
1 Parent(s): 86cb0d4

Upload 6 files

Browse files
Files changed (6) hide show
  1. CBD extraction process.png +0 -0
  2. app.py +439 -0
  3. cannabis.jpg +0 -0
  4. data_exp.csv +28 -0
  5. data_process.csv +20 -0
  6. requirements.txt +5 -0
CBD extraction process.png ADDED
app.py ADDED
@@ -0,0 +1,439 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ import numpy as np
4
+ import plotly.graph_objects as go
5
+ from scipy.optimize import minimize, differential_evolution
6
+ from sklearn.preprocessing import PolynomialFeatures
7
+ from sklearn.linear_model import LinearRegression
8
+ from sklearn.metrics import mean_squared_error, r2_score
9
+ import matplotlib.pyplot as plt
10
+ import seaborn as sns
11
+ import io
12
+ # Configuración inicial
13
+ # Configuración de la aplicación
14
+ st.set_page_config(page_title="Optimización Avanzada", page_icon="📊",layout="wide")
15
+ # Display the image above the title
16
+ st.image('cannabis.jpg')
17
+ st.title("Optimización Avanzada con Diseño Experimental Box-Behnken")
18
+ st.write("Aplicación con regresión cuadrática y estrategias de optimización mejoradas.")
19
+
20
+ # Crear las pestañas
21
+ tabs = st.selectbox("Selecciona una opción", ["Fundamento Teórico", "Aplicación Interactiva"])
22
+
23
+ if tabs == "Fundamento Teórico":
24
+ st.header("Fundamento Teórico")
25
+
26
+ # Imagen del proceso
27
+ st.subheader("Proceso de Extracción de CBD")
28
+ st.image("CBD extraction process.png", caption="Proceso de Extracción de CBD con CO2 Supercrítico", use_column_width=True)
29
+ st.write("""
30
+ El proceso de extracción de CBD utiliza tecnología de CO2 supercrítico debido a su eficiencia y capacidad para producir extractos puros. Este método incluye etapas clave como molienda, extracción, separación y refinamiento, garantizando un producto de alta calidad para aplicaciones medicinales y comerciales.
31
+ """)
32
+
33
+ # Diseño Experimental Box-Behnken
34
+ st.subheader("Diseño Experimental Box-Behnken")
35
+ st.write("""
36
+ El diseño experimental **Box-Behnken** se utiliza para modelar y optimizar procesos complejos. En este caso, se aplica para maximizar el rendimiento de CBD considerando variables clave como **Temperatura**, **Presión**, **Flujo de CO2** y **Tiempo**.
37
+ Este enfoque reduce significativamente la cantidad de experimentos necesarios, permitiendo explorar interacciones no lineales de manera eficiente.
38
+ """)
39
+
40
+ # Proceso de Producción de CBD
41
+ st.subheader("Proceso de Producción de CBD")
42
+ st.write("""
43
+ Según el documento *Optimization of Supercritical Carbon Dioxide Fluid Extraction of Medicinal Cannabis from Quebec*, el proceso de extracción con CO2 supercrítico es preferido por su alta selectividad y pureza. Las principales etapas incluyen:
44
+ 1. **Preparación de la materia prima**: Molienda y acondicionamiento.
45
+ 2. **Extracción supercrítica**:
46
+ - El CO2 actúa como solvente bajo condiciones controladas de presión y temperatura.
47
+ - Variables clave: presión (150-320 bar), temperatura (40-70°C), flujo de CO2 (5-15 g/min), tiempo (2-4 horas).
48
+ 3. **Separación y recolección**: El CO2 se despresuriza para liberar los cannabinoides extraídos.
49
+ 4. **Refinamiento posterior**: Remoción de ceras y otros compuestos no deseados.
50
+ """)
51
+
52
+ # Caso de Negocio
53
+ st.subheader("Caso de Negocio: Optimización del Rendimiento")
54
+ st.write("""
55
+ Optimizar el rendimiento del proceso de extracción permite:
56
+ - Maximizar la cantidad de CBD extraído por lote.
57
+ - Reducir costos operativos (energía, solventes, tiempo).
58
+ - Mejorar la calidad del producto final.
59
+
60
+ Este enfoque es crucial en la industria del cannabis medicinal, donde la eficiencia del proceso impacta directamente en la rentabilidad y sostenibilidad del negocio.
61
+ """)
62
+
63
+ # Método Basado en CRISP-DM
64
+ st.subheader("Metodología Basada en CRISP-DM")
65
+ st.write("""
66
+ La metodología **CRISP-DM** estructura el desarrollo del modelo en seis etapas:
67
+ 1. **Comprensión del Negocio**: Definir objetivos y restricciones del proceso.
68
+ 2. **Comprensión de los Datos**: Analizar datos experimentales y evaluar su calidad.
69
+ 3. **Preparación de los Datos**: Limpiar y transformar datos para el modelado.
70
+ 4. **Modelado**: Ajustar un modelo de regresión cuadrática para capturar relaciones no lineales.
71
+ 5. **Evaluación**: Validar el modelo y analizar su desempeño.
72
+ 6. **Despliegue**: Implementar el modelo en una aplicación interactiva para optimización en tiempo real.
73
+ """)
74
+
75
+ # Optimización
76
+ st.subheader("Optimización")
77
+ st.write("""
78
+ Se emplean técnicas avanzadas para maximizar el rendimiento:
79
+ - **L-BFGS-B**: Método de optimización local.
80
+ - **Evolución Diferencial**: Optimización global para evitar óptimos locales.
81
+ - **Múltiples inicios aleatorios**: Combina estrategias locales y globales para robustez.
82
+ """)
83
+
84
+ # Referencias
85
+ st.subheader("Referencias")
86
+ st.write("""
87
+ - [Optimization of Supercritical Carbon Dioxide Fluid Extraction of Medicinal Cannabis from Quebec](https://www.mdpi.com/2227-9717/11/7/1953).
88
+ - Herrero, M., Cifuentes, A., & Ibañez, E. (2006). Supercritical fluid extraction: Recent advances and applications. *Journal of Chromatography A*, 1131(1), 1–24.
89
+ - Turner, C., Mathiasson, L., & Lewis, G. (2001). Supercritical fluid extraction and chromatography. *Journal of Biochemical Analysis*, 121(3), 35–58.
90
+ """)
91
+
92
+ elif tabs == "Aplicación Interactiva":
93
+ st.header("Aplicación Interactiva")
94
+ st.write("A continuación, puedes cargar tus datos, realizar predicciones y optimizar el rendimiento del proceso de extracción de cannabinoides.")
95
+
96
+ # Opciones de selección de datos de ejemplo
97
+ st.subheader("Datos de Ejemplo")
98
+ usar_datos_exp = st.checkbox("Usar datos de ejemplo: datos_exp.csv")
99
+ usar_datos_process = st.checkbox("Usar datos de ejemplo: datos_process.csv")
100
+
101
+ # Inicializar variable de datos
102
+ data = None
103
+
104
+ # Verificar qué checkbox está seleccionado y cargar el archivo correspondiente
105
+ if usar_datos_exp and not usar_datos_process:
106
+ data = pd.read_csv("data_exp.csv")
107
+ st.success("Datos de ejemplo (datos_exp.csv) cargados exitosamente.")
108
+ st.dataframe(data, use_container_width=True) # Ajustar al ancho de la app
109
+ elif usar_datos_process and not usar_datos_exp:
110
+ data = pd.read_csv("data_process.csv")
111
+ st.success("Datos de ejemplo (datos_process.csv) cargados exitosamente.")
112
+ st.dataframe(data, use_container_width=True) # Ajustar al ancho de la app
113
+ elif usar_datos_exp and usar_datos_process:
114
+ st.error("Por favor, selecciona solo un conjunto de datos de ejemplo a la vez.")
115
+
116
+ # Opción para cargar datos personalizados
117
+ st.subheader("Carga tus Datos")
118
+ uploaded_file = st.file_uploader("Carga un archivo CSV con los datos experimentales:", type="csv")
119
+
120
+ if uploaded_file is not None:
121
+ # Leer datos cargados
122
+ data = pd.read_csv(uploaded_file)
123
+ st.success("Datos cargados exitosamente desde el archivo proporcionado.")
124
+ st.dataframe(data, use_container_width=True) # Ajustar al ancho de la app
125
+
126
+ # Validación para asegurarse de que se cargaron datos
127
+ if data is None:
128
+ st.warning("No se han cargado datos. Por favor, selecciona un archivo o usa datos de ejemplo.")
129
+ else:
130
+ st.write("### Datos listos para su análisis.")
131
+
132
+ # Definir el orden fijo de variables
133
+ variable_columns = ['Temperatura', 'Presión', 'Flujo_CO2', 'Tiempo']
134
+
135
+ # Extraer variables independientes y dependiente en el orden correcto
136
+ X = data[variable_columns]
137
+ y = data['Rendimiento']
138
+
139
+ # Generar términos cuadráticos (regresión polinómica de segundo grado)
140
+ poly = PolynomialFeatures(degree=2, include_bias=False)
141
+ X_poly = poly.fit_transform(X)
142
+ columnas_poly = poly.get_feature_names_out(X.columns)
143
+
144
+ # Ajustar modelo cuadrático
145
+ modelo = LinearRegression()
146
+ modelo.fit(X_poly, y)
147
+
148
+ # Predicciones del modelo
149
+ y_pred = modelo.predict(X_poly)
150
+
151
+ # Evaluación del modelo
152
+ st.subheader("Evaluación del Modelo Cuadrático")
153
+ st.write(f"**Error Cuadrático Medio (MSE):** {mean_squared_error(y, y_pred):.4f}")
154
+ st.write(f"**R² (Coeficiente de Determinación):** {r2_score(y, y_pred):.4f}")
155
+
156
+ # Resumen del modelo: coeficientes
157
+
158
+ # Visualización paralela usando columnas
159
+ col1, col2 = st.columns(2)
160
+
161
+ # En la columna 1, mostrar el DataFrame con términos y coeficientes, adaptado al ancho de la columna
162
+ with col1:
163
+ st.markdown("#### Términos y Coeficientes del Modelo")
164
+
165
+ # Crear un DataFrame con los coeficientes
166
+ coeficientes = pd.DataFrame({
167
+ 'Término': columnas_poly,
168
+ 'Coeficiente': modelo.coef_
169
+ })
170
+
171
+ coeficientes = coeficientes.sort_values(by='Coeficiente', ascending=False)
172
+
173
+ # Función para aplicar colores a los coeficientes
174
+ def color_coef(val):
175
+ color = 'red' if val > 0 else 'blue' # Los coeficientes positivos serán rojos, negativos azules
176
+ return f'background-color: {color}; color: white;'
177
+
178
+ # Aplicar estilo a la columna 'Coeficiente' para colorear los valores
179
+ styled_coef = coeficientes.style.applymap(color_coef, subset=['Coeficiente'])
180
+
181
+ # Mostrar el DataFrame estilizado y ajustado al ancho de la columna
182
+ st.dataframe(styled_coef, use_container_width=True)
183
+
184
+ # En la columna 2, mostrar el gráfico de importancia de las variables, adaptado al ancho de la columna
185
+ with col2:
186
+ st.markdown("#### Importancia de las Variables (Feature Importance)")
187
+
188
+ # Calcular la importancia de las variables (valor absoluto de los coeficientes)
189
+ coef_abs = np.abs(modelo.coef_) # Valor absoluto de los coeficientes
190
+ feature_importance = pd.DataFrame({
191
+ 'Variable': columnas_poly,
192
+ 'Importancia': coef_abs
193
+ }).sort_values(by='Importancia', ascending=False) # De mayor a menor
194
+
195
+ # Gráfico de barras horizontal con el eje Y invertido
196
+ fig_importance = go.Figure(go.Bar(
197
+ y=feature_importance['Variable'],
198
+ x=feature_importance['Importancia'],
199
+ orientation='h',
200
+ marker=dict(color='teal')
201
+ ))
202
+ fig_importance.update_layout(
203
+ title="Importancia de las Variables en el Modelo Cuadrático",
204
+ xaxis_title="Importancia",
205
+ yaxis_title="Variables",
206
+ yaxis=dict(autorange="reversed"), # Invertir el eje Y
207
+ margin=dict(l=0, r=0, t=30, b=30) # Ajustar márgenes
208
+ )
209
+ st.plotly_chart(fig_importance, use_container_width=True)
210
+
211
+ # Superficies de respuesta dinámicas
212
+ st.subheader("Superficies de Respuesta")
213
+
214
+ # Selector de variables
215
+ eje_x = st.selectbox("Selecciona la variable para el eje X:", variable_columns, index=0)
216
+ eje_z = st.selectbox("Selecciona la variable para el eje Z:", variable_columns, index=1)
217
+
218
+ # Rango para generar puntos
219
+ x_range = np.linspace(X[eje_x].min(), X[eje_x].max(), 50)
220
+ z_range = np.linspace(X[eje_z].min(), X[eje_z].max(), 50)
221
+ X_grid, Z_grid = np.meshgrid(x_range, z_range)
222
+
223
+ # Preparar valores para las otras dos variables
224
+ otras_variables = [col for col in variable_columns if col not in [eje_x, eje_z]]
225
+
226
+ # Crear grilla de predicción con orden de columnas fijo
227
+ grid_data = []
228
+ for x_val, z_val in zip(X_grid.ravel(), Z_grid.ravel()):
229
+ # Crear un diccionario con todas las variables en el orden correcto
230
+ row_data = dict(zip(variable_columns, [
231
+ x_val if eje_x == 'Temperatura' else X['Temperatura'].mean(),
232
+ x_val if eje_x == 'Presión' else (z_val if eje_z == 'Presión' else X['Presión'].mean()),
233
+ x_val if eje_x == 'Flujo_CO2' else (z_val if eje_z == 'Flujo_CO2' else X['Flujo_CO2'].mean()),
234
+ x_val if eje_x == 'Tiempo' else (z_val if eje_z == 'Tiempo' else X['Tiempo'].mean())
235
+ ]))
236
+ grid_data.append(row_data)
237
+
238
+ # Convertir a DataFrame con orden de columnas fijo
239
+ grid_df = pd.DataFrame(grid_data)[variable_columns]
240
+
241
+ # Transformar datos para predicciones
242
+ grid_poly = poly.transform(grid_df)
243
+
244
+ # Predecir valores
245
+ Y_grid = modelo.predict(grid_poly).reshape(X_grid.shape)
246
+
247
+ # Gráfico dinámico con Plotly
248
+ fig = go.Figure(data=[go.Surface(z=Y_grid, x=X_grid, y=Z_grid, colorscale='Viridis')])
249
+ fig.update_layout(
250
+ title=f"Superficie de Respuesta: {eje_x} vs {eje_z} vs Rendimiento",
251
+ scene=dict(
252
+ xaxis_title=eje_x,
253
+ yaxis_title=eje_z,
254
+ zaxis_title="Rendimiento (%)"
255
+ )
256
+ )
257
+ st.plotly_chart(fig, use_container_width=True)
258
+
259
+ # Análisis de sensibilidad
260
+ st.subheader("Análisis de Sensibilidad")
261
+ temp = st.slider("Temperatura (°C)", int(X['Temperatura'].min()), int(X['Temperatura'].max()), int(X['Temperatura'].mean()))
262
+ pres = st.slider("Presión (Bar)", int(X['Presión'].min()), int(X['Presión'].max()), int(X['Presión'].mean()))
263
+ flujo = st.slider("Flujo CO2 (g/min)", int(X['Flujo_CO2'].min()), int(X['Flujo_CO2'].max()), int(X['Flujo_CO2'].mean()))
264
+ tiempo = st.slider("Tiempo (h)", int(X['Tiempo'].min()), int(X['Tiempo'].max()), int(X['Tiempo'].mean()))
265
+
266
+ # Predicción para los valores seleccionados
267
+ entrada_sensibilidad = pd.DataFrame({'Temperatura': [temp], 'Presión': [pres], 'Flujo_CO2': [flujo], 'Tiempo': [tiempo]})
268
+ entrada_poly = poly.transform(entrada_sensibilidad)
269
+ prediccion = modelo.predict(entrada_poly)
270
+ st.write(f"**Rendimiento Predicho:** {prediccion[0]:.2f}%")
271
+
272
+ # Optimización de puntos mejorada
273
+ st.subheader("Determinación de Puntos Óptimos")
274
+ def objetivo(params):
275
+ """Función objetivo para optimización."""
276
+ # Transformar parámetros a DataFrame
277
+ entrada = pd.DataFrame([params], columns=variable_columns)
278
+ entrada_poly = poly.transform(entrada)
279
+ return -modelo.predict(entrada_poly)[0] # Negativo para maximizar
280
+
281
+ # Métodos de Optimización
282
+ st.write("#### Comparación de Métodos de Optimización")
283
+
284
+ # Límites de las variables
285
+ limites = [(X[col].min(), X[col].max()) for col in variable_columns]
286
+
287
+ # 1. Optimización por L-BFGS-B (Método Local)
288
+ #st.write("##### Método L-BFGS-B (Optimización Local)")
289
+ x0 = [X[col].mean() for col in variable_columns]
290
+ resultado_lbfgs = minimize(
291
+ objetivo,
292
+ x0=x0,
293
+ bounds=limites,
294
+ method='L-BFGS-B'
295
+ )
296
+
297
+ # 2. Evolución Diferencial (Método Global)
298
+ #st.write("##### Evolución Diferencial (Optimización Global)")
299
+ resultado_de = differential_evolution(
300
+ objetivo,
301
+ bounds=limites,
302
+ strategy='best1bin',
303
+ popsize=15,
304
+ maxiter=100
305
+ )
306
+
307
+ # 3. Múltiples Inicios Aleatorios
308
+ #st.write("##### Múltiples Inicios Aleatorios")
309
+ def multi_start_optimize(num_starts=10):
310
+ resultados = []
311
+ for _ in range(num_starts):
312
+ # Punto inicial aleatorio
313
+ x0 = [np.random.uniform(low, high) for low, high in limites]
314
+
315
+ resultado = minimize(
316
+ objetivo,
317
+ x0=x0,
318
+ bounds=limites,
319
+ method='L-BFGS-B'
320
+ )
321
+ resultados.append((resultado, -resultado.fun))
322
+
323
+ # Encontrar el mejor resultado
324
+ return max(resultados, key=lambda x: x[1])
325
+
326
+ resultado_multi = multi_start_optimize()
327
+
328
+ # Mostrar resultados de optimización
329
+ metodos = [
330
+ ("L-BFGS-B", resultado_lbfgs, -resultado_lbfgs.fun),
331
+ ("Evolución Diferencial", resultado_de, -resultado_de.fun),
332
+ ("Múltiples Inicios", resultado_multi[0], resultado_multi[1])
333
+ ]
334
+
335
+ # Tabla comparativa de resultados
336
+ resultados_df = pd.DataFrame(columns=variable_columns + ['Rendimiento Predicho'])
337
+ for nombre, resultado, rendimiento in metodos:
338
+ if resultado.success:
339
+ fila = pd.DataFrame([list(resultado.x) + [rendimiento]],
340
+ columns=variable_columns + ['Rendimiento Predicho'])
341
+ fila.insert(0, 'Método', nombre)
342
+ resultados_df = pd.concat([resultados_df, fila], ignore_index=True)
343
+
344
+ # Mostrar tabla de resultados
345
+ #st.write("### Comparación de Resultados de Optimización")
346
+ st.dataframe(resultados_df)
347
+
348
+ # Seleccionar el mejor resultado
349
+ mejor_resultado = resultados_df.loc[resultados_df['Rendimiento Predicho'].idxmax()]
350
+ st.write("### Punto Óptimo Recomendado")
351
+ st.write(f"**Método:** {mejor_resultado['Método']}")
352
+
353
+ # Mostrar detalles del mejor punto
354
+ detalles_optimos = mejor_resultado[variable_columns].to_dict()
355
+ detalles_str = ", ".join([f"{col}: {val:.2f}" for col, val in detalles_optimos.items()])
356
+ st.write(f"**Punto Óptimo:** {detalles_str}")
357
+ st.write(f"**Rendimiento Máximo Predicho:** {mejor_resultado['Rendimiento Predicho']:.2f}%")
358
+
359
+ # Análisis de Incertidumbre
360
+ st.subheader("Análisis de Incertidumbre")
361
+
362
+ # Input para número de bootstraps
363
+ num_bootstraps = st.number_input(
364
+ "Número de Bootstraps",
365
+ min_value=10,
366
+ max_value=1000,
367
+ value=100,
368
+ step=10,
369
+ help="Número de remuestreos para el análisis de incertidumbre"
370
+ )
371
+
372
+ # Botón para realizar análisis de incertidumbre
373
+ if st.button("Realizar Análisis de Incertidumbre"):
374
+ with st.spinner('Realizando análisis de bootstrapping...'):
375
+ # Bootstrap para estimar intervalos de confianza
376
+ def bootstrap_optimize(num_bootstraps=num_bootstraps):
377
+ resultados_bootstrap = []
378
+
379
+ for _ in range(num_bootstraps):
380
+ # Muestreo con reemplazo
381
+ indices = np.random.randint(0, len(X), len(X))
382
+ X_boot = X.iloc[indices]
383
+ y_boot = y.iloc[indices]
384
+
385
+ # Ajustar modelo
386
+ poly_boot = PolynomialFeatures(degree=2, include_bias=False)
387
+ X_poly_boot = poly_boot.fit_transform(X_boot)
388
+ modelo_boot = LinearRegression()
389
+ modelo_boot.fit(X_poly_boot, y_boot)
390
+
391
+ # Definir nueva función objetivo
392
+ def objetivo_boot(params):
393
+ entrada = pd.DataFrame([params], columns=variable_columns)
394
+ entrada_poly = poly_boot.transform(entrada)
395
+ return -modelo_boot.predict(entrada_poly)[0]
396
+
397
+ # Optimizar
398
+ resultado = differential_evolution(
399
+ objetivo_boot,
400
+ bounds=limites,
401
+ strategy='best1bin',
402
+ popsize=15,
403
+ maxiter=100
404
+ )
405
+
406
+ resultados_bootstrap.append({
407
+ 'Punto': resultado.x,
408
+ 'Rendimiento': -resultado.fun
409
+ })
410
+
411
+ return resultados_bootstrap
412
+
413
+ # Realizar bootstrap
414
+ resultados_bootstrap = bootstrap_optimize()
415
+
416
+ # Convertir a DataFrame
417
+ bootstrap_df = pd.DataFrame(resultados_bootstrap)
418
+
419
+ # Calcular intervalos de confianza
420
+ intervalos_confianza = {}
421
+ for i, col in enumerate(variable_columns):
422
+ intervalos_confianza[col] = (
423
+ np.percentile(bootstrap_df['Punto'].apply(lambda x: x[i]), 2.5),
424
+ np.percentile(bootstrap_df['Punto'].apply(lambda x: x[i]), 97.5)
425
+ )
426
+
427
+ # Mostrar intervalos de confianza
428
+ st.write("### Intervalos de Confianza (95%)")
429
+ for col, (min_val, max_val) in intervalos_confianza.items():
430
+ st.write(f"**{col}:** [{min_val:.2f}, {max_val:.2f}]")
431
+
432
+ # Distribución de rendimientos
433
+ st.write("### Distribución de Rendimientos en Bootstrap")
434
+ fig_bootstrap = plt.figure(figsize=(10, 6))
435
+ plt.hist(bootstrap_df['Rendimiento'], bins=30, edgecolor='black')
436
+ plt.title(f'Distribución de Rendimientos Predichos (Bootstrap: {num_bootstraps})')
437
+ plt.xlabel('Rendimiento (%)')
438
+ plt.ylabel('Frecuencia')
439
+ st.pyplot(fig_bootstrap)
cannabis.jpg ADDED
data_exp.csv ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Run,Temperatura,Presión,Flujo_CO2,Tiempo,Rendimiento
2
+ 1,40,150,10,3,11.1
3
+ 2,70,150,10,3,18.2
4
+ 3,40,320,10,3,11.6
5
+ 4,70,320,10,3,22.9
6
+ 5,55,235,5,2,7.4
7
+ 6,55,235,15,2,22.7
8
+ 7,55,235,5,4,16.0
9
+ 8,55,235,15,4,25.9
10
+ 9,55,235,10,3,11.3
11
+ 10,40,235,10,2,15.2
12
+ 11,70,320,10,2,18.0
13
+ 12,40,235,10,4,21.1
14
+ 13,70,235,10,4,21.7
15
+ 14,55,150,5,3,12.0
16
+ 15,55,320,5,3,11.0
17
+ 16,55,150,15,3,6.7
18
+ 17,55,320,15,3,19.0
19
+ 18,55,235,10,4,9.3
20
+ 19,40,235,5,3,12.1
21
+ 20,70,235,5,3,8.5
22
+ 21,40,320,15,3,19.5
23
+ 22,70,235,15,3,12.7
24
+ 23,55,150,10,2,2.4
25
+ 24,55,320,10,2,16.2
26
+ 25,55,150,10,4,11.0
27
+ 26,55,320,10,4,24.9
28
+ 27,55,235,10,3,12.2
data_process.csv ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Timestamp,Temperatura,Presión,Flujo_CO2,Tiempo,Rendimiento
2
+ 2023-12-01 08:00:00,54.1,275.3,11.4,3.4,18.7
3
+ 2023-12-01 08:05:00,66.8,262.6,9.8,3.7,22.5
4
+ 2023-12-01 08:10:00,43.6,166.3,12.7,2.5,15.6
5
+ 2023-12-01 08:15:00,44.9,271.4,12.4,2.7,11.2
6
+ 2023-12-01 08:20:00,48.5,292.1,11.6,2.9,7.9
7
+ 2023-12-01 08:25:00,64.1,189.3,12.1,2.6,16.8
8
+ 2023-12-01 08:30:00,44.4,216.8,13.2,2.8,6.7
9
+ 2023-12-01 08:35:00,58.9,174.6,11.8,2.3,14.5
10
+ 2023-12-01 08:40:00,57.8,297.6,13.7,3.5,8.1
11
+ 2023-12-01 08:45:00,48.6,307.2,7.2,3.6,5.3
12
+ 2023-12-01 08:50:00,58.2,159.7,9.6,3.4,23.5
13
+ 2023-12-01 08:55:00,52.9,198.4,11.5,2.9,17.9
14
+ 2023-12-01 09:00:00,42.8,273.2,10.2,3.7,10.3
15
+ 2023-12-01 09:05:00,50.1,312.4,14.9,3.2,19.3
16
+ 2023-12-01 09:10:00,62.9,299.3,14.2,2.7,11.7
17
+ 2023-12-01 09:15:00,67.3,211.2,10.6,3.0,14.1
18
+ 2023-12-01 09:20:00,43.5,177.6,6.1,3.6,12.8
19
+ 2023-12-01 09:25:00,64.4,312.7,6.5,3.2,20.3
20
+ 2023-12-01 09:30:00,44.8,295.1,8.7,3.3,24.6
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ streamlit
2
+ pandas
3
+ numpy
4
+ statsmodels
5
+ plotly