分类方法代码及注释
# 分类方法代码及注释
#inx 要分类的向量, dataset 数据集, labels 数据集分类, k 取最接近的前k个分类
def classify0(inx, dataSet, labels, k):
# 获取数据集行数
dataSetSize = dataSet.shape[0]
# 复制输入向量,使其与数据集具有相同行数,做矩阵减法
# 此处tile函数把inx向量复制 dataSetSize 行、1列,使之可以与数据集做矩阵减法
# https://blog.csdn.net/cszhang570221322/article/details/85107935
diffMat = tile(inx, (dataSetSize, 1)) - dataSet
# 矩阵求平方
sqDiffMat = diffMat**2
# 每行相加
# https://blog.csdn.net/laobai1015/article/details/85720875
sqDistance = sqDiffMat.sum(axis=1)
# 取平方根
distances = sqDistance ** 0.5
# 取排序下标
# argsort 方法举例
# x=np.array([1,4,3,-1,6,9])
# 0 1 2 3 4 5
# 3 2 3 1 4 5
# x.argsort()
# [3,0,2,1,4,5]
sortedDistIndicies = distances.argsort()
# 声明字典
classCount = {}
for i in range(k):
# 获取对应的目标变量
voteIlable = labels[sortedDistIndicies[i]]
# 目标变量存入字典
classCount[voteIlable] = classCount.get(voteIlable, 0) + 1
# 根据目标变量出现频率倒序
# 参数1 为排序的数据,参数 2 为用于比较大小的字段,参数3 表示是否倒序
sortedClassCount = sorted(classCount.items(), key = operator.itemgetter(1), reverse = True)
return sortedClassCount
读取文件内容转换为矩阵方法
# 读取文件中的数据,转换为训练集
def file2matrix(filename):
fr = open(filename)
arrayOline = fr.readlines()
numberOfLines = len(arrayOline)
# 创建 numberOfLines 行 3 列的局长
returnMat = zeros((numberOfLines, 3))
classLabelVector = []
index = 0
for line in arrayOline:
# 行字符串去除前后空格
line = line.strip()
# 以table空格截取字符串
listFormLine = line.split('\t')
# 把解析后数组的前三项赋值给矩阵
returnMat[index, :] = listFormLine[0:3]
# 取解析后数组的最后一项 赋值给目标值
classLabelVector.append(int(listFormLine[-1]))
index += 1
return returnMat, classLabelVector
利用matplotlib绘制散点图方法
# 创建散点图
# datingDataMat 矩阵, datingLabels 特征值, x1 x2 绘图所取的 矩阵列数据,
def showDot(datingDataMat, datingLabels, x1, x2):
# 创建画布
# num 散点图名称
# figsize 画布宽 8 英寸长,高 8 英寸
# dpi参数指定绘图对象的分辨率,即每英寸多少个像素,缺省值为80
# facecolor 背景颜色
# edgecolor 边框颜色
# frameon 是否显示边框
fig = plt.figure(num='约会对象分类散点图', figsize = [8, 8], dpi = 80)
# 将画布分割成1行1列,图像画在从左到右从上到下的第1块
# fig.add_subplot(349) 的含义
# ----
# ----
# +---
# 其中 “+” 所在的位置为绘图位置
ax = fig.add_subplot(111)
# x、y 点的位置
# s 点的大小
# c 点的颜色
ax.scatter(x = datingDataMat[:, x1], y = datingDataMat[:, x2], s = 15.0*array(datingLabels), c = 150.0*array(datingLabels))
plt.show()
数据归一化方法
# 归一化,规范特征值,防之过大值影响计算结果
def autoNorm(dataSet):
# 获取矩阵每一列最小值
# eg: a = np.array([[1,1,3],[2,0,4],[3,5,1]])
# dataSet.min() 获取矩阵所有元素最小值: 0
# dataSet.min(0) 获取矩阵每一列最小值: [1,0,1]
# dataSet.min(1) 获取矩阵每一行最小值: [1,0,1]
minVals = dataSet.min(0)
# 同上
maxVals = dataSet.max(0)
# 矩阵减法获取最大最小值范围
ranges = maxVals - minVals
# shape 函数获取矩阵 形状,比如 3 行 4 列 矩阵结果为 (3, 4)
# zeros 函数获取跟dataSet同形状的0维数组
# np.zeros(np.shape(a)) 结果为 [[0,0,0],[0,0,0],[0,0,0]]
normDataSet = zeros(shape(dataSet))
# a = np.array([[1,1,3],[2,0,4],[3,5,1],[4,5,6]])
# a.shape[0] = 4 行数
# a.shape[1] = 4 列数
m = dataSet.shape[0]
# 归一算法 (old - min) / (max - min)
# tile(minVals, (m, 1)) 把最小值 向量复制 m 行 1 列
normDataSet = dataSet - tile(minVals, (m, 1))
# tile(ranges, (m, 1)) 把最大值 向量复制 m 行 1 列
normDataSet = normDataSet / tile(ranges, (m, 1))
return normDataSet, ranges, minVals
约会数据分类测试
# 约会数据分类测试
def datingClassTest():
hoRatio = 0.10
# 从 datingTestSet2 文件中获取矩阵和目标值
datingDataMat, datingLabels = file2matrix('datingTestSet2.txt')
# 归一化
normMat, ranges, minVals = autoNorm(datingDataMat)
# 行数
m = normMat.shape[0]
# 列数
n = normMat.shape[1]
# 获取10%的数据
numTestVecs = int(m * hoRatio)
errorCount = 0.0
# 遍历计算每条数据
for i in range(numTestVecs):
# eg: nmArr = np.array([[1,2,3],
# [4,5,6],
# [7,8,9],
# [10,11,12]])
# X[i,j] 取矩阵X的第i行第j列的元素 nmArr[2,2] = 9
# X[-1, -1]为数组X中位于最后一行,最后一列的元素
# X[:,j] 从第0行开始到最后一行结束,取矩阵X的第 i 列的元素 nmArr[:,1] = [2,5,8,11]
# X[a:, j]---->从第 a 行开始到最后一行结束,取矩阵X的第 j 列的元素 nmArr[1:,1] = [5,8,11]
# X[:b, j]---->从第 0 行开始到第b-1行结束,取矩阵X的第 j 列的元素 nmArr[:2,1] = [2,5]
# X[a:b, j]---->从第 a 行开始到第b-1行结束,取矩阵X的第 j 列的元素 nmArr[1:2,1] = [5]
# X[:, i:j]---->从第0行开始到最后一行结束,取矩阵X的第 i 列到 j-1 列的元素 nmArr[:,1:3] = [[2,3],[5,6],[8,9],[11,12]]
# X[:, i:j]---->从第0行开始到最后一行结束,取矩阵X的第 i 列到 j-1 列的元素 nmArr[1:,1:3] = [[5,6],[8,9],[11,12]]
classifierResult = classify0(normMat[i, :], normMat[numTestVecs:m, :], datingLabels[numTestVecs:m], 3)
# 获取分类结果
resultLabel = classifierResult[0][0]
print ("the classifer came back with: %d, the real anwser is: %d" % (resultLabel, datingLabels[i]))
if (resultLabel != datingLabels[i]):
print(" %d X", (i))
errorCount += 1.0
print ("the total error rate is %f" % (errorCount / float(numTestVecs)))
约会对象分类
# 约会对象分类
def classifyPerson():
resultList = ['not at all', 'in small doses', 'in large doses']
# input('XXX') 为输入提示信息
# float(input('XXX')) 把输入的信息 转换为float
ffMiles = float(input("frequent flier miles eaarned per year?"))
percentTags = float(input("percentage of time spent playing video games?"))
iceCream = float(input("liters of ice cream consumed per year?"))
datingDataMat, datingLabels = file2matrix('datingTestSet2.txt')
normMat, ranges, minVals = autoNorm(datingDataMat)
# 输入转换为计算向量
inArr = array([ffMiles, percentTags, iceCream])
# 输入向量 先归一,然后分类
classifierResult = classify0((inArr - minVals) / ranges, normMat, datingLabels, 3)
# 获取分类结果
resultMark = classifierResult[0][0]
print ("You will probably like this person: %s" % (resultList[resultMark - 1]))
图片文件转换为向量
# 图片文件转换成向量
def img2vector(filename):
returnVect = zeros((1, 1024))
fr = open(filename)
for i in range(32):
lineStr = fr.readline()
for j in range(32):
returnVect[0, 32 * i + j] = int(lineStr[j])
return returnVect
手写输入测试
# 手写数字测试
def handwritingClassTest():
hwLabels = []
# 从文件夹加载文件列表
trainingFileList = listdir('machinelearninginaction/Ch02/trainingDigits')
# 获取文件数量
m = len(trainingFileList)
# 创建训练矩阵
trainingMat = zeros((m, 1024))
for i in range(m):
fileNameStr = trainingFileList[i]
fileStr = fileNameStr.split('.')[0]
classNumStr = int(fileStr.split('_')[0])
# 收集目标向量
hwLabels.append(classNumStr)
# 训练举证赋值
trainingMat[i, :] = img2vector('machinelearninginaction/Ch02/trainingDigits/%s' % fileNameStr)
# 加载测试文件
testFileList = listdir('machinelearninginaction/Ch02/testDigits')
errorCount = 0.0
mTest = len(testFileList)
# 循环分类测试文件
for i in range(mTest):
fileNameStr = testFileList[i]
fileStr = fileNameStr.split('.')[0]
# 图片手写值
classNumStr = int(fileStr.split('_')[0])
vectorUnderTest = img2vector('machinelearninginaction/Ch02/testDigits/%s' % fileNameStr)
# 分类结果
classifierResult = classify0(vectorUnderTest, trainingMat, hwLabels, 3)[0][0]
print("the classifier came back with: %d, the real answer is: %d" % (classifierResult, classNumStr))
if(classifierResult != classNumStr):
errorCount += 1.0
print("the total number of errors is: %d" % errorCount)
print("the total error rate is: %f" % (errorCount/float(mTest)))
网友评论