一看就懂的 機器學習k-近鄰算法(KNN)

基礎知識:
1,機器學習想相關概念:
在這裏插入圖片描述

  • 機器學習(Machine Learning,ML):是人工智能的一個分支,是實現人工智能的一個途徑,即以機器學習爲手段解決人工智能中的問題。讓一個計算機程序針對某一個特定任務,從經驗中學習,並且越來越好。
  • 深度學習(DeepLearning,DL):是機器學習拉出的分支,是機器學習算法中的一種算法,一種實現機器學習的技術和學習方法。

2,機器學習和深度學習的應用:

  • 機器學習的應用: 淘寶推送、電影猜你喜歡等推薦系統,數據挖掘,計算機視覺,自然語言處理,生物特徵識別,搜索引擎,醫學診斷,檢測信用卡欺騙,語音識別與手寫識別,戰略遊戲,機器人等。
  • 深度學習的應用: AlphaGo,語音識別,圖像識別,文字識 別,智能監控。

3,機器學習類型

  • 監督學習:訓練集包含特徵x和目標y,且目標人爲標註 。根據訓練集學習出一個函數,當新的數據到來的時候,可以根據這個函數預測結果。
  • 無監督學習:有訓練集,有輸入和輸出。與監督學習相比,訓練集沒有人爲標註,不告訴模型目標是什麼。
  • 半監督學習:介於監督學習和無監督學習之間
  • 強化學習: 通過觀察來學習做成某種動作,每個動作都會對環境有所影響,學習對象根據觀察到的周圍環境的反饋來作出判斷。

K-近鄰算法(KNN)是 機器學習中的有監督學習中聚類模型

1,概念原理:K-近鄰算法(K-Nearest Neighbour algorithm, KNN),是數據挖掘技術中原理最簡單的算法。給定一個已知標籤類別的訓練數據集,輸入沒有標籤的新數據後,在訓練數據集中找到與新數據最鄰近的K個實例,如果這K個實例中的多數屬於某個類別,那麼新數據就屬於這個類別。簡單理解爲:由那些離X最近的K個點來投票 決定X歸爲哪一類。
在這裏插入圖片描述
舉個栗子:使用k-近鄰算法分類一個電影是愛情片還是動作片
在這裏插入圖片描述
在這個表格中, 每個電影有兩個特徵,我們可以通過人眼判斷出新電影屬於什麼類型,那如果是N個呢?這就需要k-近鄰算法上場啦!
我們將表格畫爲散點圖如下:
在這裏插入圖片描述
通過觀察,從散點圖中大致判斷,新電影是愛情片。那KNN算法是如何判斷的呢? 沒錯,就是距離!
二維平面兩點間距離公式:
在這裏插入圖片描述
N維空間兩點間距離公式:
在這裏插入圖片描述
通過計算我們可以得到訓練集中所有電影與未知電影的距離,如下表所示:
在這裏插入圖片描述
通過上表的計算結果,可以得出新電影到愛情片《後來的我們》距離最近,爲29.1.如果僅僅根據這個結果,就判定新電影爲愛情片,那這個算法就叫最近鄰算法,而非k-近鄰算法、
k-近鄰算法步驟如下:
在這裏插入圖片描述
在這裏插入圖片描述
2,k-近鄰算法的Python實現

 #構建數據集
import pandas as pd

filmdata = {
    '電影名稱':['無問西東','後來的我們','前任3','紅海行動','唐人街探案','戰狼2'],
    '打鬥鏡頭':[1,5,12,108,112,115],
    '接吻鏡頭':[101,89,97,5,9,8],
    '電影類型':['愛情片','愛情片','愛情片','動作片','動作片','動作片',]
}

film_data = pd.DataFrame(filmdata)
print(film_data)

#計算已知類別中數據點與當前點的距離
new_data = [24,67]
dist = list( (((film_data.iloc[:6,1:3]-new_data)**2).sum(1))**0.5 )
print(dist)

#對距離進行排序,然後選擇距離最近的k個點
k = 4
dist_l = pd.DataFrame( { 'dist':dist, 'labels':(film_data.iloc[:6,3]) } )
dr = dist_l.sort_values(by='dist')[:k]
print(dr)

3,封裝函數

import pandas as pd

filmdata = {
    '電影名稱':['無問西東','後來的我們','前任3','紅海行動','唐人街探案','戰狼2'],
    '打鬥鏡頭':[1,5,12,108,112,115],
    '接吻鏡頭':[101,89,97,5,9,8],
    '電影類型':['愛情片','愛情片','愛情片','動作片','動作片','動作片',]
}
film_data = pd.DataFrame(filmdata)
new_data = [24,67]

'''
函數功能:KNN分類器
參數說明:
    inX: 需要進行預測分類的數據集
    dataSet: 已知分類標籤的數據集(訓練集 )
    k: 超參數,選擇距離最小的k個點
返回:
     result: 預測分類結果
'''
def classify0(inX,dataSet,k):
    result = []
    dist = list((((dataSet.iloc[:, 1:3] - inX) ** 2).sum(1)) ** 0.5)
    dist_l = pd.DataFrame({'dist': dist, 'labels': (dataSet.iloc[:, 3])})
    dr = dist_l.sort_values(by='dist')[:k]
    re = dr.loc[:, 'labels'].value_counts()
    result.append(re.index[0])
    return result

inX = new_data
dataSet = film_data
k = 4

print(  classify0(inX,dataSet,k)  )

這就是我們使用k-近鄰算法構建的一個分類器,可以看出,分類器給的答案還是比較符合我們的預期的。

那麼問題來了:分類器給出的答案是否永遠都正確? 答案一定是否定的,分類器並不會得到100%正確的結果,我們可以使用很多方法來驗證分類器的準確率。 此外,分類器的性能會受到很多因素的影響,比如 k的取值,就在很大程度上影響了分類器的預測結果,還有分類器的設置、原始數據集等等。 爲了測試分類器的效果,我們可以把原始數據集分爲兩部分,一部分用來訓練算法,稱爲訓練集;另一部分用來測試算法的準確率,稱爲測試集。 我們不難發現,k-近鄰算法沒有進行數據的訓練,直接使用未知的數據與已知的數據進行比較,得到結果,因此,k-近鄰算法不具有顯示的學習過程。

4,總結
在這裏插入圖片描述
優點:

  • 簡單好用,容易理解,精度高,理論成熟,既可以用來做分類,也可以用來做迴歸
  • 可用於數值型數據和離散型數據
  • 無數據輸入假定
  • 適合對稀有事件進行分類

缺點:

  • 計算複雜性高;空間複雜性高
  • 計算量太大,所以一般數值很大的時候不用這個;但是單個樣本又不能太少,否則容易發生誤分
  • 樣本不平衡問題(即有些類別的樣本數量很多,而其他樣本的數量很小)
  • 可理解性比較差,無法給出數據的內在含義
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章