一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - 詳解Java實現的k-means聚類算法

詳解Java實現的k-means聚類算法

2021-03-19 12:02tianshl Java教程

這篇文章主要介紹了詳解Java實現的k-means聚類算法,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

需求

對MySQL數據庫中某個表的某個字段執行k-means算法,將處理后的數據寫入新表中。

源碼及驅動

kmeans.rar

源碼

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
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();
  }
}

源文件

?
1
Kmeans.java

編譯

?
1
javac Kmeans.java

運行

?
1
2
# 指定依賴庫
java -Djava.ext.dirs=./lib Kmeans

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:https://my.oschina.net/tianshl/blog/1606526

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 能免费观看的韩剧 | 国产精品久久久久这里只有精品 | 美女隐私部位视频网站 | 亚洲成在人线久久综合 | 91香蕉国产在线观看人员 | 国产在线视频自拍 | 亚洲成年网 | 欧美日韩一区二区中文字幕视频 | xxx黑人又大粗又长 xxxx性欧美极品另类 | 欧美日韩国产手机在线观看视频 | 我把寡妇日出水好爽 | 亚洲午夜精品久久久久久人妖 | 亚洲天堂成人在线观看 | 91麻豆国产福利在线观看 | 午夜AV亚洲一码二中文字幕青青 | 午夜国产精品影院在线观看 | 国产四虎 | 欧美在线播放一区二区 | jzzjzz视频免费播放 | 亚洲欧美日韩中文高清一 | 亚洲欧美日韩在线观看看另类 | 九九影院午夜理论片无码 | 色呦呦在线免费观看 | 白丝尤物的下面被疯狂蹂躏 | 国产精品亚洲精品日韩已满 | 黑帮少爷爱上我第8集最新 荷兰精品女人性hd 和日本免费不卡在线v | 亚洲AV精品一区二区三区不卡 | 欧美久久一区二区三区 | 北条麻妃黑人正在播放 | 午夜小视频网站 | 欧美久久一区二区三区 | 久久受www免费人成_看片中文 | 男人的天堂日本 | 变态 另类 人妖小说 | caoporm碰最新免费公开视频 | 毛片一区二区三区提莫影院 | 欧美日韩免费一区二区在线观看 | 性欧美4khdxxxx | 98色花堂永久地址国产精品 | 爽好舒服宝贝添奶吻戏 | 国产91精品久久久久久 |