The French version of this document is no longer maintained: be sure to check the more up-to-date English version.

A CLASSER

Lexique
A CLASSER
Mixtures
Comment se ramener à des distributions normales ?
Que faire si les données ne sont vraiment pas normales ?
A CLASSER
Exemples, à utiliser un peu plus haut
Données goégraphiques
Divers
A CLASSER : Le livre de F.E.Harrell, Regression modelling strategies
A CLASSER
Simulations
A CLASSER
R for psychologists
Exemples fabriqués
********
Divers
Types de données
Régression
A CLASSER
Manipulation des données
Programmation
A FAIRE
Distributions statistiques
A CLASSER
EN COURS
A CLASSER
A CLASSER (exemples divers)
A FAIRE
Plan de la nouvelle version de ce document
A CLASSER...
Autre graphiques pour repérer ces problèmes
Divers
Plan d'analyse
Divers
A CLASSER
Quelques exemples
A FAIRE
Graphical models (modèles graphiques ?)
Distance de Kullback-Leibler
A FAIRE

Lexique

Régression

Tentative de prédiction d'une variable statistique en fonction d'autres variables. Il s'agit donc d'étudier le lien entre plusieurs variables statistiques, mais de manière asymétrique : certaines variables sont << prédictives >> (ou indépendantes), d'autres << à prédire >> (ou dépendantes).

Variable dépendante

Variable que l'on cherche à prédire lors d'une régression.

Variable indépendante

Variables utilisée pour prédire les valeurs d'une autre variable lors d'une régression. Variable prédictive.

Variable prédictive

Variable indépendante.

Variable catégorique

Variable qui n'a qu'un nombre fini de valeurs possibles (exemples : vivant/mort, sain/infecté/malade, rouge/vert/bleu, des numéros de département, etc.).

Variable discrète

Variable catégorique

Variable quantitative

Variable à valeurs numériques (exemples : un salaire, une vitesse, une durée, une distance, un poids, etc.)

Régression multiple

Etude de la liaison entre un groupe de variables (généralement quantitatives) et une variable quantitative. Il s'agit plus précisément de prédire les valeurs de cette variable.

Régression linéaire multiple

C'est une régression multiple dans laquelle on cherche à écrire la variable à prédire comme une combinaison linéaire des autres variables. Pour tenter de simplifier le modèle ainsi obtenu, en se débarassant des variables prédictives non nécessaires, on s'amuse à faire plein de tests statistiques du genre "H0 : tel coefficient est nul".

Régression régularisée

Régression sur les composantes principales (et non pas sur l'espace tout entier). De manière générale, c'est une bonne idée de tenter de se limiter à un nombre réduit de variables.

Cela pose un léger problème : on choisit les variables que seront utilisées pour la prédiction sans tenir compte de la variable à prédire.

A FAIRE : comment contourne-t-on ce problème ???

Analyse de la variance

Régression quand toutes les variables prédictives sont qualitatives.

Plus précisément, on cherche à écrire (dans le cas de deux variables prédictives u et v)

y = qqch qui dépend de la valeur de u 
    + qqch qui dépend de la valeur de v
    + qqch qui dépend de la valeur de (u,v)
    + bruit

On évalue les différents coefficients qui apparaissent dans cette écriture et on fait plein de tests pour regarder si certains des coefficients sont nuls (par exemple, les coefficients qui correspondent aux valeurs de (u,v), et qui correspondent à une interaction entre u et v).

Analyse de la covariance

Régression quand certaines des variables prédictives sont qualitatives et d'autres quantitatives (ces dernières sont alors qualifiées de covariables).

On procède comme pour l'analyse de la variance, toujours avec plein de tests.

Covariable

Variable indépendante quantitative dans une régression, quand il y a aussi des variables indépendantes qualitatives (i.e., lors d'une analyse de la covariance).

Analyse discriminante

Etude de la liaison entre un groupe de variables et une variable qualitative.

A FAIRE

Analyse des correspondances

Etude de la liaison entre des variables qualitatives.

Régression linéaire

Voir Modèle linéaire

Modèle linéaire (ou régression linéaire)

On cherche à écrire une variable y comme combinaison linéaire d'autres variables x1, x2,... xn :

E(y) = a0 + a1 x1 + a2 x2 + ... + an xn.

Cela revient en fait à écrire

y = a0 + a1 x1 + a2 x2 + ... + an xn + bruit

où << bruit >> est un terme d'erreur (généralement normal, d'espérance nulle). On estimes les paramètres à l'aide de la méthode des moindres carrés (si le bruit est normal, c'est en fait équivalent à la méthode du maximum de vraissemblance, mais les calculs se réduisent à un peu d'algèbre linéaire).

Le modèle linéaire regroupe la régression simple (n=1), la régression multiple (n>1), l'analyse de la variance (si toutes les variables prédictives sont qualitatives) et l'analyse de la covariance (si certaines variables prédictives sont qualitatives et d'autres quantitatives).

Modéle linéaire généralisé

Cette fois-ci, on écrit plutôt

g( E(y) ) = a0 + a1 x1 + a2 x2 + ... + an xn

où g est une certaine fonction. De plus, y ne suit pas nécessairement une loi normale, mais simplement une loi de la famille exponentielle (par exemple, normale, binomiale, Poisson, gamma). Pour trouver la valeur des paramètres, on utilise la méthode du maximum de vraissemblance (dans le cas d'une loi normale, on retombe sur les moindres carrés).

C'est en particulier ce que l'on utilise si Y est qualitative. Dans ce cas, on peut chercher P(y=0) ; mais comme une probabilité est toujours comprise entre 0 et 1, on n'arrivera pas à l'exprimer comme combinaison linéaire de variables quantitatives auxquelles on ajoute du bruit. On applique alors à cette probabilité une bijection g entre l'intervalle [0;1] et la droite réelle (on dit que g est un lien). On essaye alors d'exprimer g(P(y=0)) comme combinaison linéaire des variables prédictives.

Lien

La fonction g, dans la définition du modèle linéaire généralisé ou dans la régression logistique, qui permet de passer de l'intervalle [0,1] à la droite réelle entière, s'appelle un lien. Il a souvent une forme sigmoïdale.

Les principaux exemples de liens sont la fonction logistique (ou logit), la fonction probit.

Fonction logit

Voir Fonction logistique.

Fonction logistique

C'est un exemple de lien.

                  p
logit(p) = log -------
                1 - p

On peut donc écrire

                          P(gagner)
logit( P(gagner) ) = log -----------.
                          P(perdre)

Le quotient P(gagner)/P(perdre) s'appelle la cote (vous avez surement déjà entendu l'expression << la cote est à ... contre 1 >>).

Voici le graphe de cette fonction.

x <- seq(0,1, length=100)
x <- x[2:(length(x)-1)]
logit <- function (t) {
  log( t / (1-t) )
}
plot(logit(x) ~ x, type='l')

*

Fonction probit

C'est un autre exemple de lien : c'est la fonction inverse de la fonction de répartition de la loi normale standard.

curve(logit(x), col='blue', add=F)
curve(qnorm(x), col='red', add=T)
a <- par("usr")
legend( a[1], a[4], c("logit","probit"), col=c("blue","red"), lty=1)

*

Modèle de variables latentes

On suppose ici que les variables observées sont des combinaisons linéaires de "facteurs" (variables non observées, en nombre plus réduit). Cela revient en fait à faire une analyse en composantes principales.

A FAIRE

Analyse factorielle discriminante

 A FAIRE

Il s'agit de prédire la valeur d'une variables qualitative, i.e., de mettre les individus dans des classes. (Par exemple : aide au diagnostic médical, reconnaissance des mauvais payeurs par une banque, etc.) On cherche des "fonctions linéaires discirminantes (des combinaisons linéaires dea variables, qui maximisent la variance interclasse et minimisent la variance intraclasse)

Réseaux de neurones

Ils rendent à peu près les mêmes services que l'analyse discriminante.

A FAIRE

%%%%%%%%%%%%%%%% A FAIRE %%%%%%%%%%%%
Relire tout ce qui suit...

Modèles log-linéaires

On étudie les liaisons entre des variables qualitatives, sans qu'une variable joue un rôle particulier (il n'y a pas de variable à prévoir). Les données sont représentées par un tableau de contingence. On commence par formuler une hypothèse sur ce tableau, qui donne un certain modèle et certaines valeurs pour les fréquences. Par exemple, s'il y a deux variables, si on suppose qu'elles sont indépendantes, le modèle implique que

t(i,j) = t(i,*) t(*,j)

On utilise alors un test du Chi2 pour comparer cette distribution avec celle effectivement observée. Ce modèle peut s'écrire sous forme linéaire

ln t(i,j) = a1(i) + a2(j).

S'il ne convient pas, on peut essayer de rajouter un terme traduisant l'interaction entre les deux variables.

ln t(i,j) = a1(i) + a2(j) + a12(i,j)

Plus généralement, on pourra essayer

ln t(i,j,k) = a0 + a1(i) + a2(j) + a3(k) 
              + a12(i,j) + a13(i,k) + a23(j,k)
              + a123(i,j).

Ici encore, on pourrait s'amuser à faire plein de tests pour regarder si certains de ces coefficients sont nuls. Mais généralement, on commence par essayer les modèles les plus simples, et on les complexifie au fur et à mesure : on s'arrête quand le modèle convient.

Le modèle log-linéaire est pertinent si on a peu de variables (pas plus de 5 : sinon, on préfèrera l'analyse des correspondances) et beaucoup d'individus.

Régression logistique

C'est un cas particulier du modèle linéaire généralisé, dans lequel le lien est la fonction logit.

On cherche à relier des variables qualitatives x1, x2,..., xn et une variable qualitative y qui prend deux valeurs (on parle de variable binaire ou dichotomoque). Pn cherche à estimer la probabilité

pi(x) = P ( y=1 | x ).

on considère le modèle

logit pi(x) = a0 + a1 x1 + ... + an xn

logit(t) = ln( t/(1-t) ).

Comme d'habitude, on estime les coefficients à l'aide de la méthode du maximum de vraissemblance et on fait plein de tests du genre "H0: a_i = 0".

One-way anova

Anova simple

Anova simple

Anova avec une seule variable qualitative.

Two-way Anova

Anova double

Anova double

Anova avec deux variables qualitatives.

Supposons pour l'instant que ces variables n'interagissent pas. Le modèle est le suivant.

Y(i,j) = mu + A(i) + B(j) + Erreur(i,j)

On dit que A(i) est l'effet traitement et que B(j) est l'effet bloc.

S'il y a interaction, le modèle est :

Y(i,j) = mu + A(i) + B(j) + C(i,j) + Erreur(i,j).

Effet bloc

Dans une anova double,

Y(i,j) = mu + A(i) + B(j) + C(i,j) + Erreur(i,j).

on dit que A(i) est l'effet traitement et que B(j) est l'effet bloc.

Effet traitement

Dans une anova double,

Y(i,j) = mu + A(i) + B(j) + C(i,j) + Erreur(i,j).

on dit que A(i) est l'effet traitement et que B(j) est l'effet bloc.

A CLASSER

Mixtures

(A FAIRE -- il doit y avoir d'autres morceaux sur le sujet ailleurs dans ce document...)

Comment trouver le nombre d'éléments d'une "mixture" ? Par exemple par des méthodes bayesiennes :

http://www.maths.soton.ac.uk/staff/Sahu/utrecht/adv.pdf

Comment se ramener à des distributions normales ?

Il n'est pas toujours possible ou (raisonnable) de se ramener à une distribution normale : il arrive par exemple que la distribution présente plusieurs pics...

Nettoyage des données

Pour analyser les données, il faut préalablement les vérifier (s'assurer qu'il n'y a pas d'erreurs, ni de données incohérentes : a priori ces erreurs sont rares, donc on les voit facilement, par exemple avec des boutes à moustaches ou d'autres représentations graphiques) et éventuellement les remplacer par des données plus symétriques.

En effet, beaucoup de traitements statistiques (par exemple : le calcul de la moyenne) sont très sensibles à des données (rares) qui s'éloignent beaucoup de la « norme », à des situations non symétriques et à des distributions avec des « queues épaisses » (beaucoup de données qui s'éloignent de la norme).

Comment vérifier qu'une distribution est symétrique ?

À l'aide d'une boite à moustaches ou à l'aide d'un test U de Wilcoxon, comme nous l'avons déjà vu plus haut.

A l'aide d'un graphe de symétrie.

Comment vérifier qu'une distribution est normale ?

Une première solution consiste à faire un test de Shapiro.

?shapiro.test

> shapiro.test(rnorm(100))

      Shapiro-Wilk normality test

data:  rnorm(100)
W = 0.9809, p-value = 0.1564

> shapiro.test(rnorm(100)^2)

      Shapiro-Wilk normality test

data:  rnorm(100)^2
W = 0.6976, p-value = 4.74e-13

Le test de Kolmogorov--Smirnov est plus général : il marche avec des distributions autres que la distribution normale , et permet aussi de savoir si deux échantillons sont distribués suivant la même loi.

?ks.test

Une seconde méthode consiste à utiliser un QQplot.

Transformations : racine carrée, logarithme

Certaines données ne sont pas normales, mais on peut souvent s'y ramener par des transformations, comme prendre la racine carrée ou le logarithme.

On prend la racine carrée si la distribution ressemble à une distribution normale un peu deséquilibrée

*

par exemple

*

*

On applique le logarithme quand la distribution ressemble à une distribution lognormale

*

par exemple

*

*

A FAIRE : choisir une transformation en s'aidant du test de Shapiro.

A FAIRE

?boxcox

(Donne la meilleure valeur de lambda pour que y = a x^lambda + b ???)

data(trees)
boxcox(Volume ~ log(Height) + log(Girth), data = trees,
       lambda = seq(-0.25, 0.25, length = 10))
data(quine)
boxcox(Days+1 ~ Eth*Sex*Age*Lrn, data = quine,
       lambda = seq(-0.05, 0.45, len = 20))

Transforming non-normal data into normal data. The box.cox.powers
function in the car package does unconditional univariate and
multivariate Box-Cox transformations.
(Cette bibliothèque n'est pas installée...)

Que faire si les données ne sont vraiment pas normales ?

A FAIRE : exemple (des distributions à 2 pics, par exemple faithful, les premières notes de mes élèves, ou une somme de deux distributions normales).

x <- c( 2+rnorm(100), 6+rnorm(100) )
hist(x)

Méthodes non paramétriques

Nous avons vu certains tests non paramétriques : rappelons-les.

Pour la moyenne, on peut remplacer le test T de Student par le test U de Wincoxon. Dans le cas de plus de deux échantillons, on peut remplacer l'analyse de la variance par le test de Kruskal--Wallis.

Pour la variance, on peut remplacer le test F de Fisher ou celui de Bartlett par les tests d'Ansari, Mood ou Fligner.

Comparaison de moyennes à l'aide de permutations

On se donne deux échantillons de taille n, et on veut savoir si leur moyennes sont significativement différentes. Pour cela, on commence par calculer les moyennes et leur différences. Ensuite on recommence, mais en prenant deux échantillons de taille n au hasard dans nos 2n valeurs. Et on continue jusqu'à avoir une bonne estimation de la distribution de ces différences. Ensuite, on regarde où notre différence initiale se trouve dans cette distribution : on rejette l'hypothèse d'égalité si elle semble trop marginale.

Condition d'application : équivariance (i.e., les deux échantillons ont la même variance, ce que l'on vérifie à l'aide d'un test de F).

A FAIRE : comment appelle-t-on cela en anglais ? resampling ???

A FAIRE : un exemple pratique (reprendre les données du T-test ?)

A CLASSER

Intégration numérique :

?integrate

Penalized Regression

library(Design)
?ols

Cp de Mallow : dans le cas gaussien, avec variance connue, il équivaut à l'AIC.

Dimension de Vapnik--Chernovenkis.

Définir la log-vraissemblance. On peut utiliser les quotients de vraissemblance pour faire des tests.

Likelihood ratio test: see the esample in ?loglm

scatterplot in the car package

Ellipses in the car package.

The Florida data set in the car package

"outlier" se traduit par "point atypique". "dummy variable" se traduit par "variable indicatrice".

Coefficient de détermination : corrélation entre y et \hat y. On peut donc le voir en représentant \hat y ~ y.

do.call

# The example comes from Rtips
plot(2:10,type="n")
do.call("rect",c(as.list(par("usr")[c(1,3,2,4)]),list(col="pink")))
points(2:10)

# équivalent à :

plot(2:10,type="n")
rect( par("usr")[1], par("usr")[2], par("usr")[3], par("usr")[4], col="pink" )
points(2:10)

?signif

# Pour avoir plein de petits histogrammes
latex(describe(df))

Contrastes (Dans les tests post-hoc ? Dans les tests de la régression multiple ?). On aimerait savoir si A,C>=A. On peut regarder si la moyenne de 2A-B-C est significativement non nulle. Les contrastes permettent (presque) de faire plusieurs tests en un seul.

Définir : corrélation avec les rangs de Spearman ; Corrélation avec les rangs de Kendal.

Parler de

http://dssm.unipa.it/R-php/

?termplot

Calcul parallèle :

library(help=Rpmi)
http://www.mpi-forum.org/
Par exemple, pour les clusters Beowulf    A FAIRE : URL

library(help=rpvm)
A FAIRE : URL pour PVM...

?tsSmooth ?monthplot ?decompose # classical decomposition of a time-series

Débugging:

?browser
?trace
?recover
?warning
?stop

Changements :

library(pastecs)
?turnpoints
(à utiliser par exemple après loess, sur le spectre d'une série de Fourrier, pour avoir
une idée de la période)

On peut directement récupérer des données boursières sur le Web :

library(tseries)
?get.hist.quote

Voir aussi :

?download.file

Modèle hiérarchisé. Modéle à effets croisés = modéne non hiérarchisé. Facteur à effet fixe (ou plan factoriel complet) : il y a qualque chose dans chaque case du tableau. Facteur à effet aléatoire : il n'y a pas nécessairement quelque chose dans chaque case du tableau.

Blocs. Il y a plein de variables qu'on ne connait pas, mais qui peuvent influencer le résultat. On fait donc plusieurs fois la même expérience dans les mêmes conditions (par exemple, sur le même individu, dans le même champ, etc.) : cela s'appelle un bloc. Pour pouvoir tirer des conclusions indépendemment des blocs, on refait la même expérience dans d'autres blocs. En gros, les blocs, ce sont les variables qualitatives dont on voudrait se débarasser.

Revoir la notion de M-estimateur. Quelles sont ces fonction rho et psi ?

qqplots stratified by the quantiles of Xi.

Many quantitative variables: draw a dendogram (for the variables, not the observations).

Compute and plot (dotplot(sort(...))) the adjsuted R-squared for each variable (lm(y~x[-i])).

two-way table. 2 variables qualitatives X1, X2, une variable quantitative, Y. Pour chaque couple de valeurs de (X1,X2), un seul individu. Modèle: Yij = mu + ai + bj + eij.

Median polish. Take a 2-way table. Substract its median from each row. Substract its median from each column. Iterate. (With the mean, we need not iterate). (Keep track of what you substract: these are the looked for ai and bj.)

n <- 3
p <- 5
m <- matrix( rpois(n*p,10), nr=n, nc=p )
my.median.polish <- function (m, median=median) {
  a <- rep(0, dim(m)[1])
  b <- rep(0, dim(m)[2])
  c <- median(m)
  m <- m-c
  for (i in 1:10) {
    print(paste("itération",i))
    print(m)
    a <- a + apply(m,1,median)
    m <- m - a
    b <- b + apply(m,2,median)
    m <- t(t(m)-b)
  } 
  print(a)
  print(b)
  print(c)
}
my.median.polish(m, median=mean)

A FAIRE : ça ne marche pas...

Exemples, à utiliser un peu plus haut

HairEyeColor : 3 variables quantitatives
InsectSprays : 1 variable quantitative, 1 qualitative
LifeCycleSavings : 5 variables quantitatives
Titanic : 4 variables qualitatives
ToothGrowth : 2 variables quantitatives, 1 qualitative
UCBAdmissions : 3 variables qualitatives
airmiles : time series
airquality : 4 variables quantitatives (bon pour une régression non linéaire)
anscombe : très bon exemple (construit) de régression linéaire
attenu: coplot?
chickwts: une variable quantitative, une qualitative (prédictive)
chickwts: bon exemple de boxplots avec des intervalles de confiance sur la médiane
co2: time series (looks like at+sin(bt+c))
eurodist: dist object
faithful: 1 quantitative variable
freeny: 5 variables quantitatives, régression bien linéaire
        (est-ce un bon exemple pour comparer des modèles ?)
infert: régression logistique
longley: régression linéaire (6 variables)
mtcars: une dizaine de variables, tantôt qualitatives, tantôt quantitatives
nhtemp: time series
phones: 6 séries temporelles (exemple d'utilisation de matplot)
presidents: time series
pressure: deux variables quantitatives (exemple de régression non linéaire, ou exemple d'échelle logarithmique).
quakes: pairplot avec beaucoup de points (on doit pouvoir réutiliser cet exemple pour faire un peu d'algèbre linéaire, d'ACP et de dessins en 3D).
randu: mauvais nombres aléatoires
rivers: longueur de rivières (exemple pour la loi de Benford)
sleep: deux variables, une numérique, une qualitative (prédictive)
data(state)
  state.area: pour la loi de Benford ?
  state.x77: plein de variables quantitatives (régression pas claire)
sunspots: time series (irregular sines)
swiss: plein de variables quantitatives, une qualitatives (pairplot avec des couleurs)
trees: 3 variables quantitatives, coplot
volcano: contour plot
warpbreaks: une donnée numérique, deux données qualitatives (prédictives)
            boxplot avec plusieures données qualitatives

A FAIRE:

data(package=MASS)

coplot(..., show.given=F) xyplot (in the lattice library) supercedes the coplot command.

Données goégraphiques

Variogramme:

library(geoR)
D <- matrix(scan("file.dat", n=530*3), 530,3, byrow=TRUE)
B <- as.geodata(D, coords.col=1:2, data.col=3)
variog(B, option = "cloud", max.dist = 1)

Divers

Superposer deux graphiques

x<-c(1,1,NA,2,2,NA,3,3)
y<-c(2,4,NA,3,5,NA,1,4)

par(fig=c(0,2/3,0,1))
plot(x,y)

par(fig=c(2/3,1,0,1), new=F)
qqnorm(x)

Start-up:

% cat ~/.Rprofile
cat("Running my .Rprofile...");
library(modreg)
cat("Running my .Rprofile...done");

regression and 3D graphs:

library(akima)
plan <- interp.old(x,y.z)
image(plan)

Option pricing, etc.

library(RQuantLib)

Nomogram :

library(Design)

A CLASSER : Le livre de F.E.Harrell, Regression modelling strategies

Bootstrap : derivation of distribution-free confidence intervals; estimation of optimism.

Bias: Variance often deminates bias. Biased methods are useful. eg: Penalized Maximum Likelyhood.

Deux utilisations

A CLASSER

?update
?step
# Que signifie le point dans les podèles suivants ?
data(trees)
pairs(trees, panel = panel.smooth, main = "trees data")
plot(Volume ~ Girth, data = trees, log = "xy")
coplot(log(Volume) ~ log(Girth) | Height, data = trees,
       panel = panel.smooth)
summary(fm1 <- lm(log(Volume) ~ log(Girth), data = trees))
summary(fm2 <- update(fm1, ~ . + log(Height), data = trees))
step(fm2)
## i.e. Volume ~= c * Height * Girth^2  seems reasonable

Simulations

A FAIRE

A CLASSER

R for psychologists

Différentes manières de fabriquer des tables

?table
?ave
?by (quand on étudie une variable quantitative par rapport à une/des variables(s) quantitative(s))

matplot

sines <- outer(1:20, 1:4, function(x, y) sin(x / 20 * pi * y))
matplot(sines, pch = 1:4, type = "o", col = rainbow(ncol(sines)))

Aussi pour des nuages de points :

data(iris)                  # is data.frame with  `Species' factor
table(iris$Species)
iS <- iris$Species == "setosa"
iV <- iris$Species == "versicolor"
op <- par(bg = "bisque")
matplot(c(1, 8), c(0, 4.5), type= "n", xlab = "Length", ylab = "Width",
        main = "Petal and Sepal Dimensions in Iris Blossoms")
matpoints(iris[iS,c(1,3)], iris[iS,c(2,4)], pch = "sS", col = c(2,4))
matpoints(iris[iV,c(1,3)], iris[iV,c(2,4)], pch = "vV", col = c(2,4))
legend(1, 4, c("    Setosa Petals", "    Setosa Sepals",
               "Versicolor Petals", "Versicolor Sepals"),
       pch = "sSvV", col = rep(c(2,4), 2))

Ne pas oublier de parler de

par(mfcol=c(3,2))
sink("foo.result")

Paired t-test

t.test(a1,b1,paired=TRUE)

plot(a1,b1)
abline(0,1)

# Other plot
matplot(t(cbind(a1,b1)),type="l")

Observe-t-on A plus souvent que B ?

prop.test(sum(a1>b1), sum(a1>b1)+sum(a1<b1)).

Chi-test

a1 <- c(1,1,1,1,1,1,1,0,0,0,0,0,0)
b1 <- c(1,1,1,1,1,1,0,0,0,0,0,0,1)
chisq.test(a1,b1)

On rappelle que ce test n'est qu'une approximation (d'ailleurs, R nous le dit). Pour une table 2x2, on peut utiliser le test (exact) de Fisher.

fisher.test(a1,b1)

Voir aussi :

?loglin
library(MASS)
?logml

Corrélation ???

cor.test(a1,b1)

Partial correlation is the correlation of the residuals.

cor(lm(x1~z1)$resid,lm(y1~z1)$resid)

Factor Analysis ???

factanal(m1,factors=3)

???

v1 <- kmeans(x1,3)$cluster
matplot(t(v1),t="l")

Standardize :

?scale

On ne peut pas comparer des modèles en les regardant séparémént.

summary(lm(y ~ x1 + x2))
summary(lm(y1 ~ x1 + x2 + x3 + x4))

model1 <- lm(y1 ~ x1 + x2)
model2 <- lm(y1 ~ x1 + x2 + x3 + x4)
anova(model1,model2)

A FAIRE : comparaison de modèles
library(MASS)
?addterm
data(quine)
quine.hi <- aov(log(Days + 2.5) ~ .^4, quine)
quine.lo <- aov(log(Days+2.5) ~ 1, quine)
addterm(quine.lo, quine.hi, test="F")

Simulations

v1 <- matrix(sample(c(1, 2, 3, 4, 5), size=1000, replace=T), ncol=10)

Une autre manière de remplir des matrices ou des vecteurs.

nsub1 <- nrow(q1)
cors1 <- rep(NA,ns)
for (i in 1:nsub1) cors1[i] <- cor(m1[i,],m2[i,])

AOV (within-subject) :

data1<-c(
49,47,46,47,48,47,41,46,43,47,46,45,
48,46,47,45,49,44,44,45,42,45,45,40,
49,46,47,45,49,45,41,43,44,46,45,40,
45,43,44,45,48,46,40,45,40,45,47,40) # across subjects then conditions

matrix(data1, ncol= 4, 
       dimnames = list(paste("subj", 1:12), c("Shape1.Color1", "Shape2.Color1", 
                       "Shape1.Color2", "Shape2.Color2")))        

Hays.df <- data.frame(rt = data1, 
subj = factor(rep(paste("subj", 1:12, sep=""), 4)),
shape = factor(rep(rep(c("shape1", "shape2"), c(12, 12)), 2)),
color = factor(rep(c("color1", "color2"), c(24, 24))))

aov(rt ~ shape * color + Error(subj/(shape+color)), data=Hays.df)
aov(rt ~ shape * color + Error(subj + subj:shape + subj:color), data=Hays.df)

What goes inside the Error() statement, and the order in which they
are arranged, are very important in ensuring correct statistical
tests.

Here we show you two examples of common errors. The first mistakenly
computes the repeated measure design as if it was a randomized,
between-subject design. The second only separates the subject error
stratum. The aov() function will not prevent you from fitting these
models because they are legitimate. But the tests are not what we
want.

summary(aov(rt ~ (shape * color) * subj, data=Hays.df))
summary(aov(rt ~ shape * color + Error(subj), data=Hays.df))

Autre exemple (tiré du même document, à ne pas reprendre directement)

MD497.dat <- matrix(c(
420, 420, 480, 480, 600, 780,
420, 480, 480, 360, 480, 600,
480, 480, 540, 660, 780, 780,
420, 540, 540, 480, 780, 900,
540, 660, 540, 480, 660, 720,
360, 420, 360, 360, 480, 540,
480, 480, 600, 540, 720, 840,
480, 600, 660, 540, 720, 900,
540, 600, 540, 480, 720, 780,
480, 420, 540, 540, 660, 780),
ncol = 6, byrow = T)  # byrow=T so the matrix's layout is exactly like this
  
MD497.df <- data.frame(
rt    = as.vector(MD497.dat),
subj  = factor(rep(paste("s", 1:10, sep=""), 6)),
deg   = factor(rep(rep(c(0,4,8), c(10, 10, 10)), 2)),
noise = factor(rep(c("no.noise", "noise"), c(30, 30))))

taov <- aov(rt ~ deg * noise + Error(subj / (deg + noise)), data=MD497.df)
summary(taov)

...

summary(aov(rt ~ drug + Error(subj/drug), data = Stv.df))       
summary(aov(rt ~ drug, data = Stv.df))

Un exemple assez long (un graphique fait à la main).

Ela.mat <-matrix(c(
19,22,28,16,26,22,
11,19,30,12,18,28,
20,24,24,24,22,29,
21,25,25,15,10,26,
18,24,29,19,26,28,
17,23,28,15,23,22,
20,23,23,26,21,28,
14,20,29,25,29,29,
16,20,24,30,34,36,
26,26,26,24,30,32,
22,27,23,33,36,45,
16,18,29,27,26,34,
19,21,20,22,22,21,
20,25,25,29,29,33,
21,22,23,27,26,35,
17,20,22,23,26,28), nrow = 16, byrow = T)

Ela.mul <- cbind.data.frame(subj=1:16, gp=factor(rep(1:2,rep(8,2))), Ela.mat)
dimnames(Ela.mul)[[2]] <-
c("subj","gp","d11","d12","d13","d21","d22","d23") # d12 = drug 1, dose 2

Ela.uni <- data.frame(effect = as.vector(Ela.mat),
subj = factor(paste("s", rep(1:16, 6), sep="")), 
gp = factor(paste("gp", rep(rep(c(1, 2), c(8,8)), 6), sep="")),
drug = factor(paste("dr", rep(c(1, 2), c(48, 48)), sep="")),
dose=factor(paste("do", rep(rep(c(1,2,3), rep(16, 3)), 2), sep="")), 
row.names = NULL)

attach(Ela.uni)

tmean <- tapply(effect, IND = list(gp, drug, dose), mean)
tse   <- tapply(effect, IND = list(gp, drug, dose), se)
tbarHeight <- matrix(tmean, ncol=3) 
dimnames(tbarHeight) <- list(c("gp1dr1","gp2dr1","gp1dr2","gp2dr2"), 
          c("dose1","dose2" ,"dose3")) 
tn <- tapply(effect, IND = list(gp, drug, dose), length)
tu <- tmean + qt(.975, df=tn-1) * tse    # upper bound of 95% confidence int.
tl <- tmean + qt(.025, df=tn-1) * tse    # lower bound
tcol <- c("blue", "darkblue", "yellow", "orange")  # color of the bars

tbars <- barplot(height=tbarHeight, beside=T, space=c(0, 0.5), 
                 ylab="", xlab="", axes=F, names.arg=NULL, ylim=c(-15, 40), 
                 col=tcol)

segments(x0=tbars, x1=tbars, y0=tl, y1=tu)
segments(x0=tbars-.1, x1=tbars+0.1, y0=tl, y1=tl)    # lower whiskers
segments(x0=tbars-.1, x1=tbars+0.1, y0=tu, y1=tu)    # upper whiskers

axis(2, at = seq(0, 40, by=10), labels = rep("", 5), las=1)
tx <- apply(tbars, 2, mean)   # center positions for 3 clusters of bars

segments(x0=0, x1=max(tbars)+1.0, y0=0, y1=0, lty=1, lwd = 2)
text(c("Dose 1", "Dose 2", "Dose 3"), x = tx, y = -1.5, cex =1.5)
mtext(text=seq(0,40,by=10), side = 2, at = seq(0,40,by=10), 
      line = 1.5, cex =1.5, las=1)
mtext(text="Drug Effectiveness", side = 2, line = 2.5, at = 20, cex =1.8)

tx1 <- c(0, 1, 1, 0)
ty1 <- c(-15, -15, -13, -13)
polygon(x=tx1, y=ty1, col=tcol[1])
polygon(x=tx1, y=ty1 + 2.5, col=tcol[2])  # 2nd, moved 2.5 points up
polygon(x=tx1, y=ty1 + 5, col=tcol[3])    # 3rd
polygon(x=tx1, y=ty1 + 7.5, col=tcol[4])  # last

text(x = 2.0, y = -14, labels="group 1, drug 1",  cex = 1.5, adj = 0)
text(x = 2.0, y = -11.5, labels="group 2, drug 1",  cex = 1.5, adj = 0)
text(x = 2.0, y = -9, labels="group 1, drug 2",  cex = 1.5, adj = 0)
text(x = 2.0, y = -6.5, labels="group 2, drug 2",  cex = 1.5, adj = 0)

A la fin, il y a une explication sur l'argument Error de la commande aov.

A FAIRE : A LIRE

Régression logistique. Il s'agit maintenant de prédire la valeur d'une variable qualitative à deux valeurs à l'aide de variables quantitatives. Pour une seule variable, on part de

P( Y=1 ) = exp(X) / (1 + exp(X) )

qui s'écrit encore

ln( P(Y) / (1-P(Y)) ) = X.

On essaye donc d'écrire

ln( P(Y) / (1-P(Y)) ) = a0 + a1 X1 + a2 X2 + ...

Sous R la fonction est glm (Generalized Linear Model). L'argument "binomial" dit quelle transformation il faut utiliser.

summary(glm(y ~ x1 + x2 + x3, family=binomial))

On a aussi souvent besoin de connaitre la pertinence du modèle.

glm1 <- glm(y ~ x1 + x2 + x3, family=binomial)
glm0 <- glm(y ~ 1, family=binomial)
anova(glm0,glm1,test="Chisq")

Modèles log-linéaires

?glm

Exemples fabriqués

(c'est moi qui les fabrique)

Test d'indépendance de deux variables qualitatives

x <- sample( c(rep(0,3),rep(1,7)), 10, replace=T )
y <- sample( c(0,1), 10, replace=T )

La commande table permet d'avoir le résultat sous forme de tableau de contingence.

> table(x,y)
   y
x   0 1
  0 2 0
  1 6 2

On peut faire un test d'indépendance en utilisant le Chi2.

> chisq.test(x,y, correct=T)

      Pearson's Chi-squared test with Yates' continuity correction

data:  x and y
X-squared = 0.0391, df = 1, p-value = 0.8433

Warning message:
Chi-squared approximation may be incorrect in: chisq.test(x, y, correct = T)

R nous rappelle à juste titre que le Chi2 n'est qu'une approximation : dans ce cas précis, elle n'est probablement pas valable (si on a plus de 30 individus et si chaque case du tableau de contingence contient un nombre au moins égal à 5, on peut y aller les yeux fermés, mais ici...). On peut alors faire un test plus exact, celui de Fisher.

> fisher.test(t)

      Fisher's Exact Test for Count Data

data:  t
p-value = 1
alternative hypothesis: true odds ratio is not equal to 1
95 percent confidence interval:
 0.03845334        Inf
sample estimates:
odds ratio
       Inf

Je ne comprends pas pourquoi il donne souvent (prés d'une fois sur deux, d'après le graphique suivant) une p-valeur égale à 1.

N <- 10000
f <- NULL
c <- NULL
for (i in 1:N) {
  x <- sample( c(rep(0,3),rep(1,7)), 10, replace=T )
  y <- sample( c(0,1), 10, replace=T )
  x <- factor(x, levels=c(0,1))
  y <- factor(y, levels=c(0,1))
  t <- table(x,y)
  f <- append(f, fisher.test(t)$p.value)
  c <- append(c, chisq.test(t)$p.value)
}
plot(sort(f), type='l')
points(sort(c), type='l', col='red')

*

*

Voici néanmoins un exemple où on n'a pas 1.

> x <- sample( c(rep(0,3),rep(1,7)), 10, replace=T )
> y <- sample( c(0,1), 10, replace=T )
> t <- table(x,y)
> t
   y
x   0 1
  0 4 1
  1 1 4
> chisq.test(t)

      Pearson's Chi-squared test with Yates' continuity correction

data:  t
X-squared = 1.6, df = 1, p-value = 0.2059

Warning message:
Chi-squared approximation may be incorrect in: chisq.test(t)
> fisher.test(t)

      Fisher's Exact Test for Count Data

data:  t
p-value = 0.2063
alternative hypothesis: true odds ratio is not equal to 1
95 percent confidence interval:
   0.45474 968.76176
sample estimates:
odds ratio
   10.9072

Calculons notre propre p-valeur à l'aide d'une simulation.

x <- sample( c(rep(0,3),rep(1,7)), 10, replace=T )
y <- sample( c(0,1), 10, replace=T )
x <- factor(x, levels=c(0,1))
y <- factor(y, levels=c(0,1))
pValeur <- function (x,y, N=1000) {
  x <- factor(x)
  y <- factor(y)
  s <- numeric(N)
  for (i in 1:N) {
    xx <- sample( x, length(x), replace=T )
    yy <- sample( y, length(y), replace=T )
    s[i] <- as.numeric(chisq.test(table(xx,yy))$statistic)
  }
  t <- table(x,y)
  p <- sum( chisq.test(t)$statistic > s )/length(s)
  if( p>.5 ) p <- 1-p
  p
}
t <- table(x,y)
c( ChiSq = chisq.test(t)$p.value, Fisher = fisher.test(t)$p.value, MonteCarlo = pValeur(x,y) )

#Représentons maintenant nos trois p-valeurs sur un même graphique.

N <- 100
f <- NULL
c <- NULL
s <- NULL
for (i in 1:N) {
  x <- sample( c(rep(0,3),rep(1,7)), 10, replace=T )
  y <- sample( c(0,1), 10, replace=T )
  x <- factor(x, levels=c(0,1))
  y <- factor(y, levels=c(0,1))
  t <- table(x,y)
  f <- append(f, fisher.test(t)$p.value)
  c <- append(c, chisq.test(t)$p.value)
  s <- append(s, pValeur(x,y,100))
}
plot(sort(f), type='l')
points(sort(c), type='l', col='green')
points(sort(s), type='l', col='red')
  
# J'ai de TRÈS gros doutes sur la pertinence de mes calculs...
# A FAIRE

*

Exemples d'Anova

library(MASS)
data(anorexia)
A FAIRE : dessin
coplot(Postwt ~ Prewt | Treat, data=anorexia)
plot(Postwt ~ Prewt, col=(2:10)[Treat])
plot( Postwt - Prewt ~ Treat)
A FAIRE : les traitements ont-ils la même efficacité ?
?aov

A FAIRE : comprendre les exemples de 
?bacteria

Avec une dizaine de variables :

data(biopsy)

Comprendre des formules du genre :

data(nlschools)
library(nlme)
nl1 <- nlschools
attach(nl1)
classMeans <- tapply(IQ, class, mean)
nl1$IQave <- classMeans[as.character(class)]
nl1$IQ <- nl1$IQ - nl1$IQave
detach()
cen <- c("IQ", "IQave", "SES")
nl1[cen] <- scale(nl1[cen], center = TRUE, scale = FALSE)

nl.lme <- lme(lang ~ IQ*COMB + IQave + SES,
              random = ~ IQ | class, data = nl1)
summary(nl.lme)

Test non paramétrique de la médiane

a <- runif(10, 0,1)
b <- runif(10, 0,5)
# On range les données dans un Data Frame
d <- data.frame( value = c(a,b), 
                 type  = c( rep("A",10),rep("B",10) ),
                 block = factor( c(1:10,1:10) ))
# test non paramétrique
t <- table( d$value > mean(d$value), d$type )
chisq.test(t) # p-value = 0.005
# Test paramétrique 
anova(lm(value~type, data=d), test="F") # p-value = 0.0002
# Test non paramétrique
wilcox.test(d$value[d$type=="A"], d$value[d$type=="B"]) # p-value = 0.0001
# Kruskal--Wallis
kruskal.test(d$value ~ d$type)
friedman.test(d$value, d$type, d$block)
# 
anova(lm(value~type+other, data=d), test="F")

Régression linéaire

Régression affine

summary(lm(y~x))

Régression vraiment linéaire (ou test sur l'annulation du coefficient)

summary(lm(y~-1+x))

Graphiques (attention, il y en a plusieurs !!!)

plot( lm(y~x), ask=T )

ou

op=par(mfrow=c(3,2))
plot( lm(y~x) )
par(op)

(les trois premiers sont faciles à comprendre ; le troisième est un QQplot des résidus, pour vérifier leur normalité ; le quatrième permet de comparer la variance expliquée et la variance résiduelle ; le dernier donne la distance de Cook, ie, la distance entre les paramètres estimés avec ou sans le point, afin de repérer les points aberrants).

Régression et analyse de la variance ???

anova(lm( y ~ x ))
anova(lm( y ~ x+z ))
anova(lm( y ~ x+z+w ))

Régression polynomiale, recherche du degré du polynôme.

anova(lm( y ~ x + poly(z,2) + w ), lm( y ~ x + poly(z,3) + w ) )

Ecriture du modèle : on utilise des << + >> quand il n'y a pas d'interaction et des << * >> quand (on pense qu') il y en a. Un point signifie "toutes les autres variables du data frame" :

y~.

Lecture des résultats

?anova
?aov # idem, avec une interface différente
?summary
?plot(..., ask=T)
?effects
?predict
?lm.influence
?glm

********

Divers

Comparaison de moyennes à l'aide de permutations.

x <- c(40,40,41)
y <- c(42,43,45)
t.test(x,y)
N <- 10000
mx <- NULL
my <- NULL
for (i in 1:N) {
  v <- sample( c(x,y), replace=F )
  x1 <- v[1:length(x)]
  y1 <- v[length(x)+1:length(y)]
  mx <- append(mx, mean(x1))
  my <- append(my, mean(y1))
}
pValue <- function (x, m) {
  p <- sum(x<=m)/length(x)
  if( p>.5 ) p <- sum(x>=m)/length(x)
  2*p
}

On trouve :

> pValue( mx, mean(x) )
[1] 0.0934
> pValue( my, mean(y) )
[1] 0.0934

Alors qu'en faisant des permutations avec remplacement, (A FAIRE : comprendre quelle est la différence, au niveau de l'interprétation du résultat) on obtiendrait :

> pValue( mx, mean(x) )
[1] 0.1834
> pValue( my, mean(y) )
[1] 0.2432

On peut représenter cela graphiquement

myPlot <- function (x,m) {
  x <- sort(x)
  plot( x ~ seq(0,1,length=length(x)), type="l", lwd=3 )
  confidence <- .05
  xx <- x[ (N*confidence/2) : (N - N*confidence/2) ]
  points( xx ~ seq(confidence/2, 1-confidence/2, length=length(xx)), type="l", col="green", lwd=3)
  abline(m,0, col="red")
  p <- sum(x<=m)/length(x)
  if( p>.5 ) p <- sum(x<m)/length(x)
  points( p,m, col='red', pch=4, lwd=2 )
}
myPlot( mx, mean(x) )

*

Voici le graphique que l'on obtiendrait avec des échantillons normaux standard de 50 individus chacun.

*

A titre de comparaison, le test de Student nous donne :

> t.test(x,y)

      Welch Two Sample t-test

data:  x and y
t = -3.182, df = 2.56, p-value = 0.06215
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -6.3143919  0.3143919
sample estimates:
mean of x mean of y
 40.33333  43.33333

Dans tous les cas, la conclusion est la même : on ne rejette pas l'hypothèse nulle << les deux moyennes sont égales >>.

----------------------

vocabulaire

Factorial design : on a variables qualitatives et on représente le sésultat de l'expérience par un tableau de contingences. On parle de << factorial design >> si aucune des cases de ce tableau n'est vide. On examine toutes ces cases, i.e., on ne se contente pas de regarder les effectgifs marginaux.

voici mes premières notes sur R

A FAIRE : les intégrer à celles ci-dessus.

Types de données

Vecteurs

Une suite d'objets, tous de même type (nombre, booléen, chaine de caractères).

Data Frame

Un tableau, avec plusieures colonnes ; chaque colonne est un vecteur et porte un titre, les colonnes peuvent être de types différents.

Régression

Régression linéaire

lm(y ~ x)

Régression résistante (il peut y avoir des données fausses).

rlm(y ~ x)

A CLASSER

curve  Tracer une courbe à l'aide de son équation

Regarder des données catégoriques.

> table(a>5)
FALSE  TRUE
   10     7
> table(a)
a
0 1 3 4 5 6 7 8 9
1 2 2 4 1 3 1 1 2

Histogramme (l'unité verticale est le nombre d'éléments).

> hist(a)

Histogramme (l'unité verticale est la proportion des éléments -- utile pour comparer deux histogrammes réalisés avec des populations différentes).

> hist(a, probability=TRUE)

*

Histogramme avec des choses en plus sur l'axe horizontal (???)

> hist(a)
> rug(jitter(a))

*

Histogramme (on spécifie le nombre de classes).

> hist(a, breaks=10)

*

Histogramme (on spécifie les classes).

> hist(a, breaks=c(0,3,5,7,max(a)))

*

Frequency polygon

> tmp = hist(a)
> lines( c(min(tmp$breaks),tmp$mids,max(tmp$breaks)),
         c(0,tmp$counts,0), 
         type="l")

*

Densités

> density(a)
Call:
      density(x = a)
Data: a (17 obs.);      Bandwidth 'bw' = 1.143
       x                y
 Min.   :-3.430   Min.   :0.0002538
 1st Qu.: 0.535   1st Qu.:0.0165095
 Median : 4.500   Median :0.0653932
 Mean   : 4.500   Mean   :0.0629752
 3rd Qu.: 8.465   3rd Qu.:0.1003278
 Max.   :12.430   Max.   :0.1404533
> hist(a, probability=TRUE)
> points(density(a),type='l')
> points(density(a,bw=.1),type='l')

*

Bar plots

> data(package='MASS')
> library("MASS")
> ?biopsy
> data(biopsy)
> barplot(table(biopsy$class, biopsy$V7), beside=TRUE)

*

> barplot(table(biopsy$V7, biopsy$class))

*

Side-by-side boxplots

> boxplot( biopsy$V7 [biopsy$class == 'benign'], 
           biopsy$V7 [biopsy$class == 'malignant'])
> boxplot( biopsy$V7 ~ biopsy$class )

*

Boxplots to compare different data.

> data(crabs)
> boxplot( crabs$RW, crabs$CW)

*

We may have to scale them (so that they have mean 0 and standard deviation 1).

> boxplot( as.data.frame(scale(data.frame( crabs$RW, crabs$CW ))))

*

Strip charts : an alternative to box plots

> stripchart(crabs$RW[1:20])

*

Side by side strip charts (hint: put the data in a data frame?)

> stripchart(data.frame(crabs$RW, crabs$CW))
> stripchart(crabs)

*

*

Scatter Plot

> plot(crabs$CL, crabs$CW)

DESSIN

Scatter plot with linear regression

> plot(crabs$CL, crabs$CW)
> lm( crabs$CL ~ crabs$CW )
Call:
lm(formula = crabs$CL ~ crabs$CW)
Coefficients:
(Intercept)     crabs$CW
    -0.6619       0.8998

> summary(lm( crabs$CL ~ crabs$CW ))

Call:
lm(formula = crabs$CL ~ crabs$CW)

Residuals:
    Min      1Q  Median      3Q     Max
-1.6732 -0.4943 -0.1069  0.5915  1.6396

Coefficients:
             Estimate Std. Error t value Pr(>|t|)
(Intercept) -0.661948   0.238574  -2.775  0.00606 **
crabs$CW     0.899846   0.006404 140.504  < 2e-16 ***
---
Signif. codes:  0 `***' 0.001 `**' 0.01 `*' 0.05 `.' 0.1 ` ' 1

Residual standard error: 0.7112 on 198 degrees of freedom
Multiple R-Squared: 0.9901,     Adjusted R-squared:  0.99
F-statistic: 1.974e+04 on 1 and 198 DF,  p-value: < 2.2e-16

> abline(lm( crabs$CL ~ crabs$CW ))

*

Histogram of residuals

> lm.res = lm(crabs$CL ~ crabs$CW)
> plot(residuals(lm.res))    # Non
> hist(residuals(lm.res))

*

Residual plot : on fait une régression, puis on fait un "scatter plot" avec en abscisse les valeurs théoriques et en ordonnées les valeurs réelles.

A FAIRE
DESSIN

On peut aussi représenter les valeurs calculées en abscisse et les valeurs résiduelles en ordonnée.

> ?lm
> plot(lm.res$fitted.values, lm.res$residuals)
> abline(0,0)

DESSIN

Paired scatter plot

A FAIRE

Normal plot : en abscisse, les quantiles d'une distribution normale, en ordonnée, les quatiles effectivement observées. Si c'est une droite, les données sont normales.

> qqnorm(a); qqline(a)

*

> qqnorm(crabs$CL); qqline(crabs$CL)

*

> x = rnorm(100); qqnorm(x); qqline(x)

*

> x = runif(100); qqnorm(x); qqline(x)

*

Normal plot of residuals : do a regression and check if the residuals are normal.

> lm.res = lm(crabs$CL ~ crabs$CW)
> qqnorm(residuals(lm.res)); qqline(residuals(lm.res))

*

> x = rnorm(1000)
> y = exp(x)
> qqnorm(y); qqline(y)

*

> y = x[x>0]
> qqnorm(y); qqline(y)

*

> y = rexp(1000)
> qqnorm(y); qqline(y)

*

Manipulation des données

Extraire un ou plusieurs éléments d'un vecteur :

> a[1]
[1] 1
> a[1:3]
[1] 1 4 9

> a[1,3,5]
Error in a[1, 3, 5] : incorrect number of dimensions
> a[c(1,3,5)]
[1] 1 9 8

Extraire un ou plusieurs éléments d'un vecteur à l'aide de conditions booléennes.

> a>5
 [1] FALSE FALSE  TRUE  TRUE  TRUE  TRUE FALSE FALSE  TRUE FALSE FALSE  TRUE
[13] FALSE FALSE  TRUE FALSE FALSE
> a[a>5]
[1] 9 6 8 6 6 9 7

Attention aux connecteurs logiques : ce sont & et |.

> a[a>3 & a<7]
[1] 4 6 6 4 6 4 5 4
> a[a<3 | a>7]
[1] 1 9 8 9 0 1

Pour la négation, c'est bien !

> a[!is.na(x)]

Compter le nombre d'éléments qui vérifient une condition.

> sum(a>5)
[1] 7

Tri des données

> sort(a)
 [1] 0 1 1 3 3 4 4 4 4 5 6 6 6 7 8 9 9

Transformer des données numériques en données catégoriques. (voir aussi le paramètre break de la fonction hist)

> b = cut(a, breaks=c(0, 3, 7, 10))
> b
 [1] (0,3]  (3,7]  (7,10] (3,7]  (7,10] (3,7]  (0,3]  (3,7]  (3,7]  (3,7]
[11] (3,7]  (7,10] <NA>   (0,3]  (3,7]  (0,3]  (3,7]
Levels:  (0,3] (3,7] (7,10]
> table(b)
b
 (0,3]  (3,7] (7,10]
     4      9      3
> ?factor

Mise à l'échelle des données pour les comparer : si le Data Frame foo contient deux colonnes numériques, on peut les mettre à la même échelle pour les comparer :

bar = as.data.frame(scale(bar))

Programmation

Boucle

> for ( i in 1:100 ) { ... }

Définition d'une fonction

> f = function(x) sqrt(var(x))
> f(a); sd(a)
[1] 2.687115
[1] 2.687115

Définition d'une fonction plus longue : on ajoute des accolades ; la dernière valeur calculée est renvoyée.

foo = function(x) {
  a = fivenum(x)
  a[4] - a[2]
}

On peut voir le code d'une fonction en tapant son nom, sans parenthèses.

> abline
function (a = NULL, b = NULL, h = NULL, v = NULL, reg = NULL,
  coef = NULL, untf = FALSE, col = par("col"), lty = par("lty"),
  lwd = NULL, ...)
{
  if (!is.null(reg))
    a <- reg
  if (!is.null(a) && is.list(a)) {
    temp <- as.vector(coefficients(a))
    if (length(temp) == 1) {
      a <- 0
      b <- temp
    }
    else {
      a <- temp[1]
      b <- temp[2]
    }
  }
  if (!is.null(coef)) {
    a <- coef[1]
    b <- coef[2]
  }
  .Internal(abline(a, b, h, v, untf, col, lty, lwd, ...))
  invisible()
}

A FAIRE

A FAIRE : les fonctions pnorm, qnorm. page 47

------------

Exemples de données

Données numériques univariées

   data(aircondit)

Données numériques bivariées

   data(cars)
   plot(cars, xlab = "Speed (mph)", ylab = "Stopping distance (ft)",
        las = 1)
   lines(lowess(cars$speed, cars$dist, f = 2/3, iter = 3), col = "red")
   title(main = "cars data")

   plot(cars, xlab = "Speed (mph)", ylab = "Stopping distance (ft)",
        las = 1, log = "xy")
   title(main = "cars data (logarithmic scales)")
   lines(lowess(cars$speed, cars$dist, f = 2/3, iter = 3), col = "red")

Autre exemple: trees

Autre exemple:
  data(longley)
  pairs(longley)

Données catégoriques bivariées.

Autre exemple: Titanic

Données multivariées en partie numériques en partie catégoriques

?ToothGrotwth
The Effect of Vitamin C on Tooth Growth in Guinea Pigs
data(ToothGrowth)

Time series

   data(nhtemp)
   plot(nhtemp, main = "nhtemp data",
     ylab = "Mean annual temperature in New Haven, CT (deg. F)")

------------

Exemples

   data(ToothGrowth)
   coplot(len ~ dose | supp, data = ToothGrowth, panel = panel.smooth,
          xlab = "ToothGrowth data: given is supplement type")


   data(HairEyeColor)
   ## Full mosaic
   mosaicplot(HairEyeColor)
   ## Aggregate over sex:
   x <- apply(HairEyeColor, c(1, 2), sum)
   x
   mosaicplot(x, main = "Relation between hair and eye color")

   data(cars)
   plot(cars, xlab = "Speed (mph)", ylab = "Stopping distance (ft)",
        las = 1)
   lines(lowess(cars$speed, cars$dist, f = 2/3, iter = 3), col = "red")
   title(main = "cars data")
   plot(cars, xlab = "Speed (mph)", ylab = "Stopping distance (ft)",
        las = 1, log = "xy")
   title(main = "cars data (logarithmic scales)")
   lines(lowess(cars$speed, cars$dist, f = 2/3, iter = 3), col = "red")
   summary(fm1 <- lm(log(dist) ~ log(speed), data = cars))
   opar <- par(mfrow = c(2, 2), oma = c(0, 0, 1.1, 0),
               mar = c(4.1, 4.1, 2.1, 1.1))
   plot(fm1)
   par(opar)

   ## An example of polynomial regression
   plot(cars, xlab = "Speed (mph)", ylab = "Stopping distance (ft)",
       las = 1, xlim = c(0, 25))
   d <- seq(0, 25, len = 200)
   for(degree in 1:4) {
     fm <- lm(dist ~ poly(speed, degree), data = cars)
     assign(paste("cars", degree, sep="."), fm)
     lines(d, predict(fm, data.frame(speed=d)), col = degree)
   }
   anova(cars.1, cars.2, cars.3, cars.4)


   data(Titanic)
   mosaicplot(Titanic, main = "Survival on the Titanic")
   ## Higher survival rates in children?
   apply(Titanic, c(3, 4), sum)
   ## Higher survival rates in females?
   apply(Titanic, c(2, 4), sum)
   ## Use loglm() in package `MASS' for further analysis ...


   data(trees)
   pairs(trees, panel = panel.smooth, main = "trees data")
   plot(Volume ~ Girth, data = trees, log = "xy")
   coplot(log(Volume) ~ log(Girth) | Height, data = trees,
          panel = panel.smooth)
   summary(fm1 <- lm(log(Volume) ~ log(Girth), data = trees))
   summary(fm2 <- update(fm1, ~ . + log(Height), data = trees))
   step(fm2)
   ## i.e. Volume ~= c * Height * Girth^2  seems reasonable


   data(faithful)
   f.tit <-  "faithful data: Eruptions of Old Faithful"

   ne60 <- round(e60 <- 60 * faithful$eruptions)
   all.equal(e60, ne60)             # relative diff. ~ 1/10000
   table(zapsmall(abs(e60 - ne60))) # 0, 0.02 or 0.04
   faithful$better.eruptions <- ne60 / 60
   te <- table(ne60)
   te[te >= 4]                      # (too) many multiples of 5 !
   plot(names(te), te, type="h", main = f.tit, xlab = "Eruption time (sec)")

   plot(faithful[, -3], main = f.tit,
        xlab = "Eruption time (min)",
        ylab = "Waiting time to next eruption (min)")
   lines(lowess(faithful$eruptions, faithful$waiting, f = 2/3, iter = 3),
         col = "red")


 data(longley)
   longley.x <- data.matrix(longley[, 1:6])
   longley.y <- longley[, "Employed"]
   pairs(longley, main = "longley data")
   summary(fm1 <- lm(Employed ~ ., data = longley))
   opar <- par(mfrow = c(2, 2), oma = c(0, 0, 1.1, 0),
               mar = c(4.1, 4.1, 2.1, 1.1))
   plot(fm1)
   par(opar)


   data(precip)
   dotchart(precip[order(precip)], main = "precip data")
   title(sub = "Average annual precipitation (in.)")


   data(iris3)
   dni3 <- dimnames(iris3)
   ii <- data.frame(matrix(aperm(iris3, c(1,3,2)), ncol=4,
                      dimnames=list(NULL, sub(" L.",".Length",
                                              sub(" W.",".Width", dni3[[2]])))),
                    Species = gl(3,50,lab=sub("S","s",sub("V","v",dni3[[3]]))))
   data(iris)
   all.equal(ii, iris) # TRUE



   matplot((-4:5)^2, main = "Quadratic") # almost identical to plot(*)
   sines <- outer(1:20, 1:4, function(x, y) sin(x / 20 * pi * y))
   matplot(sines, pch = 1:4, type = "o", col = rainbow(ncol(sines)))




   x <- 0:50/50
   matplot(x, outer(x, 1:8, function(x, k) sin(k*pi * x)),
           ylim = c(-2,2), type = "plobcsSh",
           main= "matplot(,type = \"plobcsSh\" )")
   ## pch & type =  vector of 1-chars :
   matplot(x, outer(x, 1:4, function(x, k) sin(k*pi * x)),
           pch = letters[1:4], type = c("b","p","o"))

   data(iris)                  # is data.frame with  `Species' factor
   table(iris$Species)
   iS <- iris$Species == "setosa"
   iV <- iris$Species == "versicolor"
   op <- par(bg = "bisque")
   matplot(c(1, 8), c(0, 4.5), type= "n", xlab = "Length", ylab = "Width",
           main = "Petal and Sepal Dimensions in Iris Blossoms")
   matpoints(iris[iS,c(1,3)], iris[iS,c(2,4)], pch = "sS", col = c(2,4))
   matpoints(iris[iV,c(1,3)], iris[iV,c(2,4)], pch = "vV", col = c(2,4))
   legend(1, 4, c("    Setosa Petals", "    Setosa Sepals",
                  "Versicolor Petals", "Versicolor Sepals"),
          pch = "sSvV", col = rep(c(2,4), 2))

   nam.var <- colnames(iris)[-5]
   nam.spec <- as.character(iris[1+50*0:2, "Species"])
   iris.S <- array(NA, dim = c(50,4,3), dimnames = list(NULL, nam.var, nam.spec))
   for(i in 1:3) iris.S[,,i] <- data.matrix(iris[1:50+50*(i-1), -5])

   matplot(iris.S[,"Petal.Length",], iris.S[,"Petal.Width",], pch="SCV",
           col = rainbow(3, start = .8, end = .1),
           sub = paste(c("S", "C", "V"), dimnames(iris.S)[[3]],
                       sep = "=", collapse= ",  "),
           main = "Fisher's Iris Data")

------------

   for(fn in methods("predict"))
      cat(fn,":\n\t",deparse(args(get(fn))),"\n")

revoir les histoires de conversion, à partir de la page 38. factor stack split unstack t rbind

outer paste

Je suis arrivé page 38.

Distributions statistiques

                              loi multinomiale
                              (plusieures catégories d'évènements)

loi hypergéométrique          loi binomiale                         Poisson
(tirage sans remise)          (2 catégories d'évènements)           (p=0 ou 1)

                              Loi normale
                              (chi2, student, fisher)


Chi_n^2 = somme des carrés de n lois normales
Pour n grand, Chi_n^2 ~ N(n, sqrt(2n))
Application : intervalle de confiance de l'écart-type.
Dessiner le graphe de la densité du Chi2, pour différents degrés de liberté.

Fisher
F_{n,m} = (Chi_n^2 / n) / (Chi_m^2 / m)
(test F de rapport de variances,
analyse de variance)

Student
T_n = N(0,1)/sqrt( Chi_n^2 / n )
    = sqrt( F_{1,n} )
(test de comparaison de moyenne, 
probabilité d'observer un écart donné à la moyenne,
estimation des paramètres d'une population)
C'est la distribution de la moyenne empirique d'un 
échantillon de n individus d'une population de N>>n individus.
  (moyenne empirique - moyenne réelle)/(variance empirique/sqrt(n)) ~ T_n
Pour n>1000, T_n ~ N(0,1)
Application : calcul d'intervalle de confiance pour
la moyenne.

/home/zoonek/spool/WWW/DOC/STAT/biol10.biol.umontreal.ca/BIO2041/pdf/Cours_05-Int_confiance.pdf

A CLASSER

text   affiche du texte à un endrot du dessin
mtext  affiche du texte dans la marge

EN COURS

Analyse en composantes principales.

a <- Seconde13[3:7] a <- as.matrix(a) a[is.na(a)]=10 cov(a) b <- eigen(cov(a), symmetric=TRUE) x <- b$vectors[,1] y <- b$vectors[,2] Il faut projeter orthogonalement sur Vect(x,y)

C'est déjà là...

library(mva) a <- Seconde13[3:7] a <- as.matrix(a) a[is.na(a)]=10 p <- princomp(a) p p$scores plot( p$scores[,2] ~ p$score[,1], pch=" " ) text( p$score[,1], p$score[,2], as.vector(Seconde13[,1]) ) plot(p$sdev, type="h")

EFFACER CE QUI PRECEDE

a <- Seconde13[3:7] a <- a - t( array( apply(a, 2, mean, na.rm=T), dim(t(a)) )) apply(a, 2, mean, na.rm=T) a <- as.matrix(a) a[is.na(a)]=0 a <- a / t( array( apply(a, 2, sd), dim(t(a)) )) apply(a, 2, sd) library(mva) p <- princomp(a)

# ACP : plot( p$scores[,2] ~ p$score[,1], pch=" " ) text( p$score[,1], p$score[,2], as.vector(Seconde13[,1]) )

# Les valeurs propres plot(p$sdev, type="h")

# Le cercle des covariances A FAIRE

A FAIRE : la même chose, mais à la main.

A CLASSER

A FAIRE : comprendre les fonctions :

princomp
prcomp
factanal
kmeans
hclust
plot.agnes               Plots of an Agglomerative Hierarchical Clustering
plot.diana               Plots of a Divisive Hierarchical Clustering
plot.mona                Banner of Monothetic Divisive Hierarchical Clusterings
plot.partition           Plot of a Partition of the Data Set

MASS : Modern Applied Statistics with S (avec plein de jeux de données)

library(help=MASS)
library(MASS)
...

Réseaux de neurones

library(help=nnet)
library(nnet)
...

Séries temporelles

library(help=ts)
library(ts)
...

Trois types de tableaux de nombres : valeurs d'une variable quatitative, tableau de contingence, tableau de présence-absence contenant des 0 et des 1 (sous R, ce dernier type de tableau est plutôt un tableau dont les colonnes sont des facteurs).

A FAIRE : différence entre corrélation et covariance (la covariance a une unité, pas la corrélation).

Le zoo des tests statistiques : A FAIRE

A FAIRE : le vocabulaire de la statistique est très mal conçu. Des méthodes similaires (au niveau technique ou au niveau des applications) portent des noms complètement différents. Essayer de résumer ce vocabulaire à l'aide d'un tableau.

Gauss-Markov Theorem: Least squares estimates of beta have the smallest variance among all linear unbiased estimates. (But it is not a good idea to restrict oneself to unbiased estimates...)

A CLASSER (exemples divers)

?by

Legend under the graph (not over...)

par("mar") # borders, see ?par
# [1] 5.1 4.1 4.1 2.1
# Now increase size of the bottom-border:
par(mar=c(10.1, 4.1, 4.1, 2.1))
# And set cpd=TRUE, so all plotting is clipped to the figure
# (not the plot) region:
par(xpd=TRUE)
# Your barplot:
bp <- barplot(1:3)
# Text for the legend:
legend.text <- c("cats", "dogs", "cows")
# And plot the legend below the existing plot:
legend(1,-0.5, legend.text, fill=heat.colors(length(legend.text)))
# Or much nicer, center the legend:
legend(mean(range(b)), -0.5, legend.text, xjust = 0.5,
      fill=heat.colors(length(legend.text)))

Same, horizontal.

## increase size of the bottom-border:
par(mar= c(6, 4, 4, 2) + .1)
## Set xpd=TRUE, so all plotting is clipped to the figure
## (not the plot) region:
par(xpd=TRUE)
## Your barplot:
bp <- barplot(1:3)
## Text for the legend:
legend.text <- c("cats", "dogs", "cows")
## And plot the legend below the existing plot -- centering it
legend(mean(range(bp)), -0.3, legend.text, xjust = 0.5,
      fill=heat.colors(length(legend.text)), horiz = TRUE)

Search for outliers, Mahalanobis distance

As I want to do some multivariate calibration using these data, I
checked whether some multivariate outliers existed. I calculated
Mahalanobis distances and did a

qqplot(qchisq(ppoints(382),169),XMaha)

where XMaha contained my Mahalanobis distances. The points on my QQ
plot were nicely aligned onto a y=x line, so no outliers.

A FAIRE

Beaux exemples de graphiques :
  http://www.visualmining.com/examples/index.html

?plotmath
Les symboles mathématiques dans les graphiques

Mon problème avec outer() est décrit dans la FAQ : If you have a
function that cannot handle two vectors but can handle two scalars,
then you can still use outer() but you will need to wrap your
function up first, to simulate vectorized behavior. Suppose your
function is
  foo <- function(x, y, happy) {
    stopifnot(length(x) == 1, length(y) == 1) # scalars only!
    (x + y) * happy
  }
If you define the general function
  wrapper <- function(x, y, my.fun, ...) {
    sapply(seq(along=x), FUN = function(i) my.fun(x[i], y[i], ...))
  }
then you can use outer() by writing, e.g.,
  outer(1:4, 1:2, FUN = wrapper, my.fun = foo, happy = 10)

GAM (from the FAQ):
7.17 Are GAMs implemented in R?
There is a gam() function for Generalized Additive Models in package
mgcv, but it is not an exact clone of what is described in the White
Book (no lo() for example). Package gss can fit spline-based GAMs
too. And if you can accept regression splines you can use glm(). For
gaussian GAMs you can use bruto() from package mda.

mixtures

CART
library(help=rparts)

GAM


EDA: Exploratory Data Analysis
OLS: Ordinary Least Squares
RSS: Residual Sum of Squares (la quantité que l'on cherche à minimiser avec les OLS)

Comment mentir avec des statistiques
ex: faire plein de tests afin d'augmenter le risque d'erreur de type 1
ex: prendre des hypothèses non symétriques par ce qu'on veut que le
résultat soit dans un sens.

Vérifier l'indépendance de deux variables à l'aide d'un chi-plot.
Andrew curve ???

?image
(to plot a matrix, in image analysis)
?read.pnm
(to read it from a file)

Fitting a distribution to a given law, and finding the parameters.
library(MASS)
?fitdistr

Calculs numériques
Minimiser une fonction :
?optim
?lnm
Trouver une racine (une seule variable)
?uniroot

A FAIRE : modifier plot.lm
pour ajouter qqline au qqplot des résidus
et ajouter un lissage des résidus.

Clustering (variante de l'ACP?)
  library(cluster)
  clusplot(a, pam(a, 3)$clustering, diss = FALSE, plotchar = TRUE, color = TRUE)

   data(votes.repub)
   votes.diss <- daisy(votes.repub)
   votes.clus <- pam(votes.diss, 2, diss = TRUE)$clustering
   clusplot(votes.diss, votes.clus, diss = TRUE, shade = TRUE)

   data(iris)
   iris.x <- iris[, 1:4]
   clusplot(iris.x, pam(iris.x, 3)$clustering, diss = FALSE,
            plotchar = TRUE, color = TRUE)

mentionner refcard.pdf
Pour les graphiques, renvoyer au document en espagnol (même si on ne parle pas cette langue -- je n'en comprends pas un mot, mais j'ai trouvé le document très instructif)
séries temporelles
fréquences cumulées
Intervalle de confiance pour les paramètres d'une régression
ANOVA et régression :
  quand on fait une régression, 
  variance de Y = variance expliquée par X + variance résiduelle
Le Chi2 est un test courant filtrant, pour prévenir que l'on a collecté assez de données pour rejeter H0
Le Chi2 d'indépendance (deux variables qualitatives)
Parler aussi de processus (Markov, Poisson)
  file:///home/zoonek/spool/WWW/DOC/STAT/rfv.insa-lyon.fr/%257Ejolion/STAT/poly.html
Séries temporelles : représenter les points de coordonnées (x_n, x_{n+k}), où k est un entier fixé. Par exemple, avec un mauvais générateur aléatoire. Ca sert à repérer de l'ordre dans le chaos apparent.
Tests fishériens ou tests de permutations
Exemple : analyse d'image
Exemple : analyse de son
Réseaux de neurones
ACP après avoir remplacé les variables par le rang (de Pearson)

Tracer des suites, ou des fonctions de distribution discrètes :
lines(..., type='b')

conditional logistic regression

library(nlme)

Contrasts in linear models

weibull survival analysis

Mixture Analysis: les données proviennent de deux modèles (ou plus), mais on ne sait pas à quel modèle se ratachent les individus (typiquement : l'histogramme des données a deux pics).
 
Classification à l'aide d'une droite (on a deux variables
quantitatives, un variable qualitative à deux valeurs, on fait un
diagramme de dispersion sur les deux premières variables, on
représente les individus par un symbole différent selon la valeur de
la dernière variable, on cherche un droite qui sépare le plan en
deux, selon la valeur de ce paramètre.

Contour plot / surface représentant la densité d'une v.a. bivariée.

KalmanLike(ts)          Kalman Filtering
(c'est une régression linéaire incrémentale).

Hauck-Donner phenomenon

> From <@uconnvm.uconn.edu:kent@darwin.eeb.uconn.edu> Wed Jan 7 12:51 GMT 1998 > To: ripley@stats.ox.ac.uk (Prof Brian Ripley) > Cc: s-news@utstat.toronto.edu > Subject: Re: Summary of Robust Regression Algorithms > From: kent@darwin.eeb.uconn.edu (Kent E. Holsinger) > > >>>>> "Brian" == Prof Brian Ripley <ripley@stats.ox.ac.uk> writes: > > Brian> My best example of this not knowing the literature is the > Brian> Hauck-Donner (1977) phenomenon: a small t-value in a > Brian> logistic regression indicates either an insignificant OR a > Brian> very significant effect, but step.glm assumes the first, > Brian> and I bet few users of glm() stop to think. > > All right I confess. This is a new one for me. Could some one explain > the Hauck-Donner effect to me? I understand that the t-values from > glm() are a Wald approximation and may not be terribly reliable, but I > don't understand how a small t-value could indicate "either an > insignificant OR a very significant effect." > > Thanks for the help. It's finding gems like these that make this group > so extraordinarily valuable.

There is a description in V&R2, pp. 237-8., given below. I guess I was teasing people to look up Hauck-Donner phenomenon in our index. (I seem to remember this was new to my co-author too, so you were in good company. This is why it is such a good example of a fact which would be useful to know but hardly anyone does. Don't ask me how I knew: I only know that I first saw this in about 1980.)

There is a little-known phenomenon for binomial GLMs that was pointed out by Hauck & Donner (1977: JASA 72:851-3). The standard errors and t values derive from the Wald approximation to the log-likelihood, obtained by expanding the log-likelihood in a second-order Taylor expansion at the maximum likelihood estimates. If there are some \hat\beta_i which are large, the curvature of the log-likelihood at \hat{\vec{\beta}} can be much less than near \beta_i = 0, and so the Wald approximation underestimates the change in log-likelihood on setting \beta_i = 0. This happens in such a way that as |\hat\beta_i| \to \infty, the t statistic tends to zero. Thus highly significant coefficients according to the likelihood ratio test may have non-significant t ratios.

To expand a little, if |t| is small it can EITHER mean than the Taylor expansion works and hence the likelihood ratio statistic is small OR that |\hat\beta_i| is very large, the approximation is poor and the likelihood ratio statistic is large. (I was using `significant' as meaning practically important.) But we can only tell if |\hat\beta_i| is large by looking at the curvature at \beta_i=0, not at |\hat\beta_i|. This really does happen: from later on in V&R2:

There is one fairly common circumstance in which both convergence problems and the Hauck-Donner phenomenon (and trouble with \sfn{step}) can occur. This is when the fitted probabilities are extremely close to zero or one. Consider a medical diagnosis problem with thousands of cases and around fifty binary explanatory variables (which may arise from coding fewer categorical factors); one of these indicators is rarely true but always indicates that the disease is present. Then the fitted probabilities of cases with that indicator should be one, which can only be achieved by taking \hat\beta_i = \infty. The result from \sfn{glm} will be warnings and an estimated coefficient of around +/- 10 [and an insignificant t value].

That was based on a real-life example, which prompted me to write what is now stepAIC. Once I had that to try, I found lots of examples.

Brian Ripley

Voir aussi :

http://www.r-project.org/nocvs/mail/r-help/2002/1487.html

A CLASSER

NA

Missing values: use CART or logistic regression to investigate and impute.

Do not discard missing data.

Do not categorize continuous variables during data collection.

Dummy variables for categorical predictors.

Model validation

data splitting
leave-out-one cross-validation (jackknife):
  take all the observations but one
  fit the model
  predict the missing value and compare with the actual one
  iterate
Cross-validation:
  idem, but split the data into 10 groups, fit the model with all
  the groups but one, predict its values, compare.
  Iterate with the other nine groups.
  Iterate, with other groups.
Bootstrap:
  fit the model on a bootstrap sample
  You get an idea of the bias/variance of the parameters.
  The optimism (=bias) is overestimated: multiply bay .0632 (rule of thumb)

Interpretation

The model gives associations, not causal relations

Pour les données cartographiques, on peut aussi utiliser GMT (qui n'a rien à voir avec R).

http://gmt.soest.hawaii.edu/

AIC
library(MASS); ?stepAIC

Interfaçage avec des bases de données

Estimation d'un paramètre à l'aide d'un estimateur/test/intervalle de confiance
  
?str
   data(LifeCycleSavings)
   summary(lm.SR <- lm(sr ~ pop15 + pop75 + dpi + ddpi,
                       data = LifeCycleSavings),
           corr = TRUE)
   str(lmI <- lm.influence(lm.SR))

Hachures:

m <- matrix(runif(30), ncol=5)
barplot(m, beside=FALSE, col=rep(c("white", "light green", "pink"), 2),
        border=rep(c("white", "red"), 3), horiz=TRUE,
        xlim=c(0, 6), axes=FALSE)
par(new=TRUE)
barplot(m, beside=FALSE, col="blue",
        density=rep(c(10, 5, -1), 2),
        angle=rep(c(45, -45, 0), 2), horiz=TRUE,
        xlim=c(0, 6)) 


par(fg='white', bg='black', col='white', col.axis='white', col.lab='white', col.main='white', col.sub='white');plot(0,0)

SPC: Statistics Process Control

On peut faire ses propres QQplots pour comparer deux distributions.
  x <- rexp(100)
  qqplot( qexp(ppoints(100)), sort(x) )
  abline(0,1)

qqplot : expliquer comment lire un QQplot.
En particulier : distribution décentrée, 
distribution plus dispersée qu'une normale, moins dispersée, etc.

?split
?lapply
?by

Comparer (graphiquement) la loi de Student avec la loi normale.

Donner un exemple d'utilisation de la commande legend
(c'est une commande séparée).
(par exemple quand il y a plusieurs courbes, de couleurs différentes)

?persp
?contour
Pour représenter une loi normale multivariée

Estimateurs/Tests/Intervalles de confiance
Régression: estimation des corfficients/tests sur les coefs/IC des coefs/IC des valeurs prédites/comparaison de modèles

Histogramme avec des barres coloriées (ou hachurées)
Avec des ombres
  
Colorier entre deux courbes (écrire une fonction pour ça).
x <- runif(20)
y <- 1-2*x+.1*rnorm(20)
res <- lm(y~x)
plot(y~x)
new <- data.frame( x=seq(0,1,length=21) )
p <- predict(res, new, interval='prediction')
for (l in seq(0,1,length=100)){
  points( (l*p[,2]+(1-l)*p[,3]) ~ new$x, type='l', col="red" )
}
p <- predict(res, new, interval='confidence')
for (l in seq(0,1,length=100)){
  points( (l*p[,2]+(1-l)*p[,3]) ~ new$x, type='l', col="green" )
}
points(y~x)
p <- predict(res, new)
points( p ~ new$x, type='l' )

?rug
(en dessous d'un histogramme ou d'un boxplot)

vcd: Visualization if categorical data.

Andrew curve

Chiplot

ftable : table de contingence en dim >2.

Libraries: 
  VR complements MASS
  wave* (wavelets)
  ade4  MVA.

Comment mentir avec des chiffres

ne pas mettre de 0 sur le graphique
confusion longueur/aire.

RFS plot : side by side, sort(yhat)~index and sort(y)~index (donner un exemple où y est quantitatif mais discret).

Rgraphviz (dans bioconductor)

?cancor

Plan de la nouvelle version de ce document

Syntaxe de R
  RTFM/Documentation (?, help.search, exampl, demo, library(), library(help=...), data)
  Les différents types de données
  Saisie des données
  Manipulations des types de données
  Matrices et algèbre linéaire
  Structures de contrôle
  Fonctions (elles n'ont pas d'effet de bord : en clair, il n'y a pas de variables globales)
  Persistance
  library
    R CMD ...
  Objets
  ESS
  sweave
  
Graphiques avec R
  Commandes de base
  Options (détailler)

Mise en garde : je suis incompétent

Le Zoo des lois de probabilités

Données univariées
  paramètres statistiques (mean, var, sd, median, quartiles, mad, etc.)
  dotplot
  scatterplot
  boxplot
  stem-and-leaf plot
  histogramme
  rug
  symetry plot (mentionner le test de Wilcoxon)
  qqplot (mentionner le test de Shapiro)
  ces quatre graphiques sur une seule figure
  Transformations des données, boxcox
  (données ordonnées)
  barplot : données qualitatives
  pie    

Tests statistiques : théorie
Zoo des tests statistiques
  (dans un premier paragraphe, lister tous les tests,
  si possible dans un tableau)
Méthodes non paramétriques
  robustesse
  résistance
  breakdown (la proportion d'individus que l'on peut modifier sans parvenir à envoyer les estimateurs à l'infini).

Représentation graphiques de données multivariées (sans la régression)
  deux variables quantitatives
  une variable quantitative, une qualitative
  deux variables qualitatives
  Plusieurs variables quantitatives : pairs
  Plusieurs variables quantitatives : treillis
  Trois variables quantitatives : ternary plot
  Plus de deux variables : découpage en tranches (treillis)
  starplots

Représentation graphiques de données multivariées (suite)
  ACP
  Analyse en composantes robustes
  Aggrégation autour des centres mobiles
  Classification hiérarchique (dendogramme)
  A FAIRE : une ou plusieurs des variables sont qualitatives
  (analyse factorielle discriminante, des correspondances simples/multiples, etc.)

Régression : PLAN A REVOIR
  Régression
  Avant de commencer la régression : lissage, quelques méthodes robustes
  Avant de commencer la régression : transformations
  Régression linéaire : définition
  Comparaison avec l'ACP
  Résidus : graphiques pour explorer une régression
    (les résidus vus comme une seule variable (boxplot, hist, etc.)
    (les résidus en fonction de la prédiction, en fonction d'une variable indépendante (très mauvaise idée: prendre l'exemple d'un modèle constant y~1), de la variable indépendante)
  Résidus non normaux
  Hétéroscédasticité des résidus
  Influence, leverage (?), distance de Cook
  Autocorrélation 
  Régression multiple
  Graphiques pour explorer une régression multiple    
  Multicolinéarité
  Régression curvilinéaire
  Régression non linéaire
  Exemple : un problème de classification (régression linéaire, curvilinéaire, plus proches voisins)
  Tests statistiques sur une régression
  Lecture du résultat d'une régression : première présentation de l'Anova

  A FAIRE :
  Régression robuste (WLS,IRLS)
  Modèle linéaire généralisé
  Régression logistique

Anova
  Motivation
  Calculs détaillés sur un exemple, à la main
  Calculs détaillés sur un exemple, avec R
  Régression et sommes de carrés : une autre motivation de l'Anova
  Anova et comparaison de modèles

Séries temporelles

A FAIRE:

Nulle part je n'ai parlé de processus (mais j'utilise parfois le terme...)

La malédiction de la dimension

A CLASSER...

Autre graphiques pour repérer ces problèmes

A FAIRE  

Lack of fit: if there are several Y-values for a given X-value, compare 
  y~x with y~factor(x)

The four transformation plots

A FAIRE

(how to ensure symetry, equal spread, straightness, additive structure)

(a power plot which is a straight line with slope m suggests a power transformation whose exponent is 1-m.)

1. Transformation for equal spread. (Location/spread plot) Deux variables, une quantitative, une qualitative. Cela revient à répartir les individus dans différentes classes. On représente log(IQR) en fonction de log(median).

2. Transformation plot for symetry. (xU+xL)/2-M en fonction de ((xU-M)^2+(M-xL)^2)/(4M), où M est la médiane et xU, xL des quartiles (inférieurs et supérieurs).

3. Transformation plot for straightness. y-My-C(x-Mx) en fonction de C^2(x-Mx)^2/(2My) où Mx, My sont les médianes de x et y, C pente de la régression (que l'on ne connait pas).

4. Transformation for additivity (diagnostic plot). Two-way table. Par des DL, on remarque que si y_ij^p = m + a_i + b_j, alors y_ij = D + A_j + B_j + (1-p) A_i A_i / D. On trace donc y_ij-(m+a_i+b_j) en fonction de a_i b_j / m où y_ij=m+a_i+b_j est un un modèle additif (qui ne convient donc pas).

Divers

(Il faudra faire une partie entière sur les transformations)

Transformations: boxcox (in MASS), choose a simple exponent from the
  graph, such as 1/2, 1/3, 1/4, etc. (If 1 is in the confidence
  interval, there is no good reason to transform the data) (very
  sensitive to outliers) (The transformation should not be extreme: if
  you get 5, blame the outliers)
Other transformations: logit (for proportions, percentages),
  Fisher's Z transform (for correlations)

Do not remove the intercept: it acts as a sink for the effect of unincluded variables
Do not remove lower order terms even if they are not statistically significant: the prevent against additive modifications

Plan d'analyse

Voici comment on peut procéder pour faire une régression (à des fins de prédiction), face à un exemple réel.

1. Regarder les variables une par une, regarder s'il y a des valeurs atypiques (si elles résultent d'erreurs, les corriger), transformer éventuellement les variables pour les rapprocher de la normalité.

2. Regarder s'il y a des valeurs manquantes, regarder si elles apparaissent par hasard ou si elles obéissent à un motif, essayer de les inférer.

3. Regarder les variables dans leur ensemble (pairs, xgobi, princomp), deux par deux (partial effect plots), avec des treillis (Y ~ X1 | X2) rpart).

4. Choisir le modèle. C'est le point le plus délicat : faut-il utiliser toutes les variables ? Les dépendances entre les variables sont-elles linéaires ? Faut-il des termes d'interaction ?

5. Faire différents tests, tant numériques que graphiques : résidus, observations influentes, tests divers (annulation des coefficients, anova pour comparer des modèles). On prendra garde à ne pas faire trop de tests : plus on en fait, plus le risque d'erreur est grand... Modifier le modèle en conséquence.

6. Interpréter les résultats, à l'aide des coefficients et de tous les graphiques précédents.

Divers

A FAIRE : partial effect plots.

n <- 100
x1 <- rnorm(n)
x2 <- rnorm(n)
x3 <- rnorm(n)
y <- x1 - x2*x2 + 2*x3 + rnorm(n)
pairs(cbind(y,x1,x2))

*

y3  <- lm(y~x3)$residuals
x13 <- lm(x1~x3)$residuals
x23 <- lm(x2~x3)$residuals
plot( y3 ~ x13,
      xlab="x1 sans les effets linéaires de x3",
      ylab="y sans les effets linéaires de x3" )

*

library(lattice)
bwplot( ~ y3 | equal.count(x13), layout=c(1,6) )

*

bwplot( ~ y3 | equal.count(x13) + equal.count(x23) )

*

Missing values : CART or logistic regression Imputing missing values : transcan

Risk of overfitting : use the bootstrap to estimate the optimism (=bias) and substract it from R^2.

Regression trees
MARS
neural networks
(For small data sets or high noise level, complex methods are not justified: stick to LS.)

A CLASSER

ST Support Trees
SOTA Self Organizing Tree Algorithm
RN Relevance Networks
CAST Clustering Affinity Search Technique
SOM Self Organizing Maps
FOM Figures Of Merit
RELAGGS (relational learning algorithms)

ROC 
  ROC curve (Receiver Operating Characteristic)
  Prob(detection)~Prob(false alarm)
  area under curve
Les courbes ROC sont utilisées pour examiner la sensibilité d'un classificateur
qui renvoie une réponse qualitative après avoir comparé une pré-réponse quantitative
avec un seuil. On trace la proportion de bonnes réponses en fonction du seuil (???)
AUC: Area Under Curve. C'est ce que l'on mesure sur une courbe ROC.

Quelques exemples

Probabilité et fréquence limite

On tire à pile ou face 1000 fois et on regarde comment évolue la fréquence de « pile ». On constate qu'elle « tend » vers 0.5.

n <- 1000
x <- runif(n)
x <- x>.5
x <- cumsum(x)/(1:n)
plot(x, ylim=c(0,1), type="l")

*

Idem, sur une échelle logarithmique

plot(x, ylim=c(0,1), type="l", log="x")

*

Exemple

Simulation de 20 séries de 10 tirages aléatoires d'une variable normale.

N <- 10
n <- 20
x <- rnorm(n*N)
y <- rep(1:n, N)
boxplot(x ~ y)

*

par( mfrow = c(4,5) )
for (i in 1:n) {
  hist(x[ y==i ])
}

*

Maintenant, 20 séries de 100 tirages.

N <- 100
n <- 20
x <- rnorm(n*N)
y <- rep(1:n, N)
boxplot(x ~ y)

*

par( mfrow = c(4,5) )
for (i in 1:n) {
  hist(x[ y==i ])
}

*

20 séries de 3 tirages ; on met en évidence les séries pour lesquelles la moyenne réelle n'est pas entre les valeurs extrèmes.

N <- 3
n <- 20
x <- rnorm(n*N)
y <- rep(1:n, N)
m <- matrix(x, nrow=N, byrow=T)
c <- apply(m,2,min)>0 | apply(m,2,max)<0
boxplot(x ~ y, col=c(0,6)[1+c])

*

Echantillons gaussiens de taille de plus en plus grande.

x <- rnorm(10+100+1000+10000+100000)
y <- c( rep(5,10), rep(4,100), rep(3,1000), rep(2,10000), rep(1,100000))
boxplot(x~y, horizontal=T, axes=F)
axis(1)
axis(2, 1:5, c(10,100,1000,10000,100000) )

*

Loi de Benford

Si on prend des données numériques << réelles >>, leur premier chiffre suit une loi de Benford.

x <- 1:9
y <- log(1+1/x)/log(10)
plot(y~x, type="h")

*

Vérifions-le à l'aide de données boursières. Commençons par récupérer des cours de bourse et des volumes échangés de quelques 130 titres.

rm A
for i in AB C DE FI JN OR S TZ
do
  GET 'http://fr.finance.yahoo.com/q?s=@SRD_'$i'.PA&f=snlcvi' >> A
done
perl -n -l -e 'm#e.gif[^>]*>([0-9,]+)<# && print$1' A | 
  perl -p -e 's/\.//g; s/,/./g' > Cours.txt
perl -n -l -e 'm#.*>([0-9.]*?)</font.*Graphique# && print "$1"' A | 
  perl -p -e 's/\.//g' > Volume.txt

Récupérons les données sous R

a <- read.table("Cours.txt")
a <- a[a>0]
a <- as.vector(a)
a <- floor(a*10^-floor(log(a)/log(10)))
hist(a, probability=T)
points((x+.5), y, type='h', col='red', lwd=3)
chisq.test(table(factor(a)), p=y) # p-value = 0.06

*

a <- read.table("Volume.txt")
a <- a[a>0]
a <- as.vector(a)
a <- floor(a*10^-floor(log(a)/log(10)))
hist(a, probability=T)
points((x+.5), y, type='h', col='red', lwd=3)
chisq.test(table(factor(a)), p=y) # p-value = 0.85

*

Voici une justification théorique de ce fait :

http://www.math-info.univ-paris5.fr/smel/articles/benford/cadre_benford.html

Variable normale multidimentionnelle dont on précise la matrice des covariances

On se donne deux vaiid normales X et Y de moyenne 0 et de variance 1 et on essaye de trouver a, b et c de sorte que (aX, bY+cX) ait la bonne variance.

> rnorm2 <- function(n, mean=c(0,0), cov=c(1,1,0)) {
    a <- sqrt(cov[1])
    c <- cov[3]/a
    b <- sqrt(cov[2]-c^2)
    x <- rnorm(n)
    y <- rnorm(n)
    print(a); print(b); print(c);
    cbind( mean[1]+a*x, mean[2]+b*y+c*x )
  }
> cov(rnorm2(10000, cov=c(1,5,2)))
[1] 1
[1] 1
[1] 2
         [,1]     [,2]
[1,] 1.015107 2.034396
[2,] 2.034396 5.069416

Voir aussi :

library(MASS)
?mvrnorm

library(help=mvtnorm)

library(combinat)
?rmultinomial

library(normix)
?rmultinom

Divers

plot(sort(runif(100)))
for (i in 1:1000) {
  lines( sort(runif(100)) )
}

*

On peut tracer les bornes sup et inf de ces choses-là.

n <- 1000
m <- 200
a <- matrix( runif(n*m), c(n,m) )
b <- apply(a, 1, sort)
c <- apply(b, 1, range)
plot( c[1,], type="l" )
lines( c[2,] )

n <- 10
m <- 200
a <- matrix( runif(n*m), c(n,m) )
b <- apply(a, 1, sort)
c <- apply(b, 1, range)
lines( c[1,] )
lines( c[2,] )

*

A FAIRE

Test de Mantel : mesure la corrélation de deux matrices de distances (par exemple, une distance génétique et une distance géographique). On procède ainsi : on calcule le coefficient de corrélation entre les deux matrices (qui n'a pas grand sens, car les valeurs d'une même matrice ne sont pas indépendantes), on applique une permutation sur les lignes et les colonnes d'une des matrices et on recalcule le coefficient, on recommence plusieurs centaines de fois, on regarde enfin où se trouve la valeur initiale par rapport aux valeurs ultérieures.

Muticolinéarité : calculer le R^2 de x~. pour chaque x, s'il est supérieur à 95%, c'est inquiétant.

Graphical models (modèles graphiques ?)

Quand on manipule plusieurs variables statistiques, disons X, Y, Z, T, on essaye souvent d'exprimer leur distribution conjointe comme un produit de distributions plus simples. Dans le cas le plus trivial,

P(X,Y,Z,T) = P(X) * P(Y) * P(Z) * P(T).

Mais, on général, on a des relations de dépendance entre ces variables, par exemple

P(X,Y,Z,T) = P(X) * P(Y) * P(Z|X,Y) * P(T|Z).

On peut représenter de telles relations par un un graphe orienté (DAG : Directed Acyclic Graph).

X       Y
 \     /
  \   /
   \ /
    Z
    |
    |
    |
    T

(si je savais mieux dessiner, il y aurait des flèches vers le bas).

Distance de Kullback-Leibler

C'est une mesure de la dissimilarité de deux distributions de probabilité.

D(f,g) = Intégrale( log(f/g) * f ).

On remarquera que ça n'est pas symétrique.

A FAIRE

08_tests.txt : LR test

Vincent Zoonekynd
<zoonek@math.jussieu.fr>
latest modification on Wed Oct 13 22:33:29 BST 2004