#%% md
# K-近鄰算法(KNN)
#%% md
K nearest neighbour
#%% md
## 0、導引
#%% md
### 如何進行電影分類
衆所周知,電影可以按照題材分類,然而題材本身是如何定義的?由誰來判定某部電影屬於哪
個題材?也就是說同一題材的電影具有哪些公共特徵?這些都是在進行電影分類時必須要考慮的問
題。沒有哪個電影人會說自己製作的電影和以前的某部電影類似,但我們確實知道每部電影在風格
上的確有可能會和同題材的電影相近。那麼動作片具有哪些共有特徵,使得動作片之間非常類似,
而與愛情片存在着明顯的差別呢?動作片中也會存在接吻鏡頭,愛情片中也會存在打鬥場景,我們
不能單純依靠是否存在打鬥或者親吻來判斷影片的類型。但是愛情片中的親吻鏡頭更多,動作片中
的打鬥場景也更頻繁,基於此類場景在某部電影中出現的次數可以用來進行電影分類。
#%% md
## 1、k-近鄰算法原理
#%% md
簡單地說,K-近鄰算法採用測量不同特徵值之間的距離方法進行分類。
#%% md
- 優點:精度高、對異常值不敏感、無數據輸入假定。
- 缺點:時間複雜度高、空間複雜度高。
- 適用數據範圍:數值型和標稱型。
#%% md
### 工作原理
#%% md
存在一個樣本數據集合,也稱作訓練樣本集,並且樣本集中每個數據都存在標籤,即我們知道樣本集中每一數據
與所屬分類的對應關係。輸人沒有標籤的新數據後,將新數據的每個特徵與樣本集中數據對應的
特徵進行比較,然後算法提取樣本集中特徵最相似數據(最近鄰)的分類標籤。一般來說,我們
只選擇樣本數據集中前K個最相似的數據,這就是K-近鄰算法中K的出處,通常*K是不大於20的整數。
最後 ,選擇K個最相似數據中出現次數最多的分類,作爲新數據的分類*。
#%% md
回到前面電影分類的例子,使用K-近鄰算法分類愛情片和動作片。有人曾經統計過很多電影的打鬥鏡頭和接吻鏡頭,下圖顯示了6部電影的打鬥和接吻次數。假如有一部未看過的電影,如何確定它是愛情片還是動作片呢?我們可以使用K-近鄰算法來解決這個問題。
![1.PNG](attachment:1.PNG)
#%% md
首先我們需要知道這個未知電影存在多少個打鬥鏡頭和接吻鏡頭,上圖中問號位置是該未知電影出現的鏡頭數圖形化展示,具體數字參見下表。
![2.PNG](attachment:2.PNG)
#%% md
即使不知道未知電影屬於哪種類型,我們也可以通過某種方法計算出來。首先計算未知電影與樣本集中其他電影的距離,如圖所示。
![3.PNG](attachment:3.PNG)
#%% md
現在我們得到了樣本集中所有電影與未知電影的距離,按照距離遞增排序,可以找到K個距
離最近的電影。假定k=3,則三個最靠近的電影依次是California Man、He's Not Really into Dudes、Beautiful Woman。K-近鄰算法按照距離最近的三部電影的類型,決定未知電影的類型,而這三部電影全是愛情片,因此我們判定未知電影是愛情片。
#%% md
### 歐幾里得距離(Euclidean Distance)
#%% md
歐氏距離是最常見的距離度量,衡量的是多維空間中各個點之間的絕對距離。公式如下:
![4.png](attachment:4.png)
#%% md
## 2、在scikit-learn庫中使用k-近鄰算法
#%% md
- 分類問題:from sklearn.neighbors import KNeighborsClassifier
- 迴歸問題:from sklearn.neighbors import KNeighborsRegressor
#%% md
### 0)一個最簡單的例子
#%% md
身高、體重、鞋子尺碼數據對應性別
#%%
import numpy as np
#%%
from sklearn.neighbors import KNeighborsClassifier
#%%
X_train = np.array([[175,65,43],[160,50,37],[180,75,44],[175,55,40],[165,65,41]])
y_labels = ['男','女','男','女','男']
knn = KNeighborsClassifier()
#%%
knn.fit(X_train,y_labels)
#%%
#進行預測
x_test = np.array([[172,68,42]])
knn.predict(x_test)
#%% md
### 1)用於分類
#%% md
導包,機器學習的算法KNN、數據藍蝴蝶
#%%
import sklearn.datasets as datasets
#%%
iris = datasets.load_iris()
iris
#%%
#獲取數據
data = iris.data
target = iris.target
#%%
#導入拆分的工具
from sklearn.model_selection import train_test_split
#讓計算機學習一部分數據,另一部分,計算機沒有接觸過
#讓計算機預測沒有接觸的數據,分類,識別這些數據
#%%
X_train,x_test,y_train,y_test = train_test_split(data,target,test_size = 0.1)
#%%
#訓練
knn = KNeighborsClassifier(n_neighbors= 10)
knn.fit(X_train,y_train)
#%%
#預測數據
knn.predict(x_test)
#%%
#真實的結果
y_test
#%%
x_test.shape
#%%
knn.score(x_test,y_test)
#%%
knn.score(data,target)
#%% md
獲取訓練樣本
#%%
data.shape
#%%
data = iris.data
#%%
data = data[:,:2]
data
#%% md
繪製圖形
#%%
import matplotlib.pyplot as plt
%matplotlib inline
#%%
target
#%%
#c = target 代表分類
plt.scatter(data[:,0],data[:,1],c = target,cmap = 'rainbow')
#%% md
定義KNN分類器
#%%
knn = KNeighborsClassifier(10)
#%% md
第一步,訓練數據
#%%
# 訓練處理之後的數據data
knn.fit(data,target)
#%% md
第二步預測數據:,所預測的數據,自己創造,就是上面所顯示圖片的背景點
生成預測數據
#%%
#提取x,y軸的範圍
x_min,x_max = data[:,0].min(),data[:,0].max()
y_min,y_max = data[:,1].min(),data[:,1].max()
x = np.linspace(x_min,x_max,1000)
y = np.linspace(y_min,y_max,650)
#np.meshgrid
X,Y = np.meshgrid(x,y)
#%%
display(X.shape,Y.shape)
#%%
# X Y 就是圖像中所有的點,交叉融合
#np.c_[]
a = [1,2,3]
b = [-1,-2,-5]
#
np.c_[a,b]
#%%
c = np.array([[4.3,4.4,4.5,4.6],[4.3,4.4,4.5,4.6],[4.3,4.4,4.5,4.6]])
d = np.array([[2,2,2,2],[2.1,2.1,2.1,2.1],[2.2,2.2,2.2,2.2]])
#展開,變成1維
cc = c.ravel()
dd = d.ravel()
np.c_[cc,dd]
#%%
xy_test = np.c_[X.ravel(),Y.ravel()]
#%%
xy_test.shape
#%% md
對數據進行預測
#%%
y_ = knn.predict(xy_test)
#%% md
顯示數據
#%%
plt.scatter(data[:,0],data[:,1],c = target)
#%%
plt.pcolormesh(X,Y,y_.reshape(X.shape))
plt.scatter(data[:,0],data[:,1],c = target,cmap = 'rainbow')
#%% md
### 2)用於迴歸
迴歸用於對趨勢的預測
#%% md
導包
#%%
#%% md
生成樣本數據
#%%
#%% md
生成測試數據的結果
#%%
#%% md
第一步:生成模型,並訓練數據
#%%
#%% md
第二步:使用模型,預測數據
#%%
#%% md
繪圖顯示數據
#%%
#%%
#%% md
### 練習
人類動作識別
步行,上樓,下樓,坐着,站立和躺着
![](stand-sit-run.jpg)
數據採集每個人在腰部穿着智能手機,進行了六個活動(步行,上樓,下樓,坐着,站立和躺着)。採用嵌入式加速度計和陀螺儀,以50Hz的恆定速度捕獲3軸線性加速度和3軸角速度,來獲取數據
#%% md
導入數據
#%%
#%% md
獲取數據
#%%
#%% md
繪製
#%% md
## 3、作業
#%% md
#### 1、預測年收入是否大於50K美元
#%% md
讀取adult.txt文件,最後一列是年收入,並使用KNN算法訓練模型,然後使用模型預測一個人的年收入是否大於50
#%%
#%% md
獲取年齡、教育程度、職位、每週工作時間作爲機器學習數據
獲取薪水作爲對應結果
#%%
#%% md
數據轉換,將String類型數據轉換爲int
#%% md
【知識點】map方法,進行數據轉換
#%%
#%% md
切片:訓練數據和預測數據
#%%
#%% md
生成算法
#%%
#%% md
第一步:訓練數據
#%%
#%% md
第二步:預測數據
#%%
#%% md
保存訓練模型
from sklearn.externals import joblib
#%%
#%% md
#### 2、小麥種類預測
#%% md
讀取seeds.tsv文件,最後一列是小麥品種,其他列是小麥特徵
#%% md
#### 3、改進約會網站的匹配效果
#%% md
讀取datingTestSet.txt文件,最後一列是喜歡程度。模型:根據前幾列的信息,預測喜歡程度