数据挖掘—概念学习Candidate-Elimination算法的C++实现

本文介绍了一种概念学习算法——候选消除算法,并详细展示了其在C++中的实现过程及测试案例。该算法能够输出与训练样本一致的所有概念,适用于概念挖掘任务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Candidate-Elimination算法是数据挖掘中的一种概念学习算法,部分解决Find-S的不足,可以输出所有与训练样本一致的概念,同时利用概念间偏序关系来指导搜索,其伪代码描述如下

[cpp]  view plain  copy
  1. Initialize Gto the set of most-general hypotheses in H  
  2. Initialize Sto the set of most-specific hypotheses in H  
  3. For each training example, d, do:  
  4. If dis a positive example then:  
  5. Remove from Gany hypotheses that do not match d  
  6. For each hypothesis sin Sthat does not match d  
  7. Remove sfrom S  
  8. Add to S all minimal generalizations, h, of ssuch that:  
  9. 1) h matches d  
  10. 2) some member of Gis more general than h  
  11. Remove fromSany hthat is more general than another hypothesis in S  
  12. If dis a negative example then:  
  13. Remove from Sany hypotheses that match d  
  14. For each hypothesis gin Gthat matches d  
  15. Remove gfrom G  
  16. Add to G all minimal specializations, h, of gsuch that:  
  17. 1) hdoes not match d  
  18. 2) some member of Sis more specific than h  
  19. Remove fromG any hthat is more specific than another hypothesis in G  

花了几个小时的时间总算把这个算法用C++实现测试通过了,采用了STL中的二维Vector容器保存字符串,在调试部分浪费不少时间。主要是用VC++ 6.0查看STL容器中的变量值不太方便,比如Vector,需要在调式窗口里输入s._first,10 才可以看到全部的数据;也可以加输出的测试代码,但是比较麻烦。好了,废话不多说了,贴上代码,希望各位批评指正。

【概念挖掘需求】


基本的算法思想是,泛化边界初始化为全?,特化边界特化为全空集(@),

1、若遇到正实例,首先从G中删除不包含该实例的概念,然后对S删除与实例不相符的概念,同时做最小泛化,使其包含该实例

2、若遇到负实例,首先从S中删除包含了该实例的概念,然后对G删除包含了该实例的概念,同时做最小特化,注意最小特化集是与当前S一一枚举出可能的特化概念,删除那些符合该实例的概念

C++源码

[cpp]  view plain  copy
  1. #include <iostream>  
  2. #include <string>  
  3. #include <vector>  
  4. using namespace std;  
  5. #define MAXLEN 7//输入每行的数据个数  
  6.   
  7. //每行为标号 outlook Temperature Humidity Wind PlayTennis Swiming  
  8. //采用二维动态数组Vector保存处理  
  9. vector <vector <string> > state;//实例集  
  10. vector <vector <string> >  S;//特化边界  
  11. vector <vector <string> >  G;//泛化边界  
  12. vector <string> item(MAXLEN);//对应一行实例集  
  13. string yes("Yes");  
  14. string all("?");  
  15. string white("@");//@表示空集  
  16. string end("end");//输入结束  
  17.   
  18. //判定概念h是否包含实例d  
  19. bool checkInclude(vector <string> h, vector <string> d){  
  20.     bool res = true;  
  21.     for(int i = 1; i < MAXLEN-1; i++){  
  22.         if(!h[i].compare(all) || !h[i].compare(d[i])) continue;  
  23.         else if(!h[i].compare(white) || h[i].compare(d[i])) res = false;  
  24.         else {  
  25.             cerr<<"error in checkInclude"<<endl;  
  26.             res = false;  
  27.         }     
  28.     }  
  29.     return res;  
  30. }  
  31.   
  32. //对概念S[offset]做最小泛化,使得S[offset]包含d  
  33. void doMinGeneral(int offset, vector <string> d){  
  34.     for(int i = 1; i < MAXLEN-1; i++){  
  35.         if(!S[offset][i].compare(white)) {  
  36.             S[offset][i] = d[i];  
  37.         }  
  38.         else if(S[offset][i].compare(d[i])) S[offset][i] = all;  
  39.         else continue;//包括相等和h[i]为all的情况  
  40.     }  
  41. }  
  42.   
  43. //对概念G[offset]做最小特化,使得G[offset]包不含d,注意最小特化来自于和S的组合  
  44. void doMinSpecific(int offset, vector <string> d, vector <string> s){  
  45.     for(int i = 1; i < MAXLEN-1; i++){  
  46.         if(G[offset][i].compare(s[i]) && !G[offset][i].compare(all)){  
  47.             if(s[i].compare(d[i])){  
  48.                 //产生新的泛化边界,注意不唯一  
  49.                 vector<string> temp (G[offset]);//先拷贝一份G[offset]  
  50.                 temp[i] = s[i];  
  51.                 G.push_back(temp);  
  52.             }  
  53.         }  
  54.         if(G[offset][i].compare(s[i]) && G[offset][i].compare(all)){  
  55.             cerr<<"doMinSpecific: error in data"<<endl;//G[offset][i]不为?且其与s[i]不同的情况  
  56.         }  
  57.     }  
  58. }  
  59.   
  60. void input(){  
  61.     int i, j;  
  62.     string s;  
  63.     while(cin>>s,s.compare(end) != 0){//-1为输入结束  
  64.         item[0] = s;  
  65.         for( i = 1;i < MAXLEN; i++){  
  66.             cin>>item[i];  
  67.         }  
  68.         state.push_back(item);  
  69.     }  
  70.   
  71.     //初始化  
  72.     for( i = 0;i < MAXLEN; i++){  
  73.             item[i] = white;  
  74.     }  
  75.     S.push_back(item);  
  76.     for( i = 0;i < MAXLEN; i++){  
  77.             item[i] = all;  
  78.     }  
  79.     G.push_back(item);  
  80. }  
  81.   
  82. void output(){  
  83.     int i,j;  
  84.     cout<<"The specific boundary is:"<<endl;  
  85.     for(i = 0; i < S.size(); i++){  
  86.         for(j = 1;j < MAXLEN-1; j++){  
  87.             cout<<S[i][j]<<" ";  
  88.         }  
  89.         cout<<endl;  
  90.     }  
  91.     cout<<endl;  
  92.     cout<<"The general boundary is:"<<endl;  
  93.     for(i = 0; i < G.size(); i++){  
  94.         for(j = 1;j < MAXLEN-1; j++){  
  95.             cout<<G[i][j]<<" ";  
  96.         }  
  97.         cout<<endl;  
  98.     }  
  99.     cout<<endl;  
  100. }  
  101.   
  102. void solve(){  
  103.     int i,j;  
  104.     for( i = 0; i < state.size(); i++){  
  105.         if(!state[i][MAXLEN-1].compare(yes)){  
  106.             //正实例的情况,首先从G中删除不包含该实例的概念,  
  107.             //然后对S删除与实例不相符的概念,同时做最小泛化,使其包含该实例  
  108.             for(j = 0; j < G.size(); j++){  
  109.                 if(!checkInclude(G[j],state[i])) {  
  110.                     G.erase(G.begin() + j);  
  111.                 }  
  112.             }  
  113.             for(j = 0; j < S.size(); j++){  
  114.                 doMinGeneral(j,state[i]);  
  115.             }  
  116.         }  
  117.         else {//负实例的情况,首先从S中删除包含了该实例的概念,  
  118.               //然后对G做最小特化,与当前S一一枚举出可能的特化概念,删除那些符合该实例的概念  
  119.             for(j = 0; j < S.size(); j++){  
  120.                 if(checkInclude(S[j],state[i])){  
  121.                     S.erase(S.begin() + j);  
  122.                 }  
  123.             }  
  124.             int orginGSize = G.size();//先记下G原始大小  
  125.             for(j = 0; j < orginGSize; j++){  
  126.                 doMinSpecific(j,state[i],S[0]);  
  127.             }     
  128.             G.erase(G.begin(), G.begin() + (orginGSize));//删除G[0]到G[orginGSize-1],但是要注意括号内的参数不同  
  129.         }  
  130.     }  
  131. }  
  132.   
  133. int main(){  
  134.     input();  
  135.     solve();  
  136.     output();  
  137.     return 0;  
  138. }  

测试数据一

[plain]  view plain  copy
  1. 0 Sunny Warm High Strong Warm Yes  
  2. 1 Sunny Warm Normal Strong Warm No  
  3. 2 Rainy Cold High Strong Warm No  
  4. 3 Sunny Warm High Strong Cool Yes  
  5. end  


测试结果一

[plain]  view plain  copy
  1. The specific boundary is:  
  2. Sunny Warm High Strong ?  
  3.   
  4. The general boundary is:  
  5. Sunny ? High ? ?  
  6. ? Warm High ? ?  

测试数据二

[plain]  view plain  copy
  1. 0 Sunny Warm High Strong Warm Yes  
  2. 1 Sunny Warm Normal Strong Warm No  
  3. 2 Rainy Cold High Strong Warm No  
  4. 3 Sunny Warm High Strong Cool Yes  
  5. end  
测试结果二

[plain]  view plain  copy
  1. The specific boundary is:  
  2. Sunny Warm High Strong ?  
  3.   
  4. The general boundary is:  
  5. Sunny ? High ? ?  
  6. ? Warm High ? ?  

具体预测的方法是

1、如果给定的实例符合概念集合S,则一定去游泳

2、如果给定的实例不符合概念集合G,则一定不去游泳

3、如果给定的实例不符合概念集合S,但是符合概念集合G,则可能去游泳

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值