1. 程式人生 > >機器學習 -- kNN演算法

機器學習 -- kNN演算法

K近鄰演算法

什麼是K近鄰演算法

何謂K近鄰演算法,即K-Nearest Neighbor algorithm,簡稱KNN演算法。單從名字來猜想,可以簡單的認為:K個最近的鄰居。當K=1時,演算法便成了尋找最近的那個鄰居。

用官方的話來說,所謂K近鄰演算法,即是給定一個訓練資料集。對新的輸入例項,在訓練資料集中找到與該例項最鄰近的K個例項(也就是上面所說的K個鄰居)。這K個例項的多數屬於某個類,就把該輸入例項分類到這個類中。

我們來看下圖:
kNN

如上圖所示,有兩類不同的樣本資料,分別用藍色的小正方形和紅色的小三角形表示。而圖正中間的那個綠色的圓所標示的資料則是待分類的資料。也就是說,現在,我們不知道中間那個綠色的資料是從屬於哪一類(藍色小正方形或者紅色小三角形)。所以,我們解決問題是給這個綠色的圓分類。

我們常說,物以類聚,人以群分,判別一個人是一個什麼樣品質特徵的人,常常可以從他/她身邊的朋友入手,所謂觀其友,而識其人。我們不是要判別上圖中那個綠色的圓是屬於哪一類資料麼,好說,從它的鄰居下手。但一次性看多少個鄰居呢?

從上圖中,你還能看到:
+ 如果K=3,綠色圓點的最近的3個鄰居是2個紅色小三角形和1個藍色小正方形,基於統計的方法,判定綠色的這個待分類點屬於紅色的三角形一類。
+ 如果K=5,綠色圓點的最近的5個鄰居是2個紅色三角形和3個藍色的正方形,基於統計的方法,判定綠色的這個待分類點屬於藍色的正方形一類。

於此我們看到,當無法判定當前待分類點是從屬於已知分類中的哪一類時,我們可以依據統計學的理論看它所處的位置特徵,衡量它周圍鄰居的權重,而把它歸為(或分配)到權重更大的那一類。這就是K近鄰演算法的核心思想。

鄰近的距離度量方式

我們看到,K近鄰演算法的核心在於找到待測點的鄰居。那麼,問題就接踵而至了,如何找到鄰居,鄰居的判定標準是什麼,用什麼來度量。這一系列問題便是下面要講的距離度量方式。

這是因為特徵空間中兩個例項點的距離可以反應出兩個例項點之間的相似性程度。K近鄰模型的特徵空間一般是n維實數向量空間,使用的距離可以是歐式距離,也是可以是其它距離,既然扯到了距離,下面就來具體闡述下都有哪些距離度量的表示法,

歐式距離

最常見的兩點之間或多點之間的距離表示法,又稱之為歐幾里得度量,它定義於歐幾里得空間中,如點 x = (x1,…,xn) 和 y = (y1,…,yn) 之間的距離為:

d(x,y):=(x1y1)2+(x2y2)2+...+(xnyn)22

程式碼如下:

double euclideanDistance(const vector<double>& v1, const vector<double>& v2)
{
    assert(v1.size() == v2.size());
    double ret = 0.0;
    for (vector<double>::size_type i = 0; i != v1.size(); ++i)
    {
        ret += (v1[i] - v2[i]) * (v1[i] - v2[i]);
    }
    return sqrt(ret);
}

曼哈頓距離

我們可以定義曼哈頓距離的正式意義為L1-距離或城市區塊距離,也就是在歐幾里得空間的固定直角座標系上兩點所形成的線段對軸產生的投影的距離總和。例如在平面上,座標(x1, y1)的點P1與座標(x2, y2)的點P2的曼哈頓距離為:

|x1x2|+|y1y2|

通俗來講,想象你在曼哈頓要從一個十字路口開車到另外一個十字路口,駕駛距離是兩點間的直線距離嗎?顯然不是,除非你能穿越大樓。而實際駕駛距離就是這個曼哈頓距離,此即曼哈頓距離名稱的來源。同時,曼哈頓距離也稱為城市街區距離(City Block Distance)。

切比雪夫距離

閔可夫斯基距離(Minkowski Distance)

標準化歐氏距離 (Standardized Euclidean distance )

馬氏距離(Mahalanobis Distance)

巴氏距離(Bhattacharyya Distance)

漢明距離(Hamming distance)

夾角餘弦(Cosine)

傑卡德相似係數(Jaccard similarity coefficient)

皮爾遜係數(Pearson Correlation Coefficient)

K值的選擇

除了上述如何定義鄰居的問題之外,還有一個選擇多少個鄰居,即K值定義為多大的問題。不要小看了這個K值選擇問題,因為它對K近鄰演算法的結果會產生重大影響。如下圖所示,X是待分類樣本,‘+’和‘-’是樣本類別屬性,
K Choice

  • 如果K選小了的話,結果對噪音樣本點很敏感。

  • 如果K選大了的話,可能求出來的k最近鄰集合可能包含了太多隸屬於其它類別的樣本點,最極端的就是k取訓練集的大小,此時無論輸入例項是什麼,都只是簡單的預測它屬於在訓練例項中最多的累,模型過於簡單,忽略了訓練例項中大量有用資訊

在實際應用中,K值一般取一個比較小的數值,例如採用交叉驗證法(一部分樣本做訓練集,而另一部分做測試集,即K值初始取一個比較小的數值,之後不斷來調整K值的大小使得分類最優,得到的K值就是最優解。但是這個K值具有一定的侷限性)來選擇最優的K值。

Tensorflow中的K近鄰演算法實現

__author__ = 'Xinyou DONG'
import tensorflow as tf
import numpy as np

def loadMNIST():
    from tensorflow.examples.tutorials.mnist import input_data
    mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
    return mnist

def KNN(mnist):
    train_x,train_y = mnist.train.next_batch(5000)
    test_x,test_y = mnist.train.next_batch(200)

    xtr = tf.placeholder(tf.float32, [None,784])
    xte = tf.placeholder(tf.float32, [784])
    distance = tf.sqrt(tf.reduce_sum(tf.pow(tf.add(xtr, tf.neg(xte)), 2), reduction_indices=1))

    pred = tf.argmin(distance,0)

    init = tf.initialize_all_variables()

    sess = tf.Session()
    sess.run(init)

    right = 0
    for i in range(200):
        ansIndex = sess.run(pred,{xtr:train_x, xte:test_x[i,:]})
        print 'prediction is ', np.argmax(train_y[ansIndex])
        print 'true value is ', np.argmax(test_y[i])
        if np.argmax(test_y[i]) == np.argmax(train_y[ansIndex]):
            right += 1.0
    accracy = right/200.0
    print accracy

if __name__ == "__main__":
    mnist = loadMNIST()
    KNN(mnist)

K近鄰演算法的實現 – KD樹

背景

正如前面所講的卷積神經元演算法中影象匹配類似,特徵點的匹配和資料庫查、影象檢索本質上是同一個問題,都可以歸結為一個通過距離函式在高維向量之間進行相似性檢索的問題,如何快速而準確地找到查詢點的近鄰,不少人提出了很多高維空間索引結構和近似查詢的演算法。

一般說來,索引結構中相似性查詢有兩種基本的方式:
+ 一種是範圍查詢,範圍查詢時給定查詢點和查詢距離閾值,從資料集中查詢所有與查詢點距離小於閾值的資料
+ 另一種是K近鄰查詢,就是給定查詢點及正整數K,從資料集中找到距離查詢點最近的K個數據,當K=1時,它就是最近鄰查詢。

同樣,針對特徵點匹配也有兩種方法:
+ 最容易的辦法就是線性掃描,也就是我們常說的窮舉搜尋,依次計算樣本集E中每個樣本到輸入例項點的距離,然後抽取出計算出來的最小距離的點即為最近鄰點。此種辦法簡單直白,但當樣本集或訓練集很大時,它的缺點就立馬暴露出來了,舉個例子,在物體識別的問題中,可能有數千個甚至數萬個SIFT特徵點,而去一一計算這成千上萬的特徵點與輸入例項點的距離,明顯是不足取的。
+ 另外一種,就是構建資料索引,因為實際資料一般都會呈現簇狀的聚類形態,因此我們想到建立資料索引,然後再進行快速匹配。索引樹是一種樹結構索引方法,其基本思想是對搜尋空間進行層次劃分。根據劃分的空間是否有混疊可以分為Clipping和Overlapping兩種。前者劃分空間沒有重疊,其代表就是KD樹;後者劃分空間相互有交疊,其代表為R樹。

1975年,來自斯坦福大學的Jon Louis Bentley在ACM雜誌上發表的一篇論文:Multidimensional Binary Search Trees Used for Associative Searching中正式提出和闡述的瞭如下圖形式的把空間劃分為多個部分的KD樹。
Cup

什麼是KD樹

KD樹是K-dimension tree的縮寫,是對資料點在k維空間(如二維(x,y),三維(x,y,z),k維(x,y,z..))中劃分的一種資料結構,主要應用於多維空間關鍵資料的搜尋(如:範圍搜尋和最近鄰搜尋)。

首先必須搞清楚的是,KD樹是一種空間劃分樹,就是把整個空間劃分為特定的幾個部分,然後在特定空間的部分內進行相關搜尋操作。想像一個三維空間,K-D樹按照一定的劃分規則把這個三維空間劃分了多個空間,如下圖所示:
這裡寫圖片描述

KD樹的構建

KD樹構建的虛擬碼如下圖所示:
這裡寫圖片描述

再舉一個簡單直觀的例項來介紹KD樹構建演算法。假設有6個二維資料點{(2, 3),(5, 4),(9, 6),(4, 7),(8, 1),(7, 2)},資料點位於二維空間內,如下圖所示。為了能有效的找到最近鄰,KD樹採用分而治之的思想,即將整個空間劃分為幾個小部分,首先,粗黑線將空間一分為二,然後在兩個子空間中,細黑直線又將整個空間劃分為四部分,最後虛黑直線將這四部分進一步劃分。
這裡寫圖片描述

6個二維資料點{(2, 3),(5, 4),(9, 6),(4, 7),(8, 1),(7, 2)}構建KD樹的具體步驟為:
+ 確定split域。具體步驟是,6個數據點在x,y維度上的資料方差分別為39,28.63,所以在x軸上方差更大,故split域值為x;
+ 確定Node-data=(7, 2)。具體步驟是,根據x維上的值將資料排序,6個數據的中值(所謂中值,即中間大小的值)為7,所以Node-data域位資料點(7, 2)。這樣,該節點的分割超平面就是通過(7, 2)並垂直於split=x軸的直線x=7;
+ 確定左子空間和右子空間。具體步驟是:分割超平面x=7將整個空間分為兩部分,x<=7的部分為左子空間,包含3個節點{(2, 3),(5, 4),(4, 7)};另一部分為右子空間,包含2個節點{(9, 6),(8, 1)};

如上演算法所述,KD樹的構建是一個遞迴過程,我們對左子空間和右子空間內的資料重複根節點的過程就可以得到一級子節點(5, 4)和(9, 6),同時將空間和資料集進一步細分,如此往復直到空間中只包含一個數據點。
這裡寫圖片描述

與此同時,經過對上面所示的空間劃分之後,我們可以看出,點(7, 2)可以為根結點,從根結點出發的兩條紅粗斜線指向的(5, 4)和(9, 6)則為根結點的左右子結點,而(2, 3),(4, 7)則為(5, 4)的左右孩子(通過兩條細紅斜線相連),最後,(8,1)為(9,6)的左孩子(通過細紅斜線相連)。如此,便形成了下面這樣一棵k-d樹:
這裡寫圖片描述

KD樹的資料結構(注,本文以下程式碼分析基於Rob Hess維護的sift庫),

/** a node in a k-d tree */
struct kd_node
{
    int ki;                      /**< partition key index */
    double kv;                   /**< partition key value */
    int leaf;                    /**< 1 if node is a leaf, 0 otherwise */
    struct feature* features;    /**< features at this node */
    int n;                       /**< number of features */
    struct kd_node* kd_left;     /**< left child */
    struct kd_node* kd_right;    /**< right child */
}

也就是說,KD樹中,KD代表k-dimension,每個節點即為一個k維的點。每個非葉節點可以想象為一個分割超平面,用垂直於座標軸的超平面將空間分為兩個部分,這樣遞迴的從根節點不停的劃分,直到沒有例項為止。經典的構造k-d tree的規則如下:
+ 隨著樹的深度增加,迴圈的選取座標軸,作為分割超平面的法向量。對於3-d tree來說,根節點選取x軸,根節點的孩子選取y軸,根節點的孫子選取z軸,根節點的曾孫子選取x軸,這樣迴圈下去。
+ 每次均為所有對應例項的中位數的例項作為切分點,切分點作為父節點,左右兩側為劃分的作為左右兩子樹。

對於n個例項的k維資料來說,建立kd-tree的時間複雜度為O(k*n*logn)。

以下是構建k-d樹的程式碼:

struct kd_node* kdtree_build( struct feature* features, int n )
{
    struct kd_node* kd_root;

    if( ! features  ||  n <= 0 )
    {
        fprintf( stderr, "Warning: kdtree_build(): no features, %s, line %d\n", __FILE__, __LINE__ );
        return NULL;
    }

    kd_root = kd_node_init( features, n );  //n--number of features,initinalize root of tree.
    expand_kd_node_subtree( kd_root );  //kd tree expand

    return kd_root;
}

上面的涉及初始化操作的兩個函式kd_node_init,及expand_kd_node_subtree程式碼分別如下所示:

static struct kd_node* kd_node_init( struct feature* features, int n )
{                                     //n--number of features
    struct kd_node* kd_node;

    kd_node = (struct kd_node*)(malloc(sizeof(struct kd_node) ));
    memset( kd_node, 0, sizeof( struct kd_node ) ); //0填充
    kd_node->ki = -1;
    kd_node->features = features;
    kd_node->n = n;

    return kd_node;
}

static void expand_kd_node_subtree( struct kd_node* kd_node )
{
    /* base case: leaf node */
    if( kd_node->n == 1  ||  kd_node->n == 0 )
    {   //葉節點               //偽葉節點
        kd_node->leaf = 1;
        return;
    }

    assign_part_key( kd_node ); //get ki,kv
    partition_features( kd_node ); //creat left and right children,特徵點ki位置左樹比右樹模值小,kv作為分界模值
                                 //kd_node中關鍵點已經排序
    if( kd_node->kd_left )
        expand_kd_node_subtree( kd_node->kd_left );
    if( kd_node->kd_right )
        expand_kd_node_subtree( kd_node->kd_right );
}

KD樹的插入

元素插入到一個K-D樹的方法和二叉檢索樹類似。本質上,在偶數層比較x座標值,而在奇數層比較y座標值。當我們到達了樹的底部,(也就是當一個空指標出現),我們也就找到了結點將要插入的位置。生成的K-D樹的形狀依賴於結點插入時的順序。給定N個點,其中一個結點插入和檢索的平均代價是

$O(log2N)$。

我們來考慮如下的例子,用下列的點逐步插入KD樹中,
(3, 6),(17, 15),(13, 15),(6, 12),(9, 1),(2, 7),(10, 19)

  • 插入點(3, 6):因為此時KD樹為空,我們將此點作為樹的根節點;
  • 插入點(17, 15):將此點與KD樹的根節點比較,因為根節點是以x軸作為比較域的,所以當前點的x軸的座標值要與根節點的值相比較用以決定當前點位於根節點的左子樹還是右子樹。在插入後,當前點是以y軸作為比較域的;
  • 插入點(13, 15):當前點的x軸座標大於根節點的x軸座標,所以當前點位於根節點的右子樹。然後當前點與右子樹的根節點比較y值,當前點應位於右子樹根節點的右子樹。在插入後,當前點是以x軸作為比較域的;
  • 插入點(6, 12):同理可得,當前點位於點(17, 15)的左子樹;
  • 插入點(9, 1):同理可得,當前點位於點(6, 12)的右子樹;
  • 插入點(2, 7):同理可得,當前點位於點(3, 6)的左子樹;
  • 插入點(10, 19):同理可得,當前點位於點(13, 15)的左子樹;
    這裡寫圖片描述

KD樹的刪除

刪除步驟

  • 如果當前節點是要刪除的節點;
    • 如果當前節點是一個葉子節點,刪除;
    • 如果當前節點的右子樹非空;
      1.找到當前節點右子樹中對應比較域值的對應的最小節點;
      2.刪掉當前節點,並且用找到的最小節點代替刪掉的節點;
      3.遞迴替換;
    • 如果當前節點的右子樹為空且左子樹非空;
      1.找到當前節點左子樹中對應比較域值的對應的最小節點;
      2.刪掉當前節點,並且用找到的最小節點代替刪掉的節點;
      3.並將左子樹作為當前節點的右子樹;
      4.遞迴替換
  • 如果當前節點不是要刪除的節點;
    • 如果要刪除的節點比當前節點的比較域的值小,到當前節點的左子樹中查詢;
    • 如果相反,則到當前節點的右子樹中查詢;

KD樹節點刪除的例子:

刪除節點(30, 40):因為節點的右子樹非空並且比較域是x軸,我們需要在右子樹中查詢x軸的最小值節點代替當前節點。又因為點(35, 45)是葉子節點,可直接刪除。如下圖所示:
這裡寫圖片描述

刪除節點(70, 70):因為當前節點的比較域在y軸,且右子樹為空,所以我們需要在其左子樹中查詢對於值最小的節點。將查詢的節點(50, 30)代替(70, 70),並將左子樹作為當前節點的右子樹。如下圖所示:
這裡寫圖片描述

KD樹的最近鄰搜尋演算法

現實生活中有許多問題需要在多維資料的快速分析和快速搜尋,對於這個問題最常用的方法是所謂的KD樹。在KD樹中進行資料的查詢也是特徵匹配的重要環節,其目的是檢索在KD樹中與查詢點距離最近的資料點。在一個N維的笛卡兒空間在兩個點之間的距離是由下述公式確定:

d(x,y):=(x1y1)2+(x2y2)2+...+(xnyn)22

k-d樹查詢演算法的虛擬碼

演算法:KD樹最鄰近查詢
輸入:   Kd,       //k-d tree型別
        target     //查詢資料點
輸出:   nearest,  //最鄰近資料點
        dist       //最鄰近資料點和查詢點間的距離

1. If KDNULL,則設dist為infinite並返回
2. //進行二叉查詢,生成搜尋路徑
   Kd_point = &Kd;              //Kd-point中儲存k-d tree根節點地址
   nearest = Kd_point -> Node-data;  //初始化最近鄰點

   while(Kd_point)
     push(Kd_point)到search_path中; //search_path是一個堆疊結構,儲存著搜尋路徑節點指標

      If Dist(nearest,target) > DistKd_point -> Node-data,target)
       nearest  = Kd_point -> Node-data;    //更新最近鄰點
       Min_dist = Dist(Kd_point,target);  //更新最近鄰點與查詢點間的距離  ***/
     s = Kd_point -> split;                  //確定待分割的方向

     If target[s] <= Kd_point -> Node-data[s]     //進行二叉查詢 
       Kd_point = Kd_point -> left;
     else
       Kd_point = Kd_point ->right;
   End while

3. //回溯查詢
   while(search_path != NULL)
     back_point = 從search_path取出一個節點指標;  //從search_path堆疊彈棧
     s = back_point -> split;                   //確定分割方向
     If Dist(target[s],back_point -> Node-data[s]) < Max_dist   //判斷還需進入的子空間
       If target[s] <= back_point -> Node-data[s]
         Kd_point = back_point -> right;  //如果target位於左子空間,就應進入右子空間
       else
         Kd_point = back_point -> left;    //如果target位於右子空間,就應進入左子空間
       將Kd_point壓入search_path堆疊;

     If Dist(nearest,target) > DistKd_Point -> Node-data,target)
       nearest  = Kd_point -> Node-data;      //更新最近鄰點
       Min_dist = DistKd_point -> Node-data,target);  //更新最近鄰點與查詢點間的距離的
   End while

將Kd_point壓入search_path堆疊;”這行程式碼後,應該是調到步驟2再往下走二分搜尋的邏輯一直到葉結點,我寫了一個遞迴版本的二維kd tree的搜尋函式你對比的看看:

void innerGetClosest(NODE* pNode, PT point, PT& res, int& nMinDis)
{
    if (NULL == pNode)
        return;
    int nCurDis = abs(point.x - pNode->pt.x) + abs(point.y - pNode->pt.y);
    if (nMinDis < 0 || nCurDis < nMinDis)
    {
        nMinDis = nCurDis;
        res = pNode->pt;
    }
    if (pNode->splitX && point.x <= pNode->pt.x || !pNode->splitX && point.y <= pNode->pt.y)
        innerGetClosest(pNode->pLft, point, res, nMinDis);
    else
        innerGetClosest(pNode->pRgt, point, res, nMinDis);
    int rang = pNode->splitX ? abs(point.x - pNode->pt.x) : abs(point.y - pNode->pt.y);
    if (rang > nMinDis)
        return;
    NODE* pGoInto = pNode->pLft;
    if (pNode->splitX && point.x > pNode->pt.x || !pNode->splitX && point.y > pNode->pt.y)
        pGoInto = pNode->pRgt;
    innerGetClosest(pGoInto, point, res, nMinDis);
}

以兩個簡單的例項(例子來自影象區域性不變特性特徵與描述一書)來描述最鄰近查詢的基本思路。

查詢點(2.1, 3.1)

加號表示要查詢的點(2.1, 3.1)。通過二叉搜尋,順著搜尋路徑很快就能找到最鄰近的近似點,也就是葉子節點(2, 3)。而找到的葉子節點並不一定就是最鄰近的,最鄰近肯定距離查詢點更近,應該位於以查詢點為圓心且通過葉子節點的圓域內。為了找到真正的最近鄰,還需要進行相關的回溯操作。也就是說,演算法首先沿搜尋路徑反向查詢是否有距離查詢點更近的資料點。

以查詢(2.1, 3.1)為例:

  • 二叉樹搜尋:先從(7, 2)點開始進行二叉查詢,然後到達(5, 4),最後到達(2, 3),此時搜尋路徑中的節點為<(7, 2),(5, 4),(2, 3)>,首先以(2, 3)作為當前最近鄰點,計算其到查詢點(2.1, 3.1)的距離為0.1414,
  • 回溯查詢:在得到(2, 3)為查詢點的最近點之後,回溯到其父節點(5,4),並判斷在該父節點的其他子節點空間中是否有距離查詢點更近的資料點。以(2.1, 3.1)為圓心,以0.1414為半徑畫圓,如下圖所示。發現該圓並不和超平面y = 4交割,因此不用進入(5, 4)節點右子空間中(圖中灰色區域)去搜索;
  • 最後,再回溯到(7, 2),以(2.1, 3.1)為圓心,以0.1414為半徑的圓更不會與x = 7超平面交割,因此不用進入(7, 2)右子空間進行查詢。至此,搜尋路徑中的節點已經全部回溯完,結束整個搜尋,返回最近鄰點(2, 3),最近距離為0.1414
    這裡寫圖片描述

查詢點(2, 4.5)

一個複雜點了例子如查詢點為(2, 4.5),具體步驟依次如下:

  • 同樣先進行二叉查詢,先從(7, 2)查詢到(5, 4)節點,在進行查詢時是由y = 4為分割超平面的,由於查詢點為y值為4.5,因此進入右子空間查詢到(4, 7),形成搜尋路徑<(7, 2),(5, 4),(4, 7)>,但(4, 7)與目標查詢點的距離為3.202,而(5, 4)與查詢點之間的距離為3.041,所以(5, 4)為查詢點的最近點;
  • 以(2, 4.5)為圓心,以3.041為半徑作圓,如下圖所示。可見該圓和y = 4超平面交割,所以需要進入(5, 4)左子空間進行查詢,也就是將(2, 3)節點加入搜尋路徑中得<(7, 2),(2, 3)>;於是接著搜尋至(2, 3)葉子節點,(2, 3)距離(2, 4.5)比(5, 4)要近,所以最近鄰點更新為(2, 3),最近距離更新為1.5;
  • 回溯查詢至(5, 4),直到最後回溯到根結點(7, 2)的時候,以(2, 4.5)為圓心1.5為半徑作圓,並不和x = 7分割超平面交割,如下圖所示。至此,搜尋路徑回溯完,返回最近鄰點(2, 3),最近距離1.5。
    這裡寫圖片描述

上述兩次例項表明,當查詢點的鄰域與分割超平面兩側空間交割時,需要查詢另一側子空間,導致檢索過程複雜,效率下降。

一般來講,最臨近搜尋只需要檢測幾個葉子結點即可,如下圖所示:
這裡寫圖片描述

但是,如果當例項點的分佈比較糟糕時,幾乎要遍歷所有的結點,如下所示:
這裡寫圖片描述

研究表明N個節點的K維KD樹搜尋過程時間複雜度為:

相關推薦

機器學習——KNN演算法以及案例預測入住位置

ķ最近鄰 KNN分類演算法其核心思想是假定所有的資料物件都對應於Ñ維空間中的點,如果一個數據物件在特徵空間中的ķ個最相鄰物件中的大多數屬於某一個類別,則該物件也屬於這個類別,並具有這個類別上樣本的特性.KNN方法在進行類別決策時,只與極少量的相鄰樣本有關。 定義:如果一個樣本在特徵空間中的ķ

機器學習 KNN演算法原理

K近鄰(K-nearst neighbors,KNN)是一種基本的機器學習演算法,所謂k近鄰,就是k個最近的鄰居的意思,說的是每個樣本都可以用它最接近的k個鄰居來代表。比如:判斷一個人的人品,只需要觀察與他來往最密切的幾個人的人品好壞就可以得出,即“近朱者赤,近墨者黑”;KNN演算法既可以應用於分類應用中,也

機器學習KNN演算法

轉載請註明作者和出處:http://blog.csdn.net/c406495762 執行平臺: Windows Python版本:

吳裕雄 python 機器學習-KNN演算法(1)

import numpy as np import operator as op from os import listdir def classify0(inX, dataSet, labels, k): dataSetSize = dataSet.shape[0] diffMat

[機器學習]kNN演算法python實現(例項:數字識別)

# 使用好任何機器學習演算法的前提是選好Featuresfrom numpy import * import operator from os import listdir def classify0(inX, dataSet, labels, k):     data

機器學習 -- kNN演算法

K近鄰演算法 什麼是K近鄰演算法 何謂K近鄰演算法,即K-Nearest Neighbor algorithm,簡稱KNN演算法。單從名字來猜想,可以簡單的認為:K個最近的鄰居。當K=1時,演算法便成了尋找最近的那個鄰居。 用官方的話來說,所

機器學習-KNN演算法

一、演算法介紹   KNN演算法中文名稱叫做K近鄰演算法,是眾多機器學習演算法裡面最基礎入門的演算法。它是一個有監督的機器學習演算法,既可以用來做分類任務也可以用來做迴歸任務。KNN演算法的核心思想是未標記的樣本的類別,由距離他最近的K個鄰居投票來決定。下面我們來看個例子加深理解一下:   如上圖所描述張三

機器學習演算法knn,貝葉斯,決策樹

sklearn資料集與估計器 資料集劃分 機器學習一般的資料集會劃分為兩個部分: 訓練資料:用於訓練,構建模型 測試資料:在模型檢驗時使用,用於評估模型是否有效 資料集劃分API sklearn.model_selection.train_test_split

機器學習實戰第二章——學習KNN演算法,讀書筆記

        K近鄰演算法(簡稱KNN)學習是一種常用的監督學習方法,給定測試樣本,基於某種距離度量找出訓練集中與其最靠近的k個訓練樣本,然後基於這k個“鄰居”的資訊來進行預測。通常在分類任務中可以使用“投票法”,即

機器學習經典演算法詳解及Python實現--K近鄰(KNN)演算法

轉載http://blog.csdn.net/suipingsp/article/details/41964713 (一)KNN依然是一種監督學習演算法 KNN(K Nearest Neighbors,K近鄰 )演算法是機器學習所有演算法中理論最簡單,最好理解的。KNN

機器學習-KNN分類演算法Iris例項

概念 python知識點 KNN例項 # -*- coding: utf-8 -*- """ Created on Sat Mar 5 09:55:02 2016 @au

機器學習系列演算法1:KNN

思路:空間上距離相近的點具有相似的特徵屬性。 執行流程:   •1. 從訓練集合中獲取K個離待預測樣本距離最近的樣本資料;  •2. 根據獲取得到的K個樣本資料來預測當前待預測樣本的目標屬性值  三要素:K值選擇/距離度量(歐式距離)/決策選擇(平均值/

機器學習經典演算法KNN

一、前言 KNN 的英文叫 K-Nearest Neighbor,應該算是資料探勘演算法中最簡單的一種。 先用一個例子體會下。 /*請尊重作者勞動成果,轉載請標明原文連結:*/ /* https://www.cnblogs.com/jpcflyer/p/11111817.html * / 假設,我們想對電

機器學習-KNN分類器

pos show sha key borde 不同 簡單的 測試 solid 1. K-近鄰(k-Nearest Neighbors,KNN)的原理 通過測量不同特征值之間的距離來衡量相似度的方法進行分類。 2. KNN算法過程 訓練樣本集:樣本集中每個特征值都

機器學習-KNN算法

訓練集 nbsp 線性分類 但是 測試 優點 http 進行 inf 原理 KNN算法,又叫K近鄰算法。就是在訓練集中數據和標簽已知的情況下,輸入測試數據,將測試數據的特征與訓練集中對應的特征進行相互比較,找到訓練集中與之最為相似的前K個數據,則該測試數據對應的類別就是K個

機器學習——KNN

load -s 創建 數據 sklearn lac bsp otl 訓練數據 導入類庫 1 import numpy as np 2 from sklearn.neighbors import KNeighborsClassifier 3 from sklearn.

機器學習開源演算法

C++計算機視覺 CCV —基於C語言/提供快取/核心的機器視覺庫,新穎的機器視覺庫 OpenCV—它提供C++, C, Python, Java 以及 MATLAB介面,並支援Windows, Linux, Android and Mac OS作業系統。

吳恩達機器學習 - PCA演算法降維 吳恩達機器學習 - PCA演算法降維

原 吳恩達機器學習 - PCA演算法降維 2018年06月25日 13:08:17 離殤灬孤狼 閱讀數:152 更多

給找機器學習演算法崗工作的同學們的一些建議

轉自:https://bbs.pku.edu.cn/v2/post-read.php?bid=99&threadid=16510824   本人是數院統計專業畢業,在某大公司做演算法方面的工作,面試過不少人。   有不少學弟學妹找我諮詢過機器學習/演算法方

機器學習經典演算法梳理】一.線性迴歸

【機器學習經典演算法梳理】是一個專門梳理幾大經典機器學習演算法的部落格。我在這個系列部落格中,爭取用最簡練的語言、較簡潔的數學公式,和清晰成體系的提綱,來盡我所能,對於演算法進行詳盡的梳理。【機器學習經典演算法梳理】系列部落格對於機器學習演算法的梳理,將從“基本思想”、“基本形式”、“過程推導”、“