具体实施方式
参照说明书附图对本发明的方法作以下详细地说明。
本发明的移动互联网告警关联规则获取方法,基本工作原理如下,如图1所示。
本发明的***能够在不关联告警网元资源的条件下,获取到移动互联网告警关联规则。
***是由告警数据获取模块、告警数据处理模块、参数设置模块、算法模块、结果处理模块五部分组成,***在获取到告警数据以后,对告警数据进行合并,根据挖掘工作的需要,从中选取出我们感兴趣的数据,通过数据的处理,进行关联规则提取工作,最后将获取到的结果进行表述和解释,具体工作流程如图2所示。
(1)告警数据获取
①基于告警信息存储数据库;
②构建数据表:活动告警表,历史告警表,告警编号表;
③活动告警和历史告警:告警在没有清除以前是活动告警,需要入到活动告警表中。告警清除以后被清除的告警需要入到历史告警表里面。一条告警同一时刻的状态是唯一的。要么是活动告警,要么是历史告警,但是肯定是先活动后经处理之后清除,活动告警在清除了以后,需要从活动告警表中移植到历史告警表中,清除时每个厂家的告警都有自己的清除规则。活动告警表和历史告警表里面的告警加起来是全部完整的告警。因此告警关联规则获取应该将两个表中的数据合在一起,作为最终的待处理数据;
④告警标题编号:为每个告警标题加上一个编号;
⑤告警关联规则获取用到的存储字段:设备厂家,网元名,告警对象,告警的发生时间,告警标题,告警标题编号。
(2)数据处理
数据处理是告警关联规则获取中的一个重要步骤,数据准备是否做好将直接影响到规则获取的效率、准确度以及最终结果的有效性。这个阶段又可以进一步分成几个子步骤:数据集成、数据选取、数据预处理和数据变换。
①数据集成:数据集成是将多文件或多数据库运行环境中的数据进行合并处理。
②数据选取:从告警数据库中将不同网元发送的告警进行统一格式处理
③数据清洗:通常包括去噪声、缺值数据处理、消除重复记录等操作。包括删除告警数据中由于各种原因引起的无法识别的数据,或者在重要关键告警信息上缺失的数据。
④数据变换:将目标数据处理成便于规则获取的形式。数据变换的一个重要的步骤就是为每个告警标题加上告警编号,形成一个告警编号表,将告警标题和告警编号的一一对应。这样使得在规则获取过程中更加容易处理,并且速度快。
(3)参数设置
告警时间窗及滑动步长
由于移动互联网设备的告警是不间断的实时发生的,很难确定一个完整的告警序列的开始时间和结束时间,如果随意的获取,很可能将本来是一个完整的告警序列拆分成部分,因此告警的连续性为告警关联规则获取工作带来了很多困难。为了使数据能够适合关联规则获取工作的需要,以时间窗的方式划分告警数据,这种转换机制需要用户预先设定好时间窗口大小以及滑动步长。并且保证每一个告警时间窗和其前面的时间窗和后面的时间窗互有重叠,在最大程度上保证时间窗中取得完整的告警序列数据,这样可以将告警关系型数据转换为告警事务型数据,其工作原理如图3所示。
告警时间窗和滑动步长的具体的设置方法为:
首先读入数据库中的告警数据,获得第一条告警发生时间,作为窗口开始时间,由开始时间加上窗口大小得到窗口终止时间。逐次将接下来的告警数据读入,时间不晚于终止时间的告警都为一个事务保存下来。一旦有一条告警的开始时间晚于终止时间,则由刚才的开始时间加上滑动步长得到新的开始时间,再加上窗口大小得到新的终止时间,然后将读取告警的指针移动到与新的开始时间最接近的记录开始读入,重复上述过程。这样,就可以把预处理表中的关系型数据转化为事务型数据。若干条告警对应一个事务。这里需要注意的是,告警滑动步长的设置不能大于告警时间窗口宽度的一半。
支持度和置信度:
在关联规则的获取过程中,需要设置两个重要的参数:支持度阈值与置信度阈值。支持度阈值用来生成告警频繁项集,置信度阈值用来生成告警关联规则。支持度阈值对关联规则结果集和算法运行时间影响都很大,而置信度阈值则对算法的运行时间没有太大的影响。如果支持度阈值太低,规则中偶尔发生的关联规则也会包含到最终输出的规则集当中,如果置信度阈值过低会同样会导致一些无意义的关联规则出现在结果规则集中。较低的阈值意味着较多的关联规则以及较长的规则发现时间;如果阈值过高则会导致丢失一些潜在有意义的关联规则。
给定了以上参数之后,挖掘算法最终输出满足给定条件的关联规则集。由于参数的选择对挖掘结果影响极大,因此需要在实际工作中选择合适的参数,尽量在不耗费过多的算法运行时间的前提下找出所有意义的关联规则模式。
(4)告警关联规则获取算法
提出了基于全项集的频繁模式增长算法。该算法的具体描述如下:
①读入告警事务数据库,生成一阶频繁项集,并将一阶频繁项集按照支持数进行排序;
②再次读入事务数据库,按照频繁一项集,扫描每一条事务,如果事务中的某项不在频繁一项集中,则删除该项,然后按照频繁一项集的顺序对每一条事务排序;
③对每一条事务产生全项集,对全项集的每一个项集进行扫描,将当前项集与前面所有项集进行比较,如果当前项集中的前i个项与前面某项集的前i个项相同,则标记为false,其余标记为true。其流程如图4所示。
⑤生成全项集的编码规则:
将全项集的每一条项集***到树中,事务中的第一个节点***到根节点下,后面的每一个项作为前一项的子节点。扫描频繁模式树,如果当前节点下的孩子节点中,没有包含当前项的节点,则建立此节点,已经有包含当前项的节点,检查项集中该项下面的标记,如果为true则节点支持数加1,否则不加1。
(5)结果的表述和解释
主要对获取到的关联规则进行解释、评估等。告警关联规则获取阶段发现的告警关联规则,可能存在冗余模式或无用规则,将其剔除;对一些近似的规则,为了便于用户理解、使用,对其进行归纳整理,合并为具有更高信息量的模式;对发现的规则进行一致性检查,避免发现的规则之间存在矛盾,根据用户的需要,也可以对获取到的规则执行修改等操作。
本发明的主要创新点
针对通信告警数据库的特点,提出了一种基于全项集的频繁模式增长算法,该算法将告警事务数据库中的项集生成非空子项集,并且对子项集进行扫描,按照设定的规则对子项集进行标记,根据标记的编码生成一个包含所有告警项的频繁模式树。对于告警关联规则的获取就是遍历所建立的频繁模式树。
在对告警关联规则的获取过程中,相对于传统的频繁模式增长算法,本算法不需要生成项头列表和链接频繁模式树中相同节点的节点链,只要生成一个先序频繁模式树,就能够完成告警频繁项集的获取工作。这样就避免了生成项头链表和频繁模式树中不同位置上相同节点所需要指针链接的复杂操作,降低了算法实现过程中的复杂度。并且在对频繁模式树的遍历过程中,不需要生成条件模式基和条件模式子树。所有的频繁项集的获取工作只是从频繁模式树中每一个分支的叶子节点向根节点的遍历过程。极大地简化了关联规则获取的时间和空间复杂度。非常适用于告警种类繁多且频繁出现的移动互联网告警数据库的关联规则获取工作。
实用效果
基于本发明的通信告警关联规则获取引擎,在不依赖于通信网络模型的情况下,能够自动的提取告警中存在的关联规则,特别适合于异构的、复杂多变的大型电信网络***。本发明能够将多个告警事件归结成较少的告警事件,过滤掉无意义的告警事件,有效的减少对网络和业务运行的人工干预,辅助网络管理人员删除衍生的冗余告警,确保网络正常、可靠的运行。将基于经验的运维转变成自动化智能化的运维,因此本发明具有广泛的应用前景和良好的实用价值。
实施例
本发明采用C++语言实现,能够运行在Windows、Unix、Linux等各种平台,算法在多种C++编译器下运行通过,在有着很强的可移植性和通用性,适合于各种移动互联网环境,下面给出实现过程中的函数和类的定义等文件说明和代码说明。
1告警数据的读取说明:
时间窗口告警数据的读取在函数GetWinData中实现,在main中被调用int GetWinData(CElement*lstdb,iht&winnum,int&m_itvl,int&m_wintime);
函数GetWinData得到所有的存在告警数据的时间窗,并将其存放在lstdb中返回,winnum是时间窗口的个数,m_itvl是滑动步长,m_wintime是时间窗的大小。
读取告警数据库的步骤:
①定义宿主变量
exec sql begin declare section;exec sql end declare section;
夹在两个语句中间
②连接数据库
//连接数据库
EXEC SQL database alarm;
EXEC SQL SET LOCK MODE TO WAIT;
③SQL语句读入字符串
sprintf(strsql,″SELECT int_id FROM alarm_dm WHERE alarm_node=’JNB1’and occur_time betweenextend(’2008-10-13 00:00:00’,year to second)+interval(%d)minute(9)to minute andextend(’2008-10-13 00:00:00’,year to second)+interval(%d)minute to minute+interval(%d)minute(9)to minute″,move_minute,wintime,move_minute);
④prepare语句
EXEC SQL PREPARE get_data FROM:strsql;
⑤定义游标
EXEC SQL DECLARE cur_get_data CURSOR FOR get_data;
⑥打开游标
EXEC SQL OPEN cur_get_data;
⑦读入数据
while(1)
{
EXEC SQL FETCH cur_get_data INTO:t_title;
}
⑧关闭游标释放游标资源
EXEC SQL CLOSE cur_get_data;
EXEC SQL FREE cur_get_data;
⑨关闭数据库
EXEC SQL close database;
2关联规则获取算法实现说明:
(1)文件说明
头文件 |
说明 |
Childnode.h |
声明Childnode类 |
fp.h |
声明全局变量和方法 |
FPnode.h |
声明FPnode类 |
FPtree.h |
声明FPtree类 |
FreItemset.h |
声明FreItemset类 |
FrePat.h |
声明FrePat类 |
HeadList.h |
声明HeadList类(*) |
Headnode.h |
声明Headnode类(*) |
ItemSet.h |
声明ItemSet类 |
(2)代码说明
-全局变量说明-
全局变量:
typedef int ItemType; //项类型
typedef int item; //项类型
(*)typedef class Headnode Hnodelnk; //项头节点指针类型
typedef vector<item>CElement; //为了匹配读取informix数据库的接口而定义的项集类型
typedef class ItemSet Trans; //事务类型
typedef class Childnode*Childlink; //指向频繁模式树孩子节点的指针
typedef class Headnode*Hnodelnk; //项头链表指针
typedef class FPnode *FPTreenode; //指向频繁模式树节点的指针
const int sup=3; //支持数
const int SIZE=940; //某些项集的最大长度
const int MAX_WIN_NUM=10000; //最大窗口数量
const int MONTH=3; //挖掘时间
const int DMTIME=MONTH*30*24*60; //挖掘时长
struct Result //挖掘结果
{
FreItemset *ResultSet;
Result*next;
};
struct ResultList //挖掘结果链表
{
Result*head;
Result*tail;
Result*current;
};
struct FrePatList //频繁项集链表
{
FrePat*head;
FrePat*current;
FrePat*tail;
};
-公共方法说明-
int str_tec(char*str); //相应用于对alarm_node需求
int GetAlarm_node(); //得到所有Alarm_node
void SortTran(Trans&t,FreItemset&set1);//对事务t按照一阶频繁项集的顺序剪枝并排序
void InsTranstoIset(CElement&itemset,FreItemset&FreItemset_1);
//将事务t1***一阶频繁项集
void InsTranstoTree(Trans&t,FPtree&tree); //将事务t1***到树中。
void FPTreeillu(FPTreenode&node); //用于将树展示给设计者
void All_tranGen(Trans&t,FPtree&FPTree);//对于事务t产生其全项集并***到FPTree当中
bool equal(Trans t1,Trans t2); //判断两个事务是否相同
bool equalfre(FreItemset set1,FreItemset set2); //判断两个结果项集是否相同
void ResultClear(ResultList&list); //清楚结果链表中重复的项集
void FrePatMining(FPTreenode node,ResultList&list); //将树中的频繁项集挖掘出来
void getdata_1set(FreItemset&fp_1,int_wintime,int_itvl,char*str);
//扫描数据库并产生一介频繁项集
void getdata_FP(FreItemset&fp_1,Trans&tran,FPtree&tree,int_wintime,int_itvl,char*str);
//扫描数据库并产生FP树
int GetWinData(CElement&itemset,int&move_time,const int m_wintime,const int m_itvl,char*
str); //扫描数据库的一条事务并返回当前事务
void ResultClear(ResultList&list,ResultList&list2); //清楚结果链表中重复的项集
void Resillu(ResultList&list,FrePatList&list2); //将结果项集按照正确的格式输出
bool HavOrNot(FreItemset set,ResultList&list); //判断结果集list当中是否包含项集set
bool HavOrNot_fp(FrePat fp,FrePatList&list);//判断频繁模式链表中是否包含了频繁模式fp
bool equalfp(FrePat fp1,FrePat fp2); //判断频繁模式fp1和fp2是否相同
-类说明-
类名:ItemSet
说明:产生项集的对象。
对象:用于生成的对象有事务、清理之后的事务
成员:
私有:
int lenth; //项集长度
ItemType item[100]; //项
bool isadd[100]; //是否加一的标志
公有:
ItemSet(); //构造函数
virtual~ItemSet(); //析构函数
void Insert(ItemType e); //***项e
bool Del(int i); //删除第i个位置上的元素并将项集前移一位
bool IsIn(ItemType e); //判断e是否在项集中
bool IsLarger(ItemType a,ItemType b); //判断a是否大于等于b
ItemType illu(int i); //返回i位置的项
void ChangeItem(int i,int j); //对调两个位置上面的项
int Size(); //返回项集的长度
void DelAll(); //删除项集中的所有元素
bool reisadd(int i); //返回isadd[i]
bool falseisadd(int i); //更改isadd[i]为false
--------------------------------
(*)类名:HeadNode
说明:项头列表中的每一个节点的对象
对象:用于生成项头列表的每一项
成员:
私有:
ItemType item; //项目
int count; //频繁度计数
FPnode*link; //指向树节点的指针表
int lnklenth; //连接表当前长度
Hnodelnk*next; //指向下一个节点的指针
公有:
Headnode(); //无参数构造函数
Headnode(ItemType e,int num); //构造函数
virtual~Headnode(); //析构函数
ItemType Item(); //返回当前节点的item值
Hnodelnk renext(); //返回当前节点的next指针
void chnext(Hnodelnk lnk); //更改当前节点的下一节点的指针
bool IsFull(); //判断连接表是否已满
bool addl ink(FPTreenode node); //在节点链接表尾加入一个新的链接
--------------------------------------
(*)类名:HeadList
说明:产生项头列表的对象
对象:用于生成项头列表
成员:
私有:
Headnode*first; //头指针
Headnode*curr; //指向当前节点的指针
Headnode*tail; //尾指针
int lenth; //链表长度
公有:
HeadList(); //构造函数
virtual~HeadList(); //析构函数
void InsNode(ItemType e,int num); //***一个节点
Headnode find(ItemType e); //查找项的位置并返回如果没有此项则返回空
bool linkTreenode(FPTreenode node,ItemType e);//在项e所在节点,***树节点链接
node如果***失败,返回false
------------------------------------
类名:FreItemset
说明:产生频繁项集
对象:用于频繁一项集和其他频繁项集
成员:
私有:
int lenth; //项集长度
ItemType item[100]; //项
int count[100]; //每一项的支持数
公有:
FreItemset(); //构造函数
virtual~FreItemset(); //析构函数
void Insert(ItemType e); //***项e
void Del(int i); //删除第i个位置上的元素和支持度并将项集前
移一位
int IsIn(ItemType e); //返回e在项集中的位置
bool IsLarger(ItemType a,ItemType b); //判断a是否大于等于b
ItemType illu(int i); //返回i位置的项
void ChangeItem(int i,int j); //对调两个位置上面的项
int Size(); //返回项集的长度
int recount(ItemType e); //返回项e的支持度
bool addcount(ItemType e); //项e的支持度增一
int chcount(ItemType e,int num); //change the count of item e to be num
void SortSet(); //将频繁项集按照支持度排序
void supcut(); //根据支持数剪枝
-------------------------------
类名:FPnode
说明:产生频繁模式树中节点的对象
对象:用于生成频繁模式树中节点
成员:
私有:
ItemType item; //该节点对应的项
int count; //包含从根结点到现节点的项集的事务数
int numPath; //在以此节点为根的子树中,叶子节点的个数,
用于在FP_Growth过程中,检查是否只有一条单一路径。
FPTreenode parent; //指向父节点的指针
Childlink children; //指向孩子节点的指针
FPTreenode hlink; //连接项头链表,指向相同项的下一个节点
的指针
Headnode*first; //头指针
Headnode*curr; //指向当前节点的指针
Headnode*tail; //尾指针
int lenth; //链表长度
公有:
FPnode(); //无参数构造函数
FPnode(ItemType e,FPTreenode&pare); //无项头指针的节点
FPnode(ItemType e,FPnode pare,HeadList hl);//构造函数
virtual~FPnode(); //析构函数
Childlink reChildren(); //返回children指针
ItemType reItem(); //返回当前节点的item
int reCount(); //返回当前节点的支持数
void AddCount(); //支持数加一
FPTreenode reParent(); //返回父节点
void chChildren(Childlink link); //改变孩子节点指针
--------------------------------
类名:FPtree
说明:产生频繁模式树的对象
对象:用于频繁模式树
成员:
私有:
FPnode*Troot; //根节点
公有:
FPtree(); //构造函数
virtual~FPtree(); //析构函数
FPTreenode reTroot(); //返回根节点
FPTreenode Insertnode(FPTreenode&nod,Childlink&child,FPTreenode&pare);
//加入一个新的节点e
FPTreenode reNode(ItemType e,FPTreenode&pare);//返回节点pare的孩子中e所在的节点
bool IsIn(ItemType e,FPTreenode&pare); //在此父节点下是否有e所在节点
void FPTreeDel(FPTreenode&node); //递归释放节点
------------------------------
类名:FrePat
说明:产生最终展示的频繁项集
对象:频繁项集结果
成员:
私有:
int lenth; //项集长度
ItemType item[10]; //项
int count; //支持度
FrePat*next; //指向下一个节点
共有:
FrePat(); //构造函数
virtual~FrePat(); //析构函数
bool Insert(ItemType it); //***项it
int ReCount(); //返回支持数
bool ChCount(int num); //将支持度改为num
void illuFrePat(); //在屏幕上输出当前频繁模式
int Size(); //返回当前频繁模式的长度
FrePat*ReNext(); //返回当前节点的下一结点
void ChNext(FrePat*fp); //将当前节点的next指针指向fp
ItemType ReItem(int i); //返回第i个位置上的元素
};
----------------------------------
类名:Childnode
说明:产生频繁模式树中孩子结点的指针节点
对象:用于频繁模式树
成员:
私有:
FPTreenode node; //孩子节点
Childlink next; //指向下一个孩子的节点
公有:
Childnode(FPTreenode&nod); //构造函数,参数为要加入的节点,和父节点
virtual~Childnode(); //析构函数
FPTreenode renode(); //返回当前树节点指针
Childlink renext(); //返回当前下一个孩子节点指针
void chnext(Childlink link); //改变下一个节点链接
-主要对象说明-
FreItemset fp1; //一阶频繁项集
Trans t; //事务对象(表示一条事务)
FPtree FPTree; //频繁模式树
---------------------------------------
关联规则数据结构,将生成的关联规则保存在链表中
typedef struct Associationrulenode*AssociationRulePtr;//关联规则链表指针
链表节点结构
typedef struct Associationrulenode{
float confidenceLevel; //该关联规则的置信度
Item left[5]; //关联规则的左端项集
int leftcount; //关联规则左端项集的个数
Item right[5]; //关联规则右端项集
int rightcount; //关联规则右端项集的个数
CElement left; //关联规则中左端项集
CElement right; //关联规则右端项集
AssociationRulePtr next; //指向下一个关联规则节点的指针
}AssociationRulenode;
调用GetPatternPosition(PatternsInMain,patternnum,patternPosition);得到每一阶的频繁项集在PatternsInMain里面所存在的位置,从一阶频繁项集开始到高阶排列,声明两个变量:
int associationRuleNum=0;//记录关联规则的数目
AssociationRulePtr associationRuleHeaderPtr=NULL;关联规则链表头指针
调用函数GetPatternPosition得到关联规则,将频繁项集,存储频繁项集个数的数组patternPosition,以及频繁项集总的数目传递给函数,得到关联规则。