python-knn(簡版理解)

來自機器學習實戰一書代碼。

# !/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))
發佈了67 篇原創文章 · 獲贊 128 · 訪問量 54萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章