本人是一名数学系研究生,于2017年底第一次接触python和机器学习,作为一名新手,欢迎与大家交流。
我主要给大家讲解代码,理论部分给大家推荐3本书:
《机器学习实战中文版》
《机器学习》周志华
《统计学习方法》李航
以上3本书,第一本是基于python2的代码实现;剩余两本主要作为第一本书理论省略部分的补充,理论大部分都讲得很细。
博客上关于机器学习实战理论解释都很多,参差不齐,好作品也大都借鉴了以上3本书,网上有很多电子版的书。
与其看看一些没用的博客,真心不如以上3本书有收获。
说实话,学习一定要静下心来,切忌浮躁。不懂可以每天看一点,每天你懂一点,天天积累就多了。
操作系统:windows8.1
python版本:python3.6
运行环境:spyder(anaconda)
# -*- coding: utf-8 -*-
"""
Created on Fri Mar 23 17:33:41 2018
@author: Loulch C.C
"""
"""
K-均值聚类算法伪代码:
创建k个点作为起始质心(通常随机选择)
当任意一个点的簇分配结果发生改变时:
对数据集中的每个点:
对每个质心:
计算质心与数据点之间的距离
将数据点分配到距离其最近的簇
对每一个簇,计算簇中所有点的均值并将均值作为质心。
"""
from numpy import *
import matplotlib.pyplot as plt
def loadDataSet(fileName):
dataMat = []
fr = open(fileName)
for line in fr.readlines():
curLine = line.strip().split('\t')
fltLine = list(map(float,curLine)) #这里和书中不同 和上一章一样修改
dataMat.append(fltLine)
return dataMat
def distEclud(vecA,vecB):
return sqrt(sum(power(vecA - vecB, 2))) #向量AB的欧式距离
def randCent(dataSet, k):
"""
函数说明:为给定数据集建立一个包含k个随机质心的集合
"""
n = shape(dataSet)[1]
centroids = mat(zeros((k,n))) #初始化质心矩阵
for j in range(n):
minJ = min(dataSet[:,j])
rangeJ = float(max(dataSet[:,j]) - minJ)
centroids[:,j] = mat(minJ + rangeJ * random.rand(k,1))
"""
numpy中有一些常用的用来产生随机数的函数,randn()和rand()就属于这其中。
numpy.random.randn(d0, d1, …, dn)是从标准正态分布中返回一个或多个样本值。
numpy.random.rand(d0, d1, …, dn)的随机样本位于[0, 1)中。
"""
#random.rand(k,1)会生成一个k行1列值在[0,1)间的array
#保证随机质心的生成在min和max之间,不能超过整个数据的边界
return centroids
"""
if __name__=='__main__':
dataMat=mat(loadDataSet('testSet.txt'))
print('第一列最小值:',min(dataMat[:,0]))
print('第二列最小值:',min(dataMat[:,1]))
print('第一列最大值:',max(dataMat[:,0]))
print('第二列最大值:',max(dataMat[:,1]))
print('质心矩阵:',randCent(dataMat, 2))
print('欧氏距离:',distEclud(dataMat[0],dataMat[1]))
#"""
#K-均值算法:
def kMeans(dataSet,k,distMeas=distEclud,createCent=randCent):
#参数:dataset,num of cluster,distance func,initCen
m=shape(dataSet)[0]
clusterAssment=mat(zeros((m,2)))
#创建一个矩阵clusterAssment来储存每个点的簇分配结果,第一列记录索引值,第二列储存误差
#这里的误差是指当前点到簇质心,该误差用来评价聚类的效果
centroids=createCent(dataSet,k)
clusterChanged=True
###############################更新质心的大循环#############################
while clusterChanged:
clusterChanged=False
for i in range(m): #遍历m个样本点
minDist = inf;minIndex = -1
for j in range(k): #遍历k个质心,找到最近的质心
distJI=distMeas(centroids[j,:],dataSet[i,:]) #计算样本点i和质点j的欧氏距离
if distJI', '<']#创建不同标记图案
axprops = dict(xticks=[], yticks=[])
ax0=fig.add_axes(rect, label='ax0', **axprops)
imgP = plt.imread('Portland.png') #imread()基于图创建矩阵
ax0.imshow(imgP) #imshow()绘制该矩阵
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()
"""
if __name__=='__main__':
clusterClubs()
#"""