網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
K均值聚類(lèi)
- 預(yù)測(cè)的是一個(gè)離散值時(shí),做的工作就是“分類(lèi)”。
- 預(yù)測(cè)的是一個(gè)連續(xù)值時(shí),做的工作就是“回歸”。
機(jī)器學(xué)習(xí)模型還可以將訓(xùn)練集中的數(shù)據(jù)劃分為若干個(gè)組,每個(gè)組被稱(chēng)為一個(gè)“簇(cluster)”。這種學(xué)習(xí)方式被稱(chēng)為“聚類(lèi)(clusting)”,它的重要特點(diǎn)是在學(xué)習(xí)過(guò)程中不需要用標(biāo)簽對(duì)訓(xùn)練樣本進(jìn)行標(biāo)注。也就是說(shuō),學(xué)習(xí)過(guò)程能夠根據(jù)現(xiàn)有訓(xùn)練集自動(dòng)完成分類(lèi)(聚類(lèi))。
根據(jù)訓(xùn)練數(shù)據(jù)是否有標(biāo)簽,可以將學(xué)習(xí)劃分為監(jiān)督學(xué)習(xí)和無(wú)監(jiān)督學(xué)習(xí)。
K近鄰、支持向量機(jī)都是監(jiān)督學(xué)習(xí),提供有標(biāo)簽的數(shù)據(jù)給算法學(xué)習(xí),然后對(duì)數(shù)據(jù)分類(lèi)
聚類(lèi)是無(wú)監(jiān)督學(xué)習(xí),事先并不知道分類(lèi)標(biāo)簽是什么,直接對(duì)數(shù)據(jù)分類(lèi)。
聚類(lèi)能夠?qū)⒕哂邢嗨茖傩缘膶?duì)象劃分到同一個(gè)集合(簇)中。
聚類(lèi)方法能夠應(yīng)用于所有對(duì)象,簇內(nèi)的對(duì)象越相似,聚類(lèi)算法的效果越好。
K均值聚類(lèi)的基本步驟
K均值聚類(lèi)是一種將輸入數(shù)據(jù)劃分為k個(gè)簇的簡(jiǎn)單的聚類(lèi)算法,該算法不斷提取當(dāng)前分類(lèi)的中心點(diǎn)(也稱(chēng)為質(zhì)心或重心),并最終在分類(lèi)穩(wěn)定時(shí)完成聚類(lèi)。
從本質(zhì)上說(shuō),K均值聚類(lèi)是一種迭代算法。
在實(shí)際處理過(guò)程中需要進(jìn)行多輪的迭代,直到分組穩(wěn)定不再發(fā)生變化,即可認(rèn)為分組完成。
K均值聚類(lèi)算法的基本步驟如下:
- 隨機(jī)選取k個(gè)點(diǎn)作為分類(lèi)的中心點(diǎn)。
- 將每個(gè)數(shù)據(jù)點(diǎn)放到距離它最近的中心點(diǎn)所在的類(lèi)中。
- 重新計(jì)算各個(gè)分類(lèi)的數(shù)據(jù)點(diǎn)的平均值,將該平均值作為新的分類(lèi)中心點(diǎn)。
- 重復(fù)步驟2和步驟3,直到分類(lèi)穩(wěn)定。
可以是隨機(jī)選取k個(gè)點(diǎn)作為分類(lèi)的中心點(diǎn),也可以是隨機(jī)生成k個(gè)并不存在于原始數(shù)據(jù)中的數(shù)據(jù)點(diǎn)作為分類(lèi)中心點(diǎn)。
距離最近: 要進(jìn)行某種形式的距離計(jì)算。(在具體實(shí)現(xiàn)時(shí),可以根據(jù)需要采用不同形式的距離度量方法。)
K均值聚類(lèi)模塊
OpenCV提供了函數(shù)cv2.kmeans()來(lái)實(shí)現(xiàn)K均值聚類(lèi)。
該函數(shù)的語(yǔ)法格式為:
retval, bestLabels, centers=cv2.kmeans(data, K, bestLabels, criteria, attempts, flags)
- data:輸入的待處理數(shù)據(jù)集合,應(yīng)該是np.float32類(lèi)型,每個(gè)特征放在單獨(dú)的一列中。
- K:要分出的簇的個(gè)數(shù),即分類(lèi)的數(shù)目,最常見(jiàn)的是K=2,表示二分類(lèi)。
- bestLabels:表示計(jì)算之后各個(gè)數(shù)據(jù)點(diǎn)的最終分類(lèi)標(biāo)簽(索引)。實(shí)際調(diào)用時(shí),參數(shù)bestLabels的值設(shè)置為None。
- criteria:算法迭代的終止條件。當(dāng)達(dá)到最大循環(huán)數(shù)目或者指定的精度閾值時(shí),算法停止繼續(xù)分類(lèi)迭代計(jì)算。該參數(shù)由3個(gè)子參數(shù)構(gòu)成,分別為type、max_iter和eps。
- type表示終止的類(lèi)型,可以是三種情況
- cv2.TERM_CRITERIA_EPS:精度滿(mǎn)足eps時(shí),停止迭代。
- cv2.TERM_CRITERIA_MAX_ITER:迭代次數(shù)超過(guò)閾值max_iter時(shí),停止迭代。
- cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER:上述兩個(gè)條件中的任意一個(gè)滿(mǎn)足時(shí),停止迭代。
- type表示終止的類(lèi)型,可以是三種情況
- max_iter:最大迭代次數(shù)。
- eps:精確度的閾值。
- attempts:在具體實(shí)現(xiàn)時(shí),為了獲得最佳分類(lèi)效果,可能需要使用不同的初始分類(lèi)值進(jìn)行多次嘗試。指定attempts的值,可以讓算法使用不同的初始值進(jìn)行多次(attempts次)嘗試。
- flags:表示選擇初始中心點(diǎn)的方法,主要有以下3種。
- cv2.KMEANS_RANDOM_CENTERS:隨機(jī)選取中心點(diǎn)。
- cv2.KMEANS_PP_CENTERS:基于中心化算法選取中心點(diǎn)。
- cv2.KMEANS_USE_INITIAL_LABELS:使用用戶(hù)輸入的數(shù)據(jù)作為第一次分類(lèi)中心點(diǎn);如果算法需要嘗試多次(attempts 值大于1時(shí)),后續(xù)嘗試都是使用隨機(jī)值或者半隨機(jī)值作為第一次分類(lèi)中心點(diǎn)。
- retval:距離值(也稱(chēng)密度值或緊密度),返回 每個(gè)點(diǎn)到相應(yīng)中心點(diǎn)距離的平方和(是一個(gè)數(shù))。
- bestLabels:各個(gè)數(shù)據(jù)點(diǎn)的最終分類(lèi)標(biāo)簽(索引)。
- centers:每個(gè)分類(lèi)的中心點(diǎn)數(shù)據(jù)。
簡(jiǎn)單例子
例1:
隨機(jī)生成一組數(shù)據(jù),使用函數(shù)cv2.kmeans()對(duì)其分類(lèi)。
- 一組數(shù)據(jù)在[0,50]區(qū)間
- 另一組數(shù)據(jù)在[200,250]區(qū)間
- 使用函數(shù)cv2.kmeans()對(duì)它們分類(lèi)。
主要步驟如下:
數(shù)據(jù)預(yù)處理
使用隨機(jī)函數(shù)隨機(jī)生成兩組數(shù)據(jù),并將它們轉(zhuǎn)換為函數(shù)cv2.kmeans()可以處理的格式。
設(shè)置參數(shù)
設(shè)置函數(shù)cv2.kmeans()的參數(shù)形式。將參數(shù)criteria的值設(shè)置為“(cv2.TERM_CRITERIA_EPS+ cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)”,在達(dá)到一定次數(shù)或者滿(mǎn)足一定精度時(shí)終止迭代。
調(diào)用函數(shù)cv2.kmeans()
調(diào)用函數(shù)cv2.kmeans(),獲取返回值,用于后續(xù)步驟的操作。
確定分類(lèi)
根據(jù)函數(shù)cv2.kmeans()返回的標(biāo)簽(“0”和“1”),將原始數(shù)據(jù)分為兩組
顯示結(jié)果
繪制經(jīng)過(guò)分類(lèi)的數(shù)據(jù)及中心點(diǎn),觀(guān)察分類(lèi)結(jié)果。
完整程序:
import numpy as np?
import cv2?
from matplotlib import pyplot as plt?
# 隨機(jī)生成兩組數(shù)組?
# 生成60個(gè)值在[0,50]內(nèi)的數(shù)據(jù)?
num1 = np.random.randint(0,50,60)?
# 生成60個(gè)值在[200,250]內(nèi)的數(shù)據(jù)?
num2 = np.random.randint(200,250,60)?
# 組合數(shù)據(jù)為num
num = np.hstack((num1, num2))
# 使用reshape函數(shù)將其轉(zhuǎn)換為(120,1) ?
num = num.reshape((120,1)) ?#每個(gè)數(shù)據(jù)為1列
# 轉(zhuǎn)換為float32類(lèi)型?
num = np.float32(num)?
# 調(diào)用kmeans模塊?
# 設(shè)置參數(shù)criteria的值?
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)?
# 設(shè)置參數(shù)flags的值?
flags = cv2.KMEANS_RANDOM_CENTERS?
# 調(diào)用函數(shù)kmeans?
retval, bestLabels, centers = cv2.kmeans(num,2, None, criteria,10, flags)?
# 打印返回值?
print(retval)?
print(bestLabels)?
print(centers)?
# 獲取分類(lèi)結(jié)果?
n1 = num[bestLabels==0]?
n2 = num[bestLabels==1]?
? ??
# 繪制分類(lèi)結(jié)果?
# 繪制原始數(shù)據(jù)?
plt.plot(np.ones(len(n1)),n1,'ro')?
plt.plot(np.ones(len(n2)),n2,'bo')?
# 繪制中心點(diǎn)?
#plt.plot([1],centers[0],'rx')?
#plt.plot([1],centers[1],'bx')?
plt.show()?
?
例2:
有兩種物體:
- 物體1的長(zhǎng)和寬都在 [0,20] 內(nèi)
- 物體2的長(zhǎng)和寬都在[40,60] 內(nèi)
使用隨機(jī)數(shù)模擬兩種物體的長(zhǎng)度和寬度,并使用函數(shù)cv2.kmeans()對(duì)它們分類(lèi)。
根據(jù)題目要求,主要步驟如下:
- 隨機(jī)生成數(shù)據(jù),并將它們轉(zhuǎn)換為函數(shù)cv2.kmeans()可以處理的形式。
- 設(shè)置函數(shù)cv2.kmeans()的參數(shù)形式。
- 調(diào)用函數(shù)cv2.kmeans()。
- 根據(jù)函數(shù)cv2.kmeans()的返回值,確定分類(lèi)結(jié)果。
- 繪制經(jīng)過(guò)分類(lèi)的數(shù)據(jù)及中心點(diǎn),觀(guān)察分類(lèi)結(jié)果。
import numpy as np?
import cv2?
from matplotlib import pyplot as plt?
# 隨機(jī)生成兩組數(shù)值?
#長(zhǎng)和寬都在[0,20]內(nèi)?
m1 = np.random.randint(0,20, (30,2))?
#長(zhǎng)和寬的大小都在[40,60]?
m2 = np.random.randint(40,60, (30,2))?
# 組合數(shù)據(jù)?
m = np.vstack((m1, m2))?
# 轉(zhuǎn)換為float32類(lèi)型?
m = np.float32(m)?
# 調(diào)用kmeans模塊?
# 設(shè)置參數(shù)criteria值?
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)?
# 調(diào)用kmeans函數(shù)?
ret, label, center=cv2.kmeans(m,2, None, criteria,10, cv2.KMEANS_RANDOM_CENTERS)?
? ??
'''?
#打印返回值?
print(ret)?
print(label)?
print(center)?
'''?
# 根據(jù)kmeans的處理結(jié)果,將數(shù)據(jù)分類(lèi),兩大類(lèi)?
res1 = m[label.ravel()==0]?
res2 = m[label.ravel()==1]?
# 繪制分類(lèi)結(jié)果數(shù)據(jù)及中心點(diǎn)?
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:
使用函數(shù)cv2.kmeans()將灰度圖像處理為只有兩個(gè)灰度級(jí)的二值圖像。
需要對(duì)灰度圖像內(nèi)的色彩進(jìn)行分類(lèi),將所有的像素點(diǎn)劃分為兩類(lèi)。然后,用這兩類(lèi)的中心點(diǎn)像素值替代原有像素值,滿(mǎn)足題目的要求。
主要步驟如下:
圖像預(yù)處理
讀取圖像,并將圖像轉(zhuǎn)換為函數(shù)cv2.kmeans()可以處理的形式。
在讀取圖像時(shí),如果是3個(gè)通道的RGB圖像,需要將圖像的RGB值處理為一個(gè)單獨(dú)的特征值。具體實(shí)現(xiàn)時(shí),用函數(shù)cv2.reshape()完成對(duì)圖像特征值的調(diào)整。
為了滿(mǎn)足函數(shù)cv2.kmeans()的要求,需要將圖像的數(shù)據(jù)類(lèi)型轉(zhuǎn)換為numpy.float32類(lèi)型。
設(shè)置函數(shù)cv2.kmeans()的參數(shù)形式
設(shè)置參數(shù)criteria的值為“(cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)”,讓函數(shù)cv2.kmeans()在達(dá)到一定精度或者達(dá)到一定迭代次數(shù)時(shí),即停止迭代。
設(shè)置參數(shù)K的值為2,將所有像素劃分為兩類(lèi)。
調(diào)用函數(shù)cv2.kmeans()
調(diào)用函數(shù)cv2.kmeans(),得到距離值、分類(lèi)中心點(diǎn)和分類(lèi)標(biāo)簽,用于后續(xù)操作。
值替換
將像素點(diǎn)的值替換為當(dāng)前分類(lèi)的中心點(diǎn)的像素值。
顯示變換前后的圖像
分別顯示原始圖像和二值化圖像。
import numpy as np
import cv2
import matplotlib.pyplot as plt
# 讀取待處理圖像
img = cv2.imread('./img/hand2.png')
# 使用reshape將一個(gè)像素點(diǎn)的RGB值作為一個(gè)單元處理
data = img.reshape((-1,3)) # n行 3列
# 轉(zhuǎn)換為kmeans可以處理的類(lèi)型
data = np.float32(data)
# 調(diào)用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)
# 轉(zhuǎn)換為uint8數(shù)據(jù)類(lèi)型,將每個(gè)像素點(diǎn)都賦值為當(dāng)前分類(lèi)的中心點(diǎn)像素值
# 將center的值轉(zhuǎn)換為uint8
center = np.uint8(center)
# 使用center內(nèi)的值替換原像素點(diǎn)的值
res1 = center[label.flatten()] # 根據(jù)索引來(lái)取值,最后結(jié)果的大小同索引的大小
# 使用reshape調(diào)整替換后的圖像
res2 = res1.reshape((img.shape))
# 顯示處理結(jié)果
plt.subplot(121)
plt.imshow(img[:,:,::-1])
plt.axis('off')
plt.subplot(122)
plt.imshow(res2[:,:,::-1])
plt.axis('off')
plt.show()
調(diào)整程序中的K值,就能改變圖像的顯示結(jié)果。例如,K=8,則可以讓圖像顯示8個(gè)灰度級(jí)。
原文鏈接:https://blog.csdn.net/first_bug/article/details/123514692
相關(guān)推薦
- 2023-08-13 ps打開(kāi)之后切圖一段時(shí)間C盤(pán)存儲(chǔ)量變小怎么清理?
- 2022-07-20 C語(yǔ)言循環(huán)鏈表的原理與使用操作_C 語(yǔ)言
- 2023-01-11 C++入門(mén)教程之引用與指針_C 語(yǔ)言
- 2022-12-15 conda創(chuàng)建環(huán)境過(guò)程出現(xiàn)"Solving?environment:?failed"報(bào)錯(cuò)的詳細(xì)解決方
- 2022-06-24 Android實(shí)現(xiàn)按鈕點(diǎn)擊事件的三種方法總結(jié)_Android
- 2022-08-23 Python解析器Cpython的GIL解釋器鎖工作機(jī)制_python
- 2022-11-25 golang?實(shí)現(xiàn)時(shí)間滑動(dòng)窗口的示例代碼_Golang
- 2022-06-22 C語(yǔ)言詳解如何實(shí)現(xiàn)堆及堆的結(jié)構(gòu)與接口_C 語(yǔ)言
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門(mén)
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支