数据挖掘是SQL Server 2000中最令人激动的新功能之一。我将数据挖掘看作是一个能够自动分析数据以获取相关信息的过程,数据挖掘可以和任一关系数据库或者OLAP数据源集成使用,但它和OLAP的集成所带来的好处却是极为显著的。因为结构化的数据源使得用户无需再向数据挖掘算法提供海量信息了。尽管不是什么专家,但我从同事Greg Bernhardt那里学到东西已经足够我来对数据挖掘作一翻解释了,我还希望由此使得分析服务的数据挖掘功能不再神秘并向你展示如何在分析应用中使用数据挖掘。
数据挖掘功能 数据挖掘弥补了分析服务功能中的重要不足之处。微软在SQL Server 7.0中引入了针对特定问题的分析和探测性分析功能。在针对特定问题的分析中,分析器要清楚用户需要回答什么问题并简单地利用OALP引擎获取相关信息。例如,一个快餐店的经理可能想知道:“最近四个季度,汉堡包的营业额和利润怎么样?”
在探测性分析中,分析器可能对用户的兴趣有所了解,但不需要回答具体的问题。例如,一个公司可能知道自己的一些零售商店没有利润,但却不知道原因何在。分析器在一个OLAP多维数据集中通过获取更多的细节资料,进行多维查找,获得最感兴趣的数据,我们称这一过程为数据冲浪。
数据挖掘同“针对特定问题”的分析和探测性分析都不相同。通过数据挖掘,分析服务可以浏览信息,寻找相关数据并提交数据。数据挖掘可以说是探测性分析的理想搭档。
SQL Server 2000通过新的API━━OLE DB for Data Mining(OLE DB for DM)实现了数据挖掘的功能,这是一个为方便各种应用程序使用数据挖掘功能而设计的编程接口。通过OLE DB for DM, 微软提供了两种数据挖掘算法(其它软件供应商也可以插入新的算法)。理论上,利用OLE DB for DM开发的分析程序能够使用新发明的算法。
SQL Sever 2000中包含的两种算法是决策树和群。决策树将信息分类为一个树状结构,可以帮助我们预测数据的某些特性。例如,可以将用户信息(如收入、婚姻状况及受教育程度)交由决策树算法,对预测该用户是否具有信用风险提供帮助。可以用群集算法寻找数据中的自然分组。例如,可以将所有的用户信息送入群集算法,要求把所有客户分为三个组。算法可能会找到一个已婚、受教育程度较高而收入偏低的分组,一个单身、高收入的分组和一个受教育程度较低而收入较高的分组。通过进一步的分析可能个发现每个分组都有一个特定的购物方式。利用这些资料,我们可以进行高效益、针对性强的广告活动。注意第二、三分组并没有完全使用所有的三项输入的信息,因为对于分组来说,并不是所有的输入信息都很重要。因此,第二组的描述之所以不包括受教育程度是由于分组不是根据教育水平来划分的。
使用分析服务 如果进行数据挖掘的对象是OLAP多维数据集而不是关系数据库,就不能直接使用OLE DB for DM,因为分析服务可以通过自己的编程接口来实现数据挖掘功能。在服务器端,可以通过决策支持对象(Decision Support Objects,DSO)使用数据挖掘功能,而在客户机端则可以通过OLE DB for OLAP或ActiveX多维数据对象(ADO MD)使用数据挖掘功能。
与群集算法相比,我更喜欢决策树算法,因为它可以根据决策树算法进行数据挖掘的结果创建新的“维”,我们可以将这些“维”纳入一个新的虚拟多维数据集,还可以用数据挖掘的结果浏览现有的维。
创建挖掘模型 创建挖掘模型,需要打开分析管理器(Analysis Manager),展开左边的树形浏览窗口,打开FoodMart 2000数据库。你将看到挖掘模型文件夹(挖掘模型定义了所挖掘的具体数据和根据该信息所做的预测类型。),右击该文件夹,选择新挖掘模型(New Mining Model)运行挖掘模型向导。该向导首先要求选择是在关系型数据还是在多维数据集中进行数据挖掘。选择Multidimensional后单击Next按钮。然后选择要挖掘的数据集(在本例中选择Sale数据集)。向导的第三步是选择数据挖掘算法,选择Microsoft Decision Trees(微软的决策树)后单击Next按钮。
下一步就该选择数据挖掘容器了(容器是新挖掘多维模型挖掘的数据实体)。选择Customers维和Name层。下一步,选择所作预测的类型。假设数据挖掘算法有输入输出,本例将用户的相关信息作为输入,年收入作为被预测的实体或输出。年收入是Customer维中Name层的一个成员属性。依次选择A member property of the case level(容器层的成员属性)—> Yearly Income,如图1 所示。
(图1)
下一步需要选择为预测年收入所需要用到的OLAP多维数据集中的那部分数据。选中Customers维、Customers维中所有的层及Name层中Member属性下的所有层,如图2所示(这些都是缺省的设置)。需要注意的是,Yearly Income既是输入也是输出,这是因为我们正在训练挖掘模型。为训练挖掘模型,算法需要正确的答案。(如:现有用户的实际年收入)
(图2)
点击Next按钮,创建一个OLAP维和一个虚拟多维数据集。对话框设置按图3所示。挖掘向导模式将根据Sales多维数据集创建一个虚拟多维数据集,增加一个名为PredictIncome的新数据挖掘维, 点击Next后,为建立挖掘模型起个名字并决定是否立刻执行。我们将建立的挖掘模型命名为IncomModel, 点击Save按钮并立刻执行。当点击Finish按钮后,分析服务将对数据进行处理,并在挖掘模型编辑器中显示挖掘的结果。
(图3)
图4显示的就是OLAP挖掘模式编辑器,中间的窗口显示了结果决策树的几个结点(图5显示的是一棵完整的决策树)图4右上方标题为“Content Navigator”(内容导航员)窗口用颜色表示数据密度,用图形的方式描述了整棵决策树,其中颜色越深就代表用户越多。在中间的窗口,我选择了一个结点Customers.Name.Member Card = Normal,该结点代表所有成员属性会员卡的值为Normal的用户。中间靠右的窗口显示了该类别中用户不同年份年收入的条形图。我们发现他们中的83%的人的收入介于10000美元至30000美元之间,这就意味着会员卡值为normal可以很好地预测这一收入水平的用户。(我们对这一结论不应该感到意外,因为Member Cards属性是挖掘模型通过挖掘年收入和教育水平而创建的。)
(图4)
(图5)
不使用分析管理器分析多维数据集 现在假设你从客户端应用程序分析Trained Income多维数据集,不具有OLAP管理员权限来运行分析管理器(Analysis Manager),就可以用下面的多维表达查询(MDX)来得到相同的条形图信息,查询将返回每一个收入水平符合“Member Card = Normal”条件的用户编号。查询首先创建一个持有普通成员卡的用户的集合(CustMembers),然后创建新的方法来统计符合当前所选收入水平的用户有多少。
WITH SET [CustMembers] as 'Filter([Customers].[Name].Members, not IsEmpty([Customers].CurrentMember))'
MEMBER [Measures].[Cust Count] as 'Count( Filter( [CustMembers],
[Customers].CurrentMember.Properties("Yearly Income") =[Yearly Income].CurrentMember.Name))'
SELECT { [Measures].[Cust Count] } ON COLUMNS ,[Yearly Income].[All Yearly Income].Children ON ROWS FROM [TrainedIncome]
WHERE ([PredictIncome].[All].[Customers.Name.Member Card = Normal] )
在客户端创建挖掘模型 尝试不同的挖掘模型,从其中找到效果最好的。尽管目前的客户端应用程序还不支持这一功能,但用户希望在客户机端,而不是在服务器端创建挖掘模型。客户分析程序需要支持这项功能,可以利用MDX扩展通过OLE DB for OLAP或ADO MD来创建挖掘模型。在客户机端创建挖掘模型需要运行SQL Server企业版,因为该功能依赖于企业版的自定义累积功能。
用数据挖掘维创建虚拟数据集需要三个步骤。第一,创建挖掘模型。下面的命令生成一个挖掘决策树来根据用户的性别、婚姻和教育状况预测年收入。
CREATE OLAP MINING MODEL [Local Find Salary]
FROM [Sales]
(
CASE
DIMENSION [Customers]
LEVEL [Name]
PROPERTY [Gender] ,
PROPERTY [Marital Status] ,
PROPERTY [Education] ,
PROPERTY [Yearly Income] PREDICT
)
USING Microsoft_Decision_Trees
注意调用数据集名字的FROM语句和引出Customers维Name层的成员属性的每个PROPERTY关健字。运行上面的命令后,就会得到一个空的挖掘模型,它对你的分析服务(Analysis Services)连接是唯一的,也会与其它工作站共享。(要创建共享的挖掘模型,需要用分析管理器或DSO编程接口)。下面的命令是将Sales多维数据集中的数据送入挖掘模型。这是一个简单的指定了挖掘模型名字的INSERT INTO语句:
INSERT INTO [Local Find Salary]
最后,将根据挖掘模型、其它维以及从源多维数据集中引用的度创建一个虚拟多维数据集。下面是创建多维数据集的代码:
CREATE SESSION VIRTUAL CUBE [PredictIncomeCube]
FROM [Sales]
(
MEASURE [Sales].[Unit Sales] ,
DIMENSION [Sales].[Customers],
DIMENSION [Sales].[Time],
DIMENSION [PredictIncome] NOT_RELATED_TO_FACTS
FROM [Local Find Salary]
COLUMN [Customers.Name.Yearly Income]
)
在这一语句中,我仅仅使用了Unit Sales度、Customers和Time维。最后一个维━━PredictIncome是作为CREATE VIRTUAL CUBE语句的一部分而创建的。NOT_RELATED_TO_FACTS关键字让分析服务(Analysis Services)知道该维不是由同多维数据集相关的表得来的,FROM和COLUMN子句进一步说明了在创建虚拟多维数据集时使用了挖掘模型和挖掘模型的预测实体。
下面是用Visual Basic编写的用来演示上述的命令运行的一小段程序:
Const sGUID_SCHEMA_SERVICE_PARAMETERS As String = "{3ADD8A75-D8B9-11D2-8D2A-00E029154FDE}"
Const sGUID_SCHEMA_MINING_SERVICES As String = "{3ADD8A95-D8B9-11D2-8D2A-00E029154FDE}"
Const sGUID_SCHEMA_MINING_MODELS As String = "{3ADD8A77-D8B9-11D2-8D2A-00E029154FDE}"
Const sGUID_SCHEMA_MINING_COLUMNS As String = "{3ADD8A78-D8B9-11D2-8D2A-00E029154FDE}"
Const sGUID_SCHEMA_MODEL_CONTENT As String = "{3ADD8A76-D8B9-11D2-8D2A-00E029154FDE}"
Const sGUID_SCHEMA_MODEL_CONTENT_PMML As String = "{4290B2D5-0E9C-4AA7-9369-98C95CFD9D13}"
Dim m_conn As New ADODB.Connection
Private Sub ExecuteMDX(ByVal v_sMDX As String)
On Error GoTo ErrHandler
Dim cmd As New ADODB.Command
Dim rec As Recordset
Dim nNum As Integer
Set cmd.ActiveConnection = m_conn
cmd.CommandText = v_sMDX
Set rec = cmd.Execute(nNum)
MsgBox "Command Executed Successfully. " & nNum & " rows affected.", vbOKOnly + vbInformation
Exit Sub
ErrHandler:
MsgBox Err.Description, vbExclamation
End Sub
Private Sub Form_Load()
' Specify .2 on the provider so only SQL 2000 will work
' Connect to a server on the local PC. Change this if you are connecting
' to another PC with Analysis Services.
Call m_conn.Open("PROVIDER=MSOLAP.2;Data Source=LOCALHOST;")
' Create the mining model
Call ExecuteMDX( _"CREATE OLAP MINING MODEL [Local Find Salary] " & _
"From [Sales] " & "( " & " CASE " & _
" Dimension [Customers] " & _
" Level [Name] " & _
" PROPERTY [Gender] ," & _
" PROPERTY [Marital Status] ," & _
" PROPERTY [Education] ," & _
" PROPERTY [Yearly Income] PREDICT " & _
")" & _
"USING Microsoft_Decision_Trees")
' Fill the mining model
Call ExecuteMDX("INSERT INTO [Local Find Salary]")
' Create a virtual cube based on the mining model
Call ExecuteMDX( _
"CREATE SESSION VIRTUAL CUBE [PredictIncomeCube] " & _
"FROM [Sales] " & _
"( " & _
" MEASURE [Sales].[Unit Sales] , " & _
" DIMENSION [Sales].[Customers], " & _
" DIMENSION [Sales].[Time], " & _
" DIMENSION [PredictIncome] NOT_RELATED_TO_FACTS " & _
" FROM [Local Find Salary] " & _
" COLUMN [Customers.Name.Yearly Income] " & _
") ")
Dim recCols As Recordset
Dim vtRestrict As Variant
vtRestrict = Array(Empty, Empty, "Local Find Salary")
' open the data mining model's content as a rowset
Set recCols = m_conn.OpenSchema(adSchemaProviderSpecific, vtRestrict, sGUID_SCHEMA_MODEL_CONTENT)
' display each node caption of the resulting decision tree
Do While Not recCols.EOF
MsgBox recCols.Fields("NODE_CAPTION").Value
recCols.MoveNext
Loop
m_conn.Close
End Sub
不幸的是你不得不使用这样的程序而不是MDX范例,因为命令的执行必须用到一个返回记录集,而不是在前面讨论的三全命令中使用的标准的多维单元集,而后打开一个微软专有的图表记录集(我在例程中添加了OpenSchema函数来说明如何获取挖掘模型的内容)。例程仅仅列出了决策树中每一结点的名称,记录集被组织成象父子维表一样的结构,该记录集的每个记录在决策树中确定一个结点,并具有一个NODE_UNIQUE_NAME和PARENT_UNIQUE_NAME字段。PARENT_UNIQUE_NAME确定包含当前行的父纪录的记录。
在例程的开始,是一个包含GUID的列表,可以利用它访问所有和数据挖掘相关的特定提供者的记录集。在上面例程中没有用到它们,但如果你计划开发支持数据挖掘功能的应用程序,不妨试试它们。
比想象的要简单 当我第一次看OLE DB for DM的详细说明时,认为要完成一个简单的数据挖掘也需要程序员或应用程序用户提供如此多的信息,以至于怀疑它对于普通决策者是否有用。但通过深入的研究,我明白了它之所以看起来比较复杂,是因为在挖掘关系数据库需要较多的信息,挖掘OLAP多维数据集则不需要太多的信息。OLAP数据挖掘是简单、快速、有用的,决策树算法是一种可以帮助我们对大量数据进行结构化处理从而获取有用信息的好方法。