Update my_pages/ica.py
Browse files- my_pages/ica.py +64 -56
my_pages/ica.py
CHANGED
|
@@ -3,74 +3,82 @@ import matplotlib.pyplot as plt
|
|
| 3 |
import numpy as np
|
| 4 |
|
| 5 |
def render():
|
| 6 |
-
st.title("
|
| 7 |
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
|
|
|
| 13 |
|
| 14 |
-
#
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 18 |
|
| 19 |
-
#
|
| 20 |
-
|
| 21 |
-
if
|
| 22 |
-
|
| 23 |
-
intentional /= total
|
| 24 |
-
conventional /= total
|
| 25 |
-
arbitrary /= total
|
| 26 |
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
st.session_state.arbitrary = arbitrary
|
| 31 |
|
| 32 |
-
|
| 33 |
-
fig, ax = plt.subplots(figsize=(5, 5))
|
| 34 |
|
| 35 |
-
#
|
| 36 |
-
|
| 37 |
-
|
| 38 |
|
| 39 |
-
#
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
|
|
|
| 43 |
|
| 44 |
-
#
|
| 45 |
-
|
| 46 |
-
|
|
|
|
|
|
|
|
|
|
| 47 |
|
| 48 |
-
#
|
| 49 |
point = (
|
| 50 |
-
|
| 51 |
-
|
|
|
|
| 52 |
)
|
| 53 |
|
| 54 |
-
# Plot
|
| 55 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 56 |
|
| 57 |
-
ax.set_aspect('equal')
|
| 58 |
-
ax.axis('off')
|
| 59 |
st.pyplot(fig)
|
| 60 |
|
| 61 |
-
#
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
("
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
descriptions = {
|
| 70 |
-
"Intentional": "Example: Carefully designed rules.",
|
| 71 |
-
"Conventional": "Example: Following industry standards.",
|
| 72 |
-
"Arbitrary": "Example: Random seeds."
|
| 73 |
-
}
|
| 74 |
-
|
| 75 |
-
st.subheader(f"Dominant property: {dominant}")
|
| 76 |
-
st.write(descriptions[dominant])
|
|
|
|
| 3 |
import numpy as np
|
| 4 |
|
| 5 |
def render():
|
| 6 |
+
st.title("ICA Triangle")
|
| 7 |
|
| 8 |
+
if "weights" not in st.session_state:
|
| 9 |
+
st.session_state.weights = {
|
| 10 |
+
"Intentional": 0.33,
|
| 11 |
+
"Conventional": 0.33,
|
| 12 |
+
"Arbitrary": 0.34
|
| 13 |
+
}
|
| 14 |
|
| 15 |
+
# Which one to adjust
|
| 16 |
+
control_choice = st.radio(
|
| 17 |
+
"Select dimension to adjust",
|
| 18 |
+
["Intentional", "Conventional", "Arbitrary"],
|
| 19 |
+
horizontal=True
|
| 20 |
+
)
|
| 21 |
+
|
| 22 |
+
# Current values
|
| 23 |
+
w = st.session_state.weights
|
| 24 |
+
current_value = w[control_choice]
|
| 25 |
+
|
| 26 |
+
# Slider for selected one
|
| 27 |
+
new_value = st.slider(control_choice, 0.0, 1.0, current_value, 0.01)
|
| 28 |
|
| 29 |
+
# Adjust others proportionally
|
| 30 |
+
diff = new_value - current_value
|
| 31 |
+
others = [k for k in w.keys() if k != control_choice]
|
| 32 |
+
total_other = w[others[0]] + w[others[1]]
|
|
|
|
|
|
|
|
|
|
| 33 |
|
| 34 |
+
if total_other > 0:
|
| 35 |
+
w[others[0]] -= diff * (w[others[0]] / total_other)
|
| 36 |
+
w[others[1]] -= diff * (w[others[1]] / total_other)
|
|
|
|
| 37 |
|
| 38 |
+
w[control_choice] = new_value
|
|
|
|
| 39 |
|
| 40 |
+
# Clamp small floating point errors
|
| 41 |
+
for k in w:
|
| 42 |
+
w[k] = max(0.0, min(1.0, round(w[k], 4)))
|
| 43 |
|
| 44 |
+
# Normalize back to sum=1
|
| 45 |
+
total = sum(w.values())
|
| 46 |
+
if total != 0:
|
| 47 |
+
for k in w:
|
| 48 |
+
w[k] = round(w[k] / total, 4)
|
| 49 |
|
| 50 |
+
# Triangle vertices
|
| 51 |
+
vertices = np.array([
|
| 52 |
+
[0.5, np.sqrt(3)/2], # Intentional
|
| 53 |
+
[0, 0], # Conventional
|
| 54 |
+
[1, 0] # Arbitrary
|
| 55 |
+
])
|
| 56 |
|
| 57 |
+
# Point from barycentric coords
|
| 58 |
point = (
|
| 59 |
+
w["Intentional"] * vertices[0] +
|
| 60 |
+
w["Conventional"] * vertices[1] +
|
| 61 |
+
w["Arbitrary"] * vertices[2]
|
| 62 |
)
|
| 63 |
|
| 64 |
+
# Plot
|
| 65 |
+
fig, ax = plt.subplots()
|
| 66 |
+
ax.plot(*np.append(vertices, [vertices[0]], axis=0).T, 'k-')
|
| 67 |
+
ax.scatter(vertices[:,0], vertices[:,1], c=["blue", "green", "red"], s=100)
|
| 68 |
+
ax.text(*vertices[0], "Intentional", ha="center", va="bottom")
|
| 69 |
+
ax.text(*vertices[1], "Conventional", ha="right", va="top")
|
| 70 |
+
ax.text(*vertices[2], "Arbitrary", ha="left", va="top")
|
| 71 |
+
ax.scatter(point[0], point[1], c="orange", s=200, zorder=5)
|
| 72 |
+
ax.set_aspect("equal")
|
| 73 |
+
ax.axis("off")
|
| 74 |
|
|
|
|
|
|
|
| 75 |
st.pyplot(fig)
|
| 76 |
|
| 77 |
+
# Display interpretation
|
| 78 |
+
closest = max(w.items(), key=lambda x: x[1])[0]
|
| 79 |
+
if closest == "Arbitrary":
|
| 80 |
+
st.info("Example: Random seeds — a truly arbitrary decision.")
|
| 81 |
+
elif closest == "Intentional":
|
| 82 |
+
st.info("Example: Ethical constraints — a fully intentional choice.")
|
| 83 |
+
elif closest == "Conventional":
|
| 84 |
+
st.info("Example: Industry standard preprocessing — a conventional decision.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|