Commit 0b6cab29 authored by Antoine's avatar Antoine

feat: exo5

parent 876ffbbd
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr">
<head>
<!-- 2024-06-11 Tue 16:14 -->
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Analyse du risque de défaillance des joints toriques de la navette Challenger</title>
<meta name="author" content="Antoine Geimer" />
<meta name="generator" content="Org Mode" />
<style>
#content { max-width: 60em; margin: auto; }
.title { text-align: center;
margin-bottom: .2em; }
.subtitle { text-align: center;
font-size: medium;
font-weight: bold;
margin-top:0; }
.todo { font-family: monospace; color: red; }
.done { font-family: monospace; color: green; }
.priority { font-family: monospace; color: orange; }
.tag { background-color: #eee; font-family: monospace;
padding: 2px; font-size: 80%; font-weight: normal; }
.timestamp { color: #bebebe; }
.timestamp-kwd { color: #5f9ea0; }
.org-right { margin-left: auto; margin-right: 0px; text-align: right; }
.org-left { margin-left: 0px; margin-right: auto; text-align: left; }
.org-center { margin-left: auto; margin-right: auto; text-align: center; }
.underline { text-decoration: underline; }
#postamble p, #preamble p { font-size: 90%; margin: .2em; }
p.verse { margin-left: 3%; }
pre {
border: 1px solid #e6e6e6;
border-radius: 3px;
background-color: #f2f2f2;
padding: 8pt;
font-family: monospace;
overflow: auto;
margin: 1.2em;
}
pre.src {
position: relative;
overflow: auto;
}
pre.src:before {
display: none;
position: absolute;
top: -8px;
right: 12px;
padding: 3px;
color: #555;
background-color: #f2f2f299;
}
pre.src:hover:before { display: inline; margin-top: 14px;}
/* Languages per Org manual */
pre.src-asymptote:before { content: 'Asymptote'; }
pre.src-awk:before { content: 'Awk'; }
pre.src-authinfo::before { content: 'Authinfo'; }
pre.src-C:before { content: 'C'; }
/* pre.src-C++ doesn't work in CSS */
pre.src-clojure:before { content: 'Clojure'; }
pre.src-css:before { content: 'CSS'; }
pre.src-D:before { content: 'D'; }
pre.src-ditaa:before { content: 'ditaa'; }
pre.src-dot:before { content: 'Graphviz'; }
pre.src-calc:before { content: 'Emacs Calc'; }
pre.src-emacs-lisp:before { content: 'Emacs Lisp'; }
pre.src-fortran:before { content: 'Fortran'; }
pre.src-gnuplot:before { content: 'gnuplot'; }
pre.src-haskell:before { content: 'Haskell'; }
pre.src-hledger:before { content: 'hledger'; }
pre.src-java:before { content: 'Java'; }
pre.src-js:before { content: 'Javascript'; }
pre.src-latex:before { content: 'LaTeX'; }
pre.src-ledger:before { content: 'Ledger'; }
pre.src-lisp:before { content: 'Lisp'; }
pre.src-lilypond:before { content: 'Lilypond'; }
pre.src-lua:before { content: 'Lua'; }
pre.src-matlab:before { content: 'MATLAB'; }
pre.src-mscgen:before { content: 'Mscgen'; }
pre.src-ocaml:before { content: 'Objective Caml'; }
pre.src-octave:before { content: 'Octave'; }
pre.src-org:before { content: 'Org mode'; }
pre.src-oz:before { content: 'OZ'; }
pre.src-plantuml:before { content: 'Plantuml'; }
pre.src-processing:before { content: 'Processing.js'; }
pre.src-python:before { content: 'Python'; }
pre.src-R:before { content: 'R'; }
pre.src-ruby:before { content: 'Ruby'; }
pre.src-sass:before { content: 'Sass'; }
pre.src-scheme:before { content: 'Scheme'; }
pre.src-screen:before { content: 'Gnu Screen'; }
pre.src-sed:before { content: 'Sed'; }
pre.src-sh:before { content: 'shell'; }
pre.src-sql:before { content: 'SQL'; }
pre.src-sqlite:before { content: 'SQLite'; }
/* additional languages in org.el's org-babel-load-languages alist */
pre.src-forth:before { content: 'Forth'; }
pre.src-io:before { content: 'IO'; }
pre.src-J:before { content: 'J'; }
pre.src-makefile:before { content: 'Makefile'; }
pre.src-maxima:before { content: 'Maxima'; }
pre.src-perl:before { content: 'Perl'; }
pre.src-picolisp:before { content: 'Pico Lisp'; }
pre.src-scala:before { content: 'Scala'; }
pre.src-shell:before { content: 'Shell Script'; }
pre.src-ebnf2ps:before { content: 'ebfn2ps'; }
/* additional language identifiers per "defun org-babel-execute"
in ob-*.el */
pre.src-cpp:before { content: 'C++'; }
pre.src-abc:before { content: 'ABC'; }
pre.src-coq:before { content: 'Coq'; }
pre.src-groovy:before { content: 'Groovy'; }
/* additional language identifiers from org-babel-shell-names in
ob-shell.el: ob-shell is the only babel language using a lambda to put
the execution function name together. */
pre.src-bash:before { content: 'bash'; }
pre.src-csh:before { content: 'csh'; }
pre.src-ash:before { content: 'ash'; }
pre.src-dash:before { content: 'dash'; }
pre.src-ksh:before { content: 'ksh'; }
pre.src-mksh:before { content: 'mksh'; }
pre.src-posh:before { content: 'posh'; }
/* Additional Emacs modes also supported by the LaTeX listings package */
pre.src-ada:before { content: 'Ada'; }
pre.src-asm:before { content: 'Assembler'; }
pre.src-caml:before { content: 'Caml'; }
pre.src-delphi:before { content: 'Delphi'; }
pre.src-html:before { content: 'HTML'; }
pre.src-idl:before { content: 'IDL'; }
pre.src-mercury:before { content: 'Mercury'; }
pre.src-metapost:before { content: 'MetaPost'; }
pre.src-modula-2:before { content: 'Modula-2'; }
pre.src-pascal:before { content: 'Pascal'; }
pre.src-ps:before { content: 'PostScript'; }
pre.src-prolog:before { content: 'Prolog'; }
pre.src-simula:before { content: 'Simula'; }
pre.src-tcl:before { content: 'tcl'; }
pre.src-tex:before { content: 'TeX'; }
pre.src-plain-tex:before { content: 'Plain TeX'; }
pre.src-verilog:before { content: 'Verilog'; }
pre.src-vhdl:before { content: 'VHDL'; }
pre.src-xml:before { content: 'XML'; }
pre.src-nxml:before { content: 'XML'; }
/* add a generic configuration mode; LaTeX export needs an additional
(add-to-list 'org-latex-listings-langs '(conf " ")) in .emacs */
pre.src-conf:before { content: 'Configuration File'; }
table { border-collapse:collapse; }
caption.t-above { caption-side: top; }
caption.t-bottom { caption-side: bottom; }
td, th { vertical-align:top; }
th.org-right { text-align: center; }
th.org-left { text-align: center; }
th.org-center { text-align: center; }
td.org-right { text-align: right; }
td.org-left { text-align: left; }
td.org-center { text-align: center; }
dt { font-weight: bold; }
.footpara { display: inline; }
.footdef { margin-bottom: 1em; }
.figure { padding: 1em; }
.figure p { text-align: center; }
.equation-container {
display: table;
text-align: center;
width: 100%;
}
.equation {
vertical-align: middle;
}
.equation-label {
display: table-cell;
text-align: right;
vertical-align: middle;
}
.inlinetask {
padding: 10px;
border: 2px solid gray;
margin: 10px;
background: #ffffcc;
}
#org-div-home-and-up
{ text-align: right; font-size: 70%; white-space: nowrap; }
textarea { overflow-x: auto; }
.linenr { font-size: smaller }
.code-highlighted { background-color: #ffff00; }
.org-info-js_info-navigation { border-style: none; }
#org-info-js_console-label
{ font-size: 10px; font-weight: bold; white-space: nowrap; }
.org-info-js_search-highlight
{ background-color: #ffff00; color: #000000; font-weight: bold; }
.org-svg { }
</style>
<link rel="stylesheet" type="text/css" href="http://www.pirilampo.org/styles/readtheorg/css/htmlize.css"/>
<link rel="stylesheet" type="text/css" href="http://www.pirilampo.org/styles/readtheorg/css/readtheorg.css"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<script type="text/javascript" src="http://www.pirilampo.org/styles/lib/js/jquery.stickytableheaders.js"></script>
<script type="text/javascript" src="http://www.pirilampo.org/styles/readtheorg/js/readtheorg.js"></script>
<script>
window.MathJax = {
tex: {
ams: {
multlineWidth: '85%'
},
tags: 'ams',
tagSide: 'right',
tagIndent: '.8em'
},
chtml: {
scale: 1.0,
displayAlign: 'center',
displayIndent: '0em'
},
svg: {
scale: 1.0,
displayAlign: 'center',
displayIndent: '0em'
},
output: {
font: 'mathjax-modern',
displayOverflow: 'overflow'
}
};
</script>
<script
id="MathJax-script"
async
src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js">
</script>
</head>
<body>
<div id="content" class="content">
<h1 class="title">Analyse du risque de défaillance des joints toriques de la navette Challenger</h1>
<div id="table-of-contents" role="doc-toc">
<h2>Table des matières</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#org7ebe195">1. Chargement des données</a></li>
<li><a href="#org176bdc5">2. Inspection graphique des données</a></li>
<li><a href="#org48f8c73">3. Estimation de l'influence de la température</a></li>
<li><a href="#orgb68c49c">4. Estimation de la probabilité de dysfonctionnant des joints toriques</a></li>
</ul>
</div>
</div>
<p>
Le 27 Janvier 1986, veille du décollage de la navette <i>Challenger</i>, eu
lieu une télé-conférence de trois heures entre les ingénieurs de la
Morton Thiokol (constructeur d'un des moteurs) et de la NASA. La
discussion portait principalement sur les conséquences de la
température prévue au moment du décollage de 31°F (juste en dessous de
0°C) sur le succès du vol et en particulier sur la performance des
joints toriques utilisés dans les moteurs. En effet, aucun test
n'avait été effectué à cette température.
</p>
<p>
L'étude qui suit reprend donc une partie des analyses effectuées cette
nuit là et dont l'objectif était d'évaluer l'influence potentielle de
la température et de la pression à laquelle sont soumis les joints
toriques sur leur probabilité de dysfonctionnement. Pour cela, nous
disposons des résultats des expériences réalisées par les ingénieurs
de la NASA durant les 6 années précédant le lancement de la navette
Challenger.
</p>
<div id="outline-container-org7ebe195" class="outline-2">
<h2 id="org7ebe195"><span class="section-number-2">1.</span> Chargement des données</h2>
<div class="outline-text-2" id="text-1">
<p>
Nous commençons donc par charger ces données:
</p>
<div class="org-src-container">
<pre class="src src-python"><span style="color: #b877db;">import</span> numpy <span style="color: #b877db;">as</span> np
<span style="color: #b877db;">import</span> pandas <span style="color: #b877db;">as</span> pd
<span style="color: #e95678;">data</span> = pd.read_csv(<span style="color: #fab795;">"shuttle.csv"</span>)
data
</pre>
</div>
<pre class="example" id="org1373721">
Date Count Temperature Pressure Malfunction
0 4/12/81 6 66 50 0
1 11/12/81 6 70 50 1
2 3/22/82 6 69 50 0
3 11/11/82 6 68 50 0
4 4/04/83 6 67 50 0
5 6/18/82 6 72 50 0
6 8/30/83 6 73 100 0
7 11/28/83 6 70 100 0
8 2/03/84 6 57 200 1
9 4/06/84 6 63 200 1
10 8/30/84 6 70 200 1
11 10/05/84 6 78 200 0
12 11/08/84 6 67 200 0
13 1/24/85 6 53 200 2
14 4/12/85 6 67 200 0
15 4/29/85 6 75 200 0
16 6/17/85 6 70 200 0
17 7/29/85 6 81 200 0
18 8/27/85 6 76 200 0
19 10/03/85 6 79 200 0
20 10/30/85 6 75 200 2
21 11/26/85 6 76 200 0
22 1/12/86 6 58 200 1
</pre>
<p>
Le jeu de données nous indique la date de l'essai, le nombre de joints
toriques mesurés (il y en a 6 sur le lançeur principal), la
température (en Fahrenheit) et la pression (en psi), et enfin le
nombre de dysfonctionnements relevés.
</p>
</div>
</div>
<div id="outline-container-org176bdc5" class="outline-2">
<h2 id="org176bdc5"><span class="section-number-2">2.</span> Inspection graphique des données</h2>
<div class="outline-text-2" id="text-2">
<p>
À première vue, ni l'information de pression ni la date nous apporteront des réponses sur la fréquence des incidents. On va donc chercher à filtrer les colonnes restantes en fusionnant les doublons pour la température.
</p>
<div class="org-src-container">
<pre class="src src-python"><span style="color: #e95678;">agg_functions</span> = {<span style="color: #fab795;">'Count'</span>: <span style="color: #fab795;">'sum'</span>, <span style="color: #fab795;">'Malfunction'</span>: <span style="color: #fab795;">'sum'</span>}
<span style="color: #e95678;">data</span> = data[[<span style="color: #fab795;">'Temperature'</span>,<span style="color: #fab795;">'Count'</span>,<span style="color: #fab795;">'Malfunction'</span>]].groupby(<span style="color: #fab795;">'Temperature'</span>, as_index=<span style="color: #f09383;">False</span>).<span style="color: #b877db;">sum</span>()
data
</pre>
</div>
<pre class="example" id="org31507bf">
Temperature Count Malfunction
0 53 6 2
1 57 6 1
2 58 6 1
3 63 6 1
4 66 6 0
5 67 18 0
6 68 6 0
7 69 6 0
8 70 24 2
9 72 6 0
10 73 6 0
11 75 12 2
12 76 12 0
13 78 6 0
14 79 6 0
15 81 6 0
</pre>
<p>
Comment la fréquence d'échecs varie-t-elle avec la température ?
</p>
<div class="org-src-container">
<pre class="src src-python"><span style="color: #b877db;">import</span> matplotlib.pyplot <span style="color: #b877db;">as</span> plt
plt.clf()
<span style="color: #e95678;">data</span>[<span style="color: #fab795;">"Frequency"</span>]=data.Malfunction/data.Count
data.plot(x=<span style="color: #fab795;">"Temperature"</span>,y=<span style="color: #fab795;">"Frequency"</span>,kind=<span style="color: #fab795;">"scatter"</span>,ylim=[0,1])
plt.grid(<span style="color: #f09383;">True</span>)
plt.savefig(matplot_lib_filename)
<span style="color: #b877db;">print</span>(matplot_lib_filename)
</pre>
</div>
<div id="org8d42790" class="figure">
<p><img src="freq_temp_python.png" alt="freq_temp_python.png" />
</p>
</div>
<p>
Contrairement à l'analyse précédente où les températures sans incidents n'étaient pas incluses, on voit ici une augemntation un peu plus nette de la fréquence des incidents à mesure que la température.
</p>
<p>
On peut procéder à une estimation de l'impact de la température \(t\) sur la probabilité de dysfonctionnements d'un joint.
</p>
</div>
</div>
<div id="outline-container-org48f8c73" class="outline-2">
<h2 id="org48f8c73"><span class="section-number-2">3.</span> Estimation de l'influence de la température</h2>
<div class="outline-text-2" id="text-3">
<p>
Supposons que chacun des 6 joints toriques est endommagé avec la même probabilité et indépendamment des autres et que cette probabilité ne dépend que de la température. Si on note \(p(t)\) cette probabilité, le nombre de joints \(D\) dysfonctionnant lorsque l'on effectue le vol à température \(t\) suit une loi binomiale de paramètre \(n=6\) et \(p=p(t)\). Pour relier \(p(t)\) à \(t\), on va donc effectuer une régression logistique.
</p>
<div class="org-src-container">
<pre class="src src-python"><span style="color: #b877db;">import</span> statsmodels.api <span style="color: #b877db;">as</span> sm
<span style="color: #e95678;">data</span>[<span style="color: #fab795;">"Success"</span>]=data.Count-data.Malfunction
<span style="color: #e95678;">data</span>[<span style="color: #fab795;">"Intercept"</span>]=1
<span style="color: #e95678;">logmodel</span>=sm.GLM(data[<span style="color: #fab795;">'Frequency'</span>], data[[<span style="color: #fab795;">'Intercept'</span>,<span style="color: #fab795;">'Temperature'</span>]], family=sm.families.Binomial(sm.families.links.logit())).fit()
logmodel.summary()
</pre>
</div>
<pre class="example" id="org8ddd0b9">
Generalized Linear Model Regression Results
==============================================================================
Dep. Variable: Frequency No. Observations: 16
Model: GLM Df Residuals: 14
Model Family: Binomial Df Model: 1
Link Function: logit Scale: 1.0000
Method: IRLS Log-Likelihood: -2.4880
Date: Tue, 11 Jun 2024 Deviance: 1.1965
Time: 16:14:26 Pearson chi2: 1.82
No. Iterations: 6 Pseudo R-squ. (CS): 0.07675
Covariance Type: nonrobust
===============================================================================
coef std err z P&gt;|z| [0.025 0.975]
-------------------------------------------------------------------------------
Intercept 6.8667 8.822 0.778 0.436 -10.424 24.157
Temperature -0.1458 0.143 -1.023 0.306 -0.425 0.134
===============================================================================
</pre>
<p>
L'estimateur le plus probable du paramètre de température est -0.1458 donc on peut s'attendre à une correlation négative entre la température et la propabilité de dysfonctionnement. L'erreur standard reste plutôt élevée mais le pseudo-R² reste bas, on peut avoir une certaine confiance en nos prédictions.
</p>
</div>
</div>
<div id="outline-container-orgb68c49c" class="outline-2">
<h2 id="orgb68c49c"><span class="section-number-2">4.</span> Estimation de la probabilité de dysfonctionnant des joints toriques</h2>
<div class="outline-text-2" id="text-4">
<p>
La température prévue le jour du décollage est de 31°F. Essayons
d'estimer la probabilité de dysfonctionnement des joints toriques à
cette température à partir du modèle que nous venons de construire:
</p>
<div class="org-src-container">
<pre class="src src-python"><span style="color: #b877db;">import</span> matplotlib.pyplot <span style="color: #b877db;">as</span> plt
<span style="color: #e95678;">data_pred</span> = pd.DataFrame({<span style="color: #fab795;">'Temperature'</span>: np.linspace(start=30, stop=90, num=121), <span style="color: #fab795;">'Intercept'</span>: 1})
<span style="color: #e95678;">data_pred</span>[<span style="color: #fab795;">'Frequency'</span>] = logmodel.predict(data_pred[[<span style="color: #fab795;">'Intercept'</span>,<span style="color: #fab795;">'Temperature'</span>]])
data_pred.plot(x=<span style="color: #fab795;">"Temperature"</span>,y=<span style="color: #fab795;">"Frequency"</span>,kind=<span style="color: #fab795;">"line"</span>,ylim=[0,1])
plt.scatter(x=data[<span style="color: #fab795;">"Temperature"</span>],y=data[<span style="color: #fab795;">"Frequency"</span>])
plt.grid(<span style="color: #f09383;">True</span>)
plt.savefig(matplot_lib_filename)
<span style="color: #b877db;">print</span>(matplot_lib_filename)
</pre>
</div>
<div id="org917ab99" class="figure">
<p><img src="proba_estimate_python.png" alt="proba_estimate_python.png" />
</p>
</div>
<p>
Contrairement à l'analyze précédente, on voit que la température a bien un effet considérable sur la probabilité de dysfonctionnement des joins toriques. Ainsi à 31°F, notre modèle prédit qu'un joint torique à plus de 90% de chances de dysfonctionner.
</p>
<div class="org-src-container">
<pre class="src src-python">data_pred[data_pred.Temperature&lt;=31.0]
</pre>
</div>
<pre class="example">
Temperature Intercept Frequency
0 30.0 1 0.923566
1 30.5 1 0.918258
2 31.0 1 0.912615
</pre>
<p>
La probabilité qu'un joint défaille à cette température est de \(p=0.913\). Sachant qu'il existe un joint primaire un joint secondaire sur chacune des trois parties du lançeur, la probabilité de défaillance des deux joints d'un lançeur est de \(p^2 \approx 0.833569\). La probabilité de défaillance d'un des lançeur est donc de \(1-(1-p^2)^3 \approx 99.5%\). La catastrophe était certaine.
</p>
</div>
</div>
</div>
<div id="postamble" class="status">
<p class="author">Auteur: Antoine Geimer</p>
<p class="date">Created: 2024-06-11 Tue 16:14</p>
<p class="validation"><a href="https://validator.w3.org/check?uri=referer">Validate</a></p>
</div>
</body>
</html>
#+TITLE: Analyse du risque de défaillance des joints toriques de la navette Challenger #+TITLE: Analyse du risque de défaillance des joints toriques de la navette Challenger
#+AUTHOR: Arnaud Legrand #+AUTHOR: Antoine Geimer
#+LANGUAGE: fr #+LANGUAGE: fr
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="http://www.pirilampo.org/styles/readtheorg/css/htmlize.css"/> #+HTML_HEAD: <link rel="stylesheet" type="text/css" href="http://www.pirilampo.org/styles/readtheorg/css/htmlize.css"/>
...@@ -42,30 +42,30 @@ data ...@@ -42,30 +42,30 @@ data
#+RESULTS: #+RESULTS:
#+begin_example #+begin_example
Date Count Temperature Pressure Malfunction Date Count Temperature Pressure Malfunction
0 4/12/81 6 66 50 0 0 4/12/81 6 66 50 0
1 11/12/81 6 70 50 1 1 11/12/81 6 70 50 1
2 3/22/82 6 69 50 0 2 3/22/82 6 69 50 0
3 11/11/82 6 68 50 0 3 11/11/82 6 68 50 0
4 4/04/83 6 67 50 0 4 4/04/83 6 67 50 0
5 6/18/82 6 72 50 0 5 6/18/82 6 72 50 0
6 8/30/83 6 73 100 0 6 8/30/83 6 73 100 0
7 11/28/83 6 70 100 0 7 11/28/83 6 70 100 0
8 2/03/84 6 57 200 1 8 2/03/84 6 57 200 1
9 4/06/84 6 63 200 1 9 4/06/84 6 63 200 1
10 8/30/84 6 70 200 1 10 8/30/84 6 70 200 1
11 10/05/84 6 78 200 0 11 10/05/84 6 78 200 0
12 11/08/84 6 67 200 0 12 11/08/84 6 67 200 0
13 1/24/85 6 53 200 2 13 1/24/85 6 53 200 2
14 4/12/85 6 67 200 0 14 4/12/85 6 67 200 0
15 4/29/85 6 75 200 0 15 4/29/85 6 75 200 0
16 6/17/85 6 70 200 0 16 6/17/85 6 70 200 0
17 7/29/85 6 81 200 0 17 7/29/85 6 81 200 0
18 8/27/85 6 76 200 0 18 8/27/85 6 76 200 0
19 10/03/85 6 79 200 0 19 10/03/85 6 79 200 0
20 10/30/85 6 75 200 2 20 10/30/85 6 75 200 2
21 11/26/85 6 76 200 0 21 11/26/85 6 76 200 0
22 1/12/86 6 58 200 1 22 1/12/86 6 58 200 1
#+end_example #+end_example
Le jeu de données nous indique la date de l'essai, le nombre de joints Le jeu de données nous indique la date de l'essai, le nombre de joints
...@@ -74,29 +74,35 @@ température (en Fahrenheit) et la pression (en psi), et enfin le ...@@ -74,29 +74,35 @@ température (en Fahrenheit) et la pression (en psi), et enfin le
nombre de dysfonctionnements relevés. nombre de dysfonctionnements relevés.
* Inspection graphique des données * Inspection graphique des données
Les vols où aucun incident n'est relevé n'apportant aucune information
sur l'influence de la température ou de la pression sur les À première vue, ni l'information de pression ni la date nous apporteront des réponses sur la fréquence des incidents. On va donc chercher à filtrer les colonnes restantes en fusionnant les doublons pour la température.
dysfonctionnements, nous nous concentrons sur les expériences où au
moins un joint a été défectueux.
#+begin_src python :results value :session *python* :exports both #+begin_src python :results value :session *python* :exports both
data = data[data.Malfunction>0] agg_functions = {'Count': 'sum', 'Malfunction': 'sum'}
data = data[['Temperature','Count','Malfunction']].groupby('Temperature', as_index=False).sum()
data data
#+end_src #+end_src
#+RESULTS: #+RESULTS:
: Date Count Temperature Pressure Malfunction #+begin_example
: 1 11/12/81 6 70 50 1 Temperature Count Malfunction
: 8 2/03/84 6 57 200 1 0 53 6 2
: 9 4/06/84 6 63 200 1 1 57 6 1
: 10 8/30/84 6 70 200 1 2 58 6 1
: 13 1/24/85 6 53 200 2 3 63 6 1
: 20 10/30/85 6 75 200 2 4 66 6 0
: 22 1/12/86 6 58 200 1 5 67 18 0
6 68 6 0
Très bien, nous avons une variabilité de température importante mais 7 69 6 0
la pression est quasiment toujours égale à 200, ce qui devrait 8 70 24 2
simplifier l'analyse. 9 72 6 0
10 73 6 0
11 75 12 2
12 76 12 0
13 78 6 0
14 79 6 0
15 81 6 0
#+end_example
Comment la fréquence d'échecs varie-t-elle avec la température ? Comment la fréquence d'échecs varie-t-elle avec la température ?
#+begin_src python :results output file :var matplot_lib_filename="freq_temp_python.png" :exports both :session *python* #+begin_src python :results output file :var matplot_lib_filename="freq_temp_python.png" :exports both :session *python*
...@@ -114,19 +120,13 @@ print(matplot_lib_filename) ...@@ -114,19 +120,13 @@ print(matplot_lib_filename)
#+RESULTS: #+RESULTS:
[[file:freq_temp_python.png]] [[file:freq_temp_python.png]]
À première vue, ce n'est pas flagrant mais bon, essayons quand même Contrairement à l'analyse précédente où les températures sans incidents n'étaient pas incluses, on voit ici une augemntation un peu plus nette de la fréquence des incidents à mesure que la température.
d'estimer l'impact de la température $t$ sur la probabilité de
dysfonctionnements d'un joint. On peut procéder à une estimation de l'impact de la température $t$ sur la probabilité de dysfonctionnements d'un joint.
* Estimation de l'influence de la température * Estimation de l'influence de la température
Supposons que chacun des 6 joints toriques est endommagé avec la même Supposons que chacun des 6 joints toriques est endommagé avec la même probabilité et indépendamment des autres et que cette probabilité ne dépend que de la température. Si on note $p(t)$ cette probabilité, le nombre de joints $D$ dysfonctionnant lorsque l'on effectue le vol à température $t$ suit une loi binomiale de paramètre $n=6$ et $p=p(t)$. Pour relier $p(t)$ à $t$, on va donc effectuer une régression logistique.
probabilité et indépendamment des autres et que cette probabilité ne
dépend que de la température. Si on note $p(t)$ cette probabilité, le
nombre de joints $D$ dysfonctionnant lorsque l'on effectue le vol à
température $t$ suit une loi binomiale de paramètre $n=6$ et
$p=p(t)$. Pour relier $p(t)$ à $t$, on va donc effectuer une
régression logistique.
#+begin_src python :results value :session *python* :exports both #+begin_src python :results value :session *python* :exports both
import statsmodels.api as sm import statsmodels.api as sm
...@@ -134,9 +134,7 @@ import statsmodels.api as sm ...@@ -134,9 +134,7 @@ import statsmodels.api as sm
data["Success"]=data.Count-data.Malfunction data["Success"]=data.Count-data.Malfunction
data["Intercept"]=1 data["Intercept"]=1
logmodel=sm.GLM(data['Frequency'], data[['Intercept','Temperature']], family=sm.families.Binomial(sm.families.links.logit())).fit()
# logit_model=sm.Logit(data["Frequency"],data[["Intercept","Temperature"]]).fit()
logmodel=sm.GLM(data['Frequency'], data[['Intercept','Temperature']], family=sm.families.Binomial(sm.families.links.logit)).fit()
logmodel.summary() logmodel.summary()
#+end_src #+end_src
...@@ -145,26 +143,25 @@ logmodel.summary() ...@@ -145,26 +143,25 @@ logmodel.summary()
#+begin_example #+begin_example
Generalized Linear Model Regression Results Generalized Linear Model Regression Results
============================================================================== ==============================================================================
Dep. Variable: Frequency No. Observations: 7 Dep. Variable: Frequency No. Observations: 16
Model: GLM Df Residuals: 5 Model: GLM Df Residuals: 14
Model Family: Binomial Df Model: 1 Model Family: Binomial Df Model: 1
Link Function: logit Scale: 1.0 Link Function: logit Scale: 1.0000
Method: IRLS Log-Likelihood: -3.6370 Method: IRLS Log-Likelihood: -2.4880
Date: Fri, 20 Jul 2018 Deviance: 3.3763 Date: Tue, 11 Jun 2024 Deviance: 1.1965
Time: 16:56:08 Pearson chi2: 0.236 Time: 15:04:48 Pearson chi2: 1.82
No. Iterations: 5 No. Iterations: 6 Pseudo R-squ. (CS): 0.07675
Covariance Type: nonrobust
=============================================================================== ===============================================================================
coef std err z P>|z| [0.025 0.975] coef std err z P>|z| [0.025 0.975]
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Intercept -1.3895 7.828 -0.178 0.859 -16.732 13.953 Intercept 6.8667 8.822 0.778 0.436 -10.424 24.157
Temperature 0.0014 0.122 0.012 0.991 -0.238 0.240 Temperature -0.1458 0.143 -1.023 0.306 -0.425 0.134
=============================================================================== ===============================================================================
#+end_example #+end_example
L'estimateur le plus probable du paramètre de température est 0.0014 L'estimateur le plus probable du paramètre de température est -0.1458 donc on peut s'attendre à une correlation négative entre la température et la propabilité de dysfonctionnement. L'erreur standard reste plutôt élevée mais le pseudo-R² reste bas, on peut avoir une certaine confiance en nos prédictions.
et l'erreur standard de cet estimateur est de 0.122, autrement dit on
ne peut pas distinguer d'impact particulier et il faut prendre nos
estimations avec des pincettes.
* Estimation de la probabilité de dysfonctionnant des joints toriques * Estimation de la probabilité de dysfonctionnant des joints toriques
La température prévue le jour du décollage est de 31°F. Essayons La température prévue le jour du décollage est de 31°F. Essayons
...@@ -187,36 +184,16 @@ print(matplot_lib_filename) ...@@ -187,36 +184,16 @@ print(matplot_lib_filename)
#+RESULTS: #+RESULTS:
[[file:proba_estimate_python.png]] [[file:proba_estimate_python.png]]
Comme on pouvait s'attendre au vu des données initiales, la Contrairement à l'analyze précédente, on voit que la température a bien un effet considérable sur la probabilité de dysfonctionnement des joins toriques. Ainsi à 31°F, notre modèle prédit qu'un joint torique à plus de 90% de chances de dysfonctionner.
température n'a pas d'impact notable sur la probabilité d'échec des
joints toriques. Elle sera d'environ 0.2, comme dans les essais
précédents où nous il y a eu défaillance d'au moins un joint. Revenons
à l'ensemble des données initiales pour estimer la probabilité de
défaillance d'un joint:
#+begin_src python :results output :session *python* :exports both #+begin_src python :results value :session *python* :exports both
data = pd.read_csv("shuttle.csv") data_pred[data_pred.Temperature<=31.0]
print(np.sum(data.Malfunction)/np.sum(data.Count))
#+end_src #+end_src
#+RESULTS: #+RESULTS:
: 0.06521739130434782 : Temperature Intercept Frequency
: 0 30.0 1 0.923566
Cette probabilité est donc d'environ $p=0.065$, sachant qu'il existe : 1 30.5 1 0.918258
un joint primaire un joint secondaire sur chacune des trois parties du : 2 31.0 1 0.912615
lançeur, la probabilité de défaillance des deux joints d'un lançeur
est de $p^2 \approx 0.00425$. La probabilité de défaillance d'un des
lançeur est donc de $1-(1-p^2)^3 \approx 1.2%$. Ça serait vraiment
pas de chance... Tout est sous contrôle, le décollage peut donc avoir
lieu demain comme prévu.
Seulement, le lendemain, la navette Challenger explosera et emportera
avec elle ses sept membres d'équipages. L'opinion publique est
fortement touchée et lors de l'enquête qui suivra, la fiabilité des
joints toriques sera directement mise en cause. Au delà des problèmes
de communication interne à la NASA qui sont pour beaucoup dans ce
fiasco, l'analyse précédente comporte (au moins) un petit
problème... Saurez-vous le trouver ? Vous êtes libre de modifier cette
analyse et de regarder ce jeu de données sous tous les angles afin
d'expliquer ce qui ne va pas.
La probabilité qu'un joint défaille à cette température est de $p=0.913$. Sachant qu'il existe un joint primaire un joint secondaire sur chacune des trois parties du lançeur, la probabilité de défaillance des deux joints d'un lançeur est de $p^2 \approx 0.833569$. La probabilité de défaillance d'un des lançeur est donc de $1-(1-p^2)^3 \approx 99.5%$. La catastrophe était certaine.
#+TITLE: Analyse du risque de défaillance des joints toriques de la navette Challenger
#+AUTHOR: Arnaud Legrand
#+LANGUAGE: fr
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="http://www.pirilampo.org/styles/readtheorg/css/htmlize.css"/>
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="http://www.pirilampo.org/styles/readtheorg/css/readtheorg.css"/>
#+HTML_HEAD: <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
#+HTML_HEAD: <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
#+HTML_HEAD: <script type="text/javascript" src="http://www.pirilampo.org/styles/lib/js/jquery.stickytableheaders.js"></script>
#+HTML_HEAD: <script type="text/javascript" src="http://www.pirilampo.org/styles/readtheorg/js/readtheorg.js"></script>
#+LATEX_HEADER: \usepackage{a4}
#+LATEX_HEADER: \usepackage[french]{babel}
# #+PROPERTY: header-args :session :exports both
Le 27 Janvier 1986, veille du décollage de la navette /Challenger/, eu
lieu une télé-conférence de trois heures entre les ingénieurs de la
Morton Thiokol (constructeur d'un des moteurs) et de la NASA. La
discussion portait principalement sur les conséquences de la
température prévue au moment du décollage de 31°F (juste en dessous de
0°C) sur le succès du vol et en particulier sur la performance des
joints toriques utilisés dans les moteurs. En effet, aucun test
n'avait été effectué à cette température.
L'étude qui suit reprend donc une partie des analyses effectuées cette
nuit là et dont l'objectif était d'évaluer l'influence potentielle de
la température et de la pression à laquelle sont soumis les joints
toriques sur leur probabilité de dysfonctionnement. Pour cela, nous
disposons des résultats des expériences réalisées par les ingénieurs
de la NASA durant les 6 années précédant le lancement de la navette
Challenger.
* Chargement des données
Nous commençons donc par charger ces données:
#+begin_src python :results value :session *python* :exports both
import numpy as np
import pandas as pd
data = pd.read_csv("shuttle.csv")
data
#+end_src
#+RESULTS:
#+begin_example
Date Count Temperature Pressure Malfunction
0 4/12/81 6 66 50 0
1 11/12/81 6 70 50 1
2 3/22/82 6 69 50 0
3 11/11/82 6 68 50 0
4 4/04/83 6 67 50 0
5 6/18/82 6 72 50 0
6 8/30/83 6 73 100 0
7 11/28/83 6 70 100 0
8 2/03/84 6 57 200 1
9 4/06/84 6 63 200 1
10 8/30/84 6 70 200 1
11 10/05/84 6 78 200 0
12 11/08/84 6 67 200 0
13 1/24/85 6 53 200 2
14 4/12/85 6 67 200 0
15 4/29/85 6 75 200 0
16 6/17/85 6 70 200 0
17 7/29/85 6 81 200 0
18 8/27/85 6 76 200 0
19 10/03/85 6 79 200 0
20 10/30/85 6 75 200 2
21 11/26/85 6 76 200 0
22 1/12/86 6 58 200 1
#+end_example
Le jeu de données nous indique la date de l'essai, le nombre de joints
toriques mesurés (il y en a 6 sur le lançeur principal), la
température (en Fahrenheit) et la pression (en psi), et enfin le
nombre de dysfonctionnements relevés.
* Inspection graphique des données
Les vols où aucun incident n'est relevé n'apportant aucune information
sur l'influence de la température ou de la pression sur les
dysfonctionnements, nous nous concentrons sur les expériences où au
moins un joint a été défectueux.
#+begin_src python :results value :session *python* :exports both
data = data[data.Malfunction>0]
data
#+end_src
#+RESULTS:
: Date Count Temperature Pressure Malfunction
: 1 11/12/81 6 70 50 1
: 8 2/03/84 6 57 200 1
: 9 4/06/84 6 63 200 1
: 10 8/30/84 6 70 200 1
: 13 1/24/85 6 53 200 2
: 20 10/30/85 6 75 200 2
: 22 1/12/86 6 58 200 1
Très bien, nous avons une variabilité de température importante mais
la pression est quasiment toujours égale à 200, ce qui devrait
simplifier l'analyse.
Comment la fréquence d'échecs varie-t-elle avec la température ?
#+begin_src python :results output file :var matplot_lib_filename="freq_temp_python.png" :exports both :session *python*
import matplotlib.pyplot as plt
plt.clf()
data["Frequency"]=data.Malfunction/data.Count
data.plot(x="Temperature",y="Frequency",kind="scatter",ylim=[0,1])
plt.grid(True)
plt.savefig(matplot_lib_filename)
print(matplot_lib_filename)
#+end_src
#+RESULTS:
[[file:freq_temp_python.png]]
À première vue, ce n'est pas flagrant mais bon, essayons quand même
d'estimer l'impact de la température $t$ sur la probabilité de
dysfonctionnements d'un joint.
* Estimation de l'influence de la température
Supposons que chacun des 6 joints toriques est endommagé avec la même
probabilité et indépendamment des autres et que cette probabilité ne
dépend que de la température. Si on note $p(t)$ cette probabilité, le
nombre de joints $D$ dysfonctionnant lorsque l'on effectue le vol à
température $t$ suit une loi binomiale de paramètre $n=6$ et
$p=p(t)$. Pour relier $p(t)$ à $t$, on va donc effectuer une
régression logistique.
#+begin_src python :results value :session *python* :exports both
import statsmodels.api as sm
data["Success"]=data.Count-data.Malfunction
data["Intercept"]=1
# logit_model=sm.Logit(data["Frequency"],data[["Intercept","Temperature"]]).fit()
logmodel=sm.GLM(data['Frequency'], data[['Intercept','Temperature']], family=sm.families.Binomial(sm.families.links.logit)).fit()
logmodel.summary()
#+end_src
#+RESULTS:
#+begin_example
Generalized Linear Model Regression Results
==============================================================================
Dep. Variable: Frequency No. Observations: 7
Model: GLM Df Residuals: 5
Model Family: Binomial Df Model: 1
Link Function: logit Scale: 1.0
Method: IRLS Log-Likelihood: -3.6370
Date: Fri, 20 Jul 2018 Deviance: 3.3763
Time: 16:56:08 Pearson chi2: 0.236
No. Iterations: 5
===============================================================================
coef std err z P>|z| [0.025 0.975]
-------------------------------------------------------------------------------
Intercept -1.3895 7.828 -0.178 0.859 -16.732 13.953
Temperature 0.0014 0.122 0.012 0.991 -0.238 0.240
===============================================================================
#+end_example
L'estimateur le plus probable du paramètre de température est 0.0014
et l'erreur standard de cet estimateur est de 0.122, autrement dit on
ne peut pas distinguer d'impact particulier et il faut prendre nos
estimations avec des pincettes.
* Estimation de la probabilité de dysfonctionnant des joints toriques
La température prévue le jour du décollage est de 31°F. Essayons
d'estimer la probabilité de dysfonctionnement des joints toriques à
cette température à partir du modèle que nous venons de construire:
#+begin_src python :results output file :var matplot_lib_filename="proba_estimate_python.png" :exports both :session *python*
import matplotlib.pyplot as plt
data_pred = pd.DataFrame({'Temperature': np.linspace(start=30, stop=90, num=121), 'Intercept': 1})
data_pred['Frequency'] = logmodel.predict(data_pred[['Intercept','Temperature']])
data_pred.plot(x="Temperature",y="Frequency",kind="line",ylim=[0,1])
plt.scatter(x=data["Temperature"],y=data["Frequency"])
plt.grid(True)
plt.savefig(matplot_lib_filename)
print(matplot_lib_filename)
#+end_src
#+RESULTS:
[[file:proba_estimate_python.png]]
Comme on pouvait s'attendre au vu des données initiales, la
température n'a pas d'impact notable sur la probabilité d'échec des
joints toriques. Elle sera d'environ 0.2, comme dans les essais
précédents où nous il y a eu défaillance d'au moins un joint. Revenons
à l'ensemble des données initiales pour estimer la probabilité de
défaillance d'un joint:
#+begin_src python :results output :session *python* :exports both
data = pd.read_csv("shuttle.csv")
print(np.sum(data.Malfunction)/np.sum(data.Count))
#+end_src
#+RESULTS:
: 0.06521739130434782
Cette probabilité est donc d'environ $p=0.065$, sachant qu'il existe
un joint primaire un joint secondaire sur chacune des trois parties du
lançeur, la probabilité de défaillance des deux joints d'un lançeur
est de $p^2 \approx 0.00425$. La probabilité de défaillance d'un des
lançeur est donc de $1-(1-p^2)^3 \approx 1.2%$. Ça serait vraiment
pas de chance... Tout est sous contrôle, le décollage peut donc avoir
lieu demain comme prévu.
Seulement, le lendemain, la navette Challenger explosera et emportera
avec elle ses sept membres d'équipages. L'opinion publique est
fortement touchée et lors de l'enquête qui suivra, la fiabilité des
joints toriques sera directement mise en cause. Au delà des problèmes
de communication interne à la NASA qui sont pour beaucoup dans ce
fiasco, l'analyse précédente comporte (au moins) un petit
problème... Saurez-vous le trouver ? Vous êtes libre de modifier cette
analyse et de regarder ce jeu de données sous tous les angles afin
d'expliquer ce qui ne va pas.
module2/exo5/freq_temp_python.png

12.3 KB | W: | H:

module2/exo5/freq_temp_python.png

12.4 KB | W: | H:

module2/exo5/freq_temp_python.png
module2/exo5/freq_temp_python.png
module2/exo5/freq_temp_python.png
module2/exo5/freq_temp_python.png
  • 2-up
  • Swipe
  • Onion skin
module2/exo5/proba_estimate_python.png

14.3 KB | W: | H:

module2/exo5/proba_estimate_python.png

21.9 KB | W: | H:

module2/exo5/proba_estimate_python.png
module2/exo5/proba_estimate_python.png
module2/exo5/proba_estimate_python.png
module2/exo5/proba_estimate_python.png
  • 2-up
  • Swipe
  • Onion skin
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment