K-means(聚类算法实现)

部分数据

Id

R

F

M

1

27

6

232.61

2

3

5

1507.11

3

4

16

817.62

4

3

11

232.81

5

14

7

1913.05

6

19

6

220.07

7

5

2

615.83

8

26

2

1059.66

9

21

9

304.82

10

2

21

1227.96

11

15

2

521.02

12

26

3

438.22

13

17

11

1744.55

14

30

16

1957.44

15

5

7

1713.79

16

4

21

1768.11

17

93

2

1016.34

18

16

3

950.36

19

4

1

754.93

20

27

1

294.23

聚类算法实现

一、实验题目

数据库应用

二、实验内容

现在有部分餐饮客户的消费数据存于数据文件consumption.xls,其中R表示最近一次消费时间间隔,F表示消费频率,M表示消费总金额。编程实现K-Means聚类算法,将客户分类成3类客户群,并评价这些客户群的价值

三、实验目的

1、熟悉K-Means聚类算法

2、锻炼分析问题、解决问题并动手实践的能力

四、实验指导

1、自行采用一种语言编程实现算法(注意:生成聚类中心、分配对象类别、迭代调整等核心算法需自己编程实现)

2、用课堂例子进行正确性检验

3、用户界面友好,要考虑到输入输出

4、重复运行,分析结果,说明初始化对结果的影响

代码:

package home;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class k_means {

int k = 3;   //聚类的类别
static int iteration = 0 ; // 聚类循环次数
static String a[] = {“20”, “8”, “400”}; //随机设置3个数据中心点
static String b[] = {“30”, “13”, “626.37”};
static String c[] = {“50”, “20”, “1105.63”};

static String[][] arr1 = new String[942][4]; //在getContrast()引用
static String[][] arr2 = new String[942][4];
static String[][] arr3 = new String[942][4];

public static void main(String[] args){
String[][] arr = new String[942][4]; //
init(arr);
getContrast(arr);
getPrint();
}

public static void init(String arr[][]){
int count = 0;
String[] array = null;
File file = new File(“consumption.csv”); //获取文件consumption.csv
try {
@SuppressWarnings(“resource”)
BufferedReader buf = new BufferedReader(new FileReader(file));     //读取文件
String s = null;
while((s=buf.readLine()) != null){
array = s.split(“,”);
arr[count][0] = array[0]; //将读取的数据中数据分别存到二维数组中
arr[count][1] = array[1];
arr[count][2] = array[2];
arr[count][3] = array[3];
count++;
}
} catch (FileNotFoundException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
public static void getContrast(String arr[][]){
float value1; //采用欧氏距离判断各个数据归属哪个类
float value2; 
float value3; 

while(iteration<500){ //循环执行500次,500次的作用数字大,才能聚类彻底,直到中心点不会在变
int count1 = 0;
int count2 = 0;
int count3 = 0;
float sum1_r = 0;
float sum1_f = 0;
float sum1_m = 0;

float sum2_r = 0;
float sum2_f = 0;
float sum2_m = 0;

float sum3_r = 0;
float sum3_f = 0;
float sum3_m = 0;

for(int i=1; i<941; i++){
//欧式算法公式 a=sqrt(pow(b,2)+pow(c,2)+pow(d,2))
value1 = (float) Math.sqrt(Math.pow(Float.parseFloat(arr[i][1])-Float.parseFloat(a[0]), 2)+
Math.pow(Float.parseFloat(arr[i][2])-Float.parseFloat(a[1]), 2) + 
Math.pow(Float.parseFloat(arr[i][3])-Float.parseFloat(a[2]), 2));
value2 = (float) Math.sqrt(Math.pow(Float.parseFloat(arr[i][1])-Float.parseFloat(b[0]), 2)+
Math.pow(Float.parseFloat(arr[i][2])-Float.parseFloat(b[1]), 2) + 
Math.pow(Float.parseFloat(arr[i][3])-Float.parseFloat(b[2]), 2));
value3 = (float) Math.sqrt(Math.pow(Float.parseFloat(arr[i][1])-Float.parseFloat(c[0]), 2)+
Math.pow(Float.parseFloat(arr[i][2])-Float.parseFloat(c[1]), 2) + 
Math.pow(Float.parseFloat(arr[i][3])-Float.parseFloat(c[2]), 2));
if((value1<=value2)&&(value1<=value3)){ //选出3个value中值最小的
arr1[i][0] = arr[i][0]; //将值赋给新建的数组arr1
arr1[i][1] = arr[i][1];
arr1[i][2] = arr[i][2];
arr1[i][3] = arr[i][3];
sum1_r += Float.parseFloat(arr1[i][1]); //将赋的值相加,后面会用到
sum1_f += Float.parseFloat(arr1[i][2]);
sum1_m += Float.parseFloat(arr1[i][3]);
count1++; //计数
}else if((value2<=value1)&&(value2<=value3)){ //选出3个value中值最小的
arr2[i][0] = arr[i][0]; //将值赋给新建的数组arr2
arr2[i][1] = arr[i][1];
arr2[i][2] = arr[i][2];
arr2[i][3] = arr[i][3];
sum2_r += Float.parseFloat(arr2[i][1]);
sum2_f += Float.parseFloat(arr2[i][2]);
sum2_m += Float.parseFloat(arr2[i][3]);
count2++;
}else if((value3<=value1)&&(value3<=value2)){ //选出3个value中值最小的
arr3[i][0] = arr[i][0]; //将值赋给新建的数组arr2
arr3[i][1] = arr[i][1];
arr3[i][2] = arr[i][2];
arr3[i][3] = arr[i][3];
sum3_r += Float.parseFloat(arr3[i][1]);
sum3_f += Float.parseFloat(arr3[i][2]);
sum3_m += Float.parseFloat(arr3[i][3]);
count3++;

}
}
a[0] = String.valueOf(sum1_r/count1); //强制转换成String,将相加的和除以总个数,获得新的中心点,下同
a[1] = String.valueOf(sum1_f/count1);
a[2] = String.valueOf(sum1_m/count1);

b[0] = String.valueOf(sum2_r/count2); //强制转换成String
b[1] = String.valueOf(sum2_f/count2);
b[2] = String.valueOf(sum2_m/count2);

c[0] = String.valueOf(sum3_r/count3); //强制转换成String
c[1] = String.valueOf(sum3_f/count3);
c[2] = String.valueOf(sum3_m/count3);

iteration++;
}
}

public static void getPrint(){ //打印输出
int j1=0;
int j2=0;
int j3=0;
for(int i=0; i<arr1.length; i++){
if(arr1[i][0] != null){
System.out.println(“客户群1:”+arr1[i][0]+”,”+arr1[i][1]+”,”+arr1[i][2]+”,”+arr1[i][3]);
j1++;
}
}
//上面的算法可能不知道哪里有问题,只有下面加了这句!arr2[i][0].equals(arr1[i][0])才能正常运行,如何找到哪里的算法问题,也请大家多多指正
for(int i=0; i<arr2.length; i++){
if(arr2[i][0] != null&&!arr2[i][0].equals(arr1[i][0])){
System.out.println(“客户群2:”+arr2[i][0]+”,”+arr2[i][1]+”,”+arr2[i][2]+”,”+arr2[i][3]);
j2++;
}
}
for(int i=0; i<arr3.length; i++){
if(arr3[i][0] != null&&!arr3[i][0].equals(arr2[i][0])){
System.out.println(“客户群3:”+arr3[i][0]+”,”+arr3[i][1]+”,”+arr3[i][2]+”,”+arr3[i][3]);
j3++;
}
}
int v = j1+j2+j3;
System.out.println(“客户群1数量:”+j1+”,客户群2数量:”+j2+”,客户群3数量:”+j3+”,总数:”+v);
}

}

数据文件链接:https://pan.baidu.com/s/1Yjgu8Lqehf6VDCK5srRNBQ

    原文作者:聚类算法
    原文地址: https://blog.csdn.net/fbvukn/article/details/80635629
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞