標(biāo)題:
機(jī)器學(xué)習(xí) 花卉識(shí)別分類(lèi)C++例程
[打印本頁(yè)]
作者:
ffffaaaa
時(shí)間:
2020-6-1 19:21
標(biāo)題:
機(jī)器學(xué)習(xí) 花卉識(shí)別分類(lèi)C++例程
51hei.png
(9.06 KB, 下載次數(shù): 78)
下載附件
2020-6-2 03:32 上傳
機(jī)器學(xué)習(xí) 花卉識(shí)別分類(lèi)源程序如下:
#include <bits/stdc++.h>
using namespace std;
const int maxn=155;
vector<int> v[maxn];
map<string, int> mp;
struct Iris
{
double prop[4];
//0_Sepal_Length 1_Sepal_Width
//2_Petal_Length 3_Petal_Width
int sum;//原本分類(lèi);
int pv;//預(yù)測(cè)分類(lèi);
}all[maxn];
void print(Iris a)
{
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);
if(a.sum==a.pv) printf("\n");
else printf(" 預(yù)測(cè)錯(cuò)誤\n");
}
void Iris_Division(int t)
//分層隨機(jī)分成t份,用于t折交叉驗(yàn)證;
{
srand(time(NULL));//重置隨機(jī)數(shù)種子;
int book[maxn], cnt;
memset(book, 0, sizeof(book));
for(int i=1; i<=t; i++)
{
for(int j=1; j<=3; j++)
{
cnt=0;
while(cnt<150/(t*3))
{
int x=rand()%50+1+50*(j-1);
if(book[x]==1) continue;
book[x]=1;
v[i].push_back(x);
cnt++;
}
}
}
}
struct Tree_Node
{
int sum;//-1表示非葉節(jié)點(diǎn), 0、1、2表示該節(jié)點(diǎn)劃分種類(lèi)
int basic;//依據(jù)什么劃分
double div;//分界值
struct Tree_Node* left;//小于等于分界值的兒子節(jié)點(diǎn)
struct Tree_Node* right;//大于分界值的兒子節(jié)點(diǎn)
};
double log2(double x) { return log(x)/log((double)(2.0)); }
double Cal_Ent_D(int cnt[], int n, int sum)
{
double Ent_D=0;
for(int i=0; i<n; i++)
if(cnt[i]!=0)
{
double x;
x=cnt[i]*1.0/sum;
Ent_D=Ent_D-x*log2(x);
}
return Ent_D;
}
void Cal_Max_Gain(set<int>train, int* basic, double* div)
//計(jì)算最大的信息增益,選擇劃分依據(jù);
{
int cnt[3]={0};//3種分類(lèi)結(jié)果的數(shù)量;
int sum=train.size();
//cout<<sum<<endl;
for(auto x : train) cnt[all[x].sum]++;
double Ent_D=Cal_Ent_D(cnt, 3, sum);
vector<double> t;
double maxx=-1e5;
for(int i=0; i<4; i++)
{
t.clear();
for(auto x : train) t.push_back(all[x].prop[i]);
sort(t.begin(), t.end());//連續(xù)值排序,用于二分離散化
for(int j=0; j<(int)(t.size()-1); j++)
{
double y=(t[j]+t[j+1])/2.0;
double ans=Ent_D;
memset(cnt, 0, sizeof(cnt));
sum=0;
for(auto x : train) if(all[x].prop[i]<=y) cnt[all[x].sum]++, sum++;
if(sum!=0) ans=ans-(double)sum/(double)(t.size())*Cal_Ent_D(cnt, 3, sum);
memset(cnt, 0, sizeof(cnt));
sum=0;
for(auto x : train) if(all[x].prop[i]>y) cnt[all[x].sum]++, sum++;
if(sum!=0) ans=ans-(double)sum/(double)(t.size())*Cal_Ent_D(cnt, 3, sum);
if(ans>maxx)
{
maxx=ans;
*basic=i;
*div=y;
}
}
}
}
void Build_Tree(Tree_Node** T, set<int>train)//建立決策樹(shù)
{
*T=(Tree_Node*)malloc(sizeof(Tree_Node));
((*T)->sum)=-1; ((*T)->basic)=0; ((*T)->div)=0;
set<int> s;
for(auto x : train) s.insert(all[x].sum);
if(s.size()==1) { ((*T)->sum)=(*s.begin()); s.clear(); return; }
Cal_Max_Gain(train, &((*T)->basic), &((*T)->div));
set<int> left_train, right_train;
for(auto x : train)
{
if(all[x].prop[(*T)->basic] <= ((*T)->div)) left_train.insert(x);
else right_train.insert(x);
}
Build_Tree(&(*T)->left, left_train);
Build_Tree(&(*T)->right, right_train);
}
int Test_Data(Tree_Node* T, int x)
{
if((T->sum)!=-1) return T->sum;
if(all[x].prop[T->basic]<=(T->div))
return Test_Data(T->left, x);
else return Test_Data(T->right, x);
}
int main()
{
freopen("iris.txt","r",stdin);
int cnt=0;
for(int i=1; i<=150; i++)
{
string s;
scanf("%lf,%lf,%lf,%lf,",&all[i].prop[0],&all[i].prop[1],&all[i].prop[2],&all[i].prop[3]);
cin>>s;
if(!mp.count(s)) { mp[s]=cnt; cnt++;}
all[i].sum=mp[s];
}
int t=10;
Iris_Division(t);//分層隨機(jī)分成t份,用于t折交叉驗(yàn)證;
set<int> train, test;
double Ans=0.0;
for(int i=1; i<=10; i++)
{
train.clear(); test.clear();
for(int j=1; j<=t; j++)
{
if(j==i) for(int k=0; k<(int)v[j].size(); k++) test.insert(v[j][k]);
else for(int k=0; k<(int)v[j].size(); k++) train.insert(v[j][k]);
}
Tree_Node* tree;
Build_Tree(&tree, train);
printf("Sepal_Length Sepal_Width Petal_Length Petal_Width Actual_Value Predicted_Value\n");
int Cor_Num=0, All_Num=0;
for(auto x: test)
{
all[x].pv=Test_Data(tree, x);
if(all[x].sum==all[x].pv) Cor_Num++;
All_Num++;
print(all[x]);
}
printf("第%d次 預(yù)測(cè)正確率:%.3f\n\n", i, (double)Cor_Num/(double)All_Num);
Ans+=(double)Cor_Num/(double)All_Num;
}
printf("平均預(yù)測(cè)正確率:%.3f\n\n", Ans/(double)t);
return 0;
}
復(fù)制代碼
所有資料51hei提供下載:
機(jī)器學(xué)習(xí)程序(c++).7z
(251.07 KB, 下載次數(shù): 17)
2020-6-2 03:33 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
作者:
tieq1952
時(shí)間:
2020-6-7 08:18
謝謝分享!!!
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1