实验二kNN算法之1NN分类
2016-09-26 21:36
447 查看
k-NN处理分类问题,即分类:多数投票原则,先将数据集处理成OneHot矩阵,计算测试文本与每一个训练文本的距离,如果k = 1,则找到最小的距离,则测试文本的分类对应于该训练文本的分类。在用C++实现时,通过好多次的debug,并且将最后生成的OneHot矩阵的每一行都输出到文本中去查看,再在OneHot矩阵每行测试文本尾中输出得到的类比结果,距离,分类。这里使用了欧式距离。
训练文本和测试文本形如:
documentId emotion words
1 5 sad mortar assault leav at least dead
2 4 joy goal delight for sheva
3 4 joy nigeria hostag fear dead is freed
4 3 fear bomber kill shopper
5 6 surprise veget not fruit slow brain declin
6 4 joy pm havana deal a good experi
7 4 joy kate is marri doherti
8 6 surprise nasa revisit life on mar question
9 4 joy happi birthdai ipod
10 4 joy alonso would be happi to retir with three titl
11 4 joy madonna s new tot happi at home in london
12 5 sad nicol kidman ask dad to help stop husband s drink
13 4 joy unit find good connect in win
14 4 joy runwai make good without make nice
15 5 sad we were arrog and stupid over iraq sai us diplomat
16 5 sad bad reason to be good
有246个测试样本,为了方便我在我的源代码中直接使用246这个数字,不过也可以通过读取该文件数行数时得到这个结果,C++实现代码如下:
训练文本和测试文本形如:
documentId emotion words
1 5 sad mortar assault leav at least dead
2 4 joy goal delight for sheva
3 4 joy nigeria hostag fear dead is freed
4 3 fear bomber kill shopper
5 6 surprise veget not fruit slow brain declin
6 4 joy pm havana deal a good experi
7 4 joy kate is marri doherti
8 6 surprise nasa revisit life on mar question
9 4 joy happi birthdai ipod
10 4 joy alonso would be happi to retir with three titl
11 4 joy madonna s new tot happi at home in london
12 5 sad nicol kidman ask dad to help stop husband s drink
13 4 joy unit find good connect in win
14 4 joy runwai make good without make nice
15 5 sad we were arrog and stupid over iraq sai us diplomat
16 5 sad bad reason to be good
有246个测试样本,为了方便我在我的源代码中直接使用246这个数字,不过也可以通过读取该文件数行数时得到这个结果,C++实现代码如下:
#include<iostream> #include<fstream> #include<map> #include<vector> #include<sstream> #include<cmath> #include<algorithm> using namespace std; struct Three_Var { int i,j; bool operator<(Three_Var& t) {return i<t.i||(i==t.i&&j<t.j);} bool operator>(Three_Var& t) {return i>t.i||(i==t.i&&j>t.j);} bool operator==(Three_Var& t) {return i==t.i&&j==t.j;} }; bool Sort( Three_Var d1,Three_Var d2)//容器的比较函数 { return d1 < d2;//降序排列 } vector< vector<int> > NumsPerLines; int main() { int index=0;//依次出现的(去重)词汇的对应下标 int Lines=0;//出现的行数 int ThreeVarNums=0;//三元组的个数 ifstream Input; Input.open("train.txt");//读取文件 string line; //一个临时变量而已 map<string, int> FirstIndex;//string是对应的词汇,int是它(无视重复下)第一次出现的在该map中的下标 map<int,int> repeatTimes; vector<int> NumsOfLines;//每行的词汇个数 (重复不算1个) vector<Three_Var> smat; vector<int> Emo; bool first = true;//因为训练文本第一行没用; while(getline(Input,line)) { if(first) { first = false; continue; } stringstream ss; int temp,emotion; //几经周折注意到一个事实:用写字板或者dev_cpp打开时可以清楚地看见是一行一句话的,所以用stringstream //整行读入的特性会方便很多 ss.clear(); ss.str(line); ss>>temp; ss>>emotion; string dict; string EMO; ss>>EMO; Emo.push_back(emotion); //存储好train.txt每一行的情绪啊! map<string,int>::iterator it1; map<int,int>::iterator it2; repeatTimes.clear(); while(ss>>dict) //读入每行的数据集内容的词汇 { it1=FirstIndex.find(dict); //first元素的map查找函数 if(it1==FirstIndex.end())//迭代器到了end(),说明这个词还没出现过 { FirstIndex.insert(pair<string,int>(dict,index)); index++; //维护map中的下标 } it2=repeatTimes.find(FirstIndex[dict]);//计算该词汇在数据集中重复出现的次数 if(it2==repeatTimes.end())//这个下标第一次出现的话,放进这个repaeatTimes<int,int>中 repeatTimes.insert(pair<int,int>(FirstIndex[dict],1)); //第一个整数记录它在map中的下标,第二个整数记录它重复的次数 else it2->second++;//否则,维护好这个RepeatTimes即可。 temp++;//这行的词汇个数(重复不算1个) } //读取完这行词汇了 vector <int> Temp_Vec; for(it2=repeatTimes.begin();it2!=repeatTimes.end();it2++) //为了在vector中有序,借用这个map { Three_Var item{Lines,it2->first};//利用机构体记录这个单词出现的行数,下标,重复次数 smat.push_back(item); ThreeVarNums++;//结构体vector中放入的个数 Temp_Vec.push_back(it2->first);//这个结构存储每一行拥有的字符串的下标; } NumsPerLines.push_back(Temp_Vec); Lines++; //第几行计数 NumsOfLines.push_back(temp);//记录好每行的词汇个数 if(Lines == 246){ first = true; Input.close(); Input.open("test.txt"); } } cout<<Lines<<" "<<index<<endl; cout<<"有二元组个数"<<ThreeVarNums<<endl; Input.close(); cout<<"Input operation has done!"<<endl; //读取完整个文档 //接下来进行处理数据 sort(smat.begin(),smat.end(),Sort); ofstream OneHot,SMATRIX1; OneHot.open("OneHot.txt"); SMATRIX1.open("smatrix1.txt"); //三元组矩阵 SMATRIX1<<Lines<<endl<<index<<endl<<ThreeVarNums<<endl; int pos=0; int RightNums = 0; for(int i = 0;i<Lines;i++) //行数 { /*————————每一行的处理————————*/ for(int j = 0;j < index; j++) //字符串下标 { if(smat[pos].i==i && smat[pos].j==j) //匹配到一个字符串出现 { OneHot<<1<<" "; //OneHot矩阵为1 SMATRIX1<<i<<" "<<j<<" "<<1<<endl; //输出到三元组 pos++;//找下一个字符串了 } else { OneHot<<0<<" "; //不出现,这3个矩阵都是0,三元组则例外 } /*----————————--处理完一行了----——---*/ } if(i >= 246){//test.txt来分类咯; int MinLine = 0, MinDis = 999999; for(int r = 0; r < 246; r++){ //与训练文本的每一行求欧式距离 if(NumsPerLines[r].size() > 3) { int dis = 0, c = 0 , k = 0 , equals = 0; for(; c < NumsPerLines[i].size() ; c++){ //当前行的字符串 for(; k < NumsPerLines[r].size(); k++){ if(NumsPerLines[i][c] < NumsPerLines[r][k]){ break; } else if(NumsPerLines[i][c] == NumsPerLines[r][k]){ equals++; } } } dis = NumsPerLines[i].size() + NumsPerLines[r].size() - equals * 2; if(dis < MinDis){ MinDis = dis; MinLine = r; //cout<<"smaller, dis = "<<dis<<endl; } } } OneHot<<"min line = "<<MinLine<<"; MinDis = "<<MinDis<<"; emotion = "<<Emo[MinLine]<<"; "; if(Emo[MinLine] == Emo[i]) RightNums++; } OneHot<<endl; //每一句新闻后都换行咯 } ofstream Info; Info.open("EveryLine.txt"); for(int i = 0 ; i < Lines; i++) { Info<<i<<": "; for(int j = 0 ; j < NumsPerLines[i].size(); j++) { Info<<NumsPerLines[i][j]<<" "; } Info<<endl; } cout<<"File operation has done!"<<endl; cout<<"The right rate is "<<(double)(RightNums)/1000<<endl; /*---------------完成操作,关闭文件输出流 ---------------*/ OneHot.close(); SMATRIX1.close(); Info.close(); return 0; }
相关文章推荐
- 使用KNN算法的分类实验源代码
- KNN分类算法原理与Python+sklearn实现根据身高和体重对体型分类
- KNN最邻近规则分类算法实践实现【Python实现】
- Python机器学习库sklearn几种分类算法建模可视化(实验)
- 【JAVA实现】K-近邻(KNN)分类算法
- 机器学习与深度学习(二) k最邻近分类算法 (K-Nearest Neighbor) KNN
- 用python实现kNN分类算法
- 【C++】基于特征向量的KNN分类算法
- K-近邻分类算法KNN
- 机器学习实践-Ch02 kNN分类算法
- 用scikit-learn估计值分类——近邻算法(KNN)
- 在opencv3中实现机器学习算法之:利用最近邻算法(knn)实现手写数字分类
- 在OpenCV3中实现机器学习算法之:利用最近邻算法(knn)实现手写数字分类
- 数据挖掘回顾一:分类算法之 kNN 算法
- KNN & NaiveBayes 分类算法
- OpenCV——KNN分类算法 <摘>
- 斯坦福CS231n项目实战(一):k最近邻(kNN)分类算法
- 机器学习算法与Python实践(5) - 最邻近分类算法(KNN)
- 监督算法大比拼之BP、SVM、adaboost非线性多分类实验
- 用Python开始机器学习(4:KNN分类算法)