javakmeans聚類演算法
1. K-Means聚類演算法原理是怎麼樣的
問題:
姓名 身高 體重 眼睛
A 180 X 1.2
A X 140 X
A 180 140 X
A 168 120 1.5
姓名一樣,用java演算法,判斷出是兩個人?
2. 大數據挖掘需要學習哪些技術大數據的工作
處理大數據需要一個綜合、復雜、多方位的系統,系統中的處理模塊有很多,而數據挖掘技術以一個獨立的身份存在於處理大數據的整個系統之中,與其他模塊之間相輔相成、協調發展。在大數據時代中,數據挖掘技術的地位是無可比擬的。
數據挖掘的基本流程
在正式講數據挖掘知識清單之前,我先和你聊聊數據挖掘的基本流程。
數據挖掘的過程可以分成以下 6 個步驟。
商業理解:數據挖掘不是我們的目的,我們的目的是更好地幫助業務,所以第一步我們要從商業的角度理解項目需求,在這個基礎上,再對數據挖掘的目標進行定義。
數據理解:嘗試收集部分數據,然後對數據進行探索,包括數據描述、數據質量驗證等。這有助於你對收集的數據有個初步的認知。
數據准備:開始收集數據,並對數據進行清洗、數據集成等操作,完成數據挖掘前的准備工作。
模型建立:選擇和應用各種數據挖掘模型,並進行優化,以便得到更好的分類結果。
模型評估:對模型進行評價,並檢查構建模型的每個步驟,確認模型是否實現了預定的商業目標。
上線發布:模型的作用是從數據中找到金礦,也就是我們所說的「知識」,獲得的知識需要轉化成用戶可以使用的方式,呈現的形式可以是一份報告,也可以是實現一個比較復雜的、可重復的數據挖掘過程。數據挖掘結果如果是日常運營的一部分,那麼後續的監控和維護就會變得重要。
數據挖掘的十大演算法
為了進行數據挖掘任務,數據科學家們提出了各種模型,在眾多的數據挖掘模型中,國際權威的學術組織 ICDM (the IEEE International Conference on Data Mining)評選出了十大經典的演算法。
按照不同的目的,我可以將這些演算法分成四類,以便你更好的理解。
分類演算法:C4.5,樸素貝葉斯(Naive Bayes),SVM,KNN,Adaboost,CART
聚類演算法:K-Means,EM
關聯分析:Apriori
連接分析:PageRank
1. C4.5
C4.5 演算法是得票最高的演算法,可以說是十大演算法之首。C4.5 是決策樹的演算法,它創造性地在決策樹構造過程中就進行了剪枝,並且可以處理連續的屬性,也能對不完整的數據進行處理。它可以說是決策樹分類中,具有里程碑式意義的演算法。
2. 樸素貝葉斯(Naive Bayes)
樸素貝葉斯模型是基於概率論的原理,它的思想是這樣的:對於給出的未知物體想要進行分類,就需要求解在這個未知物體出現的條件下各個類別出現的概率,哪個最大,就認為這個未知物體屬於哪個分類。
3. SVM
SVM 的中文叫支持向量機,英文是 Support Vector Machine,簡稱 SVM。SVM 在訓練中建立了一個超平面的分類模型。如果你對超平面不理解,沒有關系,我在後面的演算法篇會給你進行介紹。
4. KNN
KNN 也叫 K 最近鄰演算法,英文是 K-Nearest Neighbor。所謂 K 近鄰,就是每個樣本都可以用它最接近的 K 個鄰居來代表。如果一個樣本,它的 K 個最接近的鄰居都屬於分類 A,那麼這個樣本也屬於分類 A。
5. AdaBoost
Adaboost 在訓練中建立了一個聯合的分類模型。boost 在英文中代表提升的意思,所以 Adaboost 是個構建分類器的提升演算法。它可以讓我們多個弱的分類器組成一個強的分類器,所以 Adaboost 也是一個常用的分類演算法。
6. CART
CART 代表分類和回歸樹,英文是 Classification and Regression Trees。像英文一樣,它構建了兩棵樹:一棵是分類樹,另一個是回歸樹。和 C4.5 一樣,它是一個決策樹學習方法。
7. Apriori
Apriori 是一種挖掘關聯規則(association rules)的演算法,它通過挖掘頻繁項集(frequent item sets)來揭示物品之間的關聯關系,被廣泛應用到商業挖掘和網路安全等領域中。頻繁項集是指經常出現在一起的物品的集合,關聯規則暗示著兩種物品之間可能存在很強的關系。
8. K-Means
K-Means 演算法是一個聚類演算法。你可以這么理解,最終我想把物體劃分成 K 類。假設每個類別裡面,都有個「中心點」,即意見領袖,它是這個類別的核心。現在我有一個新點要歸類,這時候就只要計算這個新點與 K 個中心點的距離,距離哪個中心點近,就變成了哪個類別。
9. EM
EM 演算法也叫最大期望演算法,是求參數的最大似然估計的一種方法。原理是這樣的:假設我們想要評估參數 A 和參數 B,在開始狀態下二者都是未知的,並且知道了 A 的信息就可以得到 B 的信息,反過來知道了 B 也就得到了 A。可以考慮首先賦予 A 某個初值,以此得到 B 的估值,然後從 B 的估值出發,重新估計 A 的取值,這個過程一直持續到收斂為止。
EM 演算法經常用於聚類和機器學習領域中。
10. PageRank
PageRank 起源於論文影響力的計算方式,如果一篇文論被引入的次數越多,就代表這篇論文的影響力越強。同樣 PageRank 被 Google 創造性地應用到了網頁權重的計算中:當一個頁面鏈出的頁面越多,說明這個頁面的「參考文獻」越多,當這個頁面被鏈入的頻率越高,說明這個頁面被引用的次數越高。基於這個原理,我們可以得到網站的權重劃分。
最後
演算法可以說是數據挖掘的靈魂,也是最精華的部分。這 10 個經典演算法在整個數據挖掘領域中的得票最高的,後面的一些其他演算法也基本上都是在這個基礎上進行改進和創新。今天你先對十大演算法有一個初步的了解,你只需要做到心中有數就可以了。
3. Java內存溢出主要有哪些類型
主要有三種類型
第一種OutOfMemoryError: PermGen space
發生這種問題的原意是程序中使用了緩坦大量的jar或class,使java虛擬機裝載類的空間不夠,與Permanent Generation space有關。解決這類問題有以下兩種辦法:
1. 增加java虛擬機中的XX:PermSize和XX:MaxPermSize參數的大小,其中XX:PermSize是初始永久保存區域大小,XX:MaxPermSize是最大永久保存區域大小。如針對tomcat6.0,在catalina.sh 或catalina.bat文件中一系列環境變數名說明結束處(大約在70行左右) 增加一行:
JAVA_OPTS=" -XX:PermSize=64M -XX:MaxPermSize=128m"
如果是windows伺服器還可以在系統環境變數中設置。感覺用tomcat發布sprint+struts+hibernate架構的程序時很容易發生這種內存溢出錯誤。使用上述方法,我成功解決了部署ssh項目的tomcat伺服器經常宕機的問題。
2. 清理應用程序中web-inf/lib下的jar,如果tomcat部署了多個應用,很多應用都使用了相同的jar,可以將共同的jar移到tomcat共同的lib下,減少類的重復載入。
第二種OutOfMemoryError: Java heap space
發生這種問題的原因是銷卜java虛擬機創建的對象太多,在進行垃圾回收之間,虛擬機分配的到堆內存空間已經用滿了,與Heap space有關。解決這類問題有兩種思路:
1. 檢查程序,看是否有死循環或不必要地重復創建大量對象。找到原因後,修改程序和演算法。
我以前寫一個使用K-Means文本聚類演算法對幾萬條文本記錄(每條記錄的特徵向量大約10來個)進行文本聚類時,由於程序細節上有問題,就導致了Java heap space的內存溢出問題,後來通過修改程序得到了解虧哪穗決。
2. 增加Java虛擬機中Xms(初始堆大小)和Xmx(最大堆大小)參數的大小。如:set JAVA_OPTS= -Xms256m -Xmx1024m
第三種OutOfMemoryError:unable to create new native thread
這種錯誤在Java線程個數很多的情況下容易發生
4. JVM如何確保新對象的內存分配的線程安全性
在解決java內存溢出問題之前,需要對jvm(java虛擬機)的內存管理有一定的認識。jvm管理的內存大致包括三種不同類型的內存區域:Permanent Generation space(永久保存區域)、Heap space(堆區域)、Java Stacks(Java棧)。其中永久保存區域主要存放Class(類)和Meta的信息,Class第一次被Load的時候被放入PermGen space區域,Class需要存儲的內容主要包括方法和靜態屬性。堆區域用來存放Class的實例(即對象),對象需要存儲的內容主要是非靜態屬性。每次用new創建一個對象實例後,對象實例存儲在堆區域中,這部分空間也被jvm的垃圾回收機制管理。而Java棧跟大多數編程語言包括匯編語言的棧功能相似,主要基本類型變數以及方法的輸入輸出參數。Java程序的每個線程中都有一個獨立的堆棧。容易發生內存溢出問題的內存空間包括:Permanent Generation space和Heap space。
第一種OutOfMemoryError: PermGen space
發生這種問題的原意是程序中使用了大量的jar或class,使java虛擬機裝載類的空間不夠,與Permanent Generation space有關。解決這類問題有以下兩種辦法:
增加java虛擬機中的XX:PermSize和XX:MaxPermSize參數的大小,其中XX:PermSize是初始永久保存區域大小,XX:MaxPermSize是最大永久保存區域大小。如針對tomcat6.0,在catalina.sh 或catalina.bat文件中一系列環境變數名說明結束處(大約在70行左右) 增加一行: JAVA_OPTS=" -XX:PermSize=64M -XX:MaxPermSize=128m" 如果是windows伺服器還可以在系統環境變數中設置。感覺用tomcat發布sprint+struts+hibernate架構的程序時很容易發生這種內存溢出錯誤。使用上述方法,我成功解決了部署ssh項目的tomcat伺服器經常宕機的問題。
清理應用程序中web-inf/lib下的jar,如果tomcat部署了多個應用,很多應用都使用了相同的jar,可以將共同的jar移到tomcat共同的lib下,減少類的重復載入。這種方法是網上部分人推薦的,我沒試過,但感覺減少不了太大的空間,最靠譜的還是第一種方法。
第二種OutOfMemoryError: Java heap space
發生這種問題的原因是java虛擬機創建的對象太多,在進行垃圾回收之間,虛擬機分配的到堆內存空間已經用滿了,與Heap space有關。解決這類問題有兩種思路:
檢查程序,看是否有死循環或不必要地重復創建大量對象。找到原因後,修改程序和演算法。 我以前寫一個使灶叢用K-Means文本聚類演算法對幾萬條文本記錄(每條記錄的特徵向量大約10來個)進塵余行文本聚類時,由於程序細節上有問題,就導致了Java heap space的內存溢出問題,後來通過修改程序得到了解決。
增加Java虛擬機中Xms(初始堆大小)和Xmx(最大堆大小)參數的大小。如:set JAVA_OPTS= -Xms256m -Xmx1024m
第三種OutOfMemoryError:unable to create new native thread
在java應用中,有時候會出現這樣的錯誤:OutOfMemoryError: unable to create new native thread.這種怪事是因為JVM已經被系統分配了大量的內存(比如1.5G),並且它至少要佔用可用內存的一半。有人發現,在線程個數很多的情況下,你分配給JVM的內存越多,那麼,上述錯誤發生的可能性就越大。
那麼是什麼原因造成這種問題呢?
每一個32位的進程最多可以使用2G的可用內存,因為另外2G被操作系統保留。這里假設使用1.5G給JVM,那麼還餘下500M可用內存。這500M內存中的一部分必須用於系統dll的載入,那麼真正剩下的也許只有400M,現在關鍵的地方出現了:當你使用Java創建一個線程,在JVM的內存里也隱兄櫻會創建一個Thread對象,但是同時也會在操作系統里創建一個真正的物理線程(參考JVM規范),操作系統會在餘下的400兆內存里創建這個物理線程,而不是在JVM的1500M的內存堆里創建。在jdk1.4里頭,默認的棧大小是256KB,但是在jdk1.5里頭,默認的棧大小為1M每線程,因此,在餘下400M的可用內存里邊我們最多也只能創建400個可用線程。
這樣結論就出來了,要想創建更多的線程,你必須減少分配給JVM的最大內存。還有一種做法是讓JVM宿主在你的JNI代碼里邊。
給出一個有關能夠創建線程的最大個數的估算公式:
(MaxProcessMemory - JVMMemory - ReservedOsMemory) / (ThreadStackSize) = Number of threads
對於jdk1.5而言,假設操作系統保留120M內存:
1.5GB JVM: (2GB-1.5Gb-120MB)/(1MB) = ~380 threads
1.0GB JVM: (2GB-1.0Gb-120MB)/(1MB) = ~880 threads
對於棧大小為256KB的jdk1.4而言,
1.5GB allocated to JVM: ~1520 threads
1.0GB allocated to JVM: ~3520 threads
對於這個異常我們首先需要判斷下,發生內存溢出時進程中到底都有什麼樣的線程,這些線程是否是應該存在的,是否可以通過優化來降低線程數; 另外一方面默認情況下java為每個線程分配的棧內存大小是1M,通常情況下,這1M的棧內存空間是足足夠用了,因為在通常在棧上存放的只是基礎類型的數據或者對象的引用,這些東西都不會占據太大的內存, 我們可以通過調整jvm參數,降低為每個線程分配的棧內存大小來解決問題,例如在jvm參數中添加-Xss128k將線程棧內存大小設置為128k。
5. 發現公司里的大數據開發掙得很多,想轉行,
轉行這個詞彙,一直是職場上此起彼伏的一個熱門話題,相信很多朋友都想過或已經經歷過轉行。工作可謂是我們生存乃至生活的主要收入來源,誰都希望擁有一份高薪又穩定的工作,以此來改善自己的生活和實現自己的大大小小的夢想!但又擔心轉行後的工作待遇達不到自己的預期,顧慮重重……
不少想進入大數據分析行業的零基礎學員經常會有這樣一些疑問:大數據分析零基礎應該怎麼學習?自己適合學習大數據分析嗎?人生,就是在不斷地做選擇,然後在這個選擇過程中成長,讓自己從一棵小樹苗變成參天大樹。就是我們每個對大數據充滿幻想終於下定決心行動的學員的選擇,我們給了自己4個月的時間,想要在大數據分析這個領域汲取養分,讓自己壯大成長。
【明確方向】
通過國家的戰略規劃,看到BAT的大牛們都在大數據行業布局,新聞媒體追捧這大數據分析行業的項目和熱點,我想如果我還沒有能力獨立判斷的時候,跟著國家政策和互聯網大佬們的步調走,這應該是錯不了的。
【付諸行動】
明確了方向之後,我就整裝待發,剛開始是在網路上購買了很多的視頻教程,也買了很多書籍,但是最大的問題就在於,我不知道怎麼入手,沒關系,有信心有耐心肯定能戰勝困難,我堅持了一個月,學習的節奏越來越亂,陸陸續續出現了很多的問題,沒人指導,請教了幾個業內的朋友,但對方工作繁忙,問了幾次之後就不好意思了,自學陷入了死循環。
意識到我學習效率的低下,以及無人指導的問題想想未來的康莊大道,咬咬牙告訴自己,一定好好好學,不然就浪費太多時間最後還會是一無所獲。最後找到組織(AAA教育)一起學習進步!
大數據分析零基礎學習路線,有信心能堅持學習的話,那就當下開始行動吧!
一、大數據技術基礎
1、linux操作基礎
linux系統簡介與安裝
linux常用命令–文件操作
linux常用命令–用戶管理與許可權
linux常用命令–系統管理
linux常用命令–免密登陸配置與網路管理
linux上常用軟體安裝
linux本地yum源配置及yum軟體安裝
linux防火牆配置
linux高級文本處理命令cut、sed、awk
linux定時任務crontab
2、shell編程
shell編程–基本語法
shell編程–流程式控制制
shell編程–函數
shell編程–綜合案例–自動化部署腳本
3、內存資料庫redis
redis和nosql簡介
redis客戶端連接
redis的string類型數據結構操作及應用-對象緩存
redis的list類型數據結構操作及應用案例-任務調度隊列
redis的hash及set數據結構操作及應用案例-購物車
redis的sortedset數據結構操作及應用案例-排行榜
4、布式協調服務zookeeper
zookeeper簡介及應用場景
zookeeper集群安裝部署
zookeeper的數據節點與命令行操作
zookeeper的java客戶端基本操作及事件監聽
zookeeper核心機制及數據節點
zookeeper應用案例–分布式共享資源鎖
zookeeper應用案例–伺服器上下線動態感知
zookeeper的數據一致性原理及leader選舉機制
5、java高級特性增強
Java多線程基本知識
Java同步關鍵詞詳解
java並發包線程池及在開源軟體中的應用
Java並發包消息隊里及在開源軟體中的應用
Java JMS技術
Java動態代理反射
6、輕量級RPC框架開發
RPC原理學習
Nio原理學習
Netty常用API學習
輕量級RPC框架需求分析及原理分析
輕量級RPC框架開發
二、離線計算系統
1、hadoop快速入門
hadoop背景介紹
分布式系統概述
離線數據分析流程介紹
集群搭建
集群使用初步
2、HDFS增強
HDFS的概念和特性
HDFS的shell(命令行客戶端)操作
HDFS的工作機制
NAMENODE的工作機制
java的api操作
案例1:開發shell採集腳本
3、MAPREDUCE詳解
自定義hadoop的RPC框架
Maprece編程規范及示例編寫
Maprece程序運行模式及debug方法
maprece程序運行模式的內在機理
maprece運算框架的主體工作流程
自定義對象的序列化方法
MapRece編程案例
4、MAPREDUCE增強
Maprece排序
自定義partitioner
Maprece的combiner
maprece工作機制詳解
5、MAPREDUCE實戰
maptask並行度機制-文件切片
maptask並行度設置
倒排索引
共同好友
6、federation介紹和hive使用
Hadoop的HA機制
HA集群的安裝部署
集群運維測試之Datanode動態上下線
集群運維測試之Namenode狀態切換管理
集群運維測試之數據塊的balance
HA下HDFS-API變化
hive簡介
hive架構
hive安裝部署
hvie初使用
7、hive增強和flume介紹
HQL-DDL基本語法
HQL-DML基本語法
HIVE的join
HIVE 參數配置
HIVE 自定義函數和Transform
HIVE 執行HQL的實例分析
HIVE最佳實踐注意點
HIVE優化策略
HIVE實戰案例
Flume介紹
Flume的安裝部署
案例:採集目錄到HDFS
案例:採集文件到HDFS
三、流式計算
1、Storm從入門到精通
Storm是什麼
Storm架構分析
Storm架構分析
Storm編程模型、Tuple源碼、並發度分析
Storm WordCount案例及常用Api分析
Storm集群部署實戰
Storm+Kafka+Redis業務指標計算
Storm源碼下載編譯
Strom集群啟動及源碼分析
Storm任務提交及源碼分析
Storm數據發送流程分析
Storm通信機制分析
Storm消息容錯機制及源碼分析
Storm多stream項目分析
編寫自己的流式任務執行框架
2、Storm上下游及架構集成
消息隊列是什麼
Kakfa核心組件
Kafka集群部署實戰及常用命令
Kafka配置文件梳理
Kakfa JavaApi學習
Kafka文件存儲機制分析
Redis基礎及單機環境部署
Redis數據結構及典型案例
Flume快速入門
Flume+Kafka+Storm+Redis整合
四、內存計算體系Spark
1、scala編程
scala編程介紹
scala相關軟體安裝
scala基礎語法
scala方法和函數
scala函數式編程特點
scala數組和集合
scala編程練習(單機版WordCount)
scala面向對象
scala模式匹配
actor編程介紹
option和偏函數
實戰:actor的並發WordCount
柯里化
隱式轉換
2、AKKA與RPC
Akka並發編程框架
實戰:RPC編程實戰
3、Spark快速入門
spark介紹
spark環境搭建
RDD簡介
RDD的轉換和動作
實戰:RDD綜合練習
RDD高級運算元
自定義Partitioner
實戰:網站訪問次數
廣播變數
實戰:根據IP計算歸屬地
自定義排序
利用JDBC RDD實現數據導入導出
WorldCount執行流程詳解
4、RDD詳解
RDD依賴關系
RDD緩存機制
RDD的Checkpoint檢查點機制
Spark任務執行過程分析
RDD的Stage劃分
5、Spark-Sql應用
Spark-SQL
Spark結合Hive
DataFrame
實戰:Spark-SQL和DataFrame案例
6、SparkStreaming應用實戰
Spark-Streaming簡介
Spark-Streaming編程
實戰:StageFulWordCount
Flume結合Spark Streaming
Kafka結合Spark Streaming
窗口函數
ELK技術棧介紹
ElasticSearch安裝和使用
Storm架構分析
Storm編程模型、Tuple源碼、並發度分析
Storm WordCount案例及常用Api分析
7、Spark核心源碼解析
Spark源碼編譯
Spark遠程debug
Spark任務提交行流程源碼分析
Spark通信流程源碼分析
SparkContext創建過程源碼分析
DriverActor和ClientActor通信過程源碼分析
Worker啟動Executor過程源碼分析
Executor向DriverActor注冊過程源碼分析
Executor向Driver注冊過程源碼分析
DAGScheler和TaskScheler源碼分析
Shuffle過程源碼分析
Task執行過程源碼分析
五、機器學習演算法
1、python及numpy庫
機器學習簡介
機器學習與python
python語言–快速入門
python語言–數據類型詳解
python語言–流程式控制制語句
python語言–函數使用
python語言–模塊和包
phthon語言–面向對象
python機器學習演算法庫–numpy
機器學習必備數學知識–概率論
2、常用演算法實現
knn分類演算法–演算法原理
knn分類演算法–代碼實現
knn分類演算法–手寫字識別案例
lineage回歸分類演算法–演算法原理
lineage回歸分類演算法–演算法實現及demo
樸素貝葉斯分類演算法–演算法原理
樸素貝葉斯分類演算法–演算法實現
樸素貝葉斯分類演算法–垃圾郵件識別應用案例
kmeans聚類演算法–演算法原理
kmeans聚類演算法–演算法實現
kmeans聚類演算法–地理位置聚類應用
決策樹分類演算法–演算法原理
決策樹分類演算法–演算法實現
時下的大數據分析時代與人工智慧熱潮,相信有許多對大數據分析師非常感興趣、躍躍欲試想著轉行的朋友,但面向整個社會,最不缺的其實就是人才,對於是否轉行大數據分析行列,對於能否勇敢一次跳出自己的舒適圈,不少人還是躊躇滿志啊!畢竟好多決定,一旦做出了就很難再回頭了。不過如果你已經轉行到大數據分析領域,就不要後悔,做到如何脫穎而出才是關鍵。因此本文給出一些建議,針對想要轉行大數據分析行列且是零基礎轉行的小夥伴們,希望對你們有所裨益,也希望你們將來學有所成,不後悔,更不灰心!
相關推薦:
《轉行大數據分析師後悔了》、《ui設計培訓四個月騙局大爆料》、《零基礎學大數據分析現實嗎》、《大數據分析十八般工具》
6. k-means演算法怎麼為對稱矩陣進行聚類
幾種典型的聚類融合演算法:
1.基於超圖劃分的聚類融合演算法
(1)Cluster-based Similarity Partitioning Algorithm(GSPA)
(2)Hyper Graph-Partitioning Algorithm(HGPA)
(3)Meta-Clustering Algorithm(MCLA)
2.基於關聯矩陣的聚類融合演算法
Voting-K-Means演算法。
3.基於投票策略的聚類融合演算法
w-vote是一種典型的基於加權投票的聚類融合演算法。
同時還有基於互信息的聚類融合演算法和基於有限混合模型的聚類融合演算法。
二、基於關聯矩陣的聚類融合演算法——Voting-K-Means演算法
Voting-K-Means演算法是一種基於關聯矩陣的聚類融合演算法,關聯矩陣的每一行和每一列代表一個數據點,關聯矩陣的元素表示數據集中數據點對共同出現在同一個簇中的概率。
演算法過程:
1.在一個數據集上得到若干個聚類成員;
2.依次掃描這些聚類成員,如果數據點i和j在某個聚類成員中被劃分到同一個簇中,那麼就在關聯矩陣對應的位置計數加1;關聯矩陣中的元素值越大,說明該元素對應的兩個數據點被劃分到同一個簇中的概率越大;
3.得到關聯矩陣之後,Voting-K-Means演算法依次檢查關聯矩陣中的每個元素,如果它的值大於演算法預先設定的閥值,就把這個元素對應的兩個數據點劃分到同一個簇中。
Voting-K-Means演算法的優缺點:
Voting-K-Means演算法不需要設置任何參數,在聚類融合的過程中可以自動地的選擇簇的個數 並且可以處理任意形狀的簇。因為Voting-K-Means演算法在聚類融合過程中是根據兩個數據點共同出現在同一個簇中的可能性大小對它們進行劃分的,所以只要兩個數據點距離足夠近,它們就會被劃分到一個簇中。
Voting-K-Means演算法的缺點是時間復雜度較高,它的時間復雜度是O(n^2);需要較多的聚類成員,如果聚類成員達不到一定規模,那麼關聯矩陣就不能准確反映出兩個數據點出現在同一個簇的概率。
package clustering;import java.io.FileWriter;import weka.clusterers.ClusterEvaluation;import weka.clusterers.SimpleKMeans;import weka.core.DistanceFunction;import weka.core.EuclideanDistance;import weka.core.Instances;import weka.core.converters.ConverterUtils.DataSource;import weka.filters.unsupervised.attribute.Remove;public class Votingkmeans2 extends SimpleKMeans { /** 生成的序列號 */ private static final long serialVersionUID = 1557181390469997876L; /** 劃分的簇數 */ private int m_NumClusters; /** 每個劃分的簇中的實例的數量 */ public int[] m_ClusterSizes; /** 使用的距離函數,這里是歐幾里德距離 */ protected DistanceFunction m_DistanceFunction = new EuclideanDistance(); /** 實例的簇號賦值 */ protected int[] m_Assignments; /** 設定聚類成員融合閥值 */ private final static double THREASOD = 0.5; /** 生成一個聚類器 */ public void buildClusterer(Instances data) throws Exception{ final int numinst = data.numInstances(); // 數據集的大小 double [][]association = new double[numinst][numinst]; // 定義並初始化一個關聯矩陣 int numIteration = 40; // 設置生成的聚類成員數 final int k = (int)Math.sqrt(numinst); // 設置K-Means聚類演算法參數——簇數 for(int i = 0; i < numIteration; i++) { if(data.classIndex() == -1) data.setClassIndex(data.numAttributes() - 1); // 索引是從0開始 String[] filteroption = new String[2]; filteroption[0] = "-R"; filteroption[1] = String.valueOf(data.classIndex() + 1);// 索引是從1開始 Remove remove = new Remove(); remove.setOptions(filteroption); remove.setInputFormat(data); /* 使用過濾器模式生成新的數據集;新數據集是去掉類標簽之後的數據集 */ Instances newdata = weka.filters.Filter.useFilter(data, remove); /* 生成一個K-Means聚類器 */ SimpleKMeans sm = new SimpleKMeans(); sm.setNumClusters(k); sm.setPreserveInstancesOrder(true); // 保持數據集實例的原始順序 sm.setSeed(i); // 通過設置不同的種子,設置不同的簇初始中心點,從而得到不同的聚類結果 sm.buildClusterer(newdata); int[] assigm = sm.getAssignments(); // 得到數據集各個實例的賦值 /* 建立關聯矩陣 */ for(int j = 0; j < numinst; j++) { for(int m = j; m < numinst; m++) { if(assigm[j] == assigm[m]) { association[j][m] = association[j][m] + 1.0 / numIteration ; } } } } System.out.println(); /* 將生成的關聯矩陣寫入.txt文件(註:生成的txt文本文件在e:/result.txt中) */ FileWriter fw = new FileWriter("e://result.txt"); for(int j = 0; j < numinst; j++) { for(int m = j; m < numinst; m++) { //由於關聯矩陣是對稱的,為了改進演算法的效率,只計算矩陣的上三角 String number = String.format("%8.2f", association[j][m]); fw.write(number); } fw.write("\n"); } /* 處理關聯矩陣,分別考慮了兩種情況 :1.關聯矩陣中某個元素對應的兩個數據點已經被劃分到了不同的簇中 * 2.兩個數據點中有一個或者兩個都沒有被劃分到某個簇中。 */ int[] flag = new int[numinst]; int[] flagk = new int[k]; int[] finallabel = new int[numinst]; for(int m = 0; m < numinst; m++) { for(int n = m; n < numinst; n++) { if(association[m][n] > THREASOD) { if(flag[m] == 0 && flag[n] == 0) { // 兩個數據點都沒有被劃分到某個簇中, int i = 0; // 將他們劃分到同一個簇中即可 while (i < k && flagk[i] == 1) i = i + 1; finallabel[m] = i; finallabel[n] = i; flag[m] = 1; flag[n] = 1; flagk[i] = 1; } else if (flag[m] == 0 && flag[n] == 1) { // 兩個數據點中有一個沒有被劃分到某個簇中, finallabel[m] = finallabel[n]; // 將他們劃分到同一個簇中即可 flag[m] = 1; } else if (flag[m] == 1 && flag[n] == 0) { finallabel[n] = finallabel[m]; flag[n] = 1; } else if (flag[m] == 1 && flag[n] == 1 && finallabel[m] != finallabel[n]) { // 兩個數據點已被劃分到了不同的簇中, flagk[finallabel[n]] = 0; // 將它們所在的簇合並 int temp = finallabel[n]; for(int i = 0; i < numinst; i++) { if(finallabel[i] == temp) finallabel[i] = finallabel[m]; } } } } } m_Assignments = new int[numinst]; System.out.println("基於關聯矩陣的聚類融合演算法——Voting-K-Means演算法的最終聚類結果"); for(int i = 0; i < numinst; i++) { m_Assignments[i] = finallabel[i]; System.out.print(finallabel[i] + " "); if((i+1) % 50 == 0) System.out.println(); } for(int i = 0; i < k; i++) { if(flagk[i] == 1) m_NumClusters++; } } /** * return a string describing this clusterer * * @return a description of the clusterer as a string */ public String toString() { return "Voting-KMeans\n"; } public static void main(String []args) { try {String filename="e://weka-data//iris.arff"; Instances data = DataSource.read(filename); Votingkmeans2 vk = new Votingkmeans2(); vk.buildClusterer(data); /* 要生成Voting-K-Means的聚類評估結果包括准確率等需要覆蓋重寫toString()方法; * 因為沒有覆蓋重寫,所以這里生產的評估結果沒有具體內容。 */ ClusterEvaluation eval = new ClusterEvaluation(); eval.setClusterer(vk); eval.evaluateClusterer(new Instances(data)); System.out.println(eval.clusterResultsToString()); } catch (Exception e) { e.printStackTrace(); }}}
分析代碼時注意:得到的類成員變數m_Assignments就是最終Voting-K-Means聚類結果;由於是採用了開源機器學習軟體Weka中實現的SimpleKMeans聚類演算法,初始時要指定簇的個數,這里是數據集大小開根號向下取整;指定的閥值為0.5,即當關聯矩陣元素的值大於閥值時,才對該元素對應的兩個數據點進行融合,劃分到一個簇中,考慮兩種情況,代碼注釋已有,這里不再詳述。但聚類融合的實驗結果並不理想,鶯尾花數據集irsi.arff是數據挖掘實驗中最常用的數據集,原數據集共有三個類;但本實驗進行四十個聚類成員的融合,其最終聚類結果劃分成兩個簇;其原因可能有兩個:一是演算法本身的問題,需要使用其他更加優化的聚類融合演算法;二是實現上的問題,主要就在聚類結果的融合上,需要進行一步對照關聯矩陣進行邏輯上的分析,找出代碼中的問題。關聯矩陣文本文件http://download.csdn.net/detail/lhkaikai/7294323
---------------------
本文來自 Turingkk 的CSDN 博客 ,全文地址請點擊:https://blog.csdn.net/lhkaikai/article/details/25004823?utm_source=
7. 做了這么多年Java開發,如何快速轉行大數據
一、學習大數據是需要學習java和linux的
二、你有多年的java開發經驗,那麼可以直接跳過java課程部分,學習大數據技術!
三、分享一份大數據技術課程大綱供你了解參考