基于VGI签到类目关联规则挖掘
用c#语言写的一个数据挖掘的算法,数据是深圳和香港的2015新浪微博签到数据。 1.数据分析签到数据中能够体现用户行为特性的只有[Category]。这个字段下的数据都可以表示用户当前的一个行为。用户每一条签到数据代表了该用户当下的一个行为,所以用户所有的签到数据放一起,就可以形成该用户的一个签到轨迹,同时也代表了该用户的一个行为轨迹。不同的用户有不同的行为轨迹,这些大量的行为轨迹放一起,其实就是代表人们的一种生活轨迹,试想如果能对这种生活轨迹进一步分析,可挖掘出这些行为之间的关联性。 2.探索性数据分析探索性数据分析是对当前获得的杂乱无章的数据,在尽量缺少先验假定下进行处理,通过制图、制表等方式,探索数据结构和规律的一种分析方法。因此对于签到数据,可分别从签到位置、签到类目和签到时间三个角度进行分析。 2.1基于签到位置的热点图分析签到位置代表的用户的兴趣点,所有用户的签到位置做成图的形式可以看出签到密集的区域,也就是签到热点。采用ArcGIS MapsFor Office插件可制作出基于签到位置的热点图。 图2.2 签到位置热点图 从图中可看出签到位置主要集中于深圳市中心和香港维多利亚港附近。这两个地方是用户的活跃区域 2.2基于签到类目的兴趣点分析签到类目也就是[Category]字段主要表示用户签到位置的类别,可以代表用户当前的个体行为特征,所以这个字段是个体行为分析的关键,也是后面进行数据挖掘的重点。首先对该字段进行统计,得到下面234个类别。 表2.1 签到地点类别统计 图2.3 香港签到类目兴趣分析 注:统计图中剔除了小于1%的地点类别 从图中可以看出香港签到地点类别主要集中于:出商场、楼宇、飞机场、住宅区;深圳签到地点类别主要集中在:住宅区、飞机场、商场、楼宇。 2.3从签到时间的角度分析签到时间代表了用户活跃的时间点,同样利用SPSS Statistics工具制作用户24小时签到次数统计条形图 图2.6深圳 从图中可以看出香港签到高峰期(峰值15时)集中午后,签到高峰过后,香港地区用户签到数量有明显的回落趋势;深圳签到高峰集中在深夜(23时),午后至深夜用户签到数量呈现逐渐上升趋势。 3基于关联规则的签到类目关联分析每个用户有不同的签到数据,这些数据构成了该用户的签到轨迹。所以获取各用户的签到轨迹主要是把用户的所有签到数据的Category合并到一起,并且剔除重复的签到类目,即可得到该用户的签到轨迹 Apriori算法是数据挖掘中最经典的关联规则算法,其核心思想是通过候选集生成和情节的向下封闭检测两个阶段来挖掘频繁项集。通过程序实现Apriori算法可以通过输入初始事务集来计算关联规则,其中可以通过设置最小支持度和最小置信度来控制输出结果,通过“试错法”来获取这两个参数的值。还可以通过设置每个事务项最小签到次数来控制初始事务集,从而剔除一些关联规则较弱的签到数据。 支持度(support)和置信度(confidence)是关联规则中的两个指标,代表规则的有用性和确定性。比如对于规则“住宅区->海鲜酒楼”,Support=0.32表示这两个同时出现的概率是32%,Confidence=0.36表示在住宅区签到的条件下,在海鲜酒楼签到的概率为36%。 4.Apriori代码C#版本using System; using System.Collections; using System.Collections.Generic; using System.Data; using System.IO; using System.Linq; using System.Text; using System.Text.RegularExpressions; namespace ProjectDemo { class Apriori { /// <summary> /// Apiori算法过程 /// </summary> public ArrayList D = null;//事务项目集 private double minSup;//最小支持度 private double minConf;//最小置信度 private ArrayList F = new ArrayList();//频繁集 private Dictionary<string,int> Dic = new Dictionary<string,int>(); private ArrayList R = new ArrayList(); private string connStr; private clusterAnalysis ca = null; public DataTable rDataTable = new DataTable(); public Apriori(double sup,double conf,string connstr) { minSup = sup; minConf = conf; connStr = connstr; ca=new clusterAnalysis(connstr); rDataTable.Columns.Add("Rule",typeof(string)); rDataTable.Columns.Add("Support",typeof(string)); rDataTable.Columns.Add("Confidence",typeof(string)); } /// <summary> /// 生成1-频繁集 /// </summary> private void generateOneFrequentSet() { int i,j; ArrayList frequentList = new ArrayList(); var r = new Regex(","); for (i = 0; i < D.Count; ++i) { string[] v = r.Split(D[i].ToString()); for (j = 0; j < v.Length; ++j) { if (Dic.ContainsKey(v[j])) Dic[v[j]]++; else { Dic.Add(v[j],1); } } } foreach (var dic in Dic) { if (dic.Value >= minSup * D.Count) frequentList.Add(dic.Key); } F.Add(D); if (frequentList.Count != 0) F.Add(frequentList); } /// <summary> /// 判断s1、s2是否只有最后一项不同 /// </summary> /// <param name="s1"></param> /// <param name="s2"></param> /// <returns></returns> private bool judgeItem(string[] s1,string[] s2) { int i = 0,j = 0; while (i < s1.Length - 1 && j < s2.Length - 1) { if (s1[i] != s2[j]) return false; i++; j++; } return true; } /// <summary> /// 判断 /// </summary> /// <param name="v"></param> /// <param name="f"></param> /// <returns></returns> private bool judgeSubset(ArrayList v,ArrayList f) { bool flag = true; for (int i = 0; i < v.Count; ++i) { string str = null; for (int j = 0; j < v.Count; ++j) { if (j != i) str += v[j].ToString() + ","; } str = str.Substring(0,str.Length - 1); foreach (var list in f) { if (str.Equals(list.ToString())) flag = false; } } return flag; } /// <summary> /// 计算支持数 /// </summary> /// <param name="v"></param> /// <returns></returns> private int calculateSupportCount(ArrayList v) { int count = 0; var r = new Regex(","); for (int i = 0; i < D.Count; ++i) { string[] t = r.Split(D[i].ToString()); int j = 0; for (; j < v.Count; ++j) { bool find = false; foreach (var s in t) { if (v[j].ToString() == s) find = true; } if (!find) break; } if (j == v.Count) count++; } return count; } /// <summary> /// 判断是否满足支持度 /// </summary> /// <param name="v"></param> /// <returns></returns> private bool judgeSupport(ArrayList v) { int count = calculateSupportCount(v); if (count >= minSup * D.Count) return true; return false; } /// <summary> /// 生成k-频繁集 /// </summary> private void generateKFrequenceSet() { int k; var r = new Regex(","); for (k = 2; k <= Dic.Count; ++k) { if (F.Count < k) break; else { int i,j; ArrayList c = new ArrayList(); ArrayList f = (ArrayList)F[k - 1]; for (i = 0; i < f.Count - 1; i++) { string[] v1 = r.Split(f[i].ToString()); for (j = i + 1; j < f.Count; j++) { string[] v2 = r.Split(f[j].ToString()); if (judgeItem(v1,v2)) { ArrayList tempArrayList = new ArrayList(); foreach (var s in v1) { tempArrayList.Add(s); } tempArrayList.Add(v2[v2.Length - 1]); tempArrayList.Sort(); if (judgeSubset(tempArrayList,F) && judgeSupport(tempArrayList)) { string tempStr = null; int p; for (p = 0; p < tempArrayList.Count - 1; ++p) tempStr += tempArrayList[p].ToString() + ","; tempStr += tempArrayList[p].ToString(); c.Add(tempStr); } } } } if (c.Count != 0) F.Add(c); } } } /// <summary> /// 剪枝 /// </summary> /// <param name="v1"></param> /// <param name="v2"></param> /// <returns></returns> private ArrayList removeItemFromSet(string[] v1,string[] v2) { ArrayList result = new ArrayList (v1) ; for (int i = 0; i < v2.Length; ++i) { bool find = false; foreach (var s in v1) { if (v2[i].ToString() == s) find = true; } if (find) result.Remove(v2[i]); } return result; } private string getstr(ArrayList v1,ArrayList v2) { string rstr = null; for (int i = 0; i < v1.Count; ++i) { string strv1=ca.getCategoryName(Convert.ToInt32(v1[i].ToString())); rstr += strv1 + ","; } rstr = rstr.Substring(0,rstr.Length - 1); rstr += "->"; for (int i = 0; i < v2.Count; ++i) { string strv2=ca.getCategoryName(Convert.ToInt32(v2[i].ToString())); rstr += strv2 + ",rstr.Length - 1); return rstr; } /// <summary> /// 关联规则生成 /// </summary> /// <param name="fs"></param> private void ap_generateRules(string fs) { ArrayList h = new ArrayList(); ArrayList H = new ArrayList(); var r = new Regex(","); string[] v = r.Split(fs); int fcount = calculateSupportCount(new ArrayList(v)); for (int i = 0; i < v.Length; ++i) { ArrayList tempArrayList = new ArrayList(); for (int j = 0; j < v.Length; ++j) if (j != i) tempArrayList.Add(v[j]); int acount = calculateSupportCount(tempArrayList); if (fcount >= (acount * minConf)) { DataRow dr = rDataTable.NewRow(); h.Add(v[i]); string tempstr = null; for (int j = 0; j < v.Length; ++j) { if (j != i) { string strv=ca.getCategoryName(Convert.ToInt32(v[j].ToString())); tempstr += strv + ","; } } tempstr = tempstr.Substring(0,tempstr.Length - 1); tempstr += "->" + ca.getCategoryName(Convert.ToInt32(v[i].ToString())); double sup = fcount*1.0f / D.Count; double conf = fcount*1.0f / acount; object[] rules={tempstr,sup.ToString("0.00"),conf.ToString("0.00")}; dr.ItemArray=rules; rDataTable.Rows.Add(dr); R.Add(tempstr); } } H.Add(new ArrayList(v)); if (h.Count != 0) H.Add(h); for (int k = 2; k < v.Length; ++k) { if (H.Count < k) break; h = (ArrayList)H[k - 1]; ArrayList addH = new ArrayList(); for (int i = 0; i < h.Count - 1; ++i) { string[] v1 = r.Split(h[i].ToString()); for (int j = i + 1; j < h.Count; ++j) { string[] v2 = r.Split(h[j].ToString()); if (judgeItem(v1,v2)) { ArrayList tempArrayList = new ArrayList(); foreach (var s in v1) { tempArrayList.Add(s); } tempArrayList.Add(v2[v2.Length - 1]); tempArrayList.Sort(); ArrayList filterV = removeItemFromSet(v1,v2); int acount = calculateSupportCount(filterV); if (fcount >= acount * minConf) { DataRow dr = rDataTable.NewRow(); string str = getstr(filterV,tempArrayList); string hstr = null; for (int s = 0; s < tempArrayList.Count; ++s) hstr += tempArrayList[s].ToString() + ","; hstr = hstr.Substring(0,hstr.Length - 1); addH.Add(hstr); double sup = fcount*1.0f/ D.Count; double conf = fcount*1.0f / acount; object[] rules = { str,conf.ToString("0.00") }; dr.ItemArray=rules; rDataTable.Rows.Add(dr); R.Add(str); } } } } if (addH.Count != 0) H.Add(addH); } } private void generateRules() { for (int k = 2; k < F.Count; ++k) { ArrayList f = (ArrayList)F[k]; for (int i = 0; i < f.Count; ++i) { ap_generateRules((string)f[i]); } } } /// <summary> /// 将规则输出到文件 /// </summary> /// <param name="fileName"></param> public void outputRules(String fileName) { StreamWriter sw = null; if (!File.Exists(fileName)) { //文件夹不存在则创建该文件夹 FileStream fs1 = new FileStream(fileName,FileMode.Create,FileAccess.Write);//创 sw = new StreamWriter(fs1); } else { sw = new StreamWriter(fileName); } for (int k = 1; k < F.Count; ++k) { sw.WriteLine("{0}-频繁项目集",k); ArrayList f = (ArrayList)F[k]; foreach (var fs in f) { sw.WriteLine("{0}n",fs); } } sw.WriteLine("关联规则:n"); foreach (DataRow dr in rDataTable.Rows) { sw.WriteLine(dr["Rule"].ToString()+" | "+dr["Support"]+" | "+dr["Confidence"]); } sw.Close(); } public void doApriori() { generateOneFrequentSet(); generateKFrequenceSet(); generateRules(); } } } (编辑:长春站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |