來自機器學習實戰一書代碼。
# !/usr/bin/python
# -*- coding: utf-8 -*-
import numpy as np
import operator
def creatDataSet():
group = np.array([[1.0, 1.1], [1.0, 1.0], [0,0], [0,0.1]])
labels = ['A','A','B','B']
return group, labels
def classify0(inX, dataSet, labels, k):
"""
# 作用:判斷某一數據集最近(歐氏距離)的k個點的類別數目,通過多數表決決定輸入Inx的類別
# Args:inX : 進行判斷的數據,矩陣格式,1行
# dataSet: 訓練集
# labels:訓練集標籤
# k:最近的k個點
# return: 投票數目最多的類別
"""
dataSetSize = dataSet.shape[0] # shape 返還行長度,列長度 類似於R的dim
diffMat = np.tile(inX, (dataSetSize,1)) - dataSet # tile 類似 rep操作, 代碼 (x0-x1),(y0-y1)
sqDiffMat = diffMat ** 2 # 開方 (x0-x1)^2,(y0-y1)^2
sqDistances = sqDiffMat.sum(axis = 1) # 按行求和 (x0-x1)^2+(y0-y1)^2
distances = sqDistances ** 0.5 # 開根號 sqrt((x0-x1)^2+(y0-y1)^2) # 求歐式距離
sorteDistIndicies = distances.argsort() # 類似於order操作 返還排序後的下標
classCount = {} # 變量聲明 dist格式
for i in range(k): # 最近K個點的類別結果
voteIlabel = labels[sorteDistIndicies[i]]
classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1
sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True) # 多數表決
return sortedClassCount[0][0] # 返還投票最多的類別
def file2matrix(filename):
"""
# 作用:txt數據讀取
# Args:filename:讀取數據的名字,目錄名以'/'分隔
# return: returnMat:矩陣格式,讀取的數據
# classLabelVector:list格式,數據標籤
"""
fr = open(filename)
arrayOLines = fr.readlines()
numberOfLines = len(arrayOLines) # 獲取 list 長度
returnMat = np.zeros((numberOfLines, 3)) # 預分配內存,原始數據有 arrayOLines行,3列
classLabelVector = [] # 變量聲明 list格式
index = 0
for line in arrayOLines: # 循環list, 類似lapply,對每一個list進行操作
line = line.strip() # 截取回車字符
listFromLine = line.split('\t') # 分隔符
returnMat[index,:] = listFromLine[0:3] # 按行賦值
classLabelVector.append(int(listFromLine[-1])) # append添加行,listFromLine[-1],-指的是倒數,與R語言的刪除意思不同
index += 1 # i++
return returnMat, classLabelVector
def autoNorm(dataSet):
"""
# 作用:最大最小值-標準化數據
# Args: dataSet:矩陣格式,進行標準化的數據
# return: normDataSet: 矩陣格式,標準化後的dataSet
# ranges:每列 max - min
# minVals:每列 min
"""
minVals = dataSet.min(0) # 獲取每列最小值
maxVals = dataSet.max(0) # 獲取每列最大值
ranges = maxVals - minVals # 分母 max - min
normDataSet = np.zeros(np.shape(dataSet)) # 預分配內存,生成全爲0的矩陣
m = dataSet.shape[0] # 獲取行長度
normDataSet = dataSet - np.tile(minVals, (m, 1)) # 分子: x - min
normDataSet = normDataSet/np.tile(ranges, (m, 1)) # 分子/分母
return normDataSet, ranges, minVals
# 測試
import knn
hoRatio = 0.1 # 設置測試集比例
datingDataMat, datingLabels = knn.file2matrix('Data/datingTestSet2.txt') # 數據集讀取
normMat, ranges, minVals = knn.autoNorm(datingDataMat) # 標準化數據
m = normMat.shape[0]
numTestVecs = int(m * hoRatio) # 測試集長度
errorCount = 0.0
classifierResultAll = [] # 變量聲明,list格式
for i in range(numTestVecs):
classifierResult = knn.classify0(normMat[i, :], normMat[numTestVecs:m, :], datingLabels[numTestVecs:m], 3)
classifierResultAll.append(classifierResult)
print "the classifier came back with :%d, the real answer is : %d" % (classifierResult, datingLabels[i])
if( classifierResult != datingLabels[i]):
errorCount += 1
print "the total error rate is : %f" % (errorCount / float(numTestVecs))