【web搜索】学习笔记-层次汇合聚类HAC算法
层次汇合聚类(Hierarchical Agglomerative Clustering,HAC)
算法如下:
相关链接:
层次聚类算法原理及实现
学习笔记:
先附上上一段链接中的代码:
// HAC_learning.cpp: 定义控制台应用程序的入口点。
//#include "stdafx.h"
#include <iostream>
#include <vector>
#include <algorithm>
#include <fstream>
using namespace std;
const int iniClusNum = 12;
const int stopNum = 3;class Point
{public:double x;double y;int NumPBelong;Point(){x = 0;y = 0;NumPBelong = -1;}Point(double x1, double y1, int f = -1) :x(x1), y(y1), NumPBelong(f) {}const Point& operator=(const Point& p){x = p.x;y = p.y;NumPBelong = p.NumPBelong;return *this;}
};class ManagerP
{public:double getDistance(const Point& p1, const Point& p2){return sqrt(pow((p1.x - p2.x), 2) + pow((p1.y - p2.y), 2));}Point getMean(const Point& p1, const Point& p2){Point p;p.x = (p1.x + p2.x) / 2;p.y = (p1.y + p2.y) / 2;return p;}
};class ManagerC
{public:Point Cluster[iniClusNum];vector<int> ClusterLast[iniClusNum];bool isIndexClose[iniClusNum];bool isIndexClose2[iniClusNum];void initCluster()//use txt to init, import txt{ifstream myfile("point.txt");if (!myfile){cout << "cannot open file."; return;}Point p;int x, y;int i = 0;while (!myfile.eof()){myfile >> x >> y;p.x = x;p.y = y;Cluster[i] = p;i++;}myfile.close();}void initIndexClose(){for (int i = 0; i<iniClusNum; i++){isIndexClose[i] = false;isIndexClose2[i] = false;}}void print(){for (int i = 0; i<iniClusNum; i++){if (ClusterLast[i].empty()){continue;}cout << "cluster " << i + 1 << endl;vector<int>::iterator ite = ClusterLast[i].begin();for (; ite != ClusterLast[i].end(); ite++){cout << *ite << "\t";}cout << endl;}cout << endl;}void ClusterAlgo()//use minheap to realize, to optimize{int ClustNum = iniClusNum;int clus_index = 0;while (ClustNum>stopNum){double min = INT_MAX;int x = -1, y = -1;ManagerP mp;for (int i = 0; i<iniClusNum; i++){if (isIndexClose[i]){continue;}for (int j = i + 1; j<iniClusNum; j++){if (isIndexClose[j]){continue;}double new_d = mp.getDistance(Cluster[i], Cluster[j]);if (new_d < min){min = new_d;x = i; y = j;}}}if (x == -1 || y == -1){break;}Point p = mp.getMean(Cluster[x], Cluster[y]);//x<y store the resultif (Cluster[x].NumPBelong == -1 && Cluster[y].NumPBelong == -1){cout << "a0" << endl;ClusterLast[clus_index].push_back(x);//xchange to p, y closeClusterLast[clus_index].push_back(y);p.NumPBelong = clus_index;isIndexClose[y] = true;//y is closedCluster[x] = p;//new p is openisIndexClose[x] = false;isIndexClose2[x] = true;isIndexClose2[y] = true;clus_index++;}else if (Cluster[x].NumPBelong == -1 && Cluster[y].NumPBelong != -1)//already exists one cluster{cout << "a1" << endl;ClusterLast[Cluster[y].NumPBelong].push_back(x);isIndexClose[x] = true;//x is closedp.NumPBelong = Cluster[y].NumPBelong;Cluster[y] = p;//new p is openisIndexClose2[x] = true;}else if (Cluster[x].NumPBelong != -1 && Cluster[y].NumPBelong == -1){cout << "a2" << endl;ClusterLast[Cluster[x].NumPBelong].push_back(y);isIndexClose[y] = true;//y is closedp.NumPBelong = Cluster[x].NumPBelong;Cluster[x] = p;//new p is openisIndexClose2[y] = true;}else if (Cluster[x].NumPBelong != -1 && Cluster[y].NumPBelong != -1)//both are clusteroid{cout << "a3" << endl;vector<int>::iterator ite = ClusterLast[Cluster[y].NumPBelong].begin();//put y's node in xfor (; ite != ClusterLast[Cluster[y].NumPBelong].end(); ite++){ClusterLast[Cluster[x].NumPBelong].push_back(*ite);}ClusterLast[Cluster[y].NumPBelong].clear();isIndexClose[y] = true;//y is closedp.NumPBelong = Cluster[x].NumPBelong;Cluster[x] = p;//new p is open}ClustNum--;}int total_size = 0;for (int i = 0; i<stopNum; i++){total_size += ClusterLast[i].size();}if (total_size<iniClusNum){int j = 0;for (int i = 0; i<iniClusNum; i++){if (isIndexClose2[i] == false){ClusterLast[stopNum - 1 - j].push_back(i);j++;}}}}};int main()
{ManagerC M;M.initCluster();M.initIndexClose();M.ClusterAlgo();M.print();system("pause");
}
其中,
point.txt:
4 10
4 8
7 10
6 8
3 4
2 2
5 2
9 3
10 5
11 4
12 3
12 6
运行结果:
草图:
代码理解:
定义类point,含有x,y(坐标)及NumPBelong(类别)
M.initCluster();输入数据
M.initIndexClose();开启所有点(设为false)
M.ClusterAlgo();HAC聚类
M.print();打印聚类结果
详细理解M.ClusterAlgo();
设定预期分类数stopNum,令实际分类数初始值为输入数据数(每个数据自成一类)
当(实际分类数>预期分类数stopNum)时
{clus_index=0;在x,y的isIndexClose值都不为true(关)的条件下(不为中心点/没有改变过)找出距离最小的两个点x,y并计算他们的距离min如果所有的点的isIndexClose值都为true(关)跳出循环//计算x,y的中点pa0:如果x,y都不是某类的中心点将x,y分入第clus_index类关闭y(isIndexClose=true)(y不再是某类中心点)把x,y的中点设为x,并令这个新的x为此类的中心点打开x(isIndexClose=true)(x为此类中心点)标记x,y(isIndexClose2= true;)a1:如果x不是某类中心点,y是某类中心点将x放入y所在的类别中关闭x把x,y的中点设为y标记xa2:如果x是某类中心点,y不是某类中心点将y放入x所在的类别中关闭y把x,y的中点设为x标记ya3:如果x,y都是中心点把y所在类别的所有点移入x所在类别中关闭y把x,y的中点设为x
实际分类数-1
}
计算所有已分类类别中数据的总数total_size
如果已分类数据总数total_size<原始输入数据总数iniClusNum(有数据未分类)
{对每一个数进行检查,将所有未标记数(isIndexClose2 == false)平均分给各个类
}
【web搜索】学习笔记-层次汇合聚类HAC算法相关推荐
- ELK搜索学习笔记--Day1
ELK搜索学习笔记–Day1 1. 课程简介 1.1 课程内容 ELK是包含但不限于Elasticsearch(简称es).Logstash.Kibana 三个开源软件的组成的一个整体.这三个软件合成 ...
- 基于Solr的空间搜索学习笔记
基于Solr的空间搜索学习笔记 在Solr中基于空间地址查询主要围绕2个概念实现: (1) Cartesian Tiers 笛卡尔层 Cartesian Tiers是通过将一个平面地图的根据设定的层次 ...
- Java web与web gis学习笔记(二)——百度地图API调用
系列链接: Java web与web gis学习笔记(一)--Tomcat环境搭建 Java web与web gis学习笔记(二)--百度地图API调用 JavaWeb和WebGIS学习笔记(三)-- ...
- web安全学习笔记--sql语句(sql注入基础上)
一.基础知和表内操作语法 1.sql语句对大小写不敏感!!! SELECT - 从数据库表中获取数据:select * from (columns/tables/databases); UPDATE ...
- web前端学习笔记(最新)
web前端学习笔记 大家好,我是链表哥,新的学期,新的学习,我会为您展示我的学习进程. 一:什么是WEB前端? 所谓的Web前端指的是用户所能接触到的,并服务于用户的前沿端口,经我们程序员编辑修饰后展 ...
- Web Components 学习笔记一: Web Components是什么?解决了什么问题?
公众号:妙蛙种子前端 文章原文地址:Web Components笔记一: Web Components是什么?解决了什么问题? | 妙蛙种子 - 记录WEB前端技术学习成长过程的博客 Web Comp ...
- 深度学习笔记(10) 优化算法(二)
深度学习笔记(10) 优化算法(二) 1. Adam 优化算法 2. 学习率衰减 3. 局部最优的问题 1. Adam 优化算法 Adam代表的是 Adaptive Moment Estimation ...
- 深度学习笔记(9) 优化算法(一)
深度学习笔记(9) 优化算法(一) 1. Mini-batch 梯度下降 2. 指数加权平均数 3. 动量梯度下降法 4. 均方根反向传播 1. Mini-batch 梯度下降 把训练样本放大巨大的矩 ...
- 【C++ Primer 学习笔记】: 容器和算法之【泛型算法】
本系列博客主要是在学习 C++ Primer 时的一些总结和笔记. [C++ Primer 学习笔记]: 容器和算法之[泛型算法] 本文地址:http://blog.csdn.net/shanglia ...
最新文章
- MultiBinding的StringFormat参数问题
- 【错误记录】Windows 系统 bat 脚本报错 ( 使用 pause 拦截窗口自动关闭 | 方便查看错误 )
- 编译arm平台的ethtool
- tp框架 db::name_玩! 框架:为什么我会爱上它
- 玩家在RTX 3090显卡中发现了指套
- 【清北学堂】广州OI学习游记
- Jstatd命令 Java Statistics Monitoring Daemon
- OpenShift 4.3 - 基于虚拟机的BareMetal离线安装(7-9)
- python 多次匹配_Python学习记录14
- VSCode:vscode设置侧边资源管理器文字大小
- dx绘制2d图像_【3D建模】聊聊2D动画软件
- java模拟面试题目_JAVA模拟面试题库
- 一个不错的Fortran教程
- 财务分析报表APP的功能优势
- 3500振动监测系统培训总结
- mysql 回滚 大小设置_MySQL事物提交与回滚
- LC152---乘积最大子数组
- 蓝牙通信工作流程讲解
- 【洛谷】P5960 【模板】差分约束算法
- 催眠曲用计算机怎么弹,在电脑中巧播“催眠曲”