KNN(線性模型)

KNN最鄰近結(jié)點算法

一、算法原理

kNN算法的核心思想是如果一個樣本在特征空間中的k個最相鄰的樣本中的大多數(shù)屬于某一個類別,則該樣本也屬于這個類別,并具有這個類別上樣本的特性。



二换吧、算法實現(xiàn)

import numpy as np
from math import sqrt
from collections import Counter

def kNN_classify(k, X_train, y_train, x):
    assert 1 <= k <= X_train.shape[0], "ERROR: k must be valid!"
    assert X_train.shape[0] == y_train.shape[0], "ERROR: the size of X_train must equal to the size of y_train!"
    assert X_train.shape[1] == x.shape[0], "ERROR: the feature number of x must be equal to X_train!"
    
    # 求被測點到所有樣本點的歐氏距離
    distances = [sqrt(np.sum((x_train - x)**2)) for x_train in X_train]
    # 返回按距離升序排列后的索引列表
    nearest = np.argsort(distances)
    # 返回前k小的距離
    topK_y = [y_train[i] for i in nearest[:k]]
    # collections的Counter()方法:求出數(shù)組的相同元素的個數(shù),返回一個dict:{key=元素名钥星,value=元素個數(shù)}
    votes = Counter(topK_y)
    # most_common()方法:求出最多的元素對應(yīng)的那個鍵值對
    return votes.most_common(1)[0][0]

示例:

# 數(shù)據(jù)集
# 特征
raw_data_x= [[3.393533211,2.331273381],
[2.110073483,1.781539638],
[1.343808831,3.368360954],
[3.582294042,4.679179110],
[2.280362439,2.866990263],
[7.423436942,4.696522875],
[5.745051997,3.533989803],
[9.172168622,2.511101045],
[7.792783481,3.424088941],
[7.939820817,0.791637231]
]
# 所屬類別
raw_data_y = [0,0,0,0,0,1,1,1,1,1]

X_train = np.array(raw_data_x)
y_train = np.array(raw_data_y)
# 預(yù)測
x = np.array([8.093607318,3.365731514])
predict = kNN_classify(6,X_train,y_train,x)
predict

三沾瓦、scikit-learn KNN

from sklearn.neighbors import KNeighborsClassifier
kNN_classifier = KNeighborsClassifier(n_neighbors=6)
kNN_classifier.fit(X_train, y_train)

示例:
訓(xùn)練數(shù)據(jù)集同上

# 預(yù)測
x = np.array([[8.093607318,3.365731514]])
kNN_classifier.predict(x)

四、鳶尾花示例

1.數(shù)據(jù)準(zhǔn)備

(1)導(dǎo)入數(shù)據(jù)

from sklearn.datasets import fetch_openml
iris = fetch_openml(name='iris')

(2)初步了解數(shù)據(jù)

(3)切分?jǐn)?shù)據(jù)集

①以花萼長度、寬度為特征值

X = iris.data[:, : 2]

from sklearn.preprocessing import LabelEncoder
encoder = LabelEncoder()
y = iris.target
y = encoder.fit_transform(y)

# 數(shù)據(jù)可視化
plt.scatter(X[y==0,0], X[y==0,1], color="red", marker="o")
plt.scatter(X[y==1,0], X[y==1,1], color="blue", marker="+")
plt.scatter(X[y==2,0], X[y==2,1], color="green", marker="x")
plt.show()

②以花瓣長度暴拄、寬度為特征值

X = iris.data[:, 2:]

from sklearn.preprocessing import LabelEncoder
encoder = LabelEncoder()
y = iris.target
y = encoder.fit_transform(y)

# 數(shù)據(jù)可視化
plt.scatter(X[y==0,0], X[y==0,1], color="red", marker="o")
plt.scatter(X[y==1,0], X[y==1,1], color="blue", marker="+")
plt.scatter(X[y==2,0], X[y==2,1], color="green", marker="x")
plt.show()
  • 訓(xùn)練集測試集切分
def train_test_set_split(X, y, test_ratio=0.2, seed=None):
    assert X.shape[0] == y.shape[0], "ERROR: the size of X must be equal to the size of y!"
    assert 0.0 <= test_ratio <= 1.0, "ERROR :test_radio must be valid!"
    
    if seed:
        np.random.seed(seed)
        
    # 返回隨機打亂排列后的索引
    shuffle_indexes = np.random.permutation(len(X))
    
    tets_size = int(len(X) * test_ratio)
    test_indexes = shuffle_indexes[:tets_size]
    train_indexes = shuffle_indexes[tets_size:]
    
    X_train = X[train_indexes]
    y_train = y[train_indexes]
    X_test = X[test_indexes]
    y_test = y[test_indexes]
    
    return X_train, y_train, X_test, y_test

X_train, y_train, X_test, y_test = train_test_set_split(X, y, 0.2)

或者使用scikit-learn封裝方法

import machine_learning
from machine_learning.module_selection import train_test_split
X_train, y_train, X_test, y_test = train_test_split(X, y, test_radio=0.2)

(4)訓(xùn)練模型

from sklearn.neighbors import KNeighborsClassifier
knn_clf = KNeighborsClassifier(n_neighbors=6)
knn_clf.fit(X_train, y_train)

(5)測試模型

y_predict = knn_clf.predict(X_test)
print("模型分類準(zhǔn)確率為{}".format(sum(y_predict==y_test)/len(y_test)))
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末漓滔,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子乖篷,更是在濱河造成了極大的恐慌响驴,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件撕蔼,死亡現(xiàn)場離奇詭異豁鲤,居然都是意外死亡,警方通過查閱死者的電腦和手機鲸沮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進(jìn)店門琳骡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人讼溺,你說我怎么就攤上這事楣号。” “怎么了怒坯?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵炫狱,是天一觀的道長。 經(jīng)常有香客問我剔猿,道長视译,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任归敬,我火速辦了婚禮酷含,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘汪茧。我一直安慰自己椅亚,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布陆爽。 她就那樣靜靜地躺著什往,像睡著了一般扳缕。 火紅的嫁衣襯著肌膚如雪慌闭。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天躯舔,我揣著相機與錄音驴剔,去河邊找鬼。 笑死粥庄,一個胖子當(dāng)著我的面吹牛丧失,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播惜互,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼布讹,長吁一口氣:“原來是場噩夢啊……” “哼琳拭!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起描验,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤白嘁,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后膘流,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體絮缅,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年呼股,在試婚紗的時候發(fā)現(xiàn)自己被綠了耕魄。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡彭谁,死狀恐怖吸奴,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情缠局,我是刑警寧澤奄抽,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站甩鳄,受9級特大地震影響逞度,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜妙啃,卻給世界環(huán)境...
    茶點故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一档泽、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧揖赴,春花似錦馆匿、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至铭拧,卻和暖如春赃蛛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背搀菩。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工呕臂, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人肪跋。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓歧蒋,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子谜洽,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,486評論 2 348

推薦閱讀更多精彩內(nèi)容