Create app.py
Browse files
app.py
ADDED
@@ -0,0 +1,227 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
os.system('pip install gradio seaborn scipy scikit-learn openpyxl pydantic==1.10.0')
|
3 |
+
|
4 |
+
from pydantic import BaseModel, ConfigDict
|
5 |
+
|
6 |
+
class YourModel(BaseModel):
|
7 |
+
class Config:
|
8 |
+
arbitrary_types_allowed = True
|
9 |
+
|
10 |
+
import numpy as np
|
11 |
+
import networkx as nx
|
12 |
+
import matplotlib.pyplot as plt
|
13 |
+
import gradio as gr
|
14 |
+
from sklearn.linear_model import LinearRegression
|
15 |
+
from sklearn.preprocessing import PolynomialFeatures
|
16 |
+
from sklearn.metrics import r2_score
|
17 |
+
from itertools import combinations
|
18 |
+
import tempfile
|
19 |
+
|
20 |
+
# Clase para el modelo de regresi贸n
|
21 |
+
class RegressionModel:
|
22 |
+
def __init__(self, degree=1):
|
23 |
+
self.degree = degree
|
24 |
+
self.model = LinearRegression()
|
25 |
+
self.poly = PolynomialFeatures(degree=degree, include_bias=False)
|
26 |
+
|
27 |
+
def fit(self, X, y):
|
28 |
+
X_poly = self.poly.fit_transform(X)
|
29 |
+
self.model.fit(X_poly, y)
|
30 |
+
|
31 |
+
def predict(self, X):
|
32 |
+
X_poly = self.poly.transform(X)
|
33 |
+
return self.model.predict(X_poly)
|
34 |
+
|
35 |
+
def r2_score(self, X, y):
|
36 |
+
y_pred = self.predict(X)
|
37 |
+
return r2_score(y, y_pred)
|
38 |
+
|
39 |
+
# Clase para el dise帽o experimental
|
40 |
+
class ExperimentalDesign:
|
41 |
+
def __init__(self, regression_degree=1):
|
42 |
+
self.pb_design = None
|
43 |
+
self.bb_design = None
|
44 |
+
self.factor_values = None
|
45 |
+
self.variable1_values = None
|
46 |
+
self.variable2_values = None
|
47 |
+
self.active_factors = None
|
48 |
+
self.regression_degree = regression_degree
|
49 |
+
|
50 |
+
def set_design(self, pb_design, bb_design):
|
51 |
+
self.pb_design = pb_design
|
52 |
+
self.bb_design = bb_design
|
53 |
+
|
54 |
+
def set_factors(self, factor_values):
|
55 |
+
self.factor_values = factor_values
|
56 |
+
|
57 |
+
def set_dependent_variables(self, variable1_values, variable2_values):
|
58 |
+
self.variable1_values = variable1_values
|
59 |
+
self.variable2_values = variable2_values
|
60 |
+
|
61 |
+
def set_active_factors(self, active_factors):
|
62 |
+
self.active_factors = active_factors
|
63 |
+
|
64 |
+
def fit_models(self):
|
65 |
+
active_columns = [i for i, factor in enumerate(self.factor_values.keys()) if factor in self.active_factors]
|
66 |
+
X = self.pb_design[:, active_columns]
|
67 |
+
|
68 |
+
self.model_variable1 = RegressionModel(degree=self.regression_degree)
|
69 |
+
self.model_variable2 = RegressionModel(degree=self.regression_degree)
|
70 |
+
|
71 |
+
self.model_variable1.fit(X, self.variable1_values)
|
72 |
+
self.model_variable2.fit(X, self.variable2_values)
|
73 |
+
|
74 |
+
self.r2_variable1 = self.model_variable1.r2_score(X, self.variable1_values)
|
75 |
+
self.r2_variable2 = self.model_variable2.r2_score(X, self.variable2_values)
|
76 |
+
|
77 |
+
# Clase para el an谩lisis de teor铆a de grafos
|
78 |
+
class GraphTheoryAnalysis:
|
79 |
+
def __init__(self, experiment):
|
80 |
+
self.experiment = experiment
|
81 |
+
self.graph = nx.Graph()
|
82 |
+
self.all_factors = None
|
83 |
+
|
84 |
+
def set_matrices_and_values(self):
|
85 |
+
self.all_factors = list(self.experiment.factor_values.keys())
|
86 |
+
|
87 |
+
def build_graph(self, level=3):
|
88 |
+
if level > len(self.all_factors):
|
89 |
+
level = len(self.all_factors) # Ajustar el nivel al n煤mero de factores disponibles
|
90 |
+
|
91 |
+
for pair in combinations(self.all_factors, level):
|
92 |
+
if len(pair) >= 2: # Asegurarse de que hay suficientes elementos para formar un par
|
93 |
+
self.experiment.set_active_factors(list(pair))
|
94 |
+
self.experiment.fit_models()
|
95 |
+
r2 = (self.experiment.r2_variable1 + self.experiment.r2_variable2) / 2
|
96 |
+
self.graph.add_edge(pair[0], pair[1], weight=r2)
|
97 |
+
|
98 |
+
def visualize_graph(self, style='Style 1'):
|
99 |
+
pos = nx.spring_layout(self.graph)
|
100 |
+
plt.figure(figsize=(10, 8))
|
101 |
+
|
102 |
+
# Estilos para el grafo
|
103 |
+
if style == 'Style 1':
|
104 |
+
node_color = 'lightblue'
|
105 |
+
edge_color = 'gray'
|
106 |
+
node_size = 3000
|
107 |
+
font_size = 12
|
108 |
+
elif style == 'Style 2':
|
109 |
+
node_color = 'lightgreen'
|
110 |
+
edge_color = 'purple'
|
111 |
+
node_size = 2500
|
112 |
+
font_size = 10
|
113 |
+
elif style == 'Style 3':
|
114 |
+
node_color = 'orange'
|
115 |
+
edge_color = 'black'
|
116 |
+
node_size = 3500
|
117 |
+
font_size = 14
|
118 |
+
elif style == 'Style 4':
|
119 |
+
node_color = 'red'
|
120 |
+
edge_color = 'blue'
|
121 |
+
node_size = 2800
|
122 |
+
font_size = 12
|
123 |
+
|
124 |
+
nx.draw_networkx_nodes(self.graph, pos, node_size=node_size, node_color=node_color)
|
125 |
+
nx.draw_networkx_labels(self.graph, pos, font_size=font_size)
|
126 |
+
|
127 |
+
edge_weights = [self.graph[u][v]['weight'] for u, v in self.graph.edges()]
|
128 |
+
nx.draw_networkx_edges(self.graph, pos, width=edge_weights, edge_color=edge_color)
|
129 |
+
|
130 |
+
edge_labels = nx.get_edge_attributes(self.graph, 'weight')
|
131 |
+
nx.draw_networkx_edge_labels(self.graph, pos, edge_labels=edge_labels, font_size=font_size)
|
132 |
+
|
133 |
+
plt.title(f"Grafo de relaciones entre factores basado en R虏 ({style})")
|
134 |
+
plt.axis('off')
|
135 |
+
plt.tight_layout()
|
136 |
+
|
137 |
+
# Guardar la imagen temporalmente usando tempfile
|
138 |
+
temp_file = tempfile.NamedTemporaryFile(suffix=".png", delete=False)
|
139 |
+
plt.savefig(temp_file.name)
|
140 |
+
plt.close()
|
141 |
+
|
142 |
+
return temp_file.name
|
143 |
+
|
144 |
+
# Definici贸n de la interfaz de Gradio
|
145 |
+
def analyze_design(level, pb_design, bb_design, variable1_values, variable2_values, style):
|
146 |
+
experiment = ExperimentalDesign(regression_degree=2)
|
147 |
+
optimizer = GraphTheoryAnalysis(experiment)
|
148 |
+
|
149 |
+
factor_values = {
|
150 |
+
'X1': [1, 5],
|
151 |
+
'X2': [0.05, 0.5],
|
152 |
+
'X3': [0.1, 1],
|
153 |
+
'X4': [0.05, 0.5]
|
154 |
+
}
|
155 |
+
|
156 |
+
experiment.set_design(np.array(pb_design), np.array(bb_design))
|
157 |
+
experiment.set_factors(factor_values)
|
158 |
+
experiment.set_dependent_variables(np.array(variable1_values), np.array(variable2_values))
|
159 |
+
|
160 |
+
optimizer.set_matrices_and_values()
|
161 |
+
optimizer.build_graph(level=level)
|
162 |
+
graph_image_path = optimizer.visualize_graph(style=style)
|
163 |
+
return graph_image_path, bb_design
|
164 |
+
|
165 |
+
# Matriz Plackett-Burman (por defecto)
|
166 |
+
default_pb_design = [
|
167 |
+
[+1, -1, -1, +1],
|
168 |
+
[+1, -1, +1, +1],
|
169 |
+
[+1, +1, -1, -1],
|
170 |
+
[-1, +1, -1, +1],
|
171 |
+
[+1, +1, +1, -1],
|
172 |
+
[-1, +1, +1, -1],
|
173 |
+
[-1, -1, +1, +1],
|
174 |
+
[-1, -1, -1, -1]
|
175 |
+
]
|
176 |
+
|
177 |
+
# Matriz Box-Behnken (por defecto)
|
178 |
+
default_bb_design = [
|
179 |
+
[-1, -1, 0, 0],
|
180 |
+
[1, -1, 0, 0],
|
181 |
+
[-1, 1, 0, 0],
|
182 |
+
[1, 1, 0, 0],
|
183 |
+
[-1, 0, -1, 0],
|
184 |
+
[1, 0, -1, 0],
|
185 |
+
[-1, 0, 1, 0],
|
186 |
+
[1, 0, 1, 0],
|
187 |
+
[-1, 0, 0, -1],
|
188 |
+
[1, 0, 0, -1],
|
189 |
+
[-1, 0, 0, 1],
|
190 |
+
[1, 0, 0, 1],
|
191 |
+
[0, -1, -1, 0],
|
192 |
+
[0, 1, -1, 0],
|
193 |
+
[0, -1, 1, 0],
|
194 |
+
[0, 1, 1, 0],
|
195 |
+
[0, -1, 0, -1],
|
196 |
+
[0, 1, 0, -1],
|
197 |
+
[0, -1, 0, 1],
|
198 |
+
[0, 1, 0, 1],
|
199 |
+
[0, 0, -1, -1],
|
200 |
+
[0, 0, 1, -1],
|
201 |
+
[0, 0, -1, 1],
|
202 |
+
[0, 0, 1, 1],
|
203 |
+
[0, 0, 0, 0]
|
204 |
+
]
|
205 |
+
|
206 |
+
# Valores por defecto para las variables dependientes
|
207 |
+
default_variable1_values = [0.066, 0.061, 0.155, 0.209, 0.158, 0.014, 0.055, 0.007]
|
208 |
+
default_variable2_values = [0.362, 0.856, 0.177, 0.261, 0.946, 0.695, 0.892, 0.084]
|
209 |
+
|
210 |
+
# Interfaz de Gradio
|
211 |
+
interface = gr.Interface(
|
212 |
+
fn=analyze_design,
|
213 |
+
inputs=[
|
214 |
+
gr.Slider(1, 4, step=1, label="Level of Combination (1 to 4)"),
|
215 |
+
gr.Dataframe(headers=["X1", "X2", "X3", "X4"], value=default_pb_design, label="Matrix 1 (Plackett-Burman)"),
|
216 |
+
gr.Dataframe(headers=["X1", "X2", "X3", "X4"], value=default_bb_design, label="Matrix 2 (Box-Behnken)"),
|
217 |
+
gr.Dataframe(headers=["Variable 1"], value=[[val] for val in default_variable1_values], label="Variable 1 Values"),
|
218 |
+
gr.Dataframe(headers=["Variable 2"], value=[[val] for val in default_variable2_values], label="Variable 2 Values"),
|
219 |
+
gr.Dropdown(["Style 1", "Style 2", "Style 3", "Style 4"], label="Graph Style", value="Style 1")
|
220 |
+
],
|
221 |
+
outputs=["image", "dataframe"],
|
222 |
+
title="Graph Theory Analysis for Experimental Design",
|
223 |
+
description="Analyze and visualize the relationships between factors in an experimental design using graph theory."
|
224 |
+
)
|
225 |
+
|
226 |
+
# Ejecutar la interfaz
|
227 |
+
interface.launch(share=True)
|