機器學習實驗報告5-K-means 算法

4.1 k-means算法簡介

聚類分析,作為機器學習領域中的一種無監督學習方法,在數據探索與知識發現過程中扮演著舉足輕重的角色。它能夠在沒有先驗知識或標簽信息的情況下,通過挖掘數據中的內在結構和規律,將數據對象自動劃分為多個類別或簇。每個簇內的對象具有高度的相似性,而不同簇間的對象則表現出明顯的差異性。

在眾多聚類算法中,K-means算法因其簡單高效而備受青睞。K-means算法的基本思想是:通過迭代的方式,將數據劃分為K個不同的簇,并使得每個數據點與其所屬簇的質心(或稱為中心點、均值點)之間的距離之和最小。

K-means算法的優點在于其直觀易懂、計算速度快且易于實現。然而,它也存在一些局限性,如對初始簇質心的選擇敏感、可能陷入局部最優解以及需要預先設定聚類數K等。因此,在實際應用中,我們需要根據具體的問題和數據特點來選擇合適的聚類算法,并可能需要對算法進行優化或改進以適應特定的需求。

4.2 算法的基本原理

(1)類和分類

類指的是具有相似性的集合。而分類是根據給定的已知類別的樣本,訓練出來一個模型,使該模型能夠對未知類別的樣本進行分類。故分類屬于有監督學習。有監督學習是指提前由人工對訓練數據做好了分類,訓練樣本同時包含有特征和類別信息。有監督學習類似于先學習帶有標準答案的復習題,學習到知識規律以后,再去參加考試。

(2)聚類

對于一些給定的樣本,不知道樣本之間的關系,不知道他們是否屬于同一類,也不知道到底可以分為多少類。此時,通過聚類把未知類別的數據,分為多個類別。聚類目的在于把相似的東西聚在一起,因此聚類屬于無監督學習。

(3)K-均值聚類思想

K-均值(K-Means)是發現給定數據集的K個簇的算法。簇個數K是用戶給定的,每一個簇通過其質心(即簇中所有點的中心)來描述。其核心思想是將數據集中的n個對象劃分為K個聚類,使得每個對象到其所屬聚類的中心(或稱為均值點、質心)的距離之和最小。這里所說的距離通常指的是歐氏距離,但也可以是其他類型的距離度量。通過迭代的方式不斷優化聚類結果,使得每個聚類內的對象盡可能緊密,而不同聚類間的對象則盡可能分開。

(4)算法步驟

K-means算法作為一種強大的無監督學習工具,具有簡單易懂、計算效率高和易于實現等優點在多個領域有著廣泛的應用下面我們將詳細探討K-means算法的實現步驟。K-means算法的執行過程通常包括以下個步驟

a.初始化選擇K個初始聚類中心在算法開始時,需要隨機選擇K個數據點作為初始的聚類中心。這些初始聚類中心的選擇對最終的聚類結果有一定的影響,因此在實際應用中,通常會采用一些啟發式的方法來選擇較好的初始聚類中心,如K-means++算法。

b.分配將每個數據點分配給最近的聚類中心對于數據集中的每個數據點,計算其與每個聚類中心的距離,并將其分配給距離最近的聚類中心。這一步通常使用歐氏距離作為距離度量,計算公式如下(1)。其中,x是數據點,ci是第i個聚類中心,d是數據的維度,xj和cij分別是x和ci在第j維上的值。

c.更新重新計算每個聚類的中心對于每個聚類,重新計算其聚類中心新的聚類中心是該聚類內所有數據點的均值,計算公式如下(2)。其中,Si是第i個聚類的數據點集合,|Si|是該集合中數據點的數量。

d.迭代,重復分配和更新步驟,直到滿足終止條件。重復執行分配和更新步驟,直到滿足某種終止條件。常見的終止條件包括,聚類中心不再發生顯著變化:即新的聚類中心與舊的聚類中心之間的距離小于某個預設的閾值。達到最大迭代次數:為了避免算法陷入無限循環,通常會設置一個最大迭代次數作為終止條件。在迭代過程中,算法會不斷優化聚類結果,使得每個聚類內的對象更加緊密,而不同聚類間的對象更加分散。最終,當滿足終止條件時,算法停止迭代并輸出最終的聚類結果。

4.3 算法實例

K-means算法作為一種強大的無監督學習工具,在多個領域有著廣泛的應用。本實驗以對俄勒岡州的波特蘭地區地圖上的點進行聚類為例,基于k-means算法實現將這些地方進行聚類的最佳策略,這樣就可以安排交通工具抵達這些簇的質心,然后步行到每個內地址。實例操作可分為以下五個過程。

  1. 收集數據

通過調用geoGrab函數來實現收集數據,geoGrab函數的作用是收集數據,通過調用雅虎地理編碼 API(Yahoo Geocoding API),將輸入的街道地址和城市名稱轉換為對應的地理坐標(經緯度等位置信息),返回 API 響應的 JSON 格式數據,包含地址對應的地理編碼信息(如坐標、地址匹配度等)。

相關代碼如下:

def geoGrab(stAddress, city):

????apiStem = 'http://where.yahooapis.com/geocode?' ?#create a dict and constants for the goecoder

????params = {}

????params['flags'] = 'J'#JSON return type

????params['appid'] = 'aaa0VN6k'

????params['location'] = '%s %s' % (stAddress, city)

????url_params = urllib.parse.urlencode(params)

????yahooApi = apiStem + url_params ?????#print url_params

????print (yahooApi)

????c=urllib.parse.urlopen(yahooApi)

????return json.loads(c.read())

  1. 準備數據

準備數據中,只保留經緯度信息。我們可以通過調用massPlaceFind函數。該函數其作用是批量處理地址數據,通過調用geoGrab函數獲取地理坐標(經緯度),并將結果寫入文件。該函數適用于批量處理地址數據,生成帶地理坐標的數據集,常用于地理信息系統(GIS)、數據分析或地圖可視化等場景。

相關代碼如下:

def massPlaceFind(fileName):

????fw = open('places.txt', 'w')

????for line in open(fileName).readlines():

????????line = line.strip()

????????lineArr = line.split('\t')

????????retDict = geoGrab(lineArr[1], lineArr[2])

????????if retDict['ResultSet']['Error'] == 0:

????????????lat = float(retDict['ResultSet']['Results'][0]['latitude'])

????????????lng = float(retDict['ResultSet']['Results'][0]['longitude'])

????????????print("%s\t%f\t%f" % (lineArr[0], lat, lng))

????????????fw.write('%s\t%f\t%f\n' % (line, lat, lng))

????????else: print ("error fetching")

????????sleep(1)

????fw.close()

  1. 分析數據

使用Matplotlib來構建一個二維數據圖,其中包含簇與地圖。我們通過調用clusterClubs函數來實現。clusterClubs函數,其核心功能是對地點的經緯度數據進行聚類分析,并在地圖背景上可視化聚類結果。該函數適用于地理數據的聚類分析與可視化,常用于城市規劃、商業選址、軌跡分析等場景,幫助快速識別數據中的空間分布模式。

圖1 調用函數

圖2 二維數據圖

相關代碼如下:

def clusterClubs(numClust=5):

????datList = []

????for line in open('places.txt').readlines():

????????lineArr = line.split('\t')

????????datList.append([float(lineArr[4]), float(lineArr[3])])

????datMat = matrix(datList)

????myCentroids, clustAssing = biKmeans(datMat, numClust, distMeas=distSLC)

????fig = plt.figure()

????rect=[0.1,0.1,0.8,0.8]

????scatterMarkers=['s', 'o', '^', '8', 'p', \'d', 'v', 'h', '>', '<']

????axprops = dict(xticks=[], yticks=[])

????ax0=fig.add_axes(rect, label='ax0', **axprops)

????imgP = plt.imread('Portland.png')

????ax0.imshow(imgP)

????ax1=fig.add_axes(rect, label='ax1', frameon=False)

????for i in range(numClust):

????????ptsInCurrCluster = datMat[nonzero(clustAssing[:,0].A==i)[0],:]

????????markerStyle = scatterMarkers[i % len(scatterMarkers)]

????????ax1.scatter(ptsInCurrCluster[:,0].flatten().A[0], ptsInCurrCluster[:,1].flatten().A[0], marker=markerStyle, s=90)

????ax1.scatter(myCentroids[:,0].flatten().A[0], myCentroids[:,1].flatten().A[0], marker='+', s=300)

????plt.show()

  1. 測試算法

通過調用biKmeans()函數來測試算法。該函數實現了二分K均值算法(Bisecting K-Means),用于對數據集進行聚類分析。其核心作用是通過 “逐步分裂簇” 的策略,將數據集劃分為指定數量的簇(k個)

圖3 測試算法

相關代碼如下:

def biKmeans(dataSet, k, distMeas=distEclud):

????m = shape(dataSet)[0]

????clusterAssment = matrix(zeros((m,2)))

????centroid0 = mean(dataSet, axis=0).tolist()[0]

????centList =[centroid0] #create a list with one centroid

????for j in range(m):#calc initial Error

????????clusterAssment[j,1] = distMeas(matrix(centroid0), dataSet[j,:])**2

????while (len(centList) < k):

????????lowestSSE = inf

????????for i in range(len(centList)):

????????????ptsInCurrCluster = dataSet[nonzero(clusterAssment[:,0].A==i)[0],:]#get the data points currently in cluster i

????????????centroidMat, splitClustAss = kMeans(ptsInCurrCluster, 2, distMeas)

????????????sseSplit = sum(splitClustAss[:,1])#compare the SSE to the currrent minimum

????????????sseNotSplit = sum(clusterAssment[nonzero(clusterAssment[:,0].A!=i)[0],1])

????????????print("sseSplit, and notSplit: ",sseSplit,sseNotSplit)

????????????if (sseSplit + sseNotSplit) < lowestSSE:

????????????????bestCentToSplit = i

????????????????bestNewCents = centroidMat

????????????????bestClustAss = splitClustAss.copy()

????????????????lowestSSE = sseSplit + sseNotSplit

????????bestClustAss[nonzero(bestClustAss[:,0].A == 1)[0],0] = len(centList) #change 1 to 3,4, or whatever

????????bestClustAss[nonzero(bestClustAss[:,0].A == 0)[0],0] = bestCentToSplit

????????print ('the bestCentToSplit is: ',bestCentToSplit)

????????print ('the len of bestClustAss is: ', len(bestClustAss))

????????centList[bestCentToSplit] = bestNewCents[0,:].tolist()[0]#replace a centroid with two best centroids

????????centList.append(bestNewCents[1,:].tolist()[0])

????????clusterAssment[nonzero(clusterAssment[:,0].A == bestCentToSplit)[0],:]= bestClustAss#reassign new clusters, and SSE

????return matrix(centList), clusterAssment

  1. 使用算法

我們通過使用clusterClubs函數來輸出包含簇及簇中心的地圖。clusterClubs函數,其核心功能是對地點的經緯度數據進行聚類分析,并在地圖背景上可視化聚類結果。操作過程與(3)分析數據相同。

圖4 簇及簇中心圖

相關代碼如下:

def clusterClubs(numClust=5):

????datList = []

????for line in open('places.txt').readlines():

????????lineArr = line.split('\t')

????????datList.append([float(lineArr[4]), float(lineArr[3])])

????datMat = matrix(datList)

????myCentroids, clustAssing = biKmeans(datMat, numClust, distMeas=distSLC)

????fig = plt.figure()

????rect=[0.1,0.1,0.8,0.8]

????scatterMarkers=['s', 'o', '^', '8', 'p', \

????????????????????'d', 'v', 'h', '>', '<']

????axprops = dict(xticks=[], yticks=[])

????ax0=fig.add_axes(rect, label='ax0', **axprops)

????imgP = plt.imread('Portland.png')

????ax0.imshow(imgP)

????ax1=fig.add_axes(rect, label='ax1', frameon=False)

????for i in range(numClust):

????????ptsInCurrCluster = datMat[nonzero(clustAssing[:,0].A==i)[0],:]

????????markerStyle = scatterMarkers[i % len(scatterMarkers)]

????????ax1.scatter(ptsInCurrCluster[:,0].flatten().A[0], ptsInCurrCluster[:,1].flatten().A[0], marker=markerStyle, s=90)

????ax1.scatter(myCentroids[:,0].flatten().A[0], myCentroids[:,1].flatten().A[0], marker='+', s=300)

????plt.show()

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/85235.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/85235.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/85235.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【已解決】yoloOnnx git工程部署

首先 yoloonnx一個VS工程下來整個工程大概1-2個g的大小因此在git的過程中總是會因為文件超過100M而觸發報錯&#xff0c;上傳不上去&#xff0c;因此現在需要做一個過濾才能把工程重新上傳上去&#xff0c;那么這個時候別人需要下載下來的時候確實不完整的工程&#xff0c;因此…

如何輕松地將照片從電腦傳輸到安卓手機

一些安卓用戶正在尋找有效可靠的方法&#xff0c;將照片從電腦傳輸到安卓設備。如果您也想將有趣或難忘的照片導入安卓手機或平板電腦&#xff0c;可以參考這篇文章&#xff0c;它提供了 6 種可靠的方法&#xff0c;讓您輕松傳輸照片。 第 1 部分&#xff1a;如何通過 Android …

準備純血鴻蒙理論高級認證的一些心得

最近在準備純血鴻蒙理論高級認證&#xff0c;一些心得記錄下來&#xff0c;希望早日考過高級&#xff01; 一、考試目標&#xff1a; HarmonyOS核心技術理念HarmonyOS應用架構設計ArkTS原理和實踐ArkUI開發HarmonyOS關鍵技術能力開發工程管理、代碼編輯、調試與定位應用上架運…

義烏購拍立淘API接入指南

一、接口概述 拍立淘是義烏購平臺提供的以圖搜貨服務&#xff0c;通過HTTP RESTful API實現。當前版本為v3.2&#xff0c;支持JPG/PNG格式圖片&#xff08;≤5MB&#xff09;&#xff0c;返回相似商品列表及供應鏈信息。 二、接入準備 申請開發者賬號 # 開發者注冊示例&…

Web 連接和跟蹤

大家讀完覺得有幫助記得及時關注和點贊&#xff01;&#xff01;&#xff01; 抽象 網絡跟蹤是一種普遍且不透明的做法&#xff0c;可實現個性化廣告、重新定位和轉化跟蹤。 隨著時間的推移&#xff0c;它已經演變成一個復雜的侵入性生態系統&#xff0c;采用越來越復雜的技術來…

前端技術棧與 SpreadJS 深度融合:打造高效數據表格應用

引言 在當今數字化的時代&#xff0c;數據表格應用在各種 Web 項目中扮演著至關重要的角色。從企業級的管理系統到電商平臺的商品展示&#xff0c;數據表格都是用戶與數據交互的重要界面。前端技術棧如 JavaScript、HTML 和 CSS 為構建用戶界面提供了強大的工具和方法&#xf…

如何用ai描述缺陷(bug)

附件1&#xff1a; 附件2&#xff1a; 將附件1和附件2發送給deepseek&#xff0c;且輸入對話框的文字&#xff1a; 然后進入禪道用戶登錄 - 禪道 ### **缺陷報告&#xff1a;登錄功能無響應缺陷** **提交平臺**&#xff1a;禪道缺陷管理系統 **發現環境**&#xff1a;測試環…

軟考 系統架構設計師系列知識點之雜項集萃(89)

接前一篇文章&#xff1a;軟考 系統架構設計師系列知識點之雜項集萃&#xff08;88&#xff09; 第161題 下面可提供安全電子郵件服務的是&#xff08; &#xff09;。 A. RSA B. SSL C. SET D. S/MIME 正確答案&#xff1a;D。 解析&#xff1a; MIME&#xff08;Multi…

開源 Arkts 鴻蒙應用 開發(一)工程文件分析

文章的目的為了記錄使用Arkts 進行Harmony app 開發學習的經歷。本職為嵌入式軟件開發&#xff0c;公司安排開發app&#xff0c;臨時學習&#xff0c;完成app的開發。開發流程和要點有些記憶模糊&#xff0c;趕緊記錄&#xff0c;防止忘記。 相關鏈接&#xff1a; 開源 Arkts …

protobuf遇到protoc-gen-go: unable to determine Go import path for “xxx“

問題 這個錯誤是因為 .proto 文件中缺少必需的 go_package 選項。在 protobuf 生成 Go 代碼時&#xff0c;這是關鍵配置項。 pandaVM:~/dev/pb$ protoc --go_out. pb.proto protoc-gen-go: unable to determine Go import path for "pb.proto"Please specify eithe…

linux unix socket 通信demo

好&#xff0c;下面是已經整合完善的版本&#xff1a; ? 功能點&#xff08;你要求的全部實現了&#xff09;&#xff1a; Unix Domain Socket (SOCK_STREAM) 服務端先啟動&#xff1a;正常通信 客戶端先啟動&#xff1a;等待服務端直到連接成功 客戶端每秒發送一條消息 服務端…

近期GitHub熱榜推薦

【1】fluentui-system-icons (HTML) &#x1f468;?&#x1f4bb; 作者&#xff1a; microsoft &#x1f4e6; 倉庫&#xff1a; microsoft / fluentui-system-icons &#x1f310; 鏈接&#xff1a; https://github.com/microsoft/fluentui-system-icons ? 星標&#xf…

Jupyter 是什么?基于瀏覽器的交互式計算環境

&#x1f9e0; 一、Jupyter 是什么&#xff1f; Jupyter 是一個基于瀏覽器的交互式計算環境&#xff0c;名字取自Julia Python R 三種語言&#xff0c;但現在已支持超過40種編程語言。它最核心的功能是讓你在同一個文檔&#xff08;.ipynb 文件&#xff09;中混合編寫代碼、…

CTF解題:[NSSCTF 2022 Spring Recruit]弱類型比較繞過

一、漏洞背景介紹 在 CTF&#xff08;Capture The Flag&#xff09;競賽和 Web 安全測試中&#xff0c;PHP 語言的類型比較漏洞是常見的考點。這類漏洞源于 PHP 的弱類型特性&#xff0c;即當使用進行比較時&#xff0c;PHP 會自動進行類型轉換&#xff0c;從而導致一些不符合…

【SQL】存儲過程 vs 普通 SQL

一、存儲過程 vs 普通 SQL 的核心區別 先明確兩者的本質&#xff1a; 普通 SQL&#xff1a;是直接執行的查詢 / 操作語句&#xff08;如SELECT、INSERT&#xff09;&#xff0c;每次執行都要編譯&#xff0c;邏輯寫在應用端或直接運行。存儲過程&#xff1a;是預編譯并存儲在…

Vue.js第一節

初識Vue、插值操作、屬性綁定 初識&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>D…

前端打斷點

這個按鈕有個點擊事件&#xff0c;然后點擊這個js 即可進入到代碼中 如果這時想打一些臨時的表達式&#xff0c;可以按esc彈出console控制臺&#xff0c; 右上角有可以使用的變量

Jmeter接口測試與性能測試

&#x1f345; 點擊文末小卡片 &#xff0c;免費獲取軟件測試全套資料&#xff0c;資料在手&#xff0c;漲薪更快 目前最新版本發展到5.0版本&#xff0c;需要Java7以上版本環境&#xff0c;下載解壓目錄后&#xff0c;進入\apache-jmeter-5.0\bin\&#xff0c;雙擊ApacheJMete…

如何利用大模型搭建本地知識庫

要利用大模型搭建本地知識庫&#xff0c;核心在于&#xff1a;構建高質量知識內容源、使用向量化技術實現語義檢索、部署大語言模型以實現自然語言問答接口、設計本地知識庫的數據更新機制、注重隱私與合規性控制。其中&#xff0c;使用向量化技術實現語義檢索至關重要&#xf…

vscode連接不上服務器問題修復

原因&#xff1a;運維人員修復漏洞&#xff0c;升級了服務器openssh版本&#xff0c;導致無法新建連接連上vscode 操作&#xff1a; 1.刪除云桌面上C:\Users\.ssh 路徑下known_hosts文件&#xff1b; 2.設置免密登錄 1&#xff09;執行 ssh-keygen -t rsa -C "your_em…