找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 2734|回復(fù): 1
打印 上一主題 下一主題
收起左側(cè)

機(jī)器學(xué)習(xí) 花卉識(shí)別分類(lèi)C++例程

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主


機(jī)器學(xué)習(xí) 花卉識(shí)別分類(lèi)源程序如下:
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int maxn=155;
  4. vector<int> v[maxn];
  5. map<string, int> mp;
  6. struct Iris
  7. {
  8.     double prop[4];
  9.     //0_Sepal_Length 1_Sepal_Width
  10.     //2_Petal_Length 3_Petal_Width
  11.     int sum;//原本分類(lèi);
  12.     int pv;//預(yù)測(cè)分類(lèi);
  13. }all[maxn];
  14. void print(Iris a)
  15. {
  16.     printf("%12.1f %11.1f %12.1f %11.1f %12d %15d ",a.prop[0],a.prop[1],a.prop[2],a.prop[3],a.sum,a.pv);
  17.     if(a.sum==a.pv) printf("\n");
  18.     else printf(" 預(yù)測(cè)錯(cuò)誤\n");
  19. }
  20. void Iris_Division(int t)
  21. //分層隨機(jī)分成t份,用于t折交叉驗(yàn)證;
  22. {
  23.     srand(time(NULL));//重置隨機(jī)數(shù)種子;
  24.     int book[maxn], cnt;
  25.     memset(book, 0, sizeof(book));
  26.     for(int i=1; i<=t; i++)
  27.     {
  28.         for(int j=1; j<=3; j++)
  29.         {
  30.             cnt=0;
  31.             while(cnt<150/(t*3))
  32.             {
  33.                 int x=rand()%50+1+50*(j-1);
  34.                 if(book[x]==1) continue;
  35.                 book[x]=1;
  36.                 v[i].push_back(x);
  37.                 cnt++;
  38.             }
  39.         }
  40.     }
  41. }
  42. struct Tree_Node
  43. {
  44.     int sum;//-1表示非葉節(jié)點(diǎn), 0、1、2表示該節(jié)點(diǎn)劃分種類(lèi)
  45.     int basic;//依據(jù)什么劃分
  46.     double div;//分界值
  47.     struct Tree_Node* left;//小于等于分界值的兒子節(jié)點(diǎn)
  48.     struct Tree_Node* right;//大于分界值的兒子節(jié)點(diǎn)
  49. };
  50. double log2(double x) { return log(x)/log((double)(2.0)); }
  51. double Cal_Ent_D(int cnt[], int n, int sum)
  52. {
  53.     double Ent_D=0;
  54.     for(int i=0; i<n; i++)
  55.         if(cnt[i]!=0)
  56.         {
  57.             double x;
  58.             x=cnt[i]*1.0/sum;
  59.             Ent_D=Ent_D-x*log2(x);
  60.         }
  61.     return Ent_D;
  62. }
  63. void Cal_Max_Gain(set<int>train, int* basic, double* div)
  64. //計(jì)算最大的信息增益,選擇劃分依據(jù);
  65. {
  66.     int cnt[3]={0};//3種分類(lèi)結(jié)果的數(shù)量;
  67.     int sum=train.size();
  68.     //cout<<sum<<endl;
  69.     for(auto x : train) cnt[all[x].sum]++;

  70.     double Ent_D=Cal_Ent_D(cnt, 3, sum);

  71.     vector<double> t;
  72.     double maxx=-1e5;
  73.     for(int i=0; i<4; i++)
  74.     {
  75.         t.clear();
  76.         for(auto x : train) t.push_back(all[x].prop[i]);
  77.         sort(t.begin(), t.end());//連續(xù)值排序,用于二分離散化
  78.         for(int j=0; j<(int)(t.size()-1); j++)
  79.         {
  80.             double y=(t[j]+t[j+1])/2.0;
  81.             double ans=Ent_D;
  82.             memset(cnt, 0, sizeof(cnt));
  83.             sum=0;
  84.             for(auto x : train) if(all[x].prop[i]<=y) cnt[all[x].sum]++, sum++;
  85.             if(sum!=0) ans=ans-(double)sum/(double)(t.size())*Cal_Ent_D(cnt, 3, sum);

  86.             memset(cnt, 0, sizeof(cnt));
  87.             sum=0;
  88.             for(auto x : train) if(all[x].prop[i]>y) cnt[all[x].sum]++, sum++;
  89.             if(sum!=0) ans=ans-(double)sum/(double)(t.size())*Cal_Ent_D(cnt, 3, sum);

  90.             if(ans>maxx)
  91.             {
  92.                 maxx=ans;
  93.                 *basic=i;
  94.                 *div=y;
  95.             }
  96.         }
  97.     }
  98. }
  99. void Build_Tree(Tree_Node** T, set<int>train)//建立決策樹(shù)
  100. {
  101.     *T=(Tree_Node*)malloc(sizeof(Tree_Node));
  102.     ((*T)->sum)=-1; ((*T)->basic)=0; ((*T)->div)=0;
  103.     set<int> s;
  104.     for(auto x : train) s.insert(all[x].sum);
  105.     if(s.size()==1) { ((*T)->sum)=(*s.begin()); s.clear(); return; }

  106.     Cal_Max_Gain(train, &((*T)->basic), &((*T)->div));

  107.     set<int> left_train, right_train;
  108.     for(auto x : train)
  109.     {
  110.         if(all[x].prop[(*T)->basic] <= ((*T)->div)) left_train.insert(x);
  111.         else right_train.insert(x);
  112.     }
  113.     Build_Tree(&(*T)->left, left_train);
  114.     Build_Tree(&(*T)->right, right_train);
  115. }

  116. int Test_Data(Tree_Node* T, int x)
  117. {
  118.     if((T->sum)!=-1) return T->sum;
  119.     if(all[x].prop[T->basic]<=(T->div))
  120.         return Test_Data(T->left, x);
  121.     else return Test_Data(T->right, x);
  122. }
  123. int main()
  124. {
  125.     freopen("iris.txt","r",stdin);
  126.     int cnt=0;
  127.     for(int i=1; i<=150; i++)
  128.     {
  129.         string s;
  130.         scanf("%lf,%lf,%lf,%lf,",&all[i].prop[0],&all[i].prop[1],&all[i].prop[2],&all[i].prop[3]);
  131.         cin>>s;
  132.         if(!mp.count(s)) { mp[s]=cnt; cnt++;}
  133.         all[i].sum=mp[s];
  134.     }
  135.     int t=10;
  136.     Iris_Division(t);//分層隨機(jī)分成t份,用于t折交叉驗(yàn)證;
  137.     set<int> train, test;
  138.     double Ans=0.0;
  139.     for(int i=1; i<=10; i++)
  140.     {
  141.         train.clear();  test.clear();
  142.         for(int j=1; j<=t; j++)
  143.         {
  144.             if(j==i) for(int k=0; k<(int)v[j].size(); k++) test.insert(v[j][k]);
  145.             else for(int k=0; k<(int)v[j].size(); k++) train.insert(v[j][k]);
  146.         }
  147.         Tree_Node* tree;
  148.         Build_Tree(&tree, train);
  149.         printf("Sepal_Length Sepal_Width Petal_Length Petal_Width Actual_Value Predicted_Value\n");
  150.         int Cor_Num=0, All_Num=0;
  151.         for(auto x: test)
  152.         {
  153.             all[x].pv=Test_Data(tree, x);
  154.             if(all[x].sum==all[x].pv) Cor_Num++;
  155.             All_Num++;
  156.             print(all[x]);
  157.         }
  158.         printf("第%d次 預(yù)測(cè)正確率:%.3f\n\n", i, (double)Cor_Num/(double)All_Num);
  159.         Ans+=(double)Cor_Num/(double)All_Num;
  160.     }
  161.     printf("平均預(yù)測(cè)正確率:%.3f\n\n", Ans/(double)t);
  162.     return 0;
  163. }
復(fù)制代碼

所有資料51hei提供下載:
機(jī)器學(xué)習(xí)程序(c++).7z (251.07 KB, 下載次數(shù): 17)


評(píng)分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:253767 發(fā)表于 2020-6-7 08:18 | 只看該作者
謝謝分享!!!
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表