人工智能AI培訓(xùn)_機(jī)器學(xué)習(xí)之K近鄰算法
1.k近鄰簡(jiǎn)介k近鄰法(k-nearest neighbor,k-NN)是1967年由Cover T和Hart P提出的一種基本分類與回歸方法。它的工作原理是:存在一個(gè)樣本數(shù)據(jù)集合,也稱作為訓(xùn)練樣本集,并且樣本集中每個(gè)數(shù)據(jù)都存在標(biāo)簽,即我們知道樣本集中每一個(gè)數(shù)據(jù)與所屬分類的對(duì)應(yīng)關(guān)系。輸入沒有標(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ù)的分類。
舉個(gè)簡(jiǎn)單的例子,我們可以使用k-近鄰算法分類一個(gè)電影是愛情片還是動(dòng)作片。
圖1 上表每部電影的打斗鏡頭數(shù)、接吻鏡頭數(shù)以及電影類型
上表就是我們已有的數(shù)據(jù)集合,也就是訓(xùn)練樣本集。這個(gè)數(shù)據(jù)集有兩個(gè)特征,即打斗鏡頭數(shù)和接吻鏡頭數(shù)。除此之外,我們也知道每個(gè)電影的所屬類型,即分類標(biāo)簽。用肉眼粗略地觀察,接吻鏡頭多的,是愛情片。打斗鏡頭多的,是動(dòng)作片。以我們多年的看片經(jīng)驗(yàn),這個(gè)分類還算合理。如果現(xiàn)在給我一部電影,你告訴我這個(gè)電影打斗鏡頭數(shù)和接吻鏡頭數(shù)。不告訴我這個(gè)電影類型,我可以根據(jù)你給我的信息進(jìn)行判斷,這個(gè)電影是屬于愛情片還是動(dòng)作片。而k-近鄰算法也可以像我們?nèi)艘粯幼龅竭@一點(diǎn),不同的地方在于,我們的經(jīng)驗(yàn)更”牛逼”,而k-鄰近算法是靠已有的數(shù)據(jù)。比如,你告訴我這個(gè)電影打斗鏡頭數(shù)為2,接吻鏡頭數(shù)為102,我的經(jīng)驗(yàn)會(huì)告訴你這個(gè)是愛情片,k-近鄰算法也會(huì)告訴你這個(gè)是愛情片。你又告訴我另一個(gè)電影打斗鏡頭數(shù)為49,接吻鏡頭數(shù)為51,我”邪惡”的經(jīng)驗(yàn)可能會(huì)告訴你,這有可能是個(gè)”愛情動(dòng)作片”,畫面太美,我不敢想象。(如果說(shuō),你不知道”愛情動(dòng)作片”是什么?請(qǐng)?jiān)u論留言與我聯(lián)系,我需要你這樣像我一樣純潔的朋友。) 但是k-近鄰算法不會(huì)告訴你這些,因?yàn)樵谒难劾铮娪邦愋椭挥袗矍槠蛣?dòng)作片,它會(huì)提取樣本集中特征最相似數(shù)據(jù)(最鄰近)的分類標(biāo)簽,得到的結(jié)果可能是愛情片,也可能是動(dòng)作片,但絕不會(huì)是”愛情動(dòng)作片”。當(dāng)然,這些取決于數(shù)據(jù)集的大小以及最近鄰的判斷標(biāo)準(zhǔn)等因素。
2.距離度量
我們已經(jīng)知道k-近鄰算法根據(jù)特征比較,然后提取樣本集中特征最相似數(shù)據(jù)(最鄰近)的分類標(biāo)簽。那么,如何進(jìn)行比較呢?比如,我們還是以表2為例,怎么判斷紅色圓點(diǎn)標(biāo)記的電影所屬的類別呢?如下圖所示:
??
圖2?
??
通過(guò)計(jì)算可知,紅色圓點(diǎn)標(biāo)記的電影到動(dòng)作片 (108,5)的距離最近,為16.55。如果算法直接根據(jù)這個(gè)結(jié)果,判斷該紅色圓點(diǎn)標(biāo)記的電影為動(dòng)作片,這個(gè)算法就是最近鄰算法,而非k-近鄰算法。那么k-鄰近算法是什么呢?k-近鄰算法步驟如下:
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è)分類。
比如,現(xiàn)在我這個(gè)k值取3,那么在電影例子中,按距離依次排序的三個(gè)點(diǎn)分別是動(dòng)作片(108,5)、動(dòng)作片(115,8)、愛情片(5,89)。在這三個(gè)點(diǎn)中,動(dòng)作片出現(xiàn)的頻率為三分之二,愛情片出現(xiàn)的頻率為三分之一,所以該紅色圓點(diǎn)標(biāo)記的電影為動(dòng)作片。這個(gè)判別過(guò)程就是k-近鄰算法。
3.k近鄰算法實(shí)例-預(yù)測(cè)入住位置??
importpandasaspdfromsklearn.model_selectionimporttrain_test_split,GridSearchCVfromsklearn.neighborsimportKNeighborsClassifierfromsklearn.preprocessingimportStandardScaler '''k近鄰'''defknncl():#讀取數(shù)據(jù)data = pd.read_csv("../data/train.csv") #處理數(shù)據(jù),選擇一部分?jǐn)?shù)據(jù)data = data.query("x>1.0 & x <1.25 & y>2.5 & y<2.75")#處理時(shí)間戳 2016-10-21 20:30:00time_value = pd.to_datetime(data["time"])#將時(shí)間轉(zhuǎn)成日歷的格式 {"day":...,"hour":...}time_value = pd.DatetimeIndex(time_value) #增加日期、小時(shí)、星期等幾個(gè)特征data["day"] = time_value.daydata["hour"] = time_value.hour data["weekday"] = time_value.weekday # 把時(shí)間戳特征刪除data = data.drop(["time"],axis=1) # 按place_id分組,統(tǒng)計(jì)每個(gè)位置的入住次數(shù)place_count = data.groupby("place_id").count()# print(place_count)# reset_index()將place_id單獨(dú)一列 tf = place_count[place_count.row_id > 3].reset_index()# 把簽到數(shù)據(jù)少于n個(gè)目標(biāo)位置刪除data = data[data['place_id'].isin(tf.place_id)] # 取出數(shù)據(jù)中的特征值的目標(biāo)值y = data['place_id']x = data.drop(['place_id'],axis=1) # 數(shù)據(jù)集分割,分成訓(xùn)練集和測(cè)試集x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.25) # 特征工程,標(biāo)準(zhǔn)化處理std = StandardScaler()# 對(duì)測(cè)試集和訓(xùn)練集的特征值進(jìn)行標(biāo)準(zhǔn)化x_train = std.fit_transform(x_train)x_test = std.transform(x_test) print(data.head(10))# 進(jìn)行算法流程 # 超參數(shù)knn = KNeighborsClassifier()knn.fit(x_train,y_train) y_predict = knn.predict(x_test) print("預(yù)測(cè)的目標(biāo)簽到位置為:",y_predict)# 得出準(zhǔn)確率print("預(yù)測(cè)的準(zhǔn)確率:",knn.score(x_test,y_test))
#進(jìn)行算法流程 # 超參數(shù) #網(wǎng)絡(luò)搜索# params = {"n_neighbors":[3,5,10]}# gc = GridSearchCV(knn,param_grid=params,cv=2)# gc.fit(x_train,y_train)## #預(yù)測(cè)數(shù)據(jù)# print("在測(cè)試集上準(zhǔn)確率:",gc.score(x_test,y_test))# print("在交叉驗(yàn)證當(dāng)中最好的結(jié)果:",gc.best_score_)# print("選擇最好的模型是:",gc.best_estimator_)# print("每個(gè)超參數(shù)每次交叉驗(yàn)證的結(jié)果:",gc.cv_results_)return None if__name__ =="__main__":knncl() |
985大學(xué) 211大學(xué) 全國(guó)院校對(duì)比 專升本