機(jī)器學(xué)習(xí)實(shí)戰(zhàn)筆記-k近鄰算法

優(yōu)點(diǎn)

精度高、對(duì)異常值不敏感俭尖、無(wú)數(shù)據(jù)輸入假定

缺點(diǎn)

計(jì)算復(fù)雜度高纫塌、空間復(fù)雜度高

適用數(shù)據(jù)范圍

數(shù)值型和標(biāo)稱型
標(biāo)稱型:標(biāo)稱型目標(biāo)變量的結(jié)果只在有限目標(biāo)集中取值,如真與假(主要用來(lái)分類)
數(shù)值型:數(shù)值型目標(biāo)變量可以從無(wú)限的數(shù)值集合中取值绊茧,如0.2300,1111.1111等(主要用來(lái)回歸)

工作原理

存在一個(gè)樣本數(shù)據(jù)集合打掘,也稱作訓(xùn)練樣本集华畏,并且樣本集中每個(gè)數(shù)據(jù)都存在標(biāo)簽,即我們知道樣本集中每一個(gè)數(shù)據(jù)與所屬分類的對(duì)應(yīng)關(guān)系尊蚁。輸入沒(méi)有標(biāo)簽的新數(shù)據(jù)后亡笑,將新數(shù)據(jù)的每個(gè)特征與樣本集中數(shù)據(jù)對(duì)應(yīng)的特征進(jìn)行比較,然后算法提取樣本集中特征最相似數(shù)據(jù)(最近鄰)的分類標(biāo)簽横朋。一般來(lái)說(shuō)仑乌,我們只選擇樣本數(shù)據(jù)集中前k個(gè)最相似的數(shù)據(jù),這就是k-近鄰算法中k的出處琴锭,通常是k不大于20的整數(shù)晰甚。最后,選擇k個(gè)最相似數(shù)據(jù)中出現(xiàn)次數(shù)最多的分類决帖,作為新數(shù)據(jù)的分類厕九。

《統(tǒng)計(jì)學(xué)習(xí)方法》中的解釋

給定一個(gè)訓(xùn)練數(shù)據(jù)集,對(duì)新的輸入實(shí)例地回,在訓(xùn)練數(shù)據(jù)集中找到與該實(shí)例最鄰近的k個(gè)實(shí)例扁远,這k個(gè)實(shí)例的多數(shù)屬于某個(gè)類,就把該輸入實(shí)例分到這個(gè)類刻像。

k-近鄰算法的一般流程

1.收集數(shù)據(jù):anyway
2.準(zhǔn)備數(shù)據(jù):距離計(jì)算所需要的數(shù)值畅买,最好是結(jié)構(gòu)化的數(shù)據(jù)格式。
3.分析數(shù)據(jù):anyway
4.訓(xùn)練算法:此步驟不適用于k-近鄰算法
5.測(cè)試算法:計(jì)算錯(cuò)誤率
6.使用算法:首先需要輸入樣本數(shù)據(jù)和結(jié)構(gòu)化的輸出結(jié)果细睡,然后運(yùn)行k-鄰近算法判定輸入數(shù)據(jù)分別屬于哪個(gè)分類谷羞,最后應(yīng)用對(duì)計(jì)算出的分類執(zhí)行后續(xù)的處理。

對(duì)未知類別屬性的數(shù)據(jù)集中的每個(gè)點(diǎn)依次執(zhí)行以下操作:

1.計(jì)算一直類別數(shù)據(jù)集中的點(diǎn)與當(dāng)前點(diǎn)之間的距離
2.按照距離遞增次序排序
3.選取與當(dāng)前距離最小的k個(gè)點(diǎn)
4.確定前k個(gè)點(diǎn)所在類別出現(xiàn)的頻率
5.返回前k個(gè)點(diǎn)出現(xiàn)頻率最高的類別作為當(dāng)前點(diǎn)的預(yù)測(cè)分類

具體代碼

import numpy as np
import operator
import matplotlib
import matplotlib.pyplot as plt
import os


def create_date_set():
    group = np.array([[1.0, 1.1], [1.0, 1.0], [0, 0], [0, 0.1]])
    labels = ['A', 'A', 'B', 'B']
    return group, labels


'''
:parameter
輸入向量:in_x, 輸入的訓(xùn)練樣本:data_set, 標(biāo)簽向量:labels, 
表示用于選擇最近鄰居的數(shù)目
'''


def classify0(in_x, data_set, labels, k):
    data_set_size = data_set.shape[0]
    # tile(original, (a, b)) 將原來(lái)的矩陣行復(fù)制倍,列復(fù)制a倍
    # 計(jì)算歐氏距離
    diff_mat = np.tile(in_x, (data_set_size, 1)) - data_set
    sq_diff_mat = diff_mat ** 2
    # 相加為一個(gè)列向量
    sq_distances = sq_diff_mat.sum(axis=1)
    # 開方
    distances = sq_distances ** 0.5
    # 從小到大排列溜徙,返回該值在原來(lái)值中的索引
    sorted_dist_indices = distances.argsort()
    class_count = {}
    # 計(jì)算在鄰居中哪一類最多
    for i in range(k):
        votel_label = labels[sorted_dist_indices[i]]
        class_count[votel_label] = class_count.get(votel_label, 0) + 1
    sorted_class_count = sorted(class_count.items(), key=operator.itemgetter(1), reverse=True)  #
    return sorted_class_count[0][0]


# 讀取文件湃缎,形成數(shù)據(jù)集和標(biāo)簽
def file2matrix(filename):
    with open(filename, 'r', encoding='UTF-8') as fr:
        lines = fr.readlines()
        number_of_lines = len(lines)
        mat = np.zeros((number_of_lines, 3))
        class_label_vector = []
        index = 0
        for line in lines:
            line = line.strip()
            content = line.split('\t')
            mat[index, :] = content[0:3]
            class_label_vector.append(int(content[-1]))
            index += 1
        return mat, class_label_vector


# 歸一化特征值
def auto_norm(data_set):
    min_value = data_set.min(0)
    max_value = data_set.max(0)
    ranges = max_value - min_value
    norm_data_set = np.zeros(np.shape(data_set))
    m = data_set.shape[0]
    norm_data_set = data_set - np.tile(min_value, (m, 1))
    norm_data_set = norm_data_set / np.tile(ranges, (m, 1))
    return norm_data_set, ranges, min_value


# 測(cè)試
def dating_class_test():
    ho_ratio = 0.2
    dating_data_mat, dating_labels = file2matrix("./MLiA_SourceCode/machinelearninginaction/Ch02"
                                                 "/datingTestSet2.txt")
    nor_mat, ranges, min_vals = auto_norm(dating_data_mat)
    m = nor_mat.shape[0]
    num_test_vecs = int(m * ho_ratio)
    error_count = 0.0
    for i in range(num_test_vecs):
        classifier_result = classify0(nor_mat[i, :], nor_mat[num_test_vecs:m, :],
                                      dating_labels[num_test_vecs:m], 3)
        print("the classifier came back with: %d, the real answer is: %d"
              % (classifier_result, dating_labels[i]))
        if classifier_result != dating_labels[i]:
            error_count += 1
    print("the total error rate is: %f" % (error_count / float(num_test_vecs)))


# 約會(huì)網(wǎng)站預(yù)測(cè)函數(shù)
def classify_person():
    result_list = ['not at all', 'in small doses', 'in large doses']
    percent_tats = float(input("percentage of time spent playing video games?"))
    ice_cream = float(input("liters of ice cream consumed per year?"))
    ff_miles = float(input("frequent flier miles earned per year?"))

    dating_data_mat, dating_labels = file2matrix("./MLiA_SourceCode/machinelearninginaction/Ch02"
                                                 "/datingTestSet2.txt")
    nor_mat, ranges, min_vals = auto_norm(dating_data_mat)
    in_arr = np.array([ff_miles, percent_tats, ice_cream])
    classifier_result = classify0((in_arr - min_vals) / ranges, nor_mat, dating_labels, 3)

    print("You will probably like this person: ", result_list[classifier_result - 1])


# 將圖片轉(zhuǎn)換為vector
def img2vector(filename):
    vector = np.zeros((1, 1024))
    with open(filename, 'r', ecoding='utf-8') as fp:
        for i in range(32):
            line_str  = fp.readline()
            for j in range(32):
                vector[0, 32 * i * j] = int(line_str[j])

    return vector

項(xiàng)目地址:https://github.com/RJzz/Machine.git

關(guān)于k值的選擇

1.k值的減小就意味著模型整體變復(fù)雜购公,相當(dāng)于用較大領(lǐng)域中的訓(xùn)練實(shí)例進(jìn)行預(yù)測(cè),容易發(fā)生過(guò)擬合雁歌。
2.k值過(guò)大,意味著整體的模型變簡(jiǎn)單知残。
3.在應(yīng)用中靠瞎,k值一般取一個(gè)比較小的數(shù)值,通常采用交叉驗(yàn)證法來(lái)選取最優(yōu)的k值求妹。

后續(xù)

這樣的kNN實(shí)際上代碼非常的高乏盐,優(yōu)化的方法可以是構(gòu)造kd樹,kd樹是一種對(duì)k維空間中的實(shí)例點(diǎn)進(jìn)行存儲(chǔ)以便對(duì)其進(jìn)行快速檢索的樹形數(shù)據(jù)結(jié)構(gòu)制恍。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末父能,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子净神,更是在濱河造成了極大的恐慌何吝,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鹃唯,死亡現(xiàn)場(chǎng)離奇詭異爱榕,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)坡慌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門黔酥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人洪橘,你說(shuō)我怎么就攤上這事跪者。” “怎么了熄求?”我有些...
    開封第一講書人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵渣玲,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我抡四,道長(zhǎng)柜蜈,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任指巡,我火速辦了婚禮淑履,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘藻雪。我一直安慰自己秘噪,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開白布勉耀。 她就那樣靜靜地躺著指煎,像睡著了一般蹋偏。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上至壤,一...
    開封第一講書人閱讀 49,111評(píng)論 1 285
  • 那天威始,我揣著相機(jī)與錄音,去河邊找鬼像街。 笑死黎棠,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的镰绎。 我是一名探鬼主播脓斩,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼畴栖!你這毒婦竟也來(lái)了随静?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤吗讶,失蹤者是張志新(化名)和其女友劉穎燎猛,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體关翎,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡扛门,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了纵寝。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片论寨。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖爽茴,靈堂內(nèi)的尸體忽然破棺而出葬凳,到底是詐尸還是另有隱情,我是刑警寧澤室奏,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布火焰,位于F島的核電站,受9級(jí)特大地震影響胧沫,放射性物質(zhì)發(fā)生泄漏昌简。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一绒怨、第九天 我趴在偏房一處隱蔽的房頂上張望纯赎。 院中可真熱鬧,春花似錦南蹂、人聲如沸犬金。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)晚顷。三九已至峰伙,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間该默,已是汗流浹背瞳氓。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留栓袖,地道東北人顿膨。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像叽赊,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子必搞,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345

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