c# c均值聚类及DBSCAN聚类
来源:互联网 发布:网络电视怎么看电影 编辑:程序博客网 时间:2024/06/05 19:22
winform的界面搭建比较简单,首先在界面上的左边产生两堆特征值为 0-100的二维样本。通过 c均值聚类及DBSCAN聚类将聚类结果显示在右边。样本点有x和y值,用List<Point>存储一个类。
using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;using System.Drawing.Text;namespace PatternRecon{ public partial class Form1 : Form { public List<Point> Cluster1=new List<Point>(); public List<Point> Cluster2=new List<Point>(); public List<Point> afterCluster1 = new List<Point>(); public List<Point> afterCluster2 = new List<Point>(); public Form1() { InitializeComponent(); InitCombo(); } public void InitCombo() { this.comboBox1.Items.Add("c均值"); this.comboBox1.Items.Add("DBSCAN"); //设置默认值 this.textBox1.Text = "1"; this.textBox2.Text = "12"; //设置背景 afterCluster1.Clear(); afterCluster2.Clear(); this.pictureBox1.Image = (DrawCluster(afterCluster1, afterCluster2, false)); this.pictureBox2.Image = (DrawCluster(afterCluster1, afterCluster2, false)); } //产生随机数种子 public static int GetRandomSeed() { byte[] bytes = new byte[4]; System.Security.Cryptography.RNGCryptoServiceProvider rng = new System.Security.Cryptography.RNGCryptoServiceProvider(); rng.GetBytes(bytes); return BitConverter.ToInt32(bytes, 0); } //产生标准正太分布 public static double[] NormalDistribution() { Random rand = new Random(GetRandomSeed()); double[] y; double u1, u2, v1=0, v2=0, s = 0, z1=0, z2=0; while (s > 1 || s == 0) { u1 = rand.NextDouble(); u2 = rand.NextDouble(); v1 = 2 * u1 - 1; v2 = 2 * u2 - 1; s = v1 * v1 + v2 * v2; } z1 = Math.Sqrt(-2 * Math.Log(s) / s) * v1; z2 = Math.Sqrt(-2 * Math.Log(s) / s) * v2; y = new double[] { z1, z2 }; return y; //返回两个服从正态分布N(0,1)的随机数z0 和 z1 } //确定 private void button1_Click(object sender, EventArgs e) { if (this.comboBox1.Text == "c均值") { //调用c均值 Caverage(); this.pictureBox2.Image = (DrawCluster(afterCluster1, afterCluster2,false)); } else if (this.comboBox1.Text == "DBSCAN") { //调用DBSCAN if (this.textBox1.Text == "" || this.textBox2.Text == "") { MessageBox.Show("请输入DBSCAN值"); } else { DBSCAN(); this.pictureBox2.Image = (DrawCluster(afterCluster1, afterCluster2, false)); } } else { MessageBox.Show("请选择聚类方法!"); } } //绘图 public Bitmap DrawCluster(List<Point> m1,List<Point> m2,bool flag) { Bitmap bmp = new Bitmap(405, 405); Graphics g = Graphics.FromImage(bmp); Pen p = new Pen(Color.Black, 2); Pen linep = new Pen(Color.FromArgb(30, Color.Black), 2); Pen pm1; Pen pm2; if (flag==true) { pm1 = new Pen(Color.Red, 2); pm2 = new Pen(Color.Green, 2); } else { pm1 = new Pen(Color.Brown, 2); pm2 = new Pen(Color.Blue, 2); } Point p1 = new Point(400, 0); Point p2 = new Point(400, 400); Point p3 = new Point(0, 400); Point p4 = new Point(400, 400); try { //画线 g.Clear(Color.White); g.DrawLine(p, p1, p2); g.DrawLine(p, p3, p4); g.DrawLine(p,new Point(0,0), p1); g.DrawLine(p, new Point(0, 0), p3); g.DrawString("高斯分布随机产生100个样品,特征值取值为0-10", new Font("宋体", 10), new SolidBrush(Color.Black), new PointF(10, 10)); for (int i = 1; i <= 9; i++) { g.DrawLine(linep, new Point(i * 40, 400), new Point(i * 40, 0)); g.DrawLine(linep, new Point(400, i * 40), new Point(0, i * 40)); g.DrawString(i.ToString(), new Font("宋体", 10), new SolidBrush(Color.Blue), new PointF(i * 40, 400 - 15)); g.DrawString(i.ToString(), new Font("宋体", 10), new SolidBrush(Color.Blue), new PointF(400 - 15, i * 40)); } //画点 foreach(Point m1Point in m1) { g.DrawEllipse(pm1, m1Point.X, m1Point.Y, 2, 2); } foreach (Point m1Point in m2) { g.DrawEllipse(pm2, m1Point.X, m1Point.Y, 2, 2); } } catch (Exception ex) { MessageBox.Show(ex.Message); } finally { g.Dispose(); p.Dispose(); pm1.Dispose(); pm2.Dispose(); linep.Dispose(); } return bmp; //描点 } //用于产生两个均值 public int count = 0; private void pictureBox1_MouseClick(object sender, MouseEventArgs e) { count++; // MessageBox.Show(count.ToString()); if (count==1) { for (int i = 0; i < 50;i++ ) { double[] point = NormalDistribution(); double x = point[0] +e.X/40; double y = point[1] +e.Y/40; int x1 = (int)(x * 40); int x2 = (int)(y * 40); Cluster1.Add(new Point(x1,x2)); } } if (count == 2) { for (int i = 0; i < 50; i++) { double[] point = NormalDistribution(); double x = point[0] + e.X / 40; double y = point[1] + e.Y / 40; int x1 = (int)(x * 40); int x2 = (int)(y * 40); Cluster2.Add(new Point(x1, x2)); } this.pictureBox1.Image=(DrawCluster(Cluster1,Cluster2,true)); } } //c均值,按照PPT上的步骤写的 public void Caverage() { this.afterCluster1.Clear(); this.afterCluster2.Clear(); //初始化聚类中心 List<Point> Cluster=new List<Point>(); foreach(Point m1Point in Cluster1) { Cluster.Add(m1Point); } foreach(Point m2Point in Cluster2) { Cluster.Add(m2Point); } Point C1=Cluster[0]; Point C2=Cluster[1]; bool flag= true; //判断聚类中心是否相等 while (flag) { // MessageBox.Show("聚类中心1:" + C1.X.ToString() + " " + C1.Y.ToString() + "聚类中心2:" + C2.X.ToString() + " " + C2.Y.ToString()); int N1 = 0; int N2 = 0; int C1x = 0; int C2x = 0; int C1y = 0; int C2y = 0; foreach (Point point in Cluster) { int s1 = Math.Abs(point.X - C1.X) + Math.Abs(point.Y - C1.Y); int s2 = Math.Abs(point.X - C2.X) + Math.Abs(point.Y - C2.Y); if(s1<s2) { N1++; C1x += point.X; C1y += point.Y; } else { N2++; C2x += point.X; C2y += point.Y; } } if(C1x/N1==C1.X&&C2.X==C2x/N2&& C1.Y==C1y/N1&& C2.Y==C2y/N2) { flag = false; } C1.X=C1x/N1; C2.X=C2x/N2; C1.Y=C1y/N1; C2.Y=C2y/N2; } foreach (Point point in Cluster) { int s1 = Math.Abs(point.X - C1.X) + Math.Abs(point.Y - C1.Y); int s2 = Math.Abs(point.X - C2.X) + Math.Abs(point.Y - C2.Y); if (s1 < s2) { afterCluster1.Add(point); } else { afterCluster2.Add(point); } } } //DBSCAN public void DBSCAN() { try { double pow = 2.0; int radius = int.Parse(this.textBox1.Text) * 40; int MinPts = int.Parse(this.textBox2.Text); this.afterCluster1.Clear(); this.afterCluster2.Clear(); List<Point> Cluster = new List<Point>(); List<Point> temp1 = new List<Point>(); List<Point> temp2 = new List<Point>(); foreach (Point m1Point in Cluster1) { Cluster.Add(m1Point); } foreach (Point m2Point in Cluster2) { Cluster.Add(m2Point); } Point C1; Point C2; bool isC1Get = false; bool isC2Get = false; foreach (Point mm in Cluster) { if (isC1Get == false) { int count = 0;//记数 temp1.Clear(); foreach (Point mm1 in Cluster) { double banjing = Math.Sqrt(Math.Pow(mm1.X - mm.X, pow) + Math.Pow(mm1.Y - mm.Y, pow)); if (banjing < radius) { count++; temp1.Add(mm1); } } if (count >= MinPts) { C1 = mm; isC1Get = true; foreach (Point mm2 in temp1) { foreach (Point mm3 in Cluster) { double banjing = Math.Sqrt(Math.Pow(mm3.X - mm2.X, pow) + Math.Pow(mm3.Y - mm2.Y, pow)); if (banjing < radius && (afterCluster1.Contains(mm3) == false)) { afterCluster1.Add(mm3); } } } } } else if (isC2Get == false) { if (afterCluster1.Contains(mm) == false) { int count = 0;//记数 temp2.Clear(); foreach (Point mm1 in Cluster) { double banjing = Math.Sqrt(Math.Pow(mm1.X - mm.X, pow) + Math.Pow(mm1.Y - mm.Y, pow)); if (banjing < radius) { count++; temp2.Add(mm1); } } if (count >= MinPts) { C2 = mm; isC2Get = true; foreach (Point mm2 in temp2) { foreach (Point mm3 in Cluster) { double banjing = Math.Sqrt(Math.Pow(mm3.X - mm2.X, pow) + Math.Pow(mm3.Y - mm2.Y, pow)); if (banjing < radius && (afterCluster1.Contains(mm3) == false) && afterCluster2.Contains(mm3) == false) { afterCluster2.Add(mm3); } } } } } else { continue; } } else { break; } } } catch(Exception ex) { MessageBox.Show(ex.Message); } } //清除 private void button2_Click(object sender, EventArgs e) { this.Cluster1.Clear(); this.Cluster2.Clear(); this.afterCluster1.Clear(); this.afterCluster2.Clear(); count = 0; Bitmap bmp = new Bitmap(405, 405); Graphics g = Graphics.FromImage(bmp); g.Clear(Color.White); g.Dispose(); this.pictureBox1.Image = (DrawCluster(afterCluster1, afterCluster2, false)); this.pictureBox2.Image = (DrawCluster(afterCluster1, afterCluster2, false)); } //圈出不同,圈的之后注意比较一下中心 private void button3_Click(object sender, EventArgs e) { Bitmap bmp = (Bitmap)this.pictureBox2.Image; Graphics g = Graphics.FromImage(bmp); Pen p = new Pen(Color.Black,2); int count1 = 0; int count2 = 0; List<Point> belongCluster1; List<Point> belongCluster2; foreach (Point m1Point in Cluster1) { if (afterCluster1.Contains(m1Point)) count1++; if (afterCluster2.Contains(m1Point)) count2++; } if (count1 > count2) { belongCluster1 = afterCluster1; belongCluster2 = afterCluster2; } else { belongCluster1 = afterCluster2; belongCluster2 = afterCluster1; } //画出不同的地方 foreach (Point m1Point in Cluster1) { if (belongCluster1.Contains(m1Point) == false) { g.DrawEllipse(p, m1Point.X, m1Point.Y, 6, 6); } } foreach (Point m1Point in Cluster2) { if (belongCluster2.Contains(m1Point) == false) { g.DrawRectangle(p, m1Point.X, m1Point.Y, 6, 6); } } g.Dispose(); p.Dispose(); this.pictureBox2.Image = bmp; } }}
最终的聚类结果:
阅读全文
0 0
- c# c均值聚类及DBSCAN聚类
- 聚类算法之DBScan(C++)
- 初识聚类算法:K均值、凝聚层次聚类和DBSCAN
- 初识聚类算法:K均值、凝聚层次聚类和DBSCAN
- 模糊C均值聚类算法及实现
- 模糊C均值聚类
- [C#]K均值聚类
- 模糊C均值聚类
- 模糊c均值聚类
- 模糊C均值聚类
- 模糊C均值聚类
- 模糊C均值聚类
- 聚类算法:DBSCAN
- DBSCAN聚类算法
- DBSCAN 聚类算法
- DBSCAN 密度聚类
- DBSCAN聚类算法
- 密度聚类DBSCAN
- 海航集团负债率始终处于一个健康状态
- 百度2016实习-编号转换
- es6基础回顾--Generator函数
- css中设置隐藏,如何对隐的部分添加点击事件
- 快速排序算法的几种实现
- c# c均值聚类及DBSCAN聚类
- instanceof 与isAssignableFrom区别
- MySQL---数据库从入门走向大神系列(三)-修改数据库编码/DOS窗口编码
- Python: PS 图像调整--黑白
- 51nod 1821 最优集合 (思维+并查集or栈)
- UIButton,设置为UIButtonTypeCustom类型时,做圆角效果
- Release版本只在iOS9.2及以下闪退
- PAT 1005. 继续(3n+1)猜想
- ARM微处理器第二弹:寄存器