聚类算法是一种无监督学习,它把数据分成若干类,同一类中的数据的相似性应尽可能地大,不同类中的数据的差异性应尽可能地大。聚类算法可分为“软聚类”和“硬聚类”,对于“硬聚类”,样本中的每一个点都是 100%确定分到某一个类别;而“软聚类”是指样本点以一定的概率被分配到一个类别中。提到聚类算法,很容易想到 K-means 算法,即 K-均值。这种方法很好理解,也很好实现。本文以 k-means 为引子,不断引出 K-means 的各种改进版本,如K-means ++ 、kernel K-means等。
K-means 的步骤可以分为:
(1)、随机选取 K 个点,作为 K 类的聚类中心,用 Ki 表示
(2)、遍历所有的数据点 Pj,通过计算距离,找到距离 Pj 最近的聚类中心点 Ki。此时可以说第 j 个数据属于第 i 类
(3)、分别计算第 i 类的所有数据的中心点,作为该类的新的聚类中心点。
(4)、重复进行(2)(3)步骤。直到每一类的聚类中心不再发生变化
下面是 K -means 的代码:
#include<iostream>
#include<sstream>
#include<fstream>
#include<string>
#include<vector>
#include<ctime>
#include<cstdlib> //srand() 在里面
#include<limits>
using namespace std;
typedef struct Point
{
float x;
float y;
int cluster;
Point(){};
Point(float a,float b,int c)
{
x = a;
y = b;
cluster = c;
}
}point;
float stringToFloat(string str)
{
stringstream sf; // 在<sstream>头文件中,进行流的输入输出操作。传入参数和目标对象的类型能够被自动推导出来
float f_num = 0;
sf << str; // 将 str 输入到流中
sf >> f_num; // 将字符串 str 转换为 int 类型的变量
return f_num;
}
vector<point> openFile(const char* dataset) // 打开文件
{
fstream file;
file.open(dataset,ios::in);
vector<point> data;
while (!file.eof())
{
string temp;
file >> temp;
int split = temp.find(',', 0);// 从 0