python機器學習實戰(zhàn)之K均值聚類
更新時間:2017年12月20日 13:39:53 作者:大牙灣
這篇文章主要為大家詳細介紹了python機器學習實戰(zhàn)之K均值聚類,具有一定的參考價值,感興趣的小伙伴們可以參考一下
本文實例為大家分享了python K均值聚類的具體代碼,供大家參考,具體內(nèi)容如下
#-*- coding:utf-8 -*-
#!/usr/bin/python
'''''
k Means K均值聚類
'''
# 測試
# K均值聚類 import kMeans as KM KM.kMeansTest()
# 二分K均值聚類 import kMeans as KM KM.biKMeansTest()
# 地理位置 二分K均值聚類 import kMeans as KM KM.clusterClubs()
from numpy import *
# 導入數(shù)據(jù)集
def loadDataSet(fileName): #
dataMat = [] #
fr = open(fileName)
for line in fr.readlines(): # 每一行
curLine = line.strip().split('\t')# 按 Tab鍵 分割成 列表
fltLine = map(float,curLine) # 映射成 浮點型
dataMat.append(fltLine) # 放入數(shù)據(jù)集里
return dataMat
# 計算歐幾里的距離
def distEclud(vecA, vecB):
return sqrt(sum(power(vecA - vecB, 2))) #la.norm(vecA-vecB)
# 初始構建質(zhì)心(隨機) 數(shù)據(jù)集 質(zhì)心個數(shù)
def randCent(dataSet, k):
n = shape(dataSet)[1] # 樣本特征維度
centroids = mat(zeros((k,n))) # 初始化 k個 質(zhì)心
for j in range(n): # 每種樣本特征
minJ = min(dataSet[:,j]) # 每種樣本特征最小值 需要轉換成 numpy 的mat
rangeJ = float(max(dataSet[:,j]) - minJ)#每種樣本特征的幅值范圍
centroids[:,j] = mat(minJ + rangeJ * random.rand(k,1))
# 在每種樣本的最大值和最小值間隨機生成K個樣本特征值
return centroids
# 簡單k均值聚類算法
# 數(shù)據(jù)集 中心數(shù)量 距離算法 初始聚類中心算法
def kMeans(dataSet, k, distMeas=distEclud, createCent=randCent):
m = shape(dataSet)[0] # 樣本個數(shù)
clusterAssment = mat(zeros((m,2)))# 樣本標記 分配結果 第一列索引 第二列誤差
centroids = createCent(dataSet, k)# 初始聚類中心
clusterChanged = True# 設置質(zhì)心是否仍然發(fā)送變化
while clusterChanged:
clusterChanged = False
for i in range(m): #對每個樣本 計算最近的中心
# 更新 樣本所屬關系
minDist = inf; minIndex = -1 # 距離變量 以及 最近的中心索引
for j in range(k): # 對每個中心
distJI = distMeas(centroids[j,:],dataSet[i,:])# 計算距離
if distJI < minDist:
minDist = distJI; minIndex = j# 得到最近的 中心 索引
if clusterAssment[i,0] != minIndex: clusterChanged = True
# 所屬索引發(fā)生了變化 即質(zhì)心還在變化,還可以優(yōu)化
clusterAssment[i,:] = minIndex,minDist**2 # 保存 所屬索引 以及距離平方 用以計算誤差平方和 SSE
# 更新質(zhì)心
print centroids # 每次迭代打印質(zhì)心
for cent in range(k):#
ptsInClust = dataSet[nonzero(clusterAssment[:,0].A==cent)[0]]# 數(shù)組過濾 得到各個中心所屬的樣本
centroids[cent,:] = mean(ptsInClust, axis=0) # 按列求平均 得到新的中心
return centroids, clusterAssment# 返回質(zhì)心 和各個樣本分配結果
def kMeansTest(k=5):
MyDatMat = mat(loadDataSet("testSet.txt"))
MyCenters, ClustAssing = kMeans(MyDatMat, k)
# bisecting K-means 二分K均值算法 克服局部最優(yōu)值
def biKmeans(dataSet, k, distMeas=distEclud):
m = shape(dataSet)[0] # 樣本個數(shù)
clusterAssment = mat(zeros((m,2)))# 樣本標記 分配結果 第一列索引 第二列誤差
centroid0 = mean(dataSet, axis=0).tolist()[0]# 創(chuàng)建一個初始質(zhì)心
centList =[centroid0] # 一個中心的 列表
for j in range(m): # 計算初始誤差
clusterAssment[j,1] = distMeas(mat(centroid0), dataSet[j,:])**2#每個樣本與中心的距離平方
while (len(centList) < k):# 中心數(shù)倆個未達到指定中心數(shù)量 繼續(xù)迭代
lowestSSE = inf # 最小的 誤差平方和 SSE
for i in range(len(centList)):# 對于每一個中心
ptsInCurrCluster = dataSet[nonzero(clusterAssment[:,0].A==i)[0],:] # 處于當前中心的樣本點
centroidMat, splitClustAss = kMeans(ptsInCurrCluster, 2, distMeas) # 對此中心內(nèi)的點進行二分類
# 該樣本中心 二分類之后的 誤差平方和 SSE
sseSplit = sum(splitClustAss[:,1])
# 其他未劃分數(shù)據(jù)集的誤差平方和 SSE
sseNotSplit = sum(clusterAssment[nonzero(clusterAssment[:,0].A!=i)[0],1])
print "sseSplit, and notSplit: ",sseSplit,sseNotSplit
# 劃分后的誤差和沒有進行劃分的數(shù)據(jù)集的誤差為本次誤差
if (sseSplit + sseNotSplit) < lowestSSE: # 小于上次 的 誤差
bestCentToSplit = i # 記錄應該被劃分的中心 的索引
bestNewCents = centroidMat # 最好的新劃分出來的中心
bestClustAss = splitClustAss.copy()# 新中心 對于的 劃分記錄 索引(0或1)以及 誤差平方
lowestSSE = sseSplit + sseNotSplit # 更新總的 誤差平方和
# 記錄中心 劃分 數(shù)據(jù)
bestClustAss[nonzero(bestClustAss[:,0].A == 1)[0],0] = len(centList) # 現(xiàn)有中心數(shù)量
bestClustAss[nonzero(bestClustAss[:,0].A == 0)[0],0] = bestCentToSplit# 最應該被劃分的中心
print 'the bestCentToSplit is: ',bestCentToSplit
print 'the len of bestClustAss is: ', len(bestClustAss)
# 將最應該被劃分的中心 替換為 劃分后的 兩個 中心(一個替換,另一個 append在最后添加)
centList[bestCentToSplit] = bestNewCents[0,:].tolist()[0]# 替換
centList.append(bestNewCents[1,:].tolist()[0]) # 添加
# 更新 樣本標記 分配結果 替換 被劃分中心的記錄
clusterAssment[nonzero(clusterAssment[:,0].A == bestCentToSplit)[0],:]= bestClustAss
return mat(centList), clusterAssment
def biKMeansTest(k=5):
MyDatMat = mat(loadDataSet("testSet.txt"))
MyCenters, ClustAssing = biKmeans(MyDatMat, k)
####位置數(shù)據(jù)聚類測試#####
# 利用雅虎的服務器將地址轉換為 經(jīng)度和緯度
import urllib
import json
def geoGrab(stAddress, city):
apiStem = 'http://where.yahooapis.com/geocode?' #
params = {}
params['flags'] = 'J' # 設置返回類型為JSON字符串
params['appid'] = 'aaa0VN6k' # 注冊 帳號后獲得 http://developer.yahoo.com
params['location'] = '%s %s' % (stAddress, city) # 位置信息
url_params = urllib.urlencode(params)# 將字典轉換成可以通過URL進行傳遞的字符串格式
yahooApi = apiStem + url_params # 加入網(wǎng)絡地址
print yahooApi # 打印 URL
c=urllib.urlopen(yahooApi) # 打開 URL
return json.loads(c.read()) # 讀取返回的jason字符串 對位置進行了編碼 得到經(jīng)度和緯度
from time import sleep
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']) #經(jīng)度
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)#延遲1s
fw.close()
# 返回地球表面兩點之間的距離 單位英里 輸入經(jīng)緯度(度) 球面余弦定理
def distSLC(vecA, vecB):#Spherical Law of Cosines
a = sin(vecA[0,1]*pi/180) * sin(vecB[0,1]*pi/180)
b = cos(vecA[0,1]*pi/180) * cos(vecB[0,1]*pi/180) * \
cos(pi * (vecB[0,0]-vecA[0,0]) /180)
return arccos(a + b)*6371.0 #pi in numpy
# 位置聚類測試 畫圖可視化顯示
import matplotlib
import matplotlib.pyplot as plt
def clusterClubs(numClust=5):
datList = [] # 樣本
for line in open('places.txt').readlines():
lineArr = line.split('\t')
datList.append([float(lineArr[4]), float(lineArr[3])])# 保存經(jīng)緯度
datMat = mat(datList)# 數(shù)據(jù)集 numpy的mat類型
# 進行二分K均值算法聚類
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()# 顯示
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Python實現(xiàn)識別圖片內(nèi)容的方法分析
這篇文章主要介紹了Python實現(xiàn)識別圖片內(nèi)容的方法,結合實例形式分析了tesseract模塊的下載、安裝配置及使用tesseract模塊進行圖片識別的相關操作技巧,需要的朋友可以參考下2018-07-07
python讀取.mat文件的數(shù)據(jù)及實例代碼
這篇文章主要介紹了python讀取.mat文件的數(shù)據(jù)的方法,本文給大家介紹的非常詳細,具有一定的參考借鑒價值 ,需要的朋友可以參考下2019-07-07
Anaconda中Python虛擬環(huán)境的創(chuàng)建使用與刪除方法詳解
這篇文章主要為大家介紹了在Anaconda環(huán)境下,創(chuàng)建、使用與刪除Python虛擬環(huán)境的方法,具有一定的借鑒價值,需要的小伙伴可以跟隨小編一起了解一下2023-08-08
python執(zhí)行系統(tǒng)命令后獲取返回值的幾種方式集合
今天小編就為大家分享一篇python執(zhí)行系統(tǒng)命令后獲取返回值的幾種方式集合,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-05-05

