Freakonometrics

To content | To menu | To search

Tag - Google

Entries feed - Comments feed

Friday, September 7 2012

De l'hebdomadaire au mensuel

Pour le devoir de série temporelles, les données fournies par Google Insight sont hebdomadaires, ce qui peut rendre la modélisation compliquée. Comme on l'a évoqué en fin de cours, il peut être plus simple de travailler sur des données mensuelles. La petite fonction suivante permet de transformer les données pour avoir des données mensuelles (avec des moyennes par mois, ce qui fait qu'un mois de 28 jours et un mois de 31 jours sont comparables). Histoire d'illustrer, prenons un mot au hasard, disons.... épilation. On commence par sauver le fichier csv, et on le lit sous R,

EPILATION=read.table(
"/home/charpentier/report-epilation.csv",
skip=4,header=TRUE,sep=",",nrows=426)

La petite fonction suivant va nous aider à convertir la base en une série temporelle mensuelle,

H2M=function(BASE){
X=BASE[,2]
date1=substr(as.character(BASE$Semaine),1,10)
date2=substr(as.character(BASE$Semaine),14,23)
D1=as.Date(date1,"%Y-%m-%d")
D2=as.Date(date2,"%Y-%m-%d")
vm=vy=N=NA
for(t in 1:length(D1)){
mois=seq(D1[t],D2[t],length=7)
vm=c(vm,as.POSIXlt(mois)$mon+1)
vy=c(vy,as.POSIXlt(mois)$year+1900)
N=c(N,rep(X[t],7))}
N=N[-1]; vm=vm[-1]; vy=vy[-1]
YM=vy*100+vm
Z=tapply(N,as.factor(YM),mean)
Zts=ts(Z,start=c(2004,1),frequency=12)
return(Zts)}

Si on travaille sur la série hebdomadaire, on a la série suivante

hebdo=ts(EPILATION$épilation,start=2004,
frequency=52)

La fonction d'autocorrélation est alors

acf(hebdo,160)

Maintenant, on peut travailler sur les données mensuelles. On utilise alors

mensuel=H2M(EPILATION)

Le graphique est alors le suivant

La fonction d'autocorrélation est cette fois la suivante

acf(mensuel,40)

On retrouve le comportement cyclique, avec une saisonnalité annuelle. Mais avec 12 retards, on devrait avoir des modèles plus simples qu'avec 52 retards. Bref, il peut être plus simple de travailler sur des données mensuelles qu'hebdomadaires. Mais chacun est libre de la série qu'il ou elle analysera...

Monday, February 27 2012

devoir de séries temporelles

Pour le second devoir maison du cours ACT6420, il s'agira de faire une prévision sur 6 mois (avec un intervalle de confiance) d'une série importée de Google Insight. Il suffit d'entrer un mot clé,

puis de sauvegarder les données sous un format csv,

Par exemple pour "vampire", on a

Ensuite le code est assez simple

seriestemporelles=read.table("report.csv",
skip=4,header=TRUE,sep=",",nrows=426)
ST=ts(seriestemporelles$vampire,start=2004, frequency=52)
plot(ST)

Il suffit de choisir un mot clé et d'importer les données. Par exemple pour "chocolat"

(on notera que Google propose une prévision... je veux bien sûr plus que cette prévision, mais une comparaison serait la bienvenue) ou pour "rhume"

voire encore "creme solaire"

ou "how I met your mother"

Bref, je laisse le choix (presque) libre pour la série: vous me contactez par courriel pour me dire sur quel mot clé vous souhaitez travailler, et je donne, ou non, mon accord.

Wednesday, January 18 2012

Gold price and fear

Via @theEconomist, I understood that there might be connections between the price of Gold (which is said to be extremely high nowadays) and the VIX SP500 index (the option volatility index, i.e. the so-called "fear index", as discussed - in French- a few months ago). This has been discussed also on several blogs, e.g. http://etfdailynews.com/ or http://blogs.marketwatch.com/. Via Yahoo quotes, it is possible to get also easily the SP500 VIX index. 

> library(tseries)
> X=get.hist.quote("^VIX")
> T=time(VIX)
> Y=as.POSIXlt(T)$year+1900
> X2011=X[Y==2011,]
> VIX=X2011[,4]
> VIX100=as.numeric(VIX)/VIX[1]*100
> T2011=T[Y==2011]
> plot(T2011,VIX100,lwd=2,col="red",type="l",
+ xlab="",ylab="",ylim=c(60,290))

And a huge xls file can give us the price of gold (on a daily basis). But we can extract only one series (with the price in USD, which is the series of interest here)

> goldprice=read.table(
+ "http://freakonometrics.blog.free.fr/
public/data/goldpriceUSD.csv"
, + header=TRUE,sep=";",dec=",") > T=as.Date(goldprice$Name,"%d/%m/%y") > GP=goldprice$USdollar > Y=as.POSIXlt(T)$year+1896 > GP2011=GP[Y==2011] > GP100=GP2011/GP2011[1]*100 > T2011=T[Y==2011] > lines(T2011-4*365.25,GP100,lwd=2,col="blue")

We can see that scales are quite different on those two series (starting at 100 at the beginning of January 2011),

An alternative might be not to consider the price of gold, but something more psychological, like Internet researches. It is possible to download the csv file for queries on gold price on Google, via google insight.

 
> google=read.table(
+ "http://freakonometrics.blog.free.fr/public/data/google.csv",
+ skip=4,header=TRUE,sep=",",nrows=51)
> W=as.Date(substr(as.character(google$Semaine),1,10))
> G=google$gold.price
> G100=G/G[1]*100
> lines(W,G100,lwd=2,col="blue")

which gives the following graph (again, starting at 100 at the beginning of January 2011),

Here, we can clearly observe that the two series are related, maybe cointegrated. Nice isn't it ?

Sunday, October 17 2010

Translating a blog ? thanks Google Translate

As mentioned already several times on that blog (here or there), since some people who do not speak French might be interested in my blog, I started to write in English. Indeed, since I work now in a more internation enviromnent, I find it more natural to write in English (or at least something that might sound like English language). For older posts, actually, @Vicnent mentioned yesterday that it is possible to get a complete translation of a blog using google translate, e.g. here. That's simply amazing... now I can read in French some blogs writen in Portuguese, such as http://drunkeynesian.blogspot.com/... there.

Thursday, September 9 2010

Le million ! le milllion !

Hier soir (ou ce matin, je suis perdu avec ce décalage horaire) Christelle me demandait de parler un peu de prévision avec R (ici). Au lieu de renvoyer vers l'aide en ligne, penons un exemple pratique (et simple, voire si possible intéressant): la fréquentation d'un blog (en l'occurrence http://blogperso.univ-rennes1.fr/arthur.charpentier/). Considérons le nombre de pages vues, par jour, selon Google Analytics.
> base=read.table("http://perso.univ-rennes1.fr/arthur.charpentier/million.csv",
+ sep=";",header=TRUE
)> X=base$nombre
> D0=as.Date("08/11/2008","%d/%m/%Y")
> D=D0+1:length(X)
> plot(D,X)
> plot(acf(X,lag=90))
La série a l'allure suivante (oui, le compteur n'a été installé qu'il y a deux ans),

Les autocorrélations montre une forte saisonnalité hebdomadaire, avec moins de consultations en semaine que le week-end,

La question que l'on cherche à résoudre est "ai-je une chance d'atteindre le million de pages vues d'ici la fin de l'année ?".

On peut traduire cette question de deux manières
  • quelle est la probabilité que le 1er janvier, j'ai atteint le million de pages vues,
  • quelle est la probabilité que la date où le million de pages vues sera atteint soit avant le 1er janvier
Une fois formalisée la question, reste à faire un peu d'économétrie.
  • modélisation économétrique
En faisant simple et rapide, afin de prendre en compte la corrélation forte avec la semaine précédente, et le fait que l'on s'intéresse à la somme cumulée, on peut considérer un modèle ARIMA
  • avec un retard d'ordre 7 pour les composantes moyennes mobiles et autorégressives,
  • avec une série intégrée à l'ordre 1,
L'ajustement se fait de la manière suivante,
> X=cumsum(base$nombre)
> model  <- arima(X,c(7 ,   # partie AR
+                                             1,    # partie I
+                                             7))   # partie MA
et la prévision se fait via
> forecast <- predict(model,200)

Ensuite, ce n'est qu'une représentation graphique,
> u=max(D)+1:200
> polygon(  c(u,rev(u)),  c(forecast$pred - 1.96*forecast$se,
+  rev(forecast$pred + 1.96*forecast$se)), col = "yellow", border=NA)
> lines(u,forecast$pred,col="blue",lwd=2)
> lines(u,forecast$pred- 1.96*forecast$se,col="blue",lty=2)
> lines(u,forecast$pred+ 1.96*forecast$se,col="blue",lty=2)
> abline(v=as.Date("01/01/2011","%d/%m/%Y"),col="red")
> abline(h=1000000,col="red")


Afin de répondre à la question posée, on peut étudier les différentes probabilités envisagées,
  • probabilité que le 1er janvier, j'ai atteint le million de pages vues
Dans un premier temps, on utilise la normalité des prédictions (en supposant une normalité du bruit) pour obtenir la loi de la prédiction à une date quelconque,
> k=which(u==as.Date("01/01/2011","%d/%m/%Y"))
> x=seq(800000,1100000,by=100)
> y=dnorm(x,mean=forecast$pred[k],sd=forecast$se[k])
> plot(x,y,type="l",lwd=2)
> x0=x[x>=1000000]
> polygon(  c(x0,rev(x0)), c(y[x>=1000000],rep(0,length(x0))), col = "yellow",border=NA)
> lines(x,y,type="l",lwd=2)
> abline(v=1000000)

Le cas de la probabilité d'atteindre plus d'un million de visiteur le 1er janvier est alors
> k=which(u==as.Date("01/01/2011","%d/%m/%Y"))
> 1-pnorm(1000000,mean=forecast$pred[k],sd=forecast$se[k])
[1] 0.2604821

  • problème dual, 
Dans un second temps, on peut envisager une autre approche, consistant à se demander quelle pourrait être la loi de la date du jour où le million de pages vues sera atteint,
> P=rep(NA,300)
> for(k in 1:300){
+ P[k]=1-pnorm(1000000,mean=forecast$pred[k],sd=forecast$se[k])}
> plot(max(D)+1:300,P,type="l",lwd=2)
> x=max(D)+1:300
> x0=x[x<=as.Date("01/01/2011","%d/%m/%Y")]
> polygon(  c(x0,rev(x0)), c(P[x<=as.Date("01/01/2011","%d/%m/%Y")],rep(0,length(x0))),  col = "yellow", border=NA)
> lines(max(D)+1:300,P,type="l",lwd=2)
> abline(v=as.Date("01/01/2011","%d/%m/%Y"))

La probabilité que cette date soit antérieure au 1er janvier est alors
> P[u==as.Date("01/01/2011","%d/%m/%Y")]
[1] 0.2604821
(ce qui, fort heureusement, correspond à la probabilité calculée par le problème primal). Bref, j'ai 1 chance sur 4 d'atteindre le million de pages vues avant la nouvelle année....
  • sensibilité à un changement de modèle
C'est bien joli tout ça, mais ces calculs sont largement soumis à la contrainte du choix de modèle que j'ai fait arbitrairement au début... on peut se demander si en changeant de modèle, les résultats changent sensiblement, ou pas. Au lieu de tenter un autre modèle ARIMA (voire SARIMA), j'ai préféré changer la série de référence... et me focaliser sur 2010 uniquement. D'un côté j'enlève les premières semaines où le niveau de fréquentation était très faible, de l'autre, je donne un poids très important aux vacances d'été, i.e. la période juin-août, pendant laquelle les internautes semblent moins sensibles à la modélisation économétrique.
Si l'on modélise la fréquentation pour 2010, seulement, on obtient

avec les distributions suivantes, tout d'abord pour la densité du nombre de visiteur atteint au 1er janvier 2011,

et pour la fonction de répartition de la date où sera atteint le million de pages vues,
soit une probabilité de l'ordre de 35%, dans les deux cas,
> P[u==as.Date("01/01/2011","%d/%m/%Y")]
[1] 0.3531648
> k=which(u==as.Date("01/01/2011","%d/%m/%Y"))
> 1-pnorm(1000000,mean=forecast2$pred[k],sd=forecast2$se[k])
[1] 0.3531648


On obtient des probabilités relativement proches avec les deux modèles, et j'aurais envie de croire que l'objectif est envisageable.... "challenge accepted" comme dirait mon ami Barney Stinson (oui, c'est mon ami). Reste juste à trouver des sujets qui attireront du monde en cette fin d'année...