99999久久久久久亚洲,欧美人与禽猛交狂配,高清日韩av在线影院,一个人在线高清免费观看,啦啦啦在线视频免费观看www

熱線電話:13121318867

登錄
首頁(yè)精彩閱讀機(jī)器學(xué)習(xí)算法與Python實(shí)踐之(一)k近鄰(KNN)
機(jī)器學(xué)習(xí)算法與Python實(shí)踐之(一)k近鄰(KNN)
2017-03-26
收藏

機(jī)器學(xué)習(xí)算法與Python實(shí)踐之(一)k近鄰(KNN

一、kNN算法分析

K最近鄰(k-Nearest Neighbor,KNN)分類算法可以說(shuō)是最簡(jiǎn)單的機(jī)器學(xué)習(xí)算法了。它采用測(cè)量不同特征值之間的距離方法進(jìn)行分類。它的思想很簡(jiǎn)單:如果一個(gè)樣本在特征空間中的k個(gè)最相似(即特征空間中最鄰近)的樣本中的大多數(shù)屬于某一個(gè)類別,則該樣本也屬于這個(gè)類別。

        比如上面這個(gè)圖,我們有兩類數(shù)據(jù),分別是藍(lán)色方塊和紅色三角形,他們分布在一個(gè)上圖的二維中間中。那么假如我們有一個(gè)綠色圓圈這個(gè)數(shù)據(jù),需要判斷這個(gè)數(shù)據(jù)是屬于藍(lán)色方塊這一類,還是與紅色三角形同類。怎么做呢?我們先把離這個(gè)綠色圓圈最近的幾個(gè)點(diǎn)找到,因?yàn)槲覀冇X得離綠色圓圈最近的才對(duì)它的類別有判斷的幫助。那到底要用多少個(gè)來(lái)判斷呢?這個(gè)個(gè)數(shù)就是k了。如果k=3,就表示我們選擇離綠色圓圈最近的3個(gè)點(diǎn)來(lái)判斷,由于紅色三角形所占比例為2/3,所以我們認(rèn)為綠色圓是和紅色三角形同類。如果k=5,由于藍(lán)色四方形比例為3/5,因此綠色圓被賦予藍(lán)色四方形類。從這里可以看到,k的值還是很重要的。

       KNN算法中,所選擇的鄰居都是已經(jīng)正確分類的對(duì)象。該方法在定類決策上只依據(jù)最鄰近的一個(gè)或者幾個(gè)樣本的類別來(lái)決定待分樣本所屬的類別。由于KNN方法主要靠周圍有限的鄰近的樣本,而不是靠判別類域的方法來(lái)確定所屬類別的,因此對(duì)于類域的交叉或重疊較多的待分樣本集來(lái)說(shuō),KNN方法較其他方法更為適合。

       該算法在分類時(shí)有個(gè)主要的不足是,當(dāng)樣本不平衡時(shí),如一個(gè)類的樣本容量很大,而其他類樣本容量很小時(shí),有可能導(dǎo)致當(dāng)輸入一個(gè)新樣本時(shí),該樣本的K個(gè)鄰居中大容量類的樣本占多數(shù)。因此可以采用權(quán)值的方法(和該樣本距離小的鄰居權(quán)值大)來(lái)改進(jìn)。該方法的另一個(gè)不足之處是計(jì)算量較大,因?yàn)閷?duì)每一個(gè)待分類的文本都要計(jì)算它到全體已知樣本的距離,才能求得它的K個(gè)最近鄰點(diǎn)。目前常用的解決方法是事先對(duì)已知樣本點(diǎn)進(jìn)行剪輯,事先去除對(duì)分類作用不大的樣本。該算法比較適用于樣本容量比較大的類域的自動(dòng)分類,而那些樣本容量較小的類域采用這種算法比較容易產(chǎn)生誤分[參考機(jī)器學(xué)習(xí)十大算法]。
       總的來(lái)說(shuō)就是我們已經(jīng)存在了一個(gè)帶標(biāo)簽的數(shù)據(jù)庫(kù),然后輸入沒(méi)有標(biāo)簽的新數(shù)據(jù)后,將新數(shù)據(jù)的每個(gè)特征與樣本集中數(shù)據(jù)對(duì)應(yīng)的特征進(jìn)行比較,然后算法提取樣本集中特征最相似(最近鄰)的分類標(biāo)簽。一般來(lái)說(shuō),只選擇樣本數(shù)據(jù)庫(kù)中前k個(gè)最相似的數(shù)據(jù)。最后,選擇k個(gè)最相似數(shù)據(jù)中出現(xiàn)次數(shù)最多的分類。其算法描述如下:

1)計(jì)算已知類別數(shù)據(jù)集中的點(diǎn)與當(dāng)前點(diǎn)之間的距離;

2)按照距離遞增次序排序;

3)選取與當(dāng)前點(diǎn)距離最小的k個(gè)點(diǎn);

4)確定前k個(gè)點(diǎn)所在類別的出現(xiàn)頻率;

5)返回前k個(gè)點(diǎn)出現(xiàn)頻率最高的類別作為當(dāng)前點(diǎn)的預(yù)測(cè)分類。

二、Python實(shí)現(xiàn)

       對(duì)于機(jī)器學(xué)習(xí)而已,Python需要額外安裝三件寶,分別是Numpy,scipy和Matplotlib。前兩者用于數(shù)值計(jì)算,后者用于畫圖。安裝很簡(jiǎn)單,直接到各自的官網(wǎng)下載回來(lái)安裝即可。安裝程序會(huì)自動(dòng)搜索我們的python版本和目錄,然后安裝到python支持的搜索路徑下。反正就python和這三個(gè)插件都默認(rèn)安裝就沒(méi)問(wèn)題了。

       另外,如果我們需要添加我們的腳本目錄進(jìn)Python的目錄(這樣Python的命令行就可以直接import),可以在系統(tǒng)環(huán)境變量中添加:PYTHONPATH環(huán)境變量,值為我們的路徑,例如:E:\Python\Machine Learning in Action
2.1、kNN基礎(chǔ)實(shí)踐
       一般實(shí)現(xiàn)一個(gè)算法后,我們需要先用一個(gè)很小的數(shù)據(jù)庫(kù)來(lái)測(cè)試它的正確性,否則一下子給個(gè)大數(shù)據(jù)給它,它也很難消化,而且還不利于我們分析代碼的有效性。
      首先,我們新建一個(gè)kNN.py腳本文件,文件里面包含兩個(gè)函數(shù),一個(gè)用來(lái)生成小數(shù)據(jù)庫(kù),一個(gè)實(shí)現(xiàn)kNN分類算法。代碼如下:
[python] view plain copy 在CODE上查看代碼片派生到我的代碼片
#########################################  
# kNN: k Nearest Neighbors  
 
# Input:      newInput: vector to compare to existing dataset (1xN)  
#             dataSet:  size m data set of known vectors (NxM)  
#             labels:   data set labels (1xM vector)  
#             k:        number of neighbors to use for comparison   
              
# Output:     the most popular class label  
#########################################  
 
from numpy import *  
import operator  
 
# create a dataset which contains 4 samples with 2 classes  
def createDataSet():  
    # create a matrix: each row as a sample  
    group = array([[1.0, 0.9], [1.0, 1.0], [0.1, 0.2], [0.0, 0.1]])  
    labels = ['A', 'A', 'B', 'B'] # four samples and two classes  
    return group, labels  
 
# classify using kNN  
def kNNClassify(newInput, dataSet, labels, k):  
    numSamples = dataSet.shape[0] # shape[0] stands for the num of row  
 
    ## step 1: calculate Euclidean distance  
    # tile(A, reps): Construct an array by repeating A reps times  
    # the following copy numSamples rows for dataSet  
    diff = tile(newInput, (numSamples, 1)) - dataSet # Subtract element-wise  
    squaredDiff = diff ** 2 # squared for the subtract  
    squaredDist = sum(squaredDiff, axis = 1) # sum is performed by row  
    distance = squaredDist ** 0.5  
 
    ## step 2: sort the distance  
    # argsort() returns the indices that would sort an array in a ascending order  
    sortedDistIndices = argsort(distance)  
 
    classCount = {} # define a dictionary (can be append element)  
    for i in xrange(k):  
        ## step 3: choose the min k distance  
        voteLabel = labels[sortedDistIndices[i]]  
 
        ## step 4: count the times labels occur  
        # when the key voteLabel is not in dictionary classCount, get()  
        # will return 0  
        classCount[voteLabel] = classCount.get(voteLabel, 0) + 1  
 
    ## step 5: the max voted class will return  
    maxCount = 0  
    for key, value in classCount.items():  
        if value > maxCount:  
            maxCount = value  
            maxIndex = key  
 
    return maxIndex  
       然后我們?cè)诿钚兄羞@樣測(cè)試即可:

[python] view plain copy 在CODE上查看代碼片派生到我的代碼片
import kNN  
from numpy import *   
 
dataSet, labels = kNN.createDataSet()  
 
testX = array([1.2, 1.0])  
k = 3  
outputLabel = kNN.kNNClassify(testX, dataSet, labels, 3)  
print "Your input is:", testX, "and classified to class: ", outputLabel  
 
testX = array([0.1, 0.3])  
outputLabel = kNN.kNNClassify(testX, dataSet, labels, 3)  
print "Your input is:", testX, "and classified to class: ", outputLabel  

       這時(shí)候會(huì)輸出:
[python] view plain copy 在CODE上查看代碼片派生到我的代碼片
Your input is: [ 1.2  1.0] and classified to class:  A  
Your input is: [ 0.1  0.3] and classified to class:  B 
2.2、kNN進(jìn)階

這里我們用kNN來(lái)分類一個(gè)大點(diǎn)的數(shù)據(jù)庫(kù),包括數(shù)據(jù)維度比較大和樣本數(shù)比較多的數(shù)據(jù)庫(kù)。這里我們用到一個(gè)手寫數(shù)字的數(shù)據(jù)庫(kù),可以到這里下載。這個(gè)數(shù)據(jù)庫(kù)包括數(shù)字0-9的手寫體。每個(gè)數(shù)字大約有200個(gè)樣本。每個(gè)樣本保持在一個(gè)txt文件中。手寫體圖像本身的大小是32x32的二值圖,轉(zhuǎn)換到txt文件保存后,內(nèi)容也是32x32個(gè)數(shù)字,0或者1,如下:

       數(shù)據(jù)庫(kù)解壓后有兩個(gè)目錄:目錄trainingDigits存放的是大約2000個(gè)訓(xùn)練數(shù)據(jù),testDigits存放大約900個(gè)測(cè)試數(shù)據(jù)。

        這里我們還是新建一個(gè)kNN.py腳本文件,文件里面包含四個(gè)函數(shù),一個(gè)用來(lái)生成將每個(gè)樣本的txt文件轉(zhuǎn)換為對(duì)應(yīng)的一個(gè)向量,一個(gè)用來(lái)加載整個(gè)數(shù)據(jù)庫(kù),一個(gè)實(shí)現(xiàn)kNN分類算法。最后就是實(shí)現(xiàn)這個(gè)加載,測(cè)試的函數(shù)。

[python] view plain copy 在CODE上查看代碼片派生到我的代碼片
#########################################  
# kNN: k Nearest Neighbors  
 
# Input:      inX: vector to compare to existing dataset (1xN)  
#             dataSet: size m data set of known vectors (NxM)  
#             labels: data set labels (1xM vector)  
#             k: number of neighbors to use for comparison   
              
# Output:     the most popular class label  
#########################################  
 
from numpy import *  
import operator  
import os  
 
 
# classify using kNN  
def kNNClassify(newInput, dataSet, labels, k):  
    numSamples = dataSet.shape[0] # shape[0] stands for the num of row  
 
    ## step 1: calculate Euclidean distance  
    # tile(A, reps): Construct an array by repeating A reps times  
    # the following copy numSamples rows for dataSet  
    diff = tile(newInput, (numSamples, 1)) - dataSet # Subtract element-wise  
    squaredDiff = diff ** 2 # squared for the subtract  
    squaredDist = sum(squaredDiff, axis = 1) # sum is performed by row  
    distance = squaredDist ** 0.5  
 
    ## step 2: sort the distance  
    # argsort() returns the indices that would sort an array in a ascending order  
    sortedDistIndices = argsort(distance)  
 
    classCount = {} # define a dictionary (can be append element)  
    for i in xrange(k):  
        ## step 3: choose the min k distance  
        voteLabel = labels[sortedDistIndices[i]]  
 
        ## step 4: count the times labels occur  
        # when the key voteLabel is not in dictionary classCount, get()  
        # will return 0  
        classCount[voteLabel] = classCount.get(voteLabel, 0) + 1  
 
    ## step 5: the max voted class will return  
    maxCount = 0  
    for key, value in classCount.items():  
        if value > maxCount:  
            maxCount = value  
            maxIndex = key  
 
    return maxIndex   
 
# convert image to vector  
def  img2vector(filename):  
    rows = 32  
    cols = 32  
    imgVector = zeros((1, rows * cols))   
    fileIn = open(filename)  
    for row in xrange(rows):  
        lineStr = fileIn.readline()  
        for col in xrange(cols):  
            imgVector[0, row * 32 + col] = int(lineStr[col])  
 
    return imgVector  
 
# load dataSet  
def loadDataSet():  
    ## step 1: Getting training set  
    print "---Getting training set..."  
    dataSetDir = 'E:/Python/Machine Learning in Action/'  
    trainingFileList = os.listdir(dataSetDir + 'trainingDigits') # load the training set  
    numSamples = len(trainingFileList)  
 
    train_x = zeros((numSamples, 1024))  
    train_y = []  
    for i in xrange(numSamples):  
        filename = trainingFileList[i]  
 
        # get train_x  
        train_x[i, :] = img2vector(dataSetDir + 'trainingDigits/%s' % filename)   
 
        # get label from file name such as "1_18.txt"  
        label = int(filename.split('_')[0]) # return 1  
        train_y.append(label)  
 
    ## step 2: Getting testing set  
    print "---Getting testing set..."  
    testingFileList = os.listdir(dataSetDir + 'testDigits') # load the testing set  
    numSamples = len(testingFileList)  
    test_x = zeros((numSamples, 1024))  
    test_y = []  
    for i in xrange(numSamples):  
        filename = testingFileList[i]  
 
        # get train_x  
        test_x[i, :] = img2vector(dataSetDir + 'testDigits/%s' % filename)   
 
        # get label from file name such as "1_18.txt"  
        label = int(filename.split('_')[0]) # return 1  
        test_y.append(label)  
 
    return train_x, train_y, test_x, test_y  
 
# test hand writing class  
def testHandWritingClass():  
    ## step 1: load data  
    print "step 1: load data..."  
    train_x, train_y, test_x, test_y = loadDataSet()  
 
    ## step 2: training...  
    print "step 2: training..."  
    pass  
 
    ## step 3: testing  
    print "step 3: testing..."  
    numTestSamples = test_x.shape[0]  
    matchCount = 0  
    for i in xrange(numTestSamples):  
        predict = kNNClassify(test_x[i], train_x, train_y, 3)  
        if predict == test_y[i]:  
            matchCount += 1  
    accuracy = float(matchCount) / numTestSamples  
 
    ## step 4: show the result  
    print "step 4: show the result..."  
    print 'The classify accuracy is: %.2f%%' % (accuracy * 100)  

       測(cè)試非常簡(jiǎn)單,只需要在命令行中輸入:

[python] view plain copy 在CODE上查看代碼片派生到我的代碼片
import kNN  
kNN.testHandWritingClass() 
       輸出結(jié)果如下:
[python] view plain copy 在CODE上查看代碼片派生到我的代碼片
step 1: load data...  數(shù)據(jù)分析師培訓(xùn)
---Getting training set...  
---Getting testing set...  
step 2: training...  
step 3: testing...  
step 4: show the result...  
The classify accuracy is: 98.84% 

數(shù)據(jù)分析咨詢請(qǐng)掃描二維碼

若不方便掃碼,搜微信號(hào):CDAshujufenxi

數(shù)據(jù)分析師資訊
更多

OK
客服在線
立即咨詢
客服在線
立即咨詢
') } function initGt() { var handler = function (captchaObj) { captchaObj.appendTo('#captcha'); captchaObj.onReady(function () { $("#wait").hide(); }).onSuccess(function(){ $('.getcheckcode').removeClass('dis'); $('.getcheckcode').trigger('click'); }); window.captchaObj = captchaObj; }; $('#captcha').show(); $.ajax({ url: "/login/gtstart?t=" + (new Date()).getTime(), // 加隨機(jī)數(shù)防止緩存 type: "get", dataType: "json", success: function (data) { $('#text').hide(); $('#wait').show(); // 調(diào)用 initGeetest 進(jìn)行初始化 // 參數(shù)1:配置參數(shù) // 參數(shù)2:回調(diào),回調(diào)的第一個(gè)參數(shù)驗(yàn)證碼對(duì)象,之后可以使用它調(diào)用相應(yīng)的接口 initGeetest({ // 以下 4 個(gè)配置參數(shù)為必須,不能缺少 gt: data.gt, challenge: data.challenge, offline: !data.success, // 表示用戶后臺(tái)檢測(cè)極驗(yàn)服務(wù)器是否宕機(jī) new_captcha: data.new_captcha, // 用于宕機(jī)時(shí)表示是新驗(yàn)證碼的宕機(jī) product: "float", // 產(chǎn)品形式,包括:float,popup width: "280px", https: true // 更多配置參數(shù)說(shuō)明請(qǐng)參見:http://docs.geetest.com/install/client/web-front/ }, handler); } }); } function codeCutdown() { if(_wait == 0){ //倒計(jì)時(shí)完成 $(".getcheckcode").removeClass('dis').html("重新獲取"); }else{ $(".getcheckcode").addClass('dis').html("重新獲取("+_wait+"s)"); _wait--; setTimeout(function () { codeCutdown(); },1000); } } function inputValidate(ele,telInput) { var oInput = ele; var inputVal = oInput.val(); var oType = ele.attr('data-type'); var oEtag = $('#etag').val(); var oErr = oInput.closest('.form_box').next('.err_txt'); var empTxt = '請(qǐng)輸入'+oInput.attr('placeholder')+'!'; var errTxt = '請(qǐng)輸入正確的'+oInput.attr('placeholder')+'!'; var pattern; if(inputVal==""){ if(!telInput){ errFun(oErr,empTxt); } return false; }else { switch (oType){ case 'login_mobile': pattern = /^1[3456789]\d{9}$/; if(inputVal.length==11) { $.ajax({ url: '/login/checkmobile', type: "post", dataType: "json", data: { mobile: inputVal, etag: oEtag, page_ur: window.location.href, page_referer: document.referrer }, success: function (data) { } }); } break; case 'login_yzm': pattern = /^\d{6}$/; break; } if(oType=='login_mobile'){ } if(!!validateFun(pattern,inputVal)){ errFun(oErr,'') if(telInput){ $('.getcheckcode').removeClass('dis'); } }else { if(!telInput) { errFun(oErr, errTxt); }else { $('.getcheckcode').addClass('dis'); } return false; } } return true; } function errFun(obj,msg) { obj.html(msg); if(msg==''){ $('.login_submit').removeClass('dis'); }else { $('.login_submit').addClass('dis'); } } function validateFun(pat,val) { return pat.test(val); }