Local Mining Models depuis des modèles serveur

Je me suis une fois posé cette question simple: est il possible, à la manière d’un CREATE GLOBAL CUBE, de créer des modèles de mining locaux stockés dans des .cub (destinés à des applications embarquées) depuis des modèles serveur déjà développés.

Les applications seraient énormes pour des terminaux mobiles déconnectés, dont on mettrait à jour périodiquement un petit modèle d’analyse généré en central.

La réponse au problème est oui, d’où ce post, modulo un petit peu de travail. J’ai fait le boulot sous SSIS pour plus de clarté mais l’intégralité peut se faire depuis du code .NET.

1) Récupérer le script ASSL de création du modèle serveur

Dans une script task, un brin d’AMO suffit à récupérer ce script, grâce à l’objet Scripter utilisé par l’ami Management Studio.

 // Connexion au serveur
Server svr = new Server();
svr.Connect(---);

//Recuperation de la MiningStructure
MajorObject[] source = new MajorObject[1];
source[0] = (MajorObject)svr.Databases["Adventure Works DW 2008 EE"].MiningStructures["Targeted Mailing"];

//Instanciation d'un scripter
Scripter scr = new Scripter();
XmlWriterSettings settings = new XmlWriterSettings();
settings.OmitXmlDeclaration = true;

//Ecriture en mémoire depuis un XMLWriter
StringBuilder sb = new StringBuilder();
XmlWriter writer = XmlWriter.Create(sb,settings);
scr.ScriptCreate(source, writer, true);
writer.Flush();
writer.Close();
svr.Disconnect();

//Affectation de la variable;
Dts.Variables["TempXMLAHolder"].Value = sb.ToString();
Dts.TaskResult = (int)ScriptResults.Success;

2) Retravailler le XMLA avec XPath

Le XMLA généré n’est pas très utilisable: il comprend encore des bindings aux DSV de la source, ainsi que des noms d’objets invalides. Un peu de DOM/XPath suffit à retravailler tout cela modulo la connaissance basique de XMLA.
De plus les modèles de mining embarqués ne supportent que les algos de clustering et de decision trees (les algos 2000), il faut donc supprimer les autres.

 string xmla = Dts.Variables["TempXMLAHolder"].Value.ToString();
string asDbName = Dts.Variables["SsasDatabaseName"].Value.ToString();

//Chargement du doc XML
XmlDocument doc = new XmlDocument();
doc.Load(new StringReader(xmla));
XmlNamespaceManager mgr = new XmlNamespaceManager(doc.NameTable);
mgr.AddNamespace("Ns", @"http://schemas.microsoft.com/analysisservices/2003/engine");

//Changement de la base de données
doc.SelectSingleNode("/Ns:Create/Ns:ParentObject/Ns:DatabaseID", mgr).InnerText = asDbName;

//Suppression du binding de la MS à la DSV
XmlNode n = doc.SelectSingleNode("/Ns:Create/Ns:ObjectDefinition/Ns:MiningStructure/Ns:Source", mgr);
n.ParentNode.RemoveChild(n);

//Suppression des MiningModels non conformes
XmlNodeList l = doc.SelectNodes("/Ns:Create/Ns:ObjectDefinition/Ns:MiningStructure/Ns:MiningModels/Ns:MiningModel", mgr);
string algo = string.Empty;
for (int i = 0; i ; i++)
{
algo = l[i].ChildNodes[2].InnerText;
if (algo != "Microsoft_Decision_Trees" && algo != "Microsoft_Clustering")
{
bool b = true;
Dts.Events.FireInformation(0,
string.Empty,
"Le modèle doit être de type MDT ou MC, modèle de type " + algo + " supprimé.",
string.Empty,
0, ref b);
l[i].ParentNode.RemoveChild(l[i]);
}
}
Dts.Variables["TempXMLAHolder"].Value = doc.OuterXml;
Dts.TaskResult = (int)ScriptResults.Success;

3) Créer un cube local et appliquer l’ASSL dessus

Ceci fait il ne reste qu’à créer un cube local, grâce à la petite ruse de Chris Webb.
Puis à appliquer le script XMLA créé à ce cube (une simple AdomdCommand XMLA du script issu du Scripter AMO et retravaillé en XML).

On dispose alors… de modèles de mining dans un cube local!

4) Entrainer le modèle local

Mais il reste encore à les entraîner. Inutile de préciser que les tâches SSIS classiques sont inopérantes. Elles envoient des erreurs exotiques aidant à comprendre que leur usage devra être contourné.
Pour l’alimentation je suis passé par un paramètre DMX de type DataTable dans un INSERT INTO MINING STRUCTURE comme expliqué par Jamie McLennan dans un de ses posts pré-départ. Cette DataTable est dérivée du très oldschool ADO Recordset de SSIS – beuark – dans un script dédié. Modulo l’ordonnancement des colonnes pour la jointure naturelle voilà un modèle entraîné.

4) Action!

Il suffit alors de l’utiliser, en ADOMD.NET avec une chaîne de connexion pointant sur le fichier .cub en tant que Data Source et voici la « belle » application:


Le package complet est disponible ici et vous pouvez le tester. Il ressemble à cela:


En espérant avoir suscité quelques scénarii de mining embarqué…

A bientôt!

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s