網站首頁 編程語言 正文
K均值聚類
- 預測的是一個離散值時,做的工作就是“分類”。
- 預測的是一個連續值時,做的工作就是“回歸”。
機器學習模型還可以將訓練集中的數據劃分為若干個組,每個組被稱為一個“簇(cluster)”。這種學習方式被稱為“聚類(clusting)”,它的重要特點是在學習過程中不需要用標簽對訓練樣本進行標注。也就是說,學習過程能夠根據現有訓練集自動完成分類(聚類)。
根據訓練數據是否有標簽,可以將學習劃分為監督學習和無監督學習。
K近鄰、支持向量機都是監督學習,提供有標簽的數據給算法學習,然后對數據分類
聚類是無監督學習,事先并不知道分類標簽是什么,直接對數據分類。
聚類能夠將具有相似屬性的對象劃分到同一個集合(簇)中。
聚類方法能夠應用于所有對象,簇內的對象越相似,聚類算法的效果越好。
K均值聚類的基本步驟
K均值聚類是一種將輸入數據劃分為k個簇的簡單的聚類算法,該算法不斷提取當前分類的中心點(也稱為質心或重心),并最終在分類穩定時完成聚類。
從本質上說,K均值聚類是一種迭代算法。
在實際處理過程中需要進行多輪的迭代,直到分組穩定不再發生變化,即可認為分組完成。
K均值聚類算法的基本步驟如下:
- 隨機選取k個點作為分類的中心點。
- 將每個數據點放到距離它最近的中心點所在的類中。
- 重新計算各個分類的數據點的平均值,將該平均值作為新的分類中心點。
- 重復步驟2和步驟3,直到分類穩定。
可以是隨機選取k個點作為分類的中心點,也可以是隨機生成k個并不存在于原始數據中的數據點作為分類中心點。
距離最近: 要進行某種形式的距離計算。(在具體實現時,可以根據需要采用不同形式的距離度量方法。)
K均值聚類模塊
OpenCV提供了函數cv2.kmeans()來實現K均值聚類。
該函數的語法格式為:
retval, bestLabels, centers=cv2.kmeans(data, K, bestLabels, criteria, attempts, flags)
- data:輸入的待處理數據集合,應該是np.float32類型,每個特征放在單獨的一列中。
- K:要分出的簇的個數,即分類的數目,最常見的是K=2,表示二分類。
- bestLabels:表示計算之后各個數據點的最終分類標簽(索引)。實際調用時,參數bestLabels的值設置為None。
- criteria:算法迭代的終止條件。當達到最大循環數目或者指定的精度閾值時,算法停止繼續分類迭代計算。該參數由3個子參數構成,分別為type、max_iter和eps。
- type表示終止的類型,可以是三種情況
- cv2.TERM_CRITERIA_EPS:精度滿足eps時,停止迭代。
- cv2.TERM_CRITERIA_MAX_ITER:迭代次數超過閾值max_iter時,停止迭代。
- cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER:上述兩個條件中的任意一個滿足時,停止迭代。
- type表示終止的類型,可以是三種情況
- max_iter:最大迭代次數。
- eps:精確度的閾值。
- attempts:在具體實現時,為了獲得最佳分類效果,可能需要使用不同的初始分類值進行多次嘗試。指定attempts的值,可以讓算法使用不同的初始值進行多次(attempts次)嘗試。
- flags:表示選擇初始中心點的方法,主要有以下3種。
- cv2.KMEANS_RANDOM_CENTERS:隨機選取中心點。
- cv2.KMEANS_PP_CENTERS:基于中心化算法選取中心點。
- cv2.KMEANS_USE_INITIAL_LABELS:使用用戶輸入的數據作為第一次分類中心點;如果算法需要嘗試多次(attempts 值大于1時),后續嘗試都是使用隨機值或者半隨機值作為第一次分類中心點。
- retval:距離值(也稱密度值或緊密度),返回 每個點到相應中心點距離的平方和(是一個數)。
- bestLabels:各個數據點的最終分類標簽(索引)。
- centers:每個分類的中心點數據。
簡單例子
例1:
隨機生成一組數據,使用函數cv2.kmeans()對其分類。
- 一組數據在[0,50]區間
- 另一組數據在[200,250]區間
- 使用函數cv2.kmeans()對它們分類。
主要步驟如下:
數據預處理
使用隨機函數隨機生成兩組數據,并將它們轉換為函數cv2.kmeans()可以處理的格式。
設置參數
設置函數cv2.kmeans()的參數形式。將參數criteria的值設置為“(cv2.TERM_CRITERIA_EPS+ cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)”,在達到一定次數或者滿足一定精度時終止迭代。
調用函數cv2.kmeans()
調用函數cv2.kmeans(),獲取返回值,用于后續步驟的操作。
確定分類
根據函數cv2.kmeans()返回的標簽(“0”和“1”),將原始數據分為兩組
顯示結果
繪制經過分類的數據及中心點,觀察分類結果。
完整程序:
import numpy as np?
import cv2?
from matplotlib import pyplot as plt?
# 隨機生成兩組數組?
# 生成60個值在[0,50]內的數據?
num1 = np.random.randint(0,50,60)?
# 生成60個值在[200,250]內的數據?
num2 = np.random.randint(200,250,60)?
# 組合數據為num
num = np.hstack((num1, num2))
# 使用reshape函數將其轉換為(120,1) ?
num = num.reshape((120,1)) ?#每個數據為1列
# 轉換為float32類型?
num = np.float32(num)?
# 調用kmeans模塊?
# 設置參數criteria的值?
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)?
# 設置參數flags的值?
flags = cv2.KMEANS_RANDOM_CENTERS?
# 調用函數kmeans?
retval, bestLabels, centers = cv2.kmeans(num,2, None, criteria,10, flags)?
# 打印返回值?
print(retval)?
print(bestLabels)?
print(centers)?
# 獲取分類結果?
n1 = num[bestLabels==0]?
n2 = num[bestLabels==1]?
? ??
# 繪制分類結果?
# 繪制原始數據?
plt.plot(np.ones(len(n1)),n1,'ro')?
plt.plot(np.ones(len(n2)),n2,'bo')?
# 繪制中心點?
#plt.plot([1],centers[0],'rx')?
#plt.plot([1],centers[1],'bx')?
plt.show()?
?
例2:
有兩種物體:
- 物體1的長和寬都在 [0,20] 內
- 物體2的長和寬都在[40,60] 內
使用隨機數模擬兩種物體的長度和寬度,并使用函數cv2.kmeans()對它們分類。
根據題目要求,主要步驟如下:
- 隨機生成數據,并將它們轉換為函數cv2.kmeans()可以處理的形式。
- 設置函數cv2.kmeans()的參數形式。
- 調用函數cv2.kmeans()。
- 根據函數cv2.kmeans()的返回值,確定分類結果。
- 繪制經過分類的數據及中心點,觀察分類結果。
import numpy as np?
import cv2?
from matplotlib import pyplot as plt?
# 隨機生成兩組數值?
#長和寬都在[0,20]內?
m1 = np.random.randint(0,20, (30,2))?
#長和寬的大小都在[40,60]?
m2 = np.random.randint(40,60, (30,2))?
# 組合數據?
m = np.vstack((m1, m2))?
# 轉換為float32類型?
m = np.float32(m)?
# 調用kmeans模塊?
# 設置參數criteria值?
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)?
# 調用kmeans函數?
ret, label, center=cv2.kmeans(m,2, None, criteria,10, cv2.KMEANS_RANDOM_CENTERS)?
? ??
'''?
#打印返回值?
print(ret)?
print(label)?
print(center)?
'''?
# 根據kmeans的處理結果,將數據分類,兩大類?
res1 = m[label.ravel()==0]?
res2 = m[label.ravel()==1]?
# 繪制分類結果數據及中心點?
plt.scatter(res1[:,0], res1[:,1], c = 'g', marker = 's')?
plt.scatter(res2[:,0], res2[:,1], c = 'r', marker = 'o')?
plt.scatter(center[0,0], center[0,1], s = 200, c = 'b', marker = 'o')?
plt.scatter(center[1,0], center[1,1], s = 200, c = 'b', marker = 's')?
plt.xlabel('Height'), plt.ylabel('Width')?
plt.show()?
例3:
使用函數cv2.kmeans()將灰度圖像處理為只有兩個灰度級的二值圖像。
需要對灰度圖像內的色彩進行分類,將所有的像素點劃分為兩類。然后,用這兩類的中心點像素值替代原有像素值,滿足題目的要求。
主要步驟如下:
圖像預處理
讀取圖像,并將圖像轉換為函數cv2.kmeans()可以處理的形式。
在讀取圖像時,如果是3個通道的RGB圖像,需要將圖像的RGB值處理為一個單獨的特征值。具體實現時,用函數cv2.reshape()完成對圖像特征值的調整。
為了滿足函數cv2.kmeans()的要求,需要將圖像的數據類型轉換為numpy.float32類型。
設置函數cv2.kmeans()的參數形式
設置參數criteria的值為“(cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)”,讓函數cv2.kmeans()在達到一定精度或者達到一定迭代次數時,即停止迭代。
設置參數K的值為2,將所有像素劃分為兩類。
調用函數cv2.kmeans()
調用函數cv2.kmeans(),得到距離值、分類中心點和分類標簽,用于后續操作。
值替換
將像素點的值替換為當前分類的中心點的像素值。
顯示變換前后的圖像
分別顯示原始圖像和二值化圖像。
import numpy as np
import cv2
import matplotlib.pyplot as plt
# 讀取待處理圖像
img = cv2.imread('./img/hand2.png')
# 使用reshape將一個像素點的RGB值作為一個單元處理
data = img.reshape((-1,3)) # n行 3列
# 轉換為kmeans可以處理的類型
data = np.float32(data)
# 調用kmeans模塊
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
K =2
ret, label, center=cv2.kmeans(data, K, None, criteria,10, cv2.KMEANS_RANDOM_CENTERS)
# 轉換為uint8數據類型,將每個像素點都賦值為當前分類的中心點像素值
# 將center的值轉換為uint8
center = np.uint8(center)
# 使用center內的值替換原像素點的值
res1 = center[label.flatten()] # 根據索引來取值,最后結果的大小同索引的大小
# 使用reshape調整替換后的圖像
res2 = res1.reshape((img.shape))
# 顯示處理結果
plt.subplot(121)
plt.imshow(img[:,:,::-1])
plt.axis('off')
plt.subplot(122)
plt.imshow(res2[:,:,::-1])
plt.axis('off')
plt.show()
調整程序中的K值,就能改變圖像的顯示結果。例如,K=8,則可以讓圖像顯示8個灰度級。
原文鏈接:https://blog.csdn.net/first_bug/article/details/123514692
相關推薦
- 2023-07-26 vscode插件安裝失敗
- 2022-09-08 Go語言中的Struct結構體_Golang
- 2023-02-12 react-router-domV6嵌套路由實現詳解_React
- 2023-02-07 Go?singleflight使用以及原理_Golang
- 2022-08-02 Oracle數據庫丟失表排查思路實戰記錄_oracle
- 2022-09-10 ELK收集Tomcat日志的實現_Tomcat
- 2022-06-16 C語言深入分析遞歸函數的實現_C 語言
- 2022-05-23 Go語言映射內部實現及基礎功能實戰_Golang
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支