需求
對MySQL數據庫中某個表的某個字段執行k-means算法,將處理后的數據寫入新表中。
源碼及驅動
kmean.rar
源碼
import java.sql.*;import java.util.*;/** * @author tianshl * @version 2018/1/13 上午11:13 */public class Kmeans {  // 源數據  private List<Integer> origins = new ArrayList<>();  // 分組數據  private Map<Double, List<Integer>> grouped;  // 初始質心列表  private List<Double> cores;  // 數據源  private String tableName;  private String colName;  /**   * 構造方法   *   * @param tableName 源數據表名稱   * @param colName  源數據列名稱   * @param cores   質心列表   */  private Kmeans(String tableName, String colName,List<Double> cores){    this.cores = cores;    this.tableName = tableName;    this.colName = colName;  }  /**   * 重新計算質心   *   * @return 新的質心列表   */  private List<Double> newCores(){    List<Double> newCores = new ArrayList<>();    for(List<Integer> v: grouped.values()){      newCores.add(v.stream().reduce(0, (sum, num) -> sum + num) / (v.size() + 0.0));    }    Collections.sort(newCores);    return newCores;  }  /**   * 判斷是否結束   *   * @return bool   */  private Boolean isOver(){    List<Double> _cores = newCores();    for(int i=0, len=cores.size(); i<len; i++){      if(!cores.get(i).toString().equals(_cores.get(i).toString())){        // 使用新質心        cores = _cores;        return false;      }    }    return true;  }  /**   * 數據分組   */  private void setGrouped(){    grouped = new HashMap<>();    Double core;    for (Integer origin: origins) {      core = getCore(origin);      if (!grouped.containsKey(core)) {        grouped.put(core, new ArrayList<>());      }      grouped.get(core).add(origin);    }  }  /**   * 選擇質心   *   * @param num  要分組的數據   * @return   質心   */  private Double getCore(Integer num){    // 差 列表    List<Double> diffs = new ArrayList<>();    // 計算差    for(Double core: cores){      diffs.add(Math.abs(num - core));    }    // 最小差 -> 索引 -> 對應的質心    return cores.get(diffs.indexOf(Collections.min(diffs)));  }  /**   * 建立數據庫連接   * @return connection   */  private Connection getConn(){    try {      // URL指向要訪問的數據庫名mydata      String url = "jdbc:mysql://localhost:3306/data_analysis_dev";      // MySQL配置時的用戶名      String user = "root";      // MySQL配置時的密碼      String password = "root";      // 加載驅動      Class.forName("com.mysql.jdbc.Driver");      //聲明Connection對象      Connection conn = DriverManager.getConnection(url, user, password);      if(conn.isClosed()){        System.out.println("連接數據庫失敗!");        return null;      }      System.out.println("連接數據庫成功!");      return conn;    } catch (Exception e) {      System.out.println("連接數據庫失敗!");      e.printStackTrace();    }    return null;  }  /**   * 關閉數據庫連接   *   * @param conn 連接   */  private void close(Connection conn){    try {      if(conn != null && !conn.isClosed()) conn.close();    } catch (Exception e){      e.printStackTrace();    }  }  /**   * 獲取源數據   */  private void getOrigins(){    Connection conn = null;    try {      conn = getConn();      if(conn == null) return;      Statement statement = conn.createStatement();      ResultSet rs = statement.executeQuery(String.format("select %s from %s", colName, tableName));      while(rs.next()){        origins.add(rs.getInt(1));      }      conn.close();    } catch (Exception e){      e.printStackTrace();    } finally {     close(conn);    }  }  /**   * 向新表中寫數據   */  private void write(){    Connection conn = null;    try {      conn = getConn();      if(conn == null) return;            // 創建表      Statement statement = conn.createStatement();      // 刪除舊數據表      statement.execute("DROP TABLE IF EXISTS k_means; ");      // 創建新表      statement.execute("CREATE TABLE IF NOT EXISTS k_means(`core` DECIMAL(11, 7), `col` INTEGER(11));");      // 禁止自動提交      conn.setAutoCommit(false);      PreparedStatement ps = conn.prepareStatement("INSERT INTO k_means VALUES (?, ?)");      for(Map.Entry<Double, List<Integer>> entry: grouped.entrySet()){        Double core = entry.getKey();        for(Integer value: entry.getValue()){          ps.setDouble(1, core);          ps.setInt(2, value);          ps.addBatch();        }      }      // 批量執行      ps.executeBatch();      // 提交事務      conn.commit();      // 關閉連接      conn.close();    } catch (Exception e){      e.printStackTrace();    } finally {      close(conn);    }  }  /**   * 處理數據   */  private void run(){    System.out.println("獲取源數據");    // 獲取源數據    getOrigins();    // 停止分組    Boolean isOver = false;    System.out.println("數據分組處理");    while(!isOver) {      // 數據分組      setGrouped();      // 判斷是否停止分組      isOver = isOver();    }    System.out.println("將處理好的數據寫入數據庫");    // 將分組數據寫入新表    write();    System.out.println("寫數據完畢");  }  public static void main(String[] args){    List<Double> cores = new ArrayList<>();    cores.add(260.0);    cores.add(600.0);    // 表名, 列名, 質心列表    new Kmeans("attributes", "attr_length", cores).run();  }}源文件
Kmeans.java
編譯
javac Kmeans.java
運行
# 指定依賴庫java -Djava.ext.dirs=./lib Kmeans
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。
新聞熱點
疑難解答
圖片精選