K-mean clustering algorithm!

S

Shum

Hi!
I need help ragarding the k-mean clustering algo. Any one have a
source code in c#.. or a dll file that could be used in the
project.... I cannot seem to identify the objects that could be used
in the algo..
I have to group the diseases according to provinces, and plot them in
graph, this will show how many diseases are more in which region. Im
confused as to what shuld be my initial clusters, the
provinces(location) or the diseases. I guess the location..
Give your ideas please!
 
D

DeveloperX

Hi!
I need help ragarding the k-mean clustering algo. Any one have a
source code in c#.. or a dll file that could be used in the
project.... I cannot seem to identify the objects that could be used
in the algo..
I have to group the diseases according to provinces, and plot them in
graph, this will show how many diseases are more in which region. Im
confused as to what shuld be my initial clusters, the
provinces(location) or the diseases. I guess the location..
Give your ideas please!

There's an explanation here with VB6 code. The only thing to bear in
mind is C# doesn't have a power operator like VB6, so 6^2 will return
4 not 36 (it's doing a binary XOR). Use Math.Pow instead.

http://people.revoledu.com/kardi/tutorial/kMean/index.html

Here's a really scrappy interpretation of the VB6 code. It's a mess
and I wasn't going to post it. It comes without warranty and watch for
line breaks.

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;

namespace KMean
{
struct Point
{
public int Cluster;
public int X;
public int Y;
public int Count;

public Point(int pCluster, int pX, int pY)
{
Cluster = pCluster;
X = pX;
Y = pY;
Count = 0;
}
public Point(Point pPoint) : this(pPoint.Cluster, pPoint.X,
pPoint.Y)
{
}
}

public class KMean : System.Windows.Forms.Form
{
private System.Windows.Forms.PictureBox pictureBox1;
private System.Windows.Forms.Label One;
private System.Windows.Forms.Label Two;
private System.Windows.Forms.Label Three;
private System.ComponentModel.Container components = null;

private ArrayList _data = new ArrayList();
private Point[] _centres = new Point[3];
private Label[] _labels = new Label[3];
public KMean()
{
InitializeComponent();
_labels[0] = One;
_labels[1] = Two;
_labels[2] = Three;
}

protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.pictureBox1 = new System.Windows.Forms.PictureBox();
this.One = new System.Windows.Forms.Label();
this.Two = new System.Windows.Forms.Label();
this.Three = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// pictureBox1
//
this.pictureBox1.BackColor =
System.Drawing.SystemColors.HighlightText;
this.pictureBox1.Dock = System.Windows.Forms.DockStyle.Fill;
this.pictureBox1.Location = new System.Drawing.Point(0, 0);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(688, 438);
this.pictureBox1.TabIndex = 0;
this.pictureBox1.TabStop = false;
this.pictureBox1.Paint += new
System.Windows.Forms.PaintEventHandler(this.pictureBox1_Paint);
this.pictureBox1.MouseUp += new
System.Windows.Forms.MouseEventHandler(this.pictureBox1_MouseUp);
//
// One
//
this.One.BackColor = System.Drawing.Color.FromArgb(((System.Byte)
(192)), ((System.Byte)(255)), ((System.Byte)(192)));
this.One.Location = new System.Drawing.Point(128, 120);
this.One.Name = "One";
this.One.Size = new System.Drawing.Size(8, 16);
this.One.TabIndex = 1;
this.One.Text = "1";
this.One.Visible = false;
//
// Two
//
this.Two.BackColor = System.Drawing.Color.FromArgb(((System.Byte)
(192)), ((System.Byte)(255)), ((System.Byte)(192)));
this.Two.Location = new System.Drawing.Point(142, 125);
this.Two.Name = "Two";
this.Two.Size = new System.Drawing.Size(8, 16);
this.Two.TabIndex = 2;
this.Two.Text = "2";
this.Two.Visible = false;
//
// Three
//
this.Three.BackColor = System.Drawing.Color.FromArgb(((System.Byte)
(192)), ((System.Byte)(255)), ((System.Byte)(192)));
this.Three.Location = new System.Drawing.Point(176, 104);
this.Three.Name = "Three";
this.Three.Size = new System.Drawing.Size(8, 16);
this.Three.TabIndex = 3;
this.Three.Text = "3";
this.Three.Visible = false;
//
// KMean
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(688, 438);
this.Controls.Add(this.Three);
this.Controls.Add(this.Two);
this.Controls.Add(this.One);
this.Controls.Add(this.pictureBox1);
this.Font = new System.Drawing.Font("Arial", 8.25F,
System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point,
((System.Byte)(0)));
this.Name = "KMean";
this.Text = "KMean";
this.ResumeLayout(false);

}
#endregion

private void pictureBox1_MouseUp(object sender,
System.Windows.Forms.MouseEventArgs e)
{
Point newData = new Point();
newData.X = e.X;
newData.Y = e.Y;
_data.Add(newData);
CalcClusters();
pictureBox1.Invalidate();
}
private void CalcClusters()
{
Point p;

switch(_data.Count)
{
case 1:
case 2:
case 3:
p = new Point((Point)_data[_data.Count-1]);
p.Cluster = _data.Count-1;
_centres[_data.Count-1] = p;
_data[_data.Count-1] = p;
break;
default:
CalcClusters2();
break;
}
}
private void CalcClusters2()
{
Boolean running = true;
double min = 10000000.0;
double distance = 0.0;
int cluster = 0;
Point p1 = (Point)_data[_data.Count-1];
foreach(Point p2 in _centres)
{
distance = Distance(p1, p2);
if(distance < min)
{
min = distance;
cluster = p2.Cluster;
}
}
p1 = (Point)_data[_data.Count-1];
p1.Cluster = cluster;
_data[_data.Count-1] = p1;

Point[] sums;
int c;
int d;

while(running)
{
sums = new Point[3];
for(c=0; c<_data.Count; c++)
{
p1 = (Point)_data[c];
sums[p1.Cluster].X+= p1.X;
sums[p1.Cluster].Y+= p1.Y;
sums[p1.Cluster].Count++;
}
for(c=0; c<=_centres.GetUpperBound(0); c++)
{
if(sums[c].Count>0)
{
_centres[c].X = sums[c].X / sums[c].Count;
_centres[c].Y = sums[c].Y / sums[c].Count;
}
}

running = false;

for(c=0; c<_data.Count; c++)
{
min = 10000000.0;
for(d=0; d<=_centres.GetUpperBound(0); d++)
{
distance = Distance((Point)_data[c], _centres[d]);
if(distance < min)
{
min = distance;
cluster = d;
}
}
p1 = (Point)_data[c];
if(p1.Cluster != cluster)
{
p1.Cluster = cluster;
running = true;
_data[c] = p1;
}
}
}
}
private double Distance(int pX1, int pY1, int pX2, int pY2)
{
return Math.Sqrt(Math.Pow((pY2 - pY1),2) + Math.Pow((pX2 - pX1),
2));
}
private double Distance(Point pP1, Point pP2)
{
return Distance(pP1.X,pP1.Y, pP2.X, pP2.Y);
}
private void pictureBox1_Paint(object sender,
System.Windows.Forms.PaintEventArgs e)
{
for(int c=0 ; c<=_centres.GetUpperBound(0) && c<_data.Count ; c++)
{
_labels[c].Visible = true;
_labels[c].Top = _centres[c].Y;
_labels[c].Left = _centres[c].X;
}

e.Graphics.Clear(Color.White);
using(Pen p = new Pen(Brushes.Black,5.0f))
{
foreach(Point pnt in _data)
{
switch(pnt.Cluster)
{
case 0:
p.Brush = Brushes.Blue;
break;
case 1:
p.Brush = Brushes.Red;
break;
case 2:
p.Brush = Brushes.Green;
break;
default:
p.Brush = Brushes.Black;
break;
}
e.Graphics.DrawEllipse(p,pnt.X, pnt.Y,10,10);
}
}
}
}
}
 
S

Shum

Im trying to understand the code.. its uncommented so hard to know
whats happening.
Thanks anyway.

Hi!
I need help ragarding the k-mean clustering algo. Any one have a
source code in c#.. or a dll file that could be used in the
project.... I cannot seem to identify the objects that could be used
in the algo..
I have to group the diseases according to provinces, and plot them in
graph, this will show how many diseases are more in which region. Im
confused as to what shuld be my initial clusters, the
provinces(location) or the diseases. I guess the location..
Give your ideas please!

There's an explanation here with VB6 code. The only thing to bear in
mind is C# doesn't have a power operator like VB6, so 6^2 will return
4 not 36 (it's doing a binary XOR). Use Math.Pow instead.

http://people.revoledu.com/kardi/tutorial/kMean/index.html

Here's a really scrappy interpretation of the VB6 code. It's a mess
and I wasn't going to post it. It comes without warranty and watch for
line breaks.

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;

namespace KMean
{
struct Point
{
public int Cluster;
public int X;
public int Y;
public int Count;

public Point(int pCluster, int pX, int pY)
{
Cluster = pCluster;
X = pX;
Y = pY;
Count = 0;
}
public Point(Point pPoint) : this(pPoint.Cluster, pPoint.X,
pPoint.Y)
{
}
}

public class KMean : System.Windows.Forms.Form
{
private System.Windows.Forms.PictureBox pictureBox1;
private System.Windows.Forms.Label One;
private System.Windows.Forms.Label Two;
private System.Windows.Forms.Label Three;
private System.ComponentModel.Container components = null;

private ArrayList _data = new ArrayList();
private Point[] _centres = new Point[3];
private Label[] _labels = new Label[3];
public KMean()
{
InitializeComponent();
_labels[0] = One;
_labels[1] = Two;
_labels[2] = Three;
}

protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.pictureBox1 = new System.Windows.Forms.PictureBox();
this.One = new System.Windows.Forms.Label();
this.Two = new System.Windows.Forms.Label();
this.Three = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// pictureBox1
//
this.pictureBox1.BackColor =
System.Drawing.SystemColors.HighlightText;
this.pictureBox1.Dock = System.Windows.Forms.DockStyle.Fill;
this.pictureBox1.Location = new System.Drawing.Point(0, 0);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(688, 438);
this.pictureBox1.TabIndex = 0;
this.pictureBox1.TabStop = false;
this.pictureBox1.Paint += new
System.Windows.Forms.PaintEventHandler(this.pictureBox1_Paint);
this.pictureBox1.MouseUp += new
System.Windows.Forms.MouseEventHandler(this.pictureBox1_MouseUp);
//
// One
//
this.One.BackColor = System.Drawing.Color.FromArgb(((System.Byte)
(192)), ((System.Byte)(255)), ((System.Byte)(192)));
this.One.Location = new System.Drawing.Point(128, 120);
this.One.Name = "One";
this.One.Size = new System.Drawing.Size(8, 16);
this.One.TabIndex = 1;
this.One.Text = "1";
this.One.Visible = false;
//
// Two
//
this.Two.BackColor = System.Drawing.Color.FromArgb(((System.Byte)
(192)), ((System.Byte)(255)), ((System.Byte)(192)));
this.Two.Location = new System.Drawing.Point(142, 125);
this.Two.Name = "Two";
this.Two.Size = new System.Drawing.Size(8, 16);
this.Two.TabIndex = 2;
this.Two.Text = "2";
this.Two.Visible = false;
//
// Three
//
this.Three.BackColor = System.Drawing.Color.FromArgb(((System.Byte)
(192)), ((System.Byte)(255)), ((System.Byte)(192)));
this.Three.Location = new System.Drawing.Point(176, 104);
this.Three.Name = "Three";
this.Three.Size = new System.Drawing.Size(8, 16);
this.Three.TabIndex = 3;
this.Three.Text = "3";
this.Three.Visible = false;
//
// KMean
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(688, 438);
this.Controls.Add(this.Three);
this.Controls.Add(this.Two);
this.Controls.Add(this.One);
this.Controls.Add(this.pictureBox1);
this.Font = new System.Drawing.Font("Arial", 8.25F,
System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point,
((System.Byte)(0)));
this.Name = "KMean";
this.Text = "KMean";
this.ResumeLayout(false);

}
#endregion

private void pictureBox1_MouseUp(object sender,
System.Windows.Forms.MouseEventArgs e)
{
Point newData = new Point();
newData.X = e.X;
newData.Y = e.Y;
_data.Add(newData);
CalcClusters();
pictureBox1.Invalidate();
}
private void CalcClusters()
{
Point p;

switch(_data.Count)
{
case 1:
case 2:
case 3:
p = new Point((Point)_data[_data.Count-1]);
p.Cluster = _data.Count-1;
_centres[_data.Count-1] = p;
_data[_data.Count-1] = p;
break;
default:
CalcClusters2();
break;
}
}
private void CalcClusters2()
{
Boolean running = true;
double min = 10000000.0;
double distance = 0.0;
int cluster = 0;
Point p1 = (Point)_data[_data.Count-1];
foreach(Point p2 in _centres)
{
distance = Distance(p1, p2);
if(distance < min)
{
min = distance;
cluster = p2.Cluster;
}
}
p1 = (Point)_data[_data.Count-1];
p1.Cluster = cluster;
_data[_data.Count-1] = p1;

Point[] sums;
int c;
int d;

while(running)
{
sums = new Point[3];
for(c=0; c<_data.Count; c++)
{
p1 = (Point)_data[c];
sums[p1.Cluster].X+= p1.X;
sums[p1.Cluster].Y+= p1.Y;
sums[p1.Cluster].Count++;
}
for(c=0; c<=_centres.GetUpperBound(0); c++)
{
if(sums[c].Count>0)
{
_centres[c].X = sums[c].X / sums[c].Count;
_centres[c].Y = sums[c].Y / sums[c].Count;
}
}

running = false;

for(c=0; c<_data.Count; c++)
{
min = 10000000.0;
for(d=0; d<=_centres.GetUpperBound(0); d++)
{
distance = Distance((Point)_data[c], _centres[d]);
if(distance < min)
{
min = distance;
cluster = d;
}
}
p1 = (Point)_data[c];
if(p1.Cluster != cluster)
{
p1.Cluster = cluster;
running = true;
_data[c] = p1;
}
}
}
}
private double Distance(int pX1, int pY1, int pX2, int pY2)
{
return Math.Sqrt(Math.Pow((pY2 - pY1),2) + Math.Pow((pX2 - pX1),
2));
}
private double Distance(Point pP1, Point pP2)
{
return Distance(pP1.X,pP1.Y, pP2.X, pP2.Y);
}
private void pictureBox1_Paint(object sender,
System.Windows.Forms.PaintEventArgs e)
{
for(int c=0 ; c<=_centres.GetUpperBound(0) && c<_data.Count ; c++)
{
_labels[c].Visible = true;
_labels[c].Top = _centres[c].Y;
_labels[c].Left = _centres[c].X;
}

e.Graphics.Clear(Color.White);
using(Pen p = new Pen(Brushes.Black,5.0f))
{
foreach(Point pnt in _data)
{
switch(pnt.Cluster)
{
case 0:
p.Brush = Brushes.Blue;
break;
case 1:
p.Brush = Brushes.Red;
break;
case 2:
p.Brush = Brushes.Green;
break;
default:
p.Brush = Brushes.Black;
break;
}
e.Graphics.DrawEllipse(p,pnt.X, pnt.Y,10,10);
}
}
}
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top