機器學習實戰一(kNN)
機器學習實戰一(kNN)
跟著老師做一個項目,關於行車記錄儀識別前方車輛,並判斷車距,不太好做。本來是用OpenCV,做著做著,突然發現需要補習一下機器學習的內容。《機器學習實戰(machine learing in action)》
這本書買了很久了,當時還是看了很多人推薦,不過到現在才想起翻出來看。第二章kNN的例子剛跟著做完,書裏講的很清楚,代碼條理分明,只不過我是用Python3實現的。具體的過程不再贅述,只是把自己的理解放在這裏。
先來看看書裏第一章的部分。
- 機器學習就是把無序的數據轉換成有用的信息。
- 機器學習橫跨計算機科學、工程技術和統計學等多個學科。
- 機器學習的主要任務,可分為監督學習
- 步驟:
- 收集數據(前期采集)
- 準備輸入數據(數據格式化)
- 分析輸入數據(探索型分析)
- 訓練算法
- 測試算法
- 使用算法
kNN(k-近鄰算法)
優點:精度高、對異常值不敏感、無數據輸入假定
缺點:計算復雜度高、空間復雜度高
適用數據範圍:數值型和標稱型
原理:已知一組數據的屬性值和類別標簽,給定一個輸入數據,判斷所屬類別。kNN的做法是計算輸入數據與所有已知數據的空間距離(歐氏距離),然後從小到大排列,取前k個數據,出現次數最多的類別標簽作為輸入數據的所屬類別。
歐式距離計算:$\sqrt {\left( x-x_{i}\right) ^{2}+\left( y-y_{i}\right) ^{2}+\ldots }$
核心代碼如下:
""" Created on 2017/12/30 19:13 kNN: k-近鄰算法 Input: inX: 用於判斷類別的矩陣 (1xN) dataSet: 已知類別的數據集向量 (NxM) labels: 數據集的標簽 (1xN) k: 用於比較的近鄰的數量 (應該是奇數) Output: 最可能的類標簽 @author: Lucifer @site: plantree.me @email: [email protected] """ import numpy as np import os import operator # kNN def classify0(inX, dataSet, labels, k): dataSetSize = dataSet.shape[0] # np.tile()將inX重復(dataSetSize, 1)次 diffMat = np.tile(inX, (dataSetSize, 1)) - dataSet sqDiffMat = diffMat ** 2 sqDistances = sqDiffMat.sum(axis=1) distances = sqDistances ** 0.5 # 排序後的索引 sortedDistanceIndices = distances.argsort() classCount = {} for i in range(k): # 尋找出現次數最的標簽 voteILabel = labels[sortedDistanceIndices[i]] classCount[voteILabel] = classCount.get(voteILabel, 0) + 1 # 字典的排序 sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True) return sortedClassCount[0][0]
核心的代碼並不算復雜,這裏用到了numpy提供的tile()
函數,用於將矩陣橫向或者縱向復制,然後利用numpy中廣播
的概念:對於矩陣的操作,會具體到矩陣中每一個元素上,這樣計算效率無疑會很高。
書裏提供的兩個例子:
- 使用k-近鄰算法改進約會網站的配對效果
- 手寫識別系統
兩個例子都提供了原始數據,都很有意思,具體代碼詳見我的GitHub。
這兩個例子,有幾點經驗需要學習。
1、數據格式化
第一步,數據的格式化是非常有必要的。因為現在數據來源廣泛,可以來自網絡,可以來自文本文件,也可以來自數據庫,但是具體到算法,輸入數據的格式是固定的,這就有必要進行數據的格式化,但是具體格式化的方式是不固定的,這個要看具體算法輸入的要求,像這裏輸入的數據必須是numpy的array格式,但是數據源是文本文件,這就需要另寫方法來自動執行這些轉換。
2、數據歸一化
不同屬性之間的數據,不具備可對比度,有些尺度相差很大,很影響算法執行的效果,因此在真正的輸入數據到算法之前,需要進行歸一化。其實歸一化也很簡單,方式也不止一種,比如:
newValue = (oldValue - min) / (max - min)
可以看出,歸一化後的數據,範圍落在[-1, 1],而且避免了不同尺度數據造成的偏差。
3、探索型數據分析
說是探索型數據分析,顯得有些專業,其實就是在具體執行機器學習算法之前,先來看看數據長什麽樣子。可以采用一些統計參數,如均值和方差等,另外一種很重要的方式就是可視化,Python中最常見的自然是Matplotlib繪圖庫了,Seaborn也不錯,可以嘗試學學,可以很直觀的看到數據長什麽樣子。
4、訓練集和預測集
通常會將原始數據分割為訓練集和預測集,比如90%的數據作為訓練集,用於訓練模型,剩下10%作為預測集,來預測模型的準確度,由於預測集的預測目標值已知,因此可以通過判斷模型輸出結果與原有結果比較,得出錯誤的數量,然後除以預測集總數,即可得到錯誤率,來表征模型質量。
kNN存在的問題:
- 訓練樣本數量較大,而且必須保存全部數據集
- 對數據集中的每個數據計算距離值,計算量較大,十分耗時
- 無法給出任何數據的基礎結構信息,對於數據的特征並不了解
Next:下一章將使用改率測量方法處理分類問題,即決策樹。
總結:初次接觸機器學習,從數據中挖掘信息聽起來十分誘人,也十分有趣。kNN作為一種比較簡單的算法,單純通過比較與已知數據的距離,這是一種十分別致的思考方式,將屬性放在坐標系空間,然後計算空間距離,方法簡單,實現起來也比較容易。
Reference:https://github.com/plantree/Machine-Learing-In-Action/tree/master/chapter2
機器學習實戰一(kNN)