K-近鄰算法(KNN) ### 如何進行電影分類 衆所周知,電影能夠按照題材分類,然而題材自己是如何定義的?由誰來斷定某部電影屬於哪 個題材?也就是說同一題材的電影具備哪些公共特徵?這些都是在進行電影分類時必需要考慮的問 題。沒有哪一個電影人會說本身製做的電影和之前的某部電影相似,但咱們確實知道每部電影在風格 上的確有可能會和同題材的電影相近。那麼動做片具備哪些共有特徵,使得動做片之間很是相似, 而與愛情片存在着明顯的差異呢?動做片中也會存在接吻鏡頭,愛情片中也會存在打鬥場景,咱們 不能單純依靠是否存在打鬥或者親吻來判斷影片的類型。可是愛情片中的親吻鏡頭更多,動做片中 的打鬥場景也更頻繁,基於此類場景在某部電影中出現的次數能夠用來進行電影分類。 本章介紹第一個機器學習算法:K-近鄰算法,它很是有效並且易於掌握
簡單地說,K-近鄰算法採用測量不一樣特徵值之間的距離方法進行分類。 - 優勢:精度高(計算距離)、對異常值不敏感(單純根據距離進行分類,會忽略特殊狀況)、無數據輸入假定(不會對數據預先進行斷定)。 - 缺點:時間複雜度高、空間複雜度高。 - 適用數據範圍:數值型和標稱型。
工做原理python
存在一個樣本數據集合,也稱做訓練樣本集,而且樣本集中每一個數據都存在標籤,即咱們知道樣本集中每一數據 與所屬分類的對應關係。輸人沒有標籤的新數據後,將新數據的每一個特徵與樣本集中數據對應的 特徵進行比較,而後算法提取樣本集中特徵最類似數據(最近鄰)的分類標籤。通常來講,咱們 只選擇樣本數據集中前K個最類似的數據,這就是K-近鄰算法中K的出處,一般*K是不大於20的整數。 最後 ,選擇K個最類似數據中出現次數最多的分類,做爲新數據的分類 回到前面電影分類的例子,使用K-近鄰算法分類愛情片和動做片。有人曾經統計過不少電影的打鬥鏡頭和接吻鏡頭,下圖顯示了6部電影的打鬥和接吻次數。假若有一部未看過的電影,如何肯定它是愛情片仍是動做片呢?咱們可使用K-近鄰算法來解決這個問題。
即便不知道未知電影屬於哪一種類型,咱們也能夠經過某種方法計算出來。首先計算未知電影與樣本集中其餘電影的距離,如圖所示。
如今咱們獲得了樣本集中全部電影與未知電影的距離,按照距離遞增排序,能夠找到K個距 離最近的電影。假定k=3,則三個最靠近的電影依次是California Man、He's Not Really into Dudes、Beautiful Woman。K-近鄰算法按照距離最近的三部電影的類型,決定未知電影的類型,而這三部電影全是愛情片,所以咱們斷定未知電影是愛情片。
歐幾里得距離(Euclidean Distance)算法
歐氏距離是最多見的距離度量,衡量的是多維空間中各個點之間的絕對距離。公式以下:機器學習
分類問題:from sklearn.neighbors import KNeighborsClassifier 0)一個最簡單的例子 對電影進行分類 import pandas as pd import numpy as np # 導入數據 data = pd.read_excel('../../my_films.xlsx') # 樣本數據的提取 feature = data[['Action lens','Love lens']] target = data['target'] # 訓練模型 from sklearn.neighbors import KNeighborsClassifier knn = KNeighborsClassifier(n_neighbors=3) # n_neighbors 就是k ,n_neighbors=3是找到附近的3個鄰居 knn.fit(feature,target) # 傳入數據 模型訓練完成 # 進行預測 knn.predict([[19,19]]) # array(['Love'], dtype=object) # 一種簡單的方法肯定k的值 # score knn.score(feature,target)
# 讀取adult.txt文件,最後一列是年收入,並使用KNN算法訓練模型,而後使用模型預測一我的的年收入是否大於50 df = pd.read_csv(r'C:\Users\lucky\Desktop\爬蟲+數據\oldBoy數據授課\1.KNN\1-KNN\data\adults.txt') # 查看數據 df.head(2) # 獲取年齡、教育程度、職位、每週工做時間做爲機器學習數據 # 獲取薪水做爲對應結果 #樣本數據的提取 feature = df[['age','education_num','occupation','hours_per_week']] target = df['salary'] # 查看數據 feature.head(3) age education_num occupation hours_per_week 0 39 13 Adm-clerical 40 1 50 13 Exec-managerial 13 2 38 9 Handlers-cleaners 40
# 數據轉換,將String類型數據轉換爲int 由於字符串沒辦法作運算 # 【知識點】map方法,進行數據轉換 s = feature['occupation'].unique() dic = {} j = 0 for i in s: dic[i] = j j += 1 feature['occupation'] = feature['occupation'].map(dic) # 查看數據 feature.head() age education_num occupation hours_per_week 0 39 13 0 40 1 50 13 1 13 2 38 9 2 40 3 53 7 2 40 4 28 13 3 40
#樣本數據的拆分 32560 x_train = feature[:32500] y_train = target[:32500] x_test = feature[32500:] y_test = target[32500:] knn = KNeighborsClassifier(n_neighbors=50) knn.fit(x_train,y_train) knn.score(x_test,y_test) # 0.7868852459016393 #使用測試數據進行測試 print('真實的分類結果:',np.array(y_test)) print('模型的分類結果:',np.array(knn.predict(x_test))) 真實的分類結果: ['<=50K' '<=50K' '<=50K' '<=50K' '>50K' '<=50K' '>50K' '<=50K' '<=50K' '<=50K' '>50K' '<=50K' '<=50K' '>50K' '<=50K' '<=50K' '<=50K' '<=50K' '>50K' '>50K' '<=50K' '<=50K' '<=50K' '<=50K' '<=50K' '<=50K' '<=50K' '<=50K' '<=50K' '<=50K' '>50K' '<=50K' '>50K' '>50K' '<=50K' '<=50K' '>50K' '<=50K' '>50K' '>50K' '<=50K' '<=50K' '<=50K' '<=50K' '<=50K' '>50K' '<=50K' '<=50K' '<=50K' '<=50K' '<=50K' '<=50K' '<=50K' '<=50K' '>50K' '<=50K' '<=50K' '>50K' '<=50K' '<=50K' '>50K'] 模型的分類結果: ['<=50K' '<=50K' '>50K' '<=50K' '>50K' '<=50K' '<=50K' '<=50K' '<=50K' '<=50K' '<=50K' '<=50K' '<=50K' '<=50K' '<=50K' '<=50K' '<=50K' '<=50K' '<=50K' '<=50K' '<=50K' '<=50K' '<=50K' '<=50K' '<=50K' '<=50K' '<=50K' '<=50K' '<=50K' '<=50K' '<=50K' '<=50K' '>50K' '>50K' '<=50K' '<=50K' '>50K' '<=50K' '>50K' '<=50K' '<=50K' '<=50K' '<=50K' '>50K' '<=50K' '<=50K' '<=50K' '<=50K' '>50K' '<=50K' '<=50K' '<=50K' '<=50K' '<=50K' '>50K' '<=50K' '<=50K' '<=50K' '<=50K' '<=50K' '<=50K'] knn.predict([[50,12,4,50]]) # array(['>50K'], dtype=object)