使用SQL Server Analysis Services數據(ju)挖掘的關聯規則實現商品推薦功(gong)能(七(qi))
假如你有一個(ge)購物類的(de)網站,那么(me)你如何給你的(de)客(ke)戶來推薦產(chan)品呢?這個(ge)功(gong)能在很多(duo)電(dian)商類網站都有,那么(me),通過SQL Server Analysis Services的(de)數據(ju)挖掘功(gong)能,你也可以輕松的(de)來構建類似的(de)功(gong)能。
上一(yi)篇(pian)中(zhong)介(jie)紹的是如何通過DMX來(lai)創建挖(wa)掘(jue)(jue)模型,這一(yi)篇(pian)講簡單介(jie)紹如何通過編程的方(fang)式來(lai)創建挖(wa)掘(jue)(jue)模型。
通過(guo)編程的(de)方式(shi)主(zhu)要通過(guo)AMO來實現,分(fen)析服(fu)務的(de)所有跟架構相(xiang)關的(de)實現,包括多維數(shu)據(ju)集(ji)和(he)數(shu)據(ju)挖掘,都通過(guo)這個接口(kou)實現。
AMO對象樹包含了支持多維數據集和數據挖掘所有的對象模型,在我這篇隨筆中可以詳細看到它的結構。
對(dui)象的結(jie)構稍(shao)微復雜一些,但我們(men)關注的有三個(ge)部分:

通過(guo)這兩個對象(xiang)連接到分析服務(wu)(wu)數(shu)據庫并且操作分析服務(wu)(wu)數(shu)據庫實(shi)例。

然后通(tong)過(guo)DataSource以(yi)及DataSourceView創建(jian)數(shu)據源(yuan)連接(jie)和數(shu)據源(yuan)視圖。

然后通(tong)過(guo)MiningStructrue下的對(dui)象體系和(he)MiningModel來創建挖掘結構和(he)挖掘模型,可以留(liu)意到(dao)Column是自包含的結構,這主(zhu)要是考慮到(dao)了挖掘結構中的嵌(qian)套模型。
通過(guo)以(yi)上的對象模型我們可(ke)以(yi)觀察(cha)到,這些對象跟我們在(zai)Visual Studio中創(chuang)建一(yi)個數(shu)據挖掘項目都(dou)是相對應的,在(zai)一(yi)個正常的過(guo)程中我們都(dou)會按(an)照下面(mian)的套路進行操(cao)作(zuo):
- 創建項目(實際上部署之后對應的就是一個數據庫)
- 創建數據源
- 創建數據源視圖
- 創建挖掘結構(定義數據結構)
- 創建挖掘模型(挖掘算法等)
以(yi)下將簡單演示(shi)如何通過AMO來創建(jian)數據挖掘項目。
打(da)開Visual Studio,此篇用到(dao)的(de)版本是2010,對應的(de)數據庫是SQL Server 2012。在Visual Studio中創(chuang)建一個控制臺項目,然后(hou)右鍵單擊(ji)References文件夾,選擇Add Reference…

點擊Browse找到AMO對(dui)象所對(dui)應的(de)dll文(wen)件。

這個文件通常在如下的位置(zhi):
C:\Program Files (x86)\Microsoft SQL Server\110\SDK\Assemblies
接下來(lai)回到控制(zhi)臺代(dai)碼中,首(shou)先需(xu)要加入AMO對象的引用。
using Microsoft.AnalysisServices;
然后,通過如下(xia)的代碼連接到分(fen)析服(fu)務實例。
Server SSASServer = new Server();
SSASServer.Connect(@".");
創建分析服務數(shu)據庫。
#region Create database
string strDataBaseName = "DMAMO";
Console.WriteLine("Check database: " + strDataBaseName);
if (SSASServer.Databases.Contains(strDataBaseName))
{
SSASServer.Databases.Remove(strDataBaseName);
Console.WriteLine("Database " + strDataBaseName + " already exists, droped.");
}
Database db = new Database(strDataBaseName, strDataBaseName);
SSASServer.Databases.Add(db);
db.Update();
#endregion

上面代碼運行完畢后,會看到在對應的(de)分析服務實例下已經創建了一個空的(de)數據庫。
創建數據源。
#region DataSource
RelationalDataSource rds = new RelationalDataSource("DMDataSource", Utils.GetSyntacticallyValidID("DMDataSource", typeof(Database)));
rds.ConnectionString = @"Data Source=.;Initial Catalog=AdventureWorksDW2012;Provider=SQLNCLI11.1;Integrated Security=SSPI;Application Name=SSASDEMO;";
rds.ImpersonationInfo = new ImpersonationInfo("wade", "iamfromcnblogs");
db.DataSources.Add(rds);
db.Update(UpdateOptions.ExpandFull);
#endregion

留意到數據源(yuan)對象的ImpersonationInfo屬性,它的設(she)置(zhi)(zhi)對應如下(xia)圖(tu)的設(she)置(zhi)(zhi)。在本(ben)機開發的時候,為了方便我們通(tong)常(chang)將其設(she)置(zhi)(zhi)成(cheng)為一個(ge)管理員賬(zhang)號。

創建數據源視圖。
#region Data Source View
DataSet dset = new DataSet();
SqlConnection sqlconn = new SqlConnection(@"Data Source=.;Initial Catalog=AdventureWorksDW2012;Integrated Security=SSPI;Application Name=SSASDEMO;");
//Line Items
SqlDataAdapter daLineItems = new SqlDataAdapter("SELECT [OrderNumber],[LineNumber],[Model] FROM [vAssocSeqLineItems]", sqlconn);
daLineItems.FillSchema(dset, SchemaType.Mapped, "vAssocSeqLineItems");
dset.Tables["vAssocSeqLineItems"].ExtendedProperties.Add("TableType", "View");
//Orders
SqlDataAdapter daOrders = new SqlDataAdapter("SELECT [OrderNumber],[CustomerKey],[Region],[IncomeGroup] FROM [vAssocSeqOrders]", sqlconn);
daOrders.FillSchema(dset, SchemaType.Mapped, "vAssocSeqOrders");
dset.Tables["vAssocSeqOrders"].ExtendedProperties.Add("TableType", "View");
//Relationship
DataRelation relateProductSubCate = new DataRelation("Rel", dset.Tables["vAssocSeqOrders"].Columns["OrderNumber"], dset.Tables["vAssocSeqLineItems"].Columns["OrderNumber"]);
dset.Relations.Add(relateProductSubCate);
DataSourceView dsv = new DataSourceView("DMDSV", "DMDSV");
dsv.DataSourceID = "DMDataSource";
dsv.Schema = dset.Clone();
db.DataSourceViews.Add(dsv);
db.Update(UpdateOptions.ExpandFull);
#endregion

創建數(shu)據源視圖是(shi)一(yi)(yi)個(ge)(ge)比較復雜(za)的(de)過程(cheng),表需要對應一(yi)(yi)個(ge)(ge)一(yi)(yi)個(ge)(ge)的(de)對象(xiang),而且(qie)關系也(ye)要一(yi)(yi)一(yi)(yi)創建,最后需要把用(yong)到的(de)表都通(tong)過DataSet對象(xiang)加載進來,然后再通(tong)過clone方法將其設置成數(shu)據源視圖的(de)架構。

創建挖掘結構。
#region Mining Structure
MiningStructure ms = new MiningStructure("MSOrder", "MSOrder");
db.MiningStructures.Add(ms);
ms.Source = new DataSourceViewBinding("DMDSV");
ScalarMiningStructureColumn scOrderNumber = ms.Columns.Add("OrderNumber", "OrderNumber");
scOrderNumber.IsKey = true;
scOrderNumber.Type = MiningStructureColumnTypes.Text;
scOrderNumber.Content = MiningStructureColumnContents.Key;
scOrderNumber.KeyColumns.Add("vAssocSeqOrders", "OrderNumber", OleDbType.WChar);
ScalarMiningStructureColumn scModel = ms.Columns.Add("Model", "Model");
scModel.IsKey = true;
scModel.Type = MiningStructureColumnTypes.Text;
scModel.Content = MiningStructureColumnContents.Key;
scModel.KeyColumns.Add("vAssocSeqLineItems", "Model", OleDbType.WChar);
TableMiningStructureColumn tcLineItems = new TableMiningStructureColumn("SeqLineitems", "SeqLineitems");
tcLineItems.ForeignKeyColumns.Add("vAssocSeqLineItems", "OrderNumber");
tcLineItems.Columns.Add(scModel);
ms.Columns.Add(tcLineItems);
ms.Update();
#endregion

挖(wa)掘(jue)(jue)結(jie)構的(de)(de)創建實(shi)際(ji)上也(ye)是(shi)把(ba)數據源視(shi)圖中(zhong)定義的(de)(de)架構映射(she)成(cheng)數據挖(wa)掘(jue)(jue)結(jie)構的(de)(de)一個過(guo)程(cheng)。需(xu)要(yao)通過(guo)對應的(de)(de)MiningColumn對象根據數據源視(shi)圖把(ba)需(xu)要(yao)用到的(de)(de)字(zi)段映射(she)進來(lai)。
創建(jian)挖(wa)掘(jue)模型(xing),其中通(tong)過(guo)枚(mei)舉屬性Algorithm來(lai)設置挖(wa)掘(jue)模型(xing)根據挖(wa)掘(jue)結構采用的(de)是哪種(zhong)挖(wa)掘(jue)算法。
#region Mining Model
MiningModel mm = ms.CreateMiningModel(true, "Basket Forecasting Model");
mm.Algorithm = MiningModelAlgorithms.MicrosoftAssociationRules;
mm.Columns["SeqLineitems"].Usage = MiningModelColumnUsages.Predict;
mm.Update();
#endregion

一(yi)個挖(wa)(wa)掘模型對應(ying)一(yi)個挖(wa)(wa)掘結(jie)構,所以(yi)很多結(jie)構直接繼承了挖(wa)(wa)掘結(jie)構。這(zhe)里(li)唯一(yi)需(xu)要做的(de)就是,根據創建出來的(de)挖(wa)(wa)掘模型,將其中(zhong)的(de)一(yi)個列設置成預(yu)測(ce)字段。
最后,通過AMO處(chu)理挖掘模型。
#region Process
SSASServer.CaptureXml = true;
db.Process();
SSASServer.CaptureXml = false;
Console.WriteLine("Processing...");
SSASServer.ExecuteCaptureLog(true, true);
#endregion
打開挖掘(jue)模型,可以看(kan)到挖掘(jue)模型生成的規則。
當(dang)然,實際上在代碼中來(lai)(lai)(lai)創建挖掘(jue)模(mo)型(xing)(xing)是不被推薦的(de)(de)(de),有(you)(you)些AMO的(de)(de)(de)深層(ceng)對(dui)象(xiang)模(mo)型(xing)(xing)目(mu)前SQL Server的(de)(de)(de)文檔里只能(neng)提供(gong)接口(kou)描(miao)述而沒有(you)(you)關(guan)于模(mo)型(xing)(xing)的(de)(de)(de)介紹(shao)和(he)講解(jie),筆者主要是根據項目(mu)里創建的(de)(de)(de)過程(cheng)然后再回過頭來(lai)(lai)(lai)理解(jie)對(dui)象(xiang)模(mo)型(xing)(xing)的(de)(de)(de)含義,而即(ji)使國外網站上關(guan)于挖掘(jue)結構和(he)模(mo)型(xing)(xing)中的(de)(de)(de)嵌套結構更是少(shao)之又少(shao),所(suo)以(yi)這篇真(zhen)的(de)(de)(de)是摸索了好久(jiu),不斷的(de)(de)(de)編譯調試(shi)和(he)對(dui)比才將(jiang)各個(ge)細節(jie)打通(tong)。無(wu)論如何,通(tong)過這個(ge)過程(cheng)我(wo)們可以(yi)更深入的(de)(de)(de)了解(jie)分(fen)析(xi)服務底層(ceng)的(de)(de)(de)對(dui)象(xiang)模(mo)型(xing)(xing)從而更好地(di)(di)去理解(jie)和(he)設計我(wo)們的(de)(de)(de)挖掘(jue)模(mo)型(xing)(xing),同(tong)時也可以(yi)通(tong)過AMO自動(dong)地(di)(di)去調整模(mo)型(xing)(xing)。希(xi)望(wang)通(tong)過此篇,會讓更多的(de)(de)(de)朋友來(lai)(lai)(lai)了解(jie)AMO對(dui)象(xiang)模(mo)型(xing)(xing)。
附:
---------------------------------------------------------------
aspnetx的BI筆(bi)記系列(lie)索引:
使用SQL Server Analysis Services數據挖掘的關聯規則實現商品推薦功能
---------------------------------------------------------------
來自博客園的宋衛東
