Skip to content

Commit

Permalink
Better mathematical expression (#52)
Browse files Browse the repository at this point in the history
* Improve style

* fix ext

* fix ut

* ext

* fix

* req

* remove

* req

* fix ut

* fix paths

* Replace \R by \mathbb{R}

* urls

* nb

* using github only

* fix ut
  • Loading branch information
xadupre authored Oct 7, 2024
1 parent 0558411 commit 5d2706f
Show file tree
Hide file tree
Showing 52 changed files with 6,120 additions and 4,122 deletions.
77 changes: 0 additions & 77 deletions .circleci/config.yml

This file was deleted.

5 changes: 4 additions & 1 deletion .github/workflows/documentation.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Documentation and Code Coverage
name: Test, Documentation and Code Coverage

on:
push:
Expand Down Expand Up @@ -51,6 +51,9 @@ jobs:
pytest --cov=./mlstatpy/ --cov-report=xml --durations=10 --ignore-glob=**LONG*.py --ignore-glob=**notebook*.py
export PYTHONPATH=
- name: test notebooks
run: python -m pytest _unittests/ut_xrun_doc/test_documentation_notebook.py --durations=10

- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v3
env:
Expand Down
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
*.pyc
*.pyd
*.so
*.gv
*.gv.*
*.jpg
.coverage
.eggs/*
_cache/*
Expand Down Expand Up @@ -31,3 +34,8 @@ _unittests/ut__main/*.html
_unittests/.hypothesis/*
_doc/notebooks/ml/*.onnx
_doc/notebooks/dsgarden/*.onnx
_doc/notebooks/nlp/frwiki-*
_doc/notebooks/nlp/sample*.txt
frwiki-*
mobilenetv2-12.onnx
sample1000.txt
10 changes: 5 additions & 5 deletions _doc/c_algo/edit_distance.rst
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ On peut définir la distance d'édition :
.. math::
\begin{array}{crcl}
d : & \mathcal{S}_\mathcal{C} \times \mathcal{S}_\mathcal{C} & \longrightarrow & \R^+\\
d : & \mathcal{S}_\mathcal{C} \times \mathcal{S}_\mathcal{C} & \longrightarrow & \mathbb{R}^+\\
& \pa{m_1,m_2} & \longrightarrow & \underset{ \begin{subarray} OO \text{ séquence} \\ \text{d'opérations} \end{subarray}}{ \min} \, d\pa{m_1,m_2,O}
\end{array}
Expand All @@ -140,7 +140,7 @@ Ce paragraphe a pour objectif de démontrer que la

Soit :math:`\mathcal{C}' = \mathcal{C} \bigcup \acc{.}`
l'ensemble des caractères ajouté au caractère vide ``.``.
On note :math:`c : \pa{\mathcal{C}'}^2 \longrightarrow \R^+`
On note :math:`c : \pa{\mathcal{C}'}^2 \longrightarrow \mathbb{R}^+`
la fonction coût définie comme suit :

.. math::
Expand Down Expand Up @@ -197,7 +197,7 @@ en utilisant les mots acceptables :
\begin{eqnarray}
\begin{array}{crcl}
d : & \mathcal{S}_\mathcal{C} \times \mathcal{S}_\mathcal{C} & \longrightarrow & \R^+\\
d : & \mathcal{S}_\mathcal{C} \times \mathcal{S}_\mathcal{C} & \longrightarrow & \mathbb{R}^+\\
& \pa{m_1,m_2} & \longrightarrow &
\min \acc{ \sum_{i=1}^{+\infty} c\pa{M_1^i, M_2^i} |
\pa{M_1,M_2} \in acc\pa{m_1} \times acc\pa{m_2}}
Expand Down Expand Up @@ -334,7 +334,7 @@ serait tenté de définir une nouvelle distance d'édition inspirée de la préc
\begin{eqnarray*}
\begin{array}{crcl}
d' : & \mathcal{S}_\mathcal{C} \times \mathcal{S}_\mathcal{C} & \longrightarrow & \R^+\\
d' : & \mathcal{S}_\mathcal{C} \times \mathcal{S}_\mathcal{C} & \longrightarrow & \mathbb{R}^+\\
& \pa{m_1,m_2} & \longrightarrow & d'\pa{m_1,m_2} = \dfrac{d^*\pa{m_1,m_2}}{ \max \acc {l\pa{m_1}, l\pa{m_2}}} \\ \\
& & & \text{où } l\pa{m} \text{ est la longueur du mot } m
\end{array}
Expand Down Expand Up @@ -604,7 +604,7 @@ par descente de gradient. Les coûts sont donc appris en deux étapes :

Dans cette étape, les coefficients :math:`\alpha_{ik}\pa{\Omega}`
restent constants. Il suffit alors de minimiser la fonction
dérivable :math:`E\pa{\Omega}` sur :math:`\R^n`, ceci peut être
dérivable :math:`E\pa{\Omega}` sur :math:`\mathbb{R}^n`, ceci peut être
effectué au moyen d'un algorithme de descente de gradient
similaire à ceux utilisés pour les réseaux de neurones.

Expand Down
32 changes: 16 additions & 16 deletions _doc/c_clus/kmeans.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ critère appelé *inertie* ou variance *intra-classe*.

.. math::
\left(X_i\right)_{1\leqslant i\leqslant P}\in\left(\R^N\right)^P
\left(X_i\right)_{1\leqslant i\leqslant P}\in\left(\mathbb{R}^N\right)^P
A chaque point est associée une classe :
:math:`\left(c_i\right)_{1\leqslant i\leqslant P}\in\left\{1,...,C\right\}^P`.
On définit les barycentres des classes :
:math:`\left( G_i\right)_{1\leqslant i\leqslant C}\in\left(\R^N\right)^C`.
:math:`\left( G_i\right)_{1\leqslant i\leqslant C}\in\left(\mathbb{R}^N\right)^C`.

*Initialisation*

Expand Down Expand Up @@ -86,9 +86,9 @@ La démonstration du théorème nécessite le lemme suivant.
:tag: Lemme
:lid: lemme_inertie_minimum

Soit :math:`\vecteur{X_1}{X_P} \in \pa{\R^N}^P`,
:math:`P` points de :math:`\R^N`, le minimum de la quantité
:math:`Q\pa{Y \in \R^N}` :
Soit :math:`\vecteur{X_1}{X_P} \in \pa{\mathbb{R}^N}^P`,
:math:`P` points de :math:`\mathbb{R}^N`, le minimum de la quantité
:math:`Q\pa{Y \in \mathbb{R}^N}` :

.. math::
:nowrap:
Expand All @@ -100,16 +100,16 @@ La démonstration du théorème nécessite le lemme suivant.
est atteint pour :math:`Y=G=\dfrac{1}{P} \sum_{i=1}^{P} X_i`
le barycentre des points :math:`\vecteur{X_1}{X_P}`.

Soit :math:`\vecteur{X_1}{X_P} \in \pa{\R^N}^P`,
:math:`P` points de :math:`\R^N`.
Soit :math:`\vecteur{X_1}{X_P} \in \pa{\mathbb{R}^N}^P`,
:math:`P` points de :math:`\mathbb{R}^N`.

.. math::
:nowrap:
\begin{eqnarray*}
\sum_{i=1}^{P} \overrightarrow{GX_{i}} = \overrightarrow{0}
&\Longrightarrow& \sum_{i=1}^{P} d^2\pa{X_i,Y} = \sum_{i=1}^{P} d^2\pa{X_i,G}+ P \, d^2\pa{G,Y} \\
&\Longrightarrow& \underset{Y\in\R^N}{\arg\min} \; \sum_{i=1}^{P} d^2\pa{X_i,Y} = \acc{G}
&\Longrightarrow& \underset{Y\in\mathbb{R}^N}{\arg\min} \; \sum_{i=1}^{P} d^2\pa{X_i,Y} = \acc{G}
\end{eqnarray*}
On peut maintenant démontrer le théorème.
Expand Down Expand Up @@ -166,7 +166,7 @@ Homogénéité des dimensions
++++++++++++++++++++++++++

Les coordonnées des points
:math:`\left(X_i\right) \in \R^N` sont généralement non homogènes :
:math:`\left(X_i\right) \in \mathbb{R}^N` sont généralement non homogènes :
les ordres de grandeurs de chaque dimension sont différents.
C'est pourquoi il est conseillé de centrer et normaliser chaque dimension.
On note : :math:`\forall i \in \intervalle{1}{P}, \; X_i = \vecteur{X_{i,1}}{X_{i,N}}` :
Expand Down Expand Up @@ -225,7 +225,7 @@ par la suivante :

.. math::
X=\left(X_i\right)_{1\leqslant i\leqslant P}\in\left(\R^N\right)^P
X=\left(X_i\right)_{1\leqslant i\leqslant P}\in\left(\mathbb{R}^N\right)^P
A chaque point est associée une classe :
:math:`\left(c_i\right)_{1\leqslant i\leqslant P}\in\left\{1,...,C\right\}^P`.
Expand Down Expand Up @@ -279,7 +279,7 @@ que :ref:`l-kmeanspp` mais plus rapide et parallélisable.

.. math::
X=\left(X_i\right)_{1\leqslant i\leqslant P}\in\left(\R^N\right)^P
X=\left(X_i\right)_{1\leqslant i\leqslant P}\in\left(\mathbb{R}^N\right)^P
A chaque point est associée une classe :
:math:`\left(c_i\right)_{1\leqslant i\leqslant P}\in\left\{1,...,C\right\}^P`.
Expand Down Expand Up @@ -429,7 +429,7 @@ Maxima de la fonction densité
L'article [Herbin2001]_ propose une méthode différente pour estimer
le nombre de classes, il s'agit tout d'abord d'estimer la fonction
densité du nuage de points qui est une fonction de
:math:`\R^n \longrightarrow \R`. Cette estimation est effectuée au moyen
:math:`\mathbb{R}^n \longrightarrow \mathbb{R}`. Cette estimation est effectuée au moyen
d'une méthode non paramètrique telle que les estimateurs à noyau
(voir [Silverman1986]_)
Soit :math:`\vecteur{X_1}{X_N}` un nuage de points inclus dans une image,
Expand All @@ -451,15 +451,15 @@ d'image qui ne peut pas être résolu par la méthode des nuées
dynamiques puisque la forme des classes n'est pas convexe,
ainsi que le montre la figure suivante. La fonction de densité
:math:`f` est seuillée de manière à obtenir une fonction
:math:`g : \R^n \longrightarrow \acc{0,1}` définie par :
:math:`g : \mathbb{R}^n \longrightarrow \acc{0,1}` définie par :

.. math::
g \pa{x} = \indicatrice{f\pa{x} \supegal s}
.. index:: composante connexe

L'ensemble :math:`g^{-1}\pa{\acc{1}} \subset \R^n`
L'ensemble :math:`g^{-1}\pa{\acc{1}} \subset \mathbb{R}^n`
est composée de :math:`N` composantes connexes notées
:math:`\vecteur{C_1}{C_N}`, la classe d'un point :math:`x`
est alors l'indice de la composante connexe à la
Expand Down Expand Up @@ -499,7 +499,7 @@ L'inertie de ce nuage de points est définie par :
I = \sum_{x \in X} \; \norme{ x - y_{C\pa{x} }}^2
On définit tout d'abord une distance
:math:`\alpha \in \R^+`, puis l'ensemble
:math:`\alpha \in \mathbb{R}^+`, puis l'ensemble
:math:`V\pa{y,\alpha} = \acc{ z \in Y \sac d\pa{y,z} \infegal \alpha }`,
:math:`V\pa{y,\alpha}` est donc l'ensemble des voisins des
centres dont la distance avec :math:`y` est inférieur à :math:`\alpha`.
Expand Down Expand Up @@ -877,7 +877,7 @@ lors de l'estimation des centres des classes, l'algorithme évite la formation d
Soit un nuage de points :math:`\vecteur{X_1}{X_N}`,
soit :math:`C` vecteurs :math:`\vecteur{\omega_1}{\omega_C}`
initialisés de manière aléatoires.
Soit :math:`F : \pa{u,t} \in \R^2 \longrightarrow \R^+`
Soit :math:`F : \pa{u,t} \in \mathbb{R}^2 \longrightarrow \mathbb{R}^+`
croissante par rapport à :math:`u`.
Soit une suite de réels :math:`\vecteur{u_1}{u_C}`,
soit une suite :math:`\epsilon\pa{t} \in \cro{0,1}` décroissante où :math:`t`
Expand Down
11 changes: 6 additions & 5 deletions _doc/c_clus/kohonen.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@ linéaire, rectangulaire, triangulaire.
:tag: Algorithme
:lid: classification_som_algo

Soient :math:`\vecteur{\mu_1^t}{\mu_N^t} \in \pa{\R^n}^N`
des neurones de l'espace vectoriel :math:`\R^n`. On
Soient :math:`\vecteur{\mu_1^t}{\mu_N^t} \in \pa{\mathbb{R}^n}^N`
des neurones de l'espace vectoriel :math:`\mathbb{R}^n`. On
désigne par :math:`V\pa{\mu_j}` l'ensemble des neurones
voisins de :math:`\mu_j` pour cette carte de Kohonen.
Par définition, on a :math:`\mu_j \in V\pa{\mu_j}`.
Soit :math:`\vecteur{X_1}{X_K} \in \pa{\R^n}^K` un nuage de points.
Soit :math:`\vecteur{X_1}{X_K} \in \pa{\mathbb{R}^n}^K` un nuage de points.
On utilise une suite de réels positifs
:math:`\pa{\alpha_t}` vérifiant
:math:`\sum_{t \supegal 0} \alpha_t^2 < \infty` et
Expand All @@ -49,7 +49,7 @@ linéaire, rectangulaire, triangulaire.
*initialisation*

Les neurones :math:`\vecteur{\mu_1^0}{\mu_N^0}`
sont répartis dans l'espace :math:`\R^n`
sont répartis dans l'espace :math:`\mathbb{R}^n`
de manière régulière selon la forme de leur voisinage.
:math:`t \longleftarrow 0`.

Expand Down Expand Up @@ -202,7 +202,8 @@ Autres utilisation des cartes de Kohenen
On peut les utiliser pour déterminer le plus court
chemin passant par tous les noeuds d'un graphe,
c'est à dire appliquer
`Kohonen au problème du voyageur de commerce <http://www.xavierdupre.fr/app/ensae_teaching_cs/helpsphinx/specials/tsp_kohonen.html>`_.
`Kohonen au problème du voyageur de commerce
<https://sdpython.github.io/doc/teachpyx/dev/c_expose/tsp/tsp_kohonen.html>`_.

Bibliographie
=============
Expand Down
13 changes: 6 additions & 7 deletions _doc/c_metric/roc.rst
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,12 @@ La courbe ROC s'obtient en faisant varier :math:`s`.
On suppose également que tous les scores sont indépendants.
On note :math:`F_Y` et :math:`F_X` les fonctions de répartition de ces variables.
:math:`F_Y(s)=\pr{Y \infegal s}` et :math:`F_X(s)=\pr{X \infegal s}`.
On définit en fonction d'un seuil :math:`s \in \R` :
On définit en fonction d'un seuil :math:`s \in \mathbb{R}` :

* :math:`R(s) = 1 - F_Y(s) = \pr{Y > s}`
* :math:`E(s) = 1 - F_X(s) = \pr{X > s}`

La courbe ROC est le graphe :math:`\pa{E(s),R(s)}` lorsque :math:`s` varie dans :math:`\R`.
La courbe ROC est le graphe :math:`\pa{E(s),R(s)}` lorsque :math:`s` varie dans :math:`\mathbb{R}`.

:math:`TP(s)` désigne les true positifs au-dessus du seuil :math:`s`,
avec les notations *TP*, *FP*, *FN*, *TN*, cela revient à :
Expand Down Expand Up @@ -181,7 +181,7 @@ De plus, soit :math:`g` une fonction intégrable quelconque, on pose :math:`u =

.. math::
\int_{\R} g(x) \, f(x) \,dx = \int_{\cro{0,1}} g(F^{-1}(u)) \, du
\int_{\mathbb{R}} g(x) \, f(x) \,dx = \int_{\cro{0,1}} g(F^{-1}(u)) \, du
**Démonstration**

Expand Down Expand Up @@ -337,7 +337,7 @@ est construite une courbe ROC (voir :ref:`Courbe ROC <def_roc_2>`).
:lid: algo_courb_ROC

On suppose qu'on dispose d'un ensemble de points :math:`\pa{X_i,\theta_i}
\in \R \times \acc{0,1}` pour :math:`i \in \ensemble{1}{n}`.
\in \mathbb{R} \times \acc{0,1}` pour :math:`i \in \ensemble{1}{n}`.
`X_i` est le score obtenu pour l'expérience :math:`i`,
`\theta_i` vaut 1 si elle a réussi et 0 si elle a échoué.
On suppose également que cette liste est triée par ordre croissant :
Expand Down Expand Up @@ -405,7 +405,7 @@ On s'inspire pour cela des méthodes de `bootstrap <https://fr.wikipedia.org/wik
:lid: roc_boostrap_algo

On dispose toujours du nuage de points
:math:`E = \pa{X_i,\theta_i} \in \R \times \acc{0,1}` avec :math:`i \in \ensemble{1}{n}`.
:math:`E = \pa{X_i,\theta_i} \in \mathbb{R} \times \acc{0,1}` avec :math:`i \in \ensemble{1}{n}`.
On choisit :math:`C \in \N` le nombre de courbes ROC qu'on désire tracer.
Pour chaque courbe :math:`c \in \ensemble{1}{C}` :

Expand Down Expand Up @@ -614,8 +614,7 @@ Le premier cas correspond par exemple à des problèmes de
`détection de fraude <https://en.wikipedia.org/wiki/Predictive_analytics#Fraud_detection>`_.
Le second cas correspond à taux de classification global. La courbe ROC
pour ce cas est en règle général moins bonne que la plupart des
courbes ROC obtenues pour chacune des classes prise séparément
(voir `Régression logistique <http://www.xavierdupre.fr/app/papierstat/helpsphinx/notebooks/wines_color.html>`_).
courbes ROC obtenues pour chacune des classes prise séparément.

Exemple
=======
Expand Down
4 changes: 2 additions & 2 deletions _doc/c_ml/index_reg_lin.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ est le modèle prédictif le plus simple et celui qu'on préfère
quand il marche car il est facilement interprétable à l'inverse
des modèles non linéaires qui gardent leurs secrets si on s'en tient
seulement à leurs coefficients. Concrètement, on dispose d'un nuage
de point :math:`(X_i, y_i)` où :math:`X_i \in \R^d` est un vecteur
de dimension *d* et :math:`y_i \in \R` un réel. La régression
de point :math:`(X_i, y_i)` où :math:`X_i \in \mathbb{R}^d` est un vecteur
de dimension *d* et :math:`y_i \in \mathbb{R}` un réel. La régression
linéaire consiste à construire une fonction prédictive
:math:`\hat{y_i} = f(X_i) = <X_i, \beta> = X_i \beta` où
:math:`\beta` est un vecteur de dimension *d*. Dans le cas le plus
Expand Down
4 changes: 2 additions & 2 deletions _doc/c_ml/index_reg_log.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ est le modèle prédictif le plus simple et celui qu'on préfère
quand il marche car il est facilement interprétable à l'inverse
des modèles non linéaires qui gardent leurs secrets si on s'en tient
seulement à leurs coefficients. Concrètement, on dispose d'un nuage
de point :math:`(X_i, y_i)` où :math:`X_i \in \R^d` est un vecteur
de point :math:`(X_i, y_i)` où :math:`X_i \in \mathbb{R}^d` est un vecteur
de dimension *d* et :math:`y_i \in \acc{0, 1}` un entier binaire.
Le problème de la régression linéaire consiste à
construire une fonction prédictive
:math:`\hat{y_i} = f(X_i) = <X_i, \beta> = X_i \beta` où
:math:`\beta` est un vecteur de dimension *d*
(voir `classification
<http://www.xavierdupre.fr/app/papierstat/helpsphinx/lectures/regclass.html#classification>`_).
<https://sdpython.github.io/doc/teachpyx/dev/c_ml/regclass.html>`_).
Le signe de la fonction :math:`f(X_i)`
indique la classe de l'observation :math:`X_i` et la valeur
:math:`\frac{1}{1 + e^{f(X)}}` la probabilité d'être dans la classe 1.
Expand Down
Loading

0 comments on commit 5d2706f

Please sign in to comment.