Les deux autres fonctions se chargent de calculer respectivement les formules 7.3 et 7.2, page 306.. d’abord on calcule le coefficient de corrélation entre l’internaute pour lequel on s’
Trang 17.4 Recommandations 313
renvoient le résultat Elles se trouvent dansclasses/Util.php Les deux autres fonctions
se chargent de calculer respectivement les formules (7.3) et (7.2), page 306 Afin de calculer une prédiction, on procède en deux étapes :
1 d’abord on calcule le coefficient de corrélation entre l’internaute pour lequel
on s’apprête à faire la prédiction et tous les autres : on stocke ces valeurs dans
un tableau associatif $tabCorr indexé par le nom des internautes ;
2 puis on prend chaque film non noté par l’internaute, on applique la fonction calculant la prédiction, et on affiche le résultat
Le calcul des prédictions pour un ensemble de films est implanté par la méthode privée prediction() du contrôleur Recomm, donnée ci-dessous
p r i v a t e f u n c t i o n p r e d i c t i o n ( $ e m a i l , $ n b _ f i l m s )
{
$ f i l m s = a r r a y ( ) ;
/ / C a l c u l d e s c o r r é l a t i o n s a v e c l e s a u t r e s i n t e r n a u t e s
$ r e q I n t e r n a u t e s = " SELECT i ∗ FROM I n t e r n a u t e i , Notation n "
" WHERE n e m a i l = i e m a i l AND i e m a i l != ’ $ e m a i l ’ " " GROUP BY i e m a i l HAVING COUNT(∗) > 10 " ;
$ l i s t e I n t e r = $ t h i s−>bd−>execRequete ( $ r e q I n t e r n a u t e s ) ;
$ t a b _ c o r r = a r r a y ( ) ;
w h i l e ( $ i n t e r n a u t e = $ t h i s−>bd−>o b j e t S u i v a n t ( $ l i s t e I n t e r ) )
$ t a b _ c o r r [ $ i n t e r n a u t e−>e m a il ] =
U t i l : : c a l c u l C o r r e l a t i o n ( $ e m a i l , $ i n t e r n a u t e−>email ,
$ t h i s−>bd ) ; / / R e c h e r c h e d e s f i l m s , e n o r d r e a l é a t o i r e
$ r e q u e t e = " SELECT ∗ FROM Film ORDER BY RAND( ) " ;
$ r e s u l t a t = $ t h i s−>bd−>execRequete ( $ r e q u e t e ) ;
$ i = 1 ;
w h i l e ( $ f i l m = $ t h i s−>bd−>o b j e t S u i v a n t ( $ r e s u l t a t ) ) {
/ / On v é r i f i e q u e c e f i l m n ’ e s t p a s n o t é p a r l ’ i n t e r n a u t e
$ n o t a t i o n = U t i l : : c h e r c h e N o t a t i o n ( $ e m a i l , $ f i l m−>id , $ t h i s
−>bd ) ;
i f ( ! $ n o t a t i o n ) {
/ / C a l c u l d e l a p r é d i c t i o n p o u r c e f i l m
$ p r e d i c t i o n = U t i l : : c a l c u l P r e d i c t i o n ( $ e m a i l , $ f i l m−>id ,
$ t a b _ c o r r , $ t h i s−>bd ) ;
$ p r e d i c t i o n = round ( $ p r e d i c t i o n∗100) / 1 0 0 ;
$ f i l m s [ $ f i l m−>i d ] = $ p r e d i c t i o n ;
i f ( $ i ++ >= $ n b _ f i l m s ) b r e a k ;
}
}
/ / On r e n v o i e l e t a b l e a u d e s p r é d i c t i o n s
r e t u r n $ f i l m s ;
}
Trang 2314 Chapitre 7 Production du site
On constate qu’il faut manipuler beaucoup d’informations pour arriver au résultat,
ce qui risque de soulever des problèmes de performance pour une base de données volumineuse En particulier, le tableau des corrélations contient autant d’éléments qu’il y a d’internautes dans la base, et le passage de ce tableau en paramètre de la fonction CalculPrediction() peut être assez pénalisant Un passage par référence éviterait cela
Une fois qu’une application est stabilisée, et dans la mesure ó elle est conçue
de manière véritablement modulaire, il est relativement facile de remettre en cause quelques fonctions pour améliorer les performances Ici une optimisation simple consisterait à ne pas recalculer systématiquement et en temps réel les corrélations entre internautes, mais à le faire périodiquement – par exemple une fois par jour – en stockant le résultat dans une table MySQL Au lieu de passer le tableau $tabCorr
en paramètre de la fonction CalculPrediction(), cette dernière pourrait alors chercher les corrélations dans la table
La méthode statique Util::calculCorrelation() calcule et renvoie le coeffi-cient de corrélation entre deux internautes, selon la formule (7.3) Elle effectue donc une boucle sur tous les films, prend ceux qui ont été notés par les deux internautes,
et calcule les composants de la formule
s t a t i c f u n c t i o n c a l c u l C o r r e l a t i o n ( $ e m a i l 1 , $ e m a i l 2 , $bd )
{
$somme_numerateur = 0 ;
$somme_denom1 = 0 ;
$somme_denom2 = 0 ;
$moyenne1 = s e l f : : m o y e n n e I n t e r n a u t e ( $ e m a i l 1 , $bd ) ;
$moyenne2 = s e l f : : m o y e n n e I n t e r n a u t e ( $ e m a i l 2 , $bd ) ;
$ r e q u e t e = " SELECT ∗ FROM Film " ;
$ l i s t e F i l m s = $bd−>execRequete ( $ r e q u e t e ) ;
w h i l e ( $ f i l m = $bd−>o b j e t S u i v a n t ( $ l i s t e F i l m s ) )
{
$ n o t a t i o n 1 = s e l f : : c h e r c h e N o t a t i o n ( $ e m a i l 1 , $ f i l m−> t i t r e ,
$bd ) ;
$ n o t a t i o n 2 = s e l f : : c h e r c h e N o t a t i o n ( $ e m a i l 2 , $ f i l m−> t i t r e ,
$bd ) ;
i f ( $ n o t a t i o n 1 and $ n o t a t i o n 2 )
{
$somme_numerateur += ( $ n o t a t i o n 1−>note − $moyenne1 )
∗ ( $notation2 −>note − $moyenne2 ) ;
$somme_denom1 += pow ( $ n o t a t i o n 1−>note − $moyenne1 , 2 ) ;
$somme_denom2 += pow ( $ n o t a t i o n 2−>note − $moyenne2 , 2 ) ;
}
}
$somme_denominateur = s q r t ( $somme_denom1 ∗ $somme_denom2 ) ;
i f ( $somme_denominateur != 0 )
$ c o r r = a b s ( $somme_numerateur ) / $somme_denominateur ;
e l s e
$ c o r r = 0 ;
Trang 37.4 Recommandations 315
r e t u r n $ c o r r ;
}
Les fonctions pow(), sqrt() et abs() font partie du riche ensemble
de fonctions de PHP (voir annexe C) Finalement la méthode statique Util::calculPrediction() applique la formule (7.2) pour calculer la prédiction sur un film comme la moyenne des notations des autres internautes sur ce film, pondérées par les coefficients de corrélation
s t a t i c f u n c t i o n c a l c u l P r e d i c t i o n ( $ e m a i l , $ i d _ f i l m , $ t a b _ c o r r ,
$bd )
{
/ / C a l c u l d e l a m o y e n n e d e s n o t e s d e l ’ i n t e r n a u t e c o u r a n t
$ma_moyenne = s e l f : : m o y e n n e I n t e r n a u t e ( $ e m a i l , $bd ) ;
/ / B o u c l e s u r t o u t e s l e s a u t r e s n o t a t i o n s du même f i l m
$ r e q _ n o t a t i o n s = " SELECT ∗ FROM Notation WHERE i d _ f i l m = ’
$ i d _ f i l m ’ " ;
$ l i s t e _ n o t a t i o n s = $bd−>execRequete ( $ r e q _ n o t a t i o n s ) ;
/ / A p p l i c a t i o n d e l a f o r m u l e d e c o r r é l a t i o n
$ s o m m e _ c o r r = 0 ;
$somme_ponderee = 0 ;
w h i l e ( $ n o t a t i o n = $bd−>o b j e t S u i v a n t ( $ l i s t e _ n o t a t i o n s ) ) {
$moyenne = s e l f : : m o y e n n e I n t e r n a u t e ( $ n o t a t i o n−>email , $bd ) ;
$ s o m m e _ c o r r += ( f l o a t ) $ t a b _ c o r r [ " $ n o t a t i o n−>e m a il " ] ;
$somme_ponderee += ( f l o a t ) $ t a b _ c o r r [ " $ n o t a t i o n−>e m a il " ] ∗
( $ n o t a t i o n−>note − $moyenne ) ;
}
i f ( $ s o m m e _ c o r r != 0 )
r e t u r n $ma_moyenne + ( $somme_ponderee / $ s o m m e _ c o r r ) ;
e l s e
r e t u r n $ma_moyenne ;
}
On peut remarquer dans cette fonction que les variables $sommeCorr
et $sommePonderee sont explicitement manipulées comme des réels, avec la commande de conversion (float) placée devant une expression Comme PHP est libre de convertir une variable en fonction du type qui lui semble le plus approprié, il vaut mieux prendre la précaution de donner explicitement ce type s’il est important
Trang 58
Ce chapitre propose une introduction à XML et présente quelques utilisations pos-sibles de ce langage dans le cadre d’un site web basé sur MySQL et PHP L’intérêt de
XML dans un tel contexte consiste essentiellement à faciliter l’échange de données,
aussi bien pour exporter des données de la base MySQL et les transmettre sur le réseau, que pour récupérer des données et les insérer dans la base Nous verrons comment représenter une base de données relationnelle en XML et comment utiliser les fonctions PHP pour extraire des données de cette représentation
Une autre possibilité d’utilisation de XML est la publication de données Un
des atouts de XML est de rendre la représentation de l’information indépendante des applications qui la manipulent Dans notre cas, cela signifie qu’un document XML produit par un site web MySQL/PHP n’est pas réduit à être affiché dans un navigateur, à la différence des documents HTML construits jusqu’à présent On peut, après une phase de transformation, proposer les informations de ce document
au format HTML, mais aussi PDF pour une lecture ou impression de qualité, SVG pour des graphiques, ou enfin RSS En d’autres termes on sépare le contenu de la
présentation, ce qui rejoint en partie les objectifs des solutions de templates présentées
dans le chapitre 5
Notre présentation de XML est bien entendu illustrée dans le cadre du site
WEBSCOPE, les fonctionnalités étant rassemblées dans le contrôleur XML dont la page d’accueil est reprise figure 8.1 On peut, à l’aide d’un formulaire semblable à celui utilisé pour la notation (voir page 295), rechercher des films et en obtenir une représentation sous forme de document XML, indépendante donc de MySQL, PHP ou HTML On peut également appliquer une transformation XSLT à ce même document pour le mettre au format HTML (selon le même principe, on pourrait obtenir de nombreux autres formats) Enfin il est possible d’effectuer l’opération inverse, à savoir transmettre au serveur un fichier contenant un document XML