correction et avancement sur le rapport
This commit is contained in:
@@ -1,20 +1,128 @@
|
||||
import os
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
data = np.loadtxt("rabbits.csv", delimiter=",", skiprows=1, usecols=(0, 1))
|
||||
month, total = data[:, 0], data[:, 1]
|
||||
OUT = os.path.join("repport", "images")
|
||||
os.makedirs(OUT, exist_ok=True)
|
||||
|
||||
# Supprime l'ancienne figure règle 3 si elle existe encore
|
||||
STALE = os.path.join(OUT, "regle3_vieillissement.png")
|
||||
if os.path.exists(STALE):
|
||||
os.remove(STALE)
|
||||
print(f"Ancien fichier supprimé : {STALE}")
|
||||
|
||||
def save_fig(fig, name):
|
||||
path = os.path.join(OUT, f"{name}.png")
|
||||
fig.savefig(path, dpi=300, bbox_inches="tight")
|
||||
plt.close(fig)
|
||||
print(f"OK -> {path}")
|
||||
|
||||
# --- Chargement ---
|
||||
df = pd.read_csv("rabbits.csv", skipinitialspace=True)
|
||||
df.columns = df.columns.str.strip()
|
||||
df = df.loc[:, ~df.columns.str.startswith("Unnamed")]
|
||||
cols = df.columns.drop("Month")
|
||||
df[cols] = df[cols].astype("float64") # effectifs > int64 max
|
||||
|
||||
m = df["Month"].values.astype(int)
|
||||
litters = df["Litters"].values
|
||||
births = (df["Kitten Male (age 1)"] + df["Kitten Female (age 1)"]).values
|
||||
adult_1 = (df["Male (age 1)"] + df["Female (age 1)"]).values
|
||||
adult_f = df.filter(regex=r"^Female \(age").sum(axis=1).values
|
||||
|
||||
km = df[[f"Kitten Male (age {i})" for i in range(1, 9)]].values
|
||||
kf = df[[f"Kitten Female (age {i})" for i in range(1, 9)]].values
|
||||
kit = km + kf # (N, 8), âges en mois
|
||||
|
||||
# Buckets adultes etanches (age 1 exclu : il recoit la maturation), ages 2..16 ans
|
||||
ages = list(range(2, 17))
|
||||
ad = df[[f"Male (age {i})" for i in ages] +
|
||||
[f"Female (age {i})" for i in ages]].values # (N, 30)
|
||||
|
||||
# --- Controle d'integrite : saut du ratio naissances/portees ? ---
|
||||
ratio_g = births[1:] / np.maximum(litters[:-1], 1)
|
||||
jumps = np.where(np.abs(np.diff(ratio_g)) > 0.75)[0]
|
||||
if jumps.size:
|
||||
print(f"⚠️ CSV incoherent : le ratio naissances/portees saute autour du mois "
|
||||
f"{m[jumps[0] + 1]} — verifie le regime de gestation !")
|
||||
|
||||
# === Regle 1 : gestation a 50 %/mois ===
|
||||
fig, ax = plt.subplots(figsize=(9, 5))
|
||||
ax.plot(month, total, lw=2, color="tab:blue")
|
||||
ax.plot(m, litters / np.maximum(adult_f, 1), lw=1, color="tab:blue")
|
||||
ax.axhline(0.5, color="red", ls="--", label="attendu : 0.50")
|
||||
ax.set_ylim(0, 1)
|
||||
ax.set_xlabel("Mois"); ax.set_ylabel("Litters / femelles adultes")
|
||||
ax.set_title("Règle 1 — Taux de gestation"); ax.legend(); ax.grid(alpha=0.3)
|
||||
fig.tight_layout(); save_fig(fig, "regle1_gestation")
|
||||
|
||||
# === Regle 2 : 3 a 6 bebes par gestation ===
|
||||
fig, ax = plt.subplots(figsize=(9, 5))
|
||||
ax.plot(m[1:], ratio_g, lw=1, color="tab:purple")
|
||||
ax.axhspan(3, 6, color="green", alpha=0.15, label="zone [3, 6]")
|
||||
ax.axhline(4.5, color="red", ls="--", label="moyenne uniforme : 4.5")
|
||||
ax.set_ylim(0, 8)
|
||||
ax.set_xlabel("Mois"); ax.set_ylabel("Nouveaux-nés / portée")
|
||||
ax.set_title("Règle 2 — Bébés par gestation"); ax.legend(); ax.grid(alpha=0.3)
|
||||
fig.tight_layout(); save_fig(fig, "regle2_portees")
|
||||
|
||||
# === Regle 2bis : distribution des portees ===
|
||||
fig, ax = plt.subplots(figsize=(9, 5))
|
||||
valid = ratio_g[(ratio_g > 1) & (ratio_g < 12)]
|
||||
ax.hist(valid, bins=60, color="tab:purple", alpha=0.8)
|
||||
ax.axvline(4.5, color="red", ls="--", label="4.5 attendu")
|
||||
ax.set_xlabel("Bébés / portée"); ax.set_ylabel("Occurrences")
|
||||
ax.set_title("Règle 2 — Distribution des portées"); ax.legend(); ax.grid(alpha=0.3)
|
||||
fig.tight_layout(); save_fig(fig, "regle2_distribution")
|
||||
|
||||
# === Regle 3 : maturation 5-8 mois (mesure seule, sans prediction) ===
|
||||
fig, ax = plt.subplots(figsize=(9, 5))
|
||||
ok3 = (m % 12 != 1) & (m >= 14) & (adult_1 > 100)
|
||||
ax.plot(m[ok3], adult_1[ok3], lw=1.5, color="tab:green", label="Adultes âge 1 (mesuré)")
|
||||
ax.set_yscale("log")
|
||||
ax.set_xlim(0, month.max())
|
||||
ax.set_ylim(10, total.max() * 3)
|
||||
ax.set_xticks(np.arange(0, month.max() + 1, 24))
|
||||
ax.grid(True, which="both", axis="y", alpha=0.3)
|
||||
ax.set_xlabel("Month")
|
||||
ax.set_ylabel("Total rabbits (log)")
|
||||
ax.set_title("Simulation Rabbit — population totale")
|
||||
ax.set_xlabel("Mois"); ax.set_ylabel("Effectifs (log)")
|
||||
ax.set_title("Règle 3 — Maturation entre 5 et 8 mois"); ax.legend(); ax.grid(alpha=0.3)
|
||||
fig.tight_layout(); save_fig(fig, "regle3_maturation")
|
||||
|
||||
fig.tight_layout()
|
||||
plt.show()
|
||||
# === Regle 5 : survie des kittens ~95 %/mois ===
|
||||
fig, ax = plt.subplots(figsize=(9, 5))
|
||||
surv = kit[1:, 1:] / np.maximum(kit[:-1, :-1], 1) # (N-1, 7)
|
||||
mask = kit[:-1, :-1] > 100 # (N-1, 7)
|
||||
xs = np.repeat(m[1:, None], 7, axis=1) # (N-1, 7)
|
||||
ax.plot(xs[mask], surv[mask], ".", ms=2, alpha=0.2, color="tab:cyan")
|
||||
ax.axhline(0.95, color="red", ls="--", label="attendu : 0.95")
|
||||
ax.set_ylim(0.8, 1.05)
|
||||
ax.set_xlabel("Mois"); ax.set_ylabel("Taux de survie mensuel")
|
||||
ax.set_title("Règle 5 — Survie des kittens (5 %/mois)"); ax.legend(); ax.grid(alpha=0.3)
|
||||
fig.tight_layout(); save_fig(fig, "regle5_survie_kittens")
|
||||
|
||||
# === Regle 4 : mortalite adultes — 40 %/an, +10 pts/an apres 10 ans ===
|
||||
trans1 = (m[1:] % 12 == 1) # (N-1,) : mois cible = bascule
|
||||
s_reg = ad[1:] / np.maximum(ad[:-1], 1) # (N-1, 30) mois reguliers
|
||||
s_diag = np.full_like(s_reg, np.nan)
|
||||
s_diag[trans1, 1:] = ad[1:][trans1, 1:] / np.maximum(ad[:-1][trans1, :-1], 1)
|
||||
s_meas = np.where(trans1[:, None], s_diag, s_reg) # (N-1, 30)
|
||||
|
||||
d_annuel = np.array([0.40 + 0.10 * max(0, a - 10) for a in ages])
|
||||
s_attendu = 1 - d_annuel / 12
|
||||
|
||||
fig, ax = plt.subplots(figsize=(10, 5.5))
|
||||
for j, a in enumerate(ages):
|
||||
ok = (ad[:-1, j] > 100) & ~np.isnan(s_meas[:, j]) & \
|
||||
(s_meas[:, j] > 0.5) & (s_meas[:, j] < 1.02)
|
||||
ax.plot(m[1:][ok], s_meas[ok, j], ".", ms=2.5, alpha=0.45, label=f"âge {a} ans")
|
||||
for a, s in zip(ages, s_attendu):
|
||||
ax.axhline(s, color="black", ls=":", lw=0.7, alpha=0.6)
|
||||
ax.text(1.01, s, f"{s:.4f}", transform=ax.get_yaxis_transform(),
|
||||
va="center", fontsize=7, color="black")
|
||||
ax.set_ylim(0.88, 1.0)
|
||||
ax.set_xlabel("Mois"); ax.set_ylabel("Taux de survie mensuel par bucket d'âge")
|
||||
ax.set_title("Règle 4 — 40 %/an jusqu'à 10 ans, +10 pts/an ensuite (appliqué /12 par mois)")
|
||||
ax.legend(ncol=2, fontsize=8, loc="lower left"); ax.grid(alpha=0.3)
|
||||
fig.tight_layout(); save_fig(fig, "regle4_mortalite_adultes")
|
||||
|
||||
print("\nTaux de survie mensuels attendus (règle 4) :")
|
||||
for a, d, s in zip(ages, d_annuel, s_attendu):
|
||||
print(f" âge {a:2d} ans : {100*d:5.1f} %/an -> survie mensuelle {s:.5f}")
|
||||
|
||||
print("\nToutes les images sont dans", OUT)
|
||||
Reference in New Issue
Block a user