Soit $M$ : l’évènement malade du Covid (aussi bien contaminé, hospitalisé, réanimation, décès).
Soit $V$: l’évènement vacciné contre le Covid.
Alors on note $P_{\overline{V}}(M)$ la probabilité d’attraper le covid sans vaccin. Un vaccin avec une efficacité $E$ (ex. 95%) signifie que la probabilité $P_V(M)$ d’attraper la maladie vacciné est réduit de 95% par rapport à $P_{\overline{V}}(M)$, comme expliqué ici. Ce qui se traduit par
\begin{array}{rcl}
\frac{P_{\overline{V}}(M)-P_V(M)}{P_{\overline{V}}(M)} & = & E
P_V(M) & = & (1-E)*P_{\overline{V}}(M)
\end{array}
Si une population a $C_v$ % de couverture vaccinale, uniformément répartis dans la société. Alors, on peut noter la probabilité qu’un personne soit vaccinées $P(V) = C_v$, ainsi que $P(\overline{V}) = 1 - C_v$.
Donc si nous voulons $R$ le ratio de gens vaccinés parmis les gens malades:
\[\begin{array}{rcl} R & = & \frac{Nb\ personnes\ vaccinées\ et\ malades}{Nb\ personnes\ malades} \\ R & = & \frac{P(V \cap M)}{P(M)} \\ R & = & \frac{P(V \cap M)}{P(V \cap M) + P(\overline{V} \cap M)} \\ R & = & 1 / \left[ 1 + \frac{P(\overline{V} \cap M)}{P(V \cap M)} \right] \\ R & = & 1 / \left[ 1 + \frac{P(\overline{V}) * P_{\overline{V}}(M)}{P(V) * P_V(M)} \right] \\ R & = & 1 / \left[ 1 + \frac{P(\overline{V}) * P_{\overline{V}}(M)}{P(V) * P_{\overline{V}}(M)*(1-E)} \right] \\ R & = & 1 / \left[ 1 + \frac{P(\overline{V})}{(1-E)*P(V)} \right] \\ R(E, C_v) & = & 1 / \left[ 1 + \frac{1 - C_v}{(1-E)*C_v} \right] \\ E(R, C_v) & = & 1 + \frac{1 - 1/C_v}{1/R - 1} \end{array}\]On peut vérifier le model avec quelques valeurs triviales:
- $\forall C_v, R(E=0, C_v) = C_v$, si le vaccin n’a aucune efficacité, le ratio des nouveaux malades vaccinés est égal au ratio des citoyens vaccinés
- $\forall C_v, R(E \to 1, C_v) \to 0$, si la vaccin est 100% efficace, il n’y a aucun nouveau malade vacciné
- $\forall E, R(E, C_v=1) = 1$, si toute la population est vaccinée, tous les nouveaux malades sont vaccinés
- $\forall E, R(E, C_v \to 0) \to 0$, si personne n’est vacciné, il n’y a aucun nouveau malade vacciné
import numpy as np
import pandas as pd
import plotly.graph_objects as go
from plotly.offline.offline import plot
def E(R, V):
return 1 + (1 - 1 / V) / (1 / R - 1)
fig = fig = go.Figure()
ratio = np.linspace(0.01, 99.99, 10000)
for vacc in range(5, 100, 5):
eff = E(ratio / 100, vacc / 100)
eff[eff < 0] = None
fig.add_trace(go.Scatter(name=f"R(Cv={vacc} %)", x=ratio, y=eff))
fig.update_layout(title="Par de l'efficacité du vaccin en fonction des vaccinés dans les nouveaux malades",
height=800)
fig.update_xaxes(title_text="% des vaccinés malades")
fig.update_yaxes(title_text="Efficacité des vaccins")
#fig.show()
plot(fig, include_plotlyjs=False, include_mathjax=False, output_type='div')
Pays | Date | Couverture | Ratio | Source | Efficacité réelle | Perte d’efficacité |
---|---|---|---|---|---|---|
Israel | Juillet 2021 | 85 % | 45 % | LeMonde | 86 % | 9 % |
France | Juin 2021 | 35 % | 7 % | Gouv | 86 % | 9 % |
France | Décembre 2021 | 70 % | 57 % | Libération | 43 % | 54% |
Belgique | Novembre 2021 | 75 % | 64 % | Lecho.be | 40 % | 58 % |
UK | Octobre 2021 | 68 % | 60 % | Gouv | 35 % | 63 % |
Analyse données de la DREES
https://data.drees.solidarites-sante.gouv.fr/explore/dataset/covid-19-resultats-issus-des-appariements-entre-si-vic-si-dep-et-vac-si/information/?disjunctive.vac_statut
df = pd.read_csv('covid-19-resultats-issus-des-appariements-entre-si-vic-si-dep-et-vac-si.csv', sep=';')
df["HC"].sum(), df["HC_PCR+"].sum()
(61813.09999999999, 45508.88)
df["date"] = pd.to_datetime(df["date"])
df = df[["date", "vac_statut", "HC_PCR+"]]
df.head()
date | vac_statut | HC_PCR+ | |
---|---|---|---|
0 | 2021-05-31 | Non-vaccinés | 214.46 |
1 | 2021-05-31 | Primo dose récente | 12.94 |
2 | 2021-06-01 | Non-vaccinés | 198.54 |
3 | 2021-06-01 | Primo dose efficace | 20.14 |
4 | 2021-06-03 | Non-vaccinés | 154.75 |
On ne garde que les hospitalisations complet avec PCR positif
df["vac_statut"].unique()
array(['Non-vaccinés', 'Primo dose récente', 'Primo dose efficace',
'Complet entre 3 mois et 6 mois - sans rappel',
'Complet de moins de 3 mois - avec rappel',
'Complet de moins de 3 mois - sans rappel',
'Complet entre 3 mois et 6 mois - avec rappel',
'Complet de 6 mois et plus - sans rappel',
'Complet de 6 mois et plus - avec rappel'], dtype=object)
pour les vaccinations sans antécédent de Covid-19 avec vaccins non monodose (hors Janssen) :
- Non vacciné (0) : personne n’ayant jamais reçu d’injection de vaccin contre le Sars-Cov-2
- Primo dose récente (1-) : personne ayant reçu une première dose depuis 14 jours ou moins
- Primo dose efficace (1+) : personne ayant reçu une première dose depuis plus de 14 jours ou ayant reçu une deuxième dose depuis 7 jours ou moins
- Complet (C) : personne ayant reçu une deuxième dose depuis plus de 7 jours
def reduce(statut):
if statut in ["Non-vaccinés", "Primo dose récente", 'Primo dose efficace']:
return 'Non-vaccinés'
else:
return 'Vaccinés'
df['vac_statut'] = df['vac_statut'].apply(reduce)
data = pd.pivot_table(df, index="date", columns="vac_statut", aggfunc=np.sum)["HC_PCR+"]
data
vac_statut | Non-vaccinés | Vaccinés |
---|---|---|
date | ||
2021-05-31 | 254.56 | 36.44 |
2021-06-01 | 232.51 | 32.50 |
2021-06-02 | 244.06 | 42.75 |
2021-06-03 | 177.71 | 32.28 |
2021-06-04 | 224.67 | 24.33 |
... | ... | ... |
2021-12-01 | 283.76 | 343.14 |
2021-12-02 | 310.36 | 329.67 |
2021-12-03 | 312.07 | 335.38 |
2021-12-04 | 245.66 | 274.24 |
2021-12-05 | 215.33 | 243.26 |
189 rows × 2 columns
fig = go.Figure()
for c in data.columns:
fig.add_trace(go.Bar(name=c, x=data.index, y=data[c]))
fig.update_layout(barmode='stack', title="Indice d'hospitalisations chaque jour")
#fig.show()
plot(fig, include_plotlyjs=False, include_mathjax=False, output_type='div')
L’échelle n’est clairement pas le nombre d’hospitalisations. Durant la 4e vague on était à 10 000 hospitalisations par jour. Cela doit être un taux d’incidence…. D’après les estimations il serait pour 300 000 habitants.
data['R'] = data['Vaccinés'] / data.sum(axis=1)
fig = go.Figure()
fig.add_trace(go.Scatter(name=c, x=data.index, y=data['R']))
fig.update_layout(title="Ratio des vaccinés en hospitalisation")
#fig.show()
plot(fig, include_plotlyjs=False, include_mathjax=False, output_type='div')
Une dernière étape, la couverture vaccinale
https://www.data.gouv.fr/fr/datasets/donnees-relatives-aux-personnes-vaccinees-contre-la-covid-19-1/
doses = pd.read_csv('vacsi12-fra-2021-12-16-19h06.csv', sep=";")
doses.tail()
fra | jour | n_dose1 | n_complet | n_rappel | n_cum_dose1 | n_cum_complet | n_cum_rappel | couv_dose1 | couv_complet | couv_rappel | |
---|---|---|---|---|---|---|---|---|---|---|---|
349 | FR | 2021-12-11 | 19439 | 30747 | 477303 | 52292401 | 51193618 | 14329978 | 90.7 | 88.8 | 24.8 |
350 | FR | 2021-12-12 | 5417 | 7172 | 158089 | 52297818 | 51200790 | 14488067 | 90.7 | 88.8 | 25.1 |
351 | FR | 2021-12-13 | 19945 | 30888 | 640845 | 52317763 | 51231678 | 15128912 | 90.7 | 88.8 | 26.2 |
352 | FR | 2021-12-14 | 25762 | 35884 | 834079 | 52343525 | 51267562 | 15962991 | 90.8 | 88.9 | 27.7 |
353 | FR | 2021-12-15 | 26016 | 39710 | 750264 | 52369541 | 51307272 | 16713255 | 90.8 | 89.0 | 29.0 |
doses.index = pd.to_datetime(doses["jour"])
couv = doses["n_complet"].cumsum() / 67400000
rappel = doses["n_rappel"].cumsum() / 67400000
fig = go.Figure()
fig.add_trace(go.Scatter(name="% rappel", x=rappel.index, y=rappel))
fig.add_trace(go.Scatter(name="% couverture", x=couv.index, y=couv))
fig.update_layout(title="Couverture complete")
#fig.show()
plot(fig, include_plotlyjs=False, include_mathjax=False, output_type='div')
On peut regrouper les deux
eff = E(data['R'], couv)
fig = go.Figure()
fig.add_trace(go.Scatter(name="% rappel", x=rappel.index, y=rappel))
fig.add_trace(go.Scatter(name="% couverture", x=couv.index, y=couv))
fig.add_trace(go.Scatter(name="% efficacité vaccin", x=eff.index, y=eff.rolling(window=10).mean()))
fig.add_trace(go.Scatter(name="% vacc hosp", x=data.index, y=data['R'].rolling(window=10).mean()))
fig.update_layout(title="Situation en France")
#fig.show()
plot(fig, include_plotlyjs=False, include_mathjax=False, output_type='div')