简易kmeans-c++版本
typedef double dtype;
主要接口:
void Kmeans(const vector<vector<dtype> > &d,int k,string distype,vector<vector<int> > &kset,map<int,int> &category,vector<vector<dtype> > &kcenter)
参数:
vector<vector<dtype> > &d: 数据矩阵mxn
int k:聚类类别数目
string distype:距离类别,"sqeuclidean"表示欧式距离,"cosine"表示余弦距离,"hamming"表示海明距
vector<vector<int> > &kset:初始化K个中心
map<int,int> &category:返回的类别号
vector<vector<dtype> > &kcenter:返回的类别中心
double SSE(const vector<vector<dtype> > &matrix,const vector<vector<dtype> > &kcenter,map<int,int> &category,string distype,map<int,double> &EverySSE)
返回总的误差平方和,map<int,double> &EverySSE返回每个类的误差平方和
#include<iostream>
#include<vector>
#include<map>
#include<algorithm>
#include<cmath>
#include<fstream>
#include<string>
#include<assert.h>
#include<stdlib.h>
#include<time.h>
int const N = 1000;
int const eps = 1e-3;
using namespace std;
typedef double dtype;
typedef vector<int>::size_type vt;
double disfun(const vector<dtype> &a,const vector<dtype> &b,string distype)
{
double dis_sum=0;
if(distype=="sqeuclidean")
{
for(vt i=0;i<a.size();++i)
dis_sum+=pow(a[i]-b[i],2);
}
if(distype=="cosine")
{
double len_a=0,len_b=0,in_product=0;
for(vt i=0;i<a.size();++i)
{
len_a+=pow(a[i],2);
len_b+=pow(b[i],2);
in_product+=a[i]*b[i];
}
dis_sum = 1-in_product*1.0/(sqrt(len_a)*sqrt(len_b));
}
if(distype=="hamming")
{
int count=0;
for(vt i=0;i<a.size();++i)
{
if(a[i]!=b[i])count++;
}
dis_sum = count*1.0/a.size();
}
return dis_sum;
}
vector<int> random_chooseK(const int n,int k)
{
map<int,int> mvis;
vector<int> vec;
int i=0;
cout<<"n:"<<n<<"k:"<<k<<endl;
cout<<"random choose K ok"<<endl;
srand((unsigned)time(NULL));
while(i<k)
{
int tmp=rand()%(n);
if(!mvis.count(tmp)){
mvis[tmp]=1;
vec.push_back(tmp);
i++;
}
}
for(int &i:vec)cout<<i<<"->";
cout<<"random choose K over"<<endl;
return vec;
}
bool nochange(const vector<vector<dtype> > &kcenter,const vector<vector<dtype> > &prekcenter)
{
for(int i=0;i<kcenter.size();++i)
{
string st("sqeuclidean");
if(disfun(kcenter[i],prekcenter[i],st)>eps)return false;
}
return true;
}
vector<dtype> sum_vector(const vector<dtype> &a,const vector<dtype> &b)
{
vector<dtype> avec;
assert(a.size()==b.size());
for(int i=0;i<a.size();++i)
{
avec.push_back(a[i]+b[i]);
}
return avec;
}
void setZero(vector<dtype> &vec)
{
for(int i=0;i<vec.size();++i)
{
vec[i]=0;
}
}
void AlterKcenter(const vector<vector<dtype> > &d,vector<vector<dtype> > &kcenter,const vector<vector<int> > &kset,string distype)
{
for(int i=0;i<kcenter.size();++i)
{
setZero(kcenter[i]);
cout<<i<<":"<<kset[i].size()<<endl;
for(int j=0;j<kset[i].size();++j)
{
kcenter[i] = sum_vector(d[kset[i][j]],kcenter[i]);
}
for(int p=0;p<kcenter[i].size();++p)
{
if(distype=="hamming")
kcenter[i][p]=int(kcenter[i][p]*1.0/kset[i].size()+0.5);
else kcenter[i][p]=kcenter[i][p]*1.0/kset[i].size();
}
}
}
void Kmeans(const vector<vector<dtype> > &d,int k,string distype,vector<vector<int> > &kset,map<int,int> &category,vector<vector<dtype> > &kcenter)
{
vector<int> kgram=random_chooseK(d.size(),k);
vector<vector<dtype> > prekcenter;
//vector<vector<int> > kset;
for(int i=0;i<k;++i){
vector<int> vitmp;
kset.push_back(vitmp);
}
cout<<"kset"<<endl;
for(vt i=0;i<kgram.size();++i)kcenter.push_back(d[kgram[i]]);
cout<<"kset over"<<endl;
bool flag =false;
int count=0;
while(!flag)
{
for(int x=0;x<k;++x)kset[x].clear();
for(int j=0;j<d.size();++j)
{
double min_dis= 1e308;
int index = -1;
for(int m =0;m <k;++m)
{
double dis=disfun(d[j],kcenter[m],distype);
if(dis<min_dis)
{
min_dis=dis;
index = m;
}
}
kset[index].push_back(j);
category[j]=index;
}
prekcenter = kcenter;
count++;
cout<<"alterkcenter begin"<<endl;
AlterKcenter(d,kcenter,kset,distype);
cout<<"alterkcenter finished"<<endl;
flag = nochange(kcenter,prekcenter);
cout<<"µÚ"<<count<<"´Îµü´ú"<<endl;
}
}
void printmatrix(const vector<vector<dtype> > &matrix)
{
for(int i=0;i<matrix.size();++i)
{
for(int j=0;j<matrix[i].size();++j)
cout<<matrix[i][j]<<" ";
cout<<endl;
}
}
double SSE(const vector<vector<dtype> > &matrix,const vector<vector<dtype> > &kcenter,map<int,int> &category,string distype,map<int,double> &EverySSE)
{
double TotalSSE=0;
//map<int,double> EverySSE;
for(int i=0;i<matrix.size();++i)
{
double tmpsse=0;
tmpsse=disfun(matrix[i],kcenter[category[i]],distype);
if(EverySSE.count(category[i]))
EverySSE[category[i]]+=tmpsse;
else EverySSE[category[i]]=tmpsse;
TotalSSE+=tmpsse;
}
return TotalSSE;
}
void saveresult(const vector<vector<dtype> > &matrix,vector<vector<int> > &kset)
{
fstream f("result.txt",ios::out);
map<int,int> category;
cout<<"kset size:"<<kset.size()<<endl;
f<<"total:"<<endl;
for(int i=0;i<kset.size();++i){
f<<"µÚ"<<i<<"Àà:"<<kset[i].size()<<endl;
}
for(int i=0;i<kset.size();++i)
{
cout<<kset[i].size()<<endl;
for(int j=0;j<kset[i].size();++j)
category[kset[i][j]]=i;
}
for(int i=0;i<matrix.size();++i)
{
f<<i<<": "<<category[i]<<endl;
}
for(int i=0;i<matrix.size();++i)
{
f<<"----------------------------------"<<category[i]<<"---------------------------------"<<endl;
for(int j=0;j<matrix[i].size();++j)
f<<matrix[i][j]<<" ";
f<<endl;
}
f.close();
}
int main()
{
vector<vector<dtype> > matrix;
int all=0;
srand((unsigned)time(0));
while(all<600)
{
vector<dtype> row;
for(int n=1;n<=600;++n)
{
int tmp=rand()%(2);
if(rand()/double(RAND_MAX)>0.6)tmp=0;
//cout<<tmp<<endl;
row.push_back(tmp);
}
matrix.push_back(row);
all++;
}
//printmatrix(matrix);
vector<vector<int> > kset;
vector<vector<dtype> > kcenter;
map<int,int> category;
string st("hamming");
Kmeans(matrix,30,st,kset,category,kcenter);
saveresult(matrix,kset);
map<int,double> EverySSE;
cout<<SSE(matrix,kcenter,category,st,EverySSE)<<endl;
map<int,double>:: const_iterator it=EverySSE.begin();
while(it!=EverySSE.end()){
cout<<it->first<<":"<<it->second<<endl;
it++;
}
system("pause");
return 0;
}
简易kmeans-c++版本的更多相关文章
- 简易 (I/O)版本通讯录
#include <stdio.h> #include<assert.h> //#include<malloc.h> #include<string.h> ...
- 简易付XP版本无法获取server.xml配置文件处理方案
博客地址:https://blog.csdn.net/zdw_wym/article/details/40892535 把它添加到C:/WINDOWS/Microsoft.NET/Framework/ ...
- WebSocket实现简易的FTP客户端
WebScoket的简单应用,实现一个简易的FTP,即文件上传下载,可以查看上传人,下载次数,打开多个Web可以多人上传. 说在前面的话 文件传输协议(File Transfer Protocol,F ...
- C#代码
http://www.cnblogs.com/zjfree/category/269738.html 超简易静态Web服务器 C# 生成不重复随机字符串 (1秒内生成1000000个) C# 读写IN ...
- Oracle 数据库 Database Express Edition 11g Release 2 (11.2) 错误解决集锦(安装方面)
前言:第一次接触数据库,想下载个oracle试玩下(虽然听说一般大企业才用),到 官网下载 了个简易版 XE 版本,安装时要注意记住自己输入的数据库密码(口令) 还有安装路径不能含有空格(Do no ...
- 从零开始学C++之STL(七):剩下5种算法代码分析与使用示例(remove 、rotate 、sort、lower_bound、accumulate)
一.移除性算法 (remove) C++ Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 ...
- ES6数组扩展
前面的话 数组是一种基础的JS对象,随着时间推进,JS中的其他部分一直在演进,而直到ES5标准才为数组对象引入一些新方法来简化使用.ES6标准继续改进数组,添加了很多新功能.本文将详细介绍ES6数组扩 ...
- 利用ADO让普通人用excel读取oracle数据库表的通用办法
Ref:http://blog.csdn.net/iamlaosong/article/details/8465177 Excel通过ADO方式连接到Oracle并操作Oracle给那些编程能力不强的 ...
- ES6 数组的扩展
1. Array.from() Array.from()将类数组(array-like)对象与可遍历的对象转化为数组并返回. 下面是一个类数组 let arr = { '0':'a', '1':'b' ...
- 使用git进行版本控制
一.git基本介绍 Git是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目.Git是目前世界上最先进的分布式版本控制系统. 与常用的版本控制工具 CVS, Subversion 等 ...
随机推荐
- linux下命令拼接
前言:我个five,一道特别简单的拼接题没有做出来,我吐了,不过也是涨知识了 直接切入正题了 linux命令是可以拼接的,也就是说在一个system("???")下我们的???可以 ...
- Noip模拟12 2021.7.12
T1 interval 亏得昨天晚上改掉了T3并且理解了单调栈,今天一扫这题目就知道要用啥了. 先预处理出以a[i]为最大值的最大左右区间.然后再将a[i]取%!!!是的,要不然会影响单调栈的使用.. ...
- 玩转C语言链表-链表各类操作详解
链表概述 链表是一种常见的重要的数据结构.它是动态地进行存储分配的一种结构.它可以根据需要开辟内存单元.链表有一个"头指针"变量,以head表示,它存放一个地址.该地址指向一个元素 ...
- Luogu P2982 [USACO10FEB]慢下来 Slowing down | dfs序、线段树
题目链接 题目大意: 有一棵N个结点树和N头奶牛,一开始所有奶牛都在一号结点,奶牛们将按从编号1到编号N的顺序依次前往自己的目的地,求每头奶牛在去往自己目的地的途中将会经过多少已经有奶牛的结点. 题解 ...
- oracle 修改表空间名
1.登录使用sys用户登录 sqlplus sys/ as sysdba 2.修改表空间名字 SQL> alter tablespace 旧表空间名 rename to 新表空间名; 表空间已更 ...
- 2020美亚团体—Daniel篇
Daniel的桌上计算机的哈希值(SHA-256)是甚么? 通过取证大师计算 SHA-256值为 07DD40CF28603F421F3A09CD38F1C8AA40A2AC4BFB46ECF8299 ...
- adduser vs useradd
Always use adduser (and deluser when deleting users) when you're creating new users from the command ...
- Spark面试题(七)——Spark程序开发调优
Spark系列面试题 Spark面试题(一) Spark面试题(二) Spark面试题(三) Spark面试题(四) Spark面试题(五)--数据倾斜调优 Spark面试题(六)--Spark资源调 ...
- Vue安装Vue Devtools调试工具提示 Error: Cannot find module '@vue-devtools/build-tools' 解决办法
我看网络上面安装Vue Devtools 调试工具的步骤几乎都是按照文章链接里的步骤进行安装, 但是在最终执行编译命令的时候 :npm run build ,提示如下错误: 尝试了很多方法,都不能解决 ...
- [loj3503]滚榜
一个小问题:题意中关于$b_{i}$的顺序只需要单调不降即可,相同时可任意选择 考虑$i$优于$j$的条件,即$val_{i}\ge val_{j}+[i>j]$,并记$del_{i,j}=\m ...