详解Java实现的k-means聚类算法
需求
对MySQL数据库中某个表的某个字段执行k-means算法,将处理后的数据写入新表中。
源码及驱动
kmeans_jb51.rar
源码
importjava.sql.*; importjava.util.*; /** *@authortianshl *@version2018/1/13上午11:13 */ publicclassKmeans{ //源数据 privateListorigins=newArrayList<>(); //分组数据 privateMap >grouped; //初始质心列表 privateList cores; //数据源 privateStringtableName; privateStringcolName; /** *构造方法 * *@paramtableName源数据表名称 *@paramcolName源数据列名称 *@paramcores质心列表 */ privateKmeans(StringtableName,StringcolName,List cores){ this.cores=cores; this.tableName=tableName; this.colName=colName; } /** *重新计算质心 * *@return新的质心列表 */ privateList newCores(){ List newCores=newArrayList<>(); for(List v:grouped.values()){ newCores.add(v.stream().reduce(0,(sum,num)->sum+num)/(v.size()+0.0)); } Collections.sort(newCores); returnnewCores; } /** *判断是否结束 * *@returnbool */ privateBooleanisOver(){ List _cores=newCores(); for(inti=0,len=cores.size();i (); Doublecore; for(Integerorigin:origins){ core=getCore(origin); if(!grouped.containsKey(core)){ grouped.put(core,newArrayList<>()); } grouped.get(core).add(origin); } } /** *选择质心 * *@paramnum要分组的数据 *@return质心 */ privateDoublegetCore(Integernum){ //差列表 List diffs=newArrayList<>(); //计算差 for(Doublecore:cores){ diffs.add(Math.abs(num-core)); } //最小差->索引->对应的质心 returncores.get(diffs.indexOf(Collections.min(diffs))); } /** *建立数据库连接 *@returnconnection */ privateConnectiongetConn(){ try{ //URL指向要访问的数据库名mydata Stringurl="jdbc:mysql://localhost:3306/data_analysis_dev"; //MySQL配置时的用户名 Stringuser="root"; //MySQL配置时的密码 Stringpassword="root"; //加载驱动 Class.forName("com.mysql.jdbc.Driver"); //声明Connection对象 Connectionconn=DriverManager.getConnection(url,user,password); if(conn.isClosed()){ System.out.println("连接数据库失败!"); returnnull; } System.out.println("连接数据库成功!"); returnconn; }catch(Exceptione){ System.out.println("连接数据库失败!"); e.printStackTrace(); } returnnull; } /** *关闭数据库连接 * *@paramconn连接 */ privatevoidclose(Connectionconn){ try{ if(conn!=null&&!conn.isClosed())conn.close(); }catch(Exceptione){ e.printStackTrace(); } } /** *获取源数据 */ privatevoidgetOrigins(){ Connectionconn=null; try{ conn=getConn(); if(conn==null)return; Statementstatement=conn.createStatement(); ResultSetrs=statement.executeQuery(String.format("select%sfrom%s",colName,tableName)); while(rs.next()){ origins.add(rs.getInt(1)); } conn.close(); }catch(Exceptione){ e.printStackTrace(); }finally{ close(conn); } } /** *向新表中写数据 */ privatevoidwrite(){ Connectionconn=null; try{ conn=getConn(); if(conn==null)return; //创建表 Statementstatement=conn.createStatement(); //删除旧数据表 statement.execute("DROPTABLEIFEXISTSk_means;"); //创建新表 statement.execute("CREATETABLEIFNOTEXISTSk_means(`core`DECIMAL(11,7),`col`INTEGER(11));"); //禁止自动提交 conn.setAutoCommit(false); PreparedStatementps=conn.prepareStatement("INSERTINTOk_meansVALUES(?,?)"); for(Map.Entry >entry:grouped.entrySet()){ Doublecore=entry.getKey(); for(Integervalue:entry.getValue()){ ps.setDouble(1,core); ps.setInt(2,value); ps.addBatch(); } } //批量执行 ps.executeBatch(); //提交事务 conn.commit(); //关闭连接 conn.close(); }catch(Exceptione){ e.printStackTrace(); }finally{ close(conn); } } /** *处理数据 */ privatevoidrun(){ System.out.println("获取源数据"); //获取源数据 getOrigins(); //停止分组 BooleanisOver=false; System.out.println("数据分组处理"); while(!isOver){ //数据分组 setGrouped(); //判断是否停止分组 isOver=isOver(); } System.out.println("将处理好的数据写入数据库"); //将分组数据写入新表 write(); System.out.println("写数据完毕"); } publicstaticvoidmain(String[]args){ List cores=newArrayList<>(); cores.add(260.0); cores.add(600.0); //表名,列名,质心列表 newKmeans("attributes","attr_length",cores).run(); } }
源文件
Kmeans.java
编译
javacKmeans.java
运行
#指定依赖库 java-Djava.ext.dirs=./libKmeans
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。