衆所周知,電影能夠按照題材分類,然而題材自己是如何定義的?由誰來斷定某部電影屬於哪一個題材?也就是說同一題材的電影具備哪些公共特徵?這些都是在進行電影分類時必需要考慮的問題。python
那麼如何基於電影中出現的親吻、打鬥出現的次數,使用k-近鄰算法構造程序,自動劃分電影的題材類型。算法
k-近鄰(KNN)算法採用測量不一樣特徵值之間的距離方法進行分類。測試
通常來講,咱們只選擇樣本數據集中前k個最類似的數據,一般k是不大於20的整數。最後,選擇k個最類似數據中出現次數最多的分類,做爲新數據的分類。spa
動做,愛情,喜劇,災難…???code
獲得了距離後,選擇前k個電影來判斷未知電影的類型排序
(1) 收集數據:可使用任何方法。
(2) 準備數據:距離計算所須要的數值,最好是結構化的數據格式。
(3) 分析數據:可使用任何方法。
(4) 訓練算法:此步驟不適用於k-近鄰算法。
(5) 測試算法:計算錯誤率。
(6) 使用算法:首先須要輸入樣本數據和結構化的輸出結果,而後運行k-近鄰算法斷定輸
入數據分別屬於哪一個分類,最後應用對計算出的分類執行後續的處理。索引
import numpy as np def createDataSet(): """建立數據集""" # 每組數據包含打鬥數和接吻數; group = np.array([[3, 104], [2, 100], [1, 81], [101, 10], [99, 5], [98, 2]]) # 每組數據對應的標籤類型; labels = ['Roman', 'Roman', 'Roman', 'Action', 'Action', 'Action'] return group, labels
對未知類別屬性的數據集中的每一個點依次執行如下操做:
(1) 計算已知類別數據集中的點與當前點之間的距離;
(2) 按照距離遞增次序排序;
(3) 選取與當前點距離最小的k個點;
(4) 肯定前k個點所在類別的出現頻率;
(5) 返回前k個點出現頻率最高的類別做爲當前點的預測分類。圖片
def classify(inx, dataSet, labels, k): """ KNN分類算法實現 :param inx:要預測電影的數據, e.g.[18, 90] :param dataSet:傳入已知數據集,e.g. group 至關於x :param labels:傳入標籤,e.g. labels至關於y :param k:KNN裏面的k,也就是咱們要選擇幾個近鄰 :return:電影類新的排序 """ dataSetSize = dataSet.shape[0] # (6,2) -- 6行2列 ===> 6 獲取行數 # tile會重複inx, 把它重複成(dataSetSize, 1)型的矩陣 # (x1 - y1), (x2 - y2) diffMat = np.tile(inx, (dataSetSize, 1)) - dataSet # 平方 sqDiffMat = diffMat ** 2 # 相加, axis=1行相加 sqDistance = sqDiffMat.sum(axis=1) # 開根號 distance = sqDistance ** 0.5 # 排序索引: 輸出的是序列號index, 而不是值 sortedDistIndicies = distance.argsort() # print(sortedDistIndicies) classCount = {} for i in range(k): # 獲取排前k個的標籤名; voteLabel = labels[sortedDistIndicies[i]] classCount[voteLabel] = classCount.get(voteLabel, 0) + 1 sortedClassCount = sorted(classCount.items(), key=lambda d: float(d[1]), reverse=True) return sortedClassCount[0]
爲了測試分類器的效果,咱們可使用已知答案的數據,固然答案不能告訴分類器,檢驗分類器給出的結果是否符合預期結果。ci
完整代碼rem
import numpy as np def createDataSet(): """建立數據集""" # 每組數據包含打鬥數和接吻數; group = np.array([[3, 104], [2, 100], [1, 81], [101, 10], [99, 5], [98, 2]]) # 每組數據對應的標籤類型; labels = ['Roman', 'Roman', 'Roman', 'Action', 'Action', 'Action'] return group, labels def classify(inx, dataSet, labels, k): """ KNN分類算法實現 :param inx:要預測電影的數據, e.g.[18, 90] :param dataSet:傳入已知數據集,e.g. group 至關於x :param labels:傳入標籤,e.g. labels至關於y :param k:KNN裏面的k,也就是咱們要選擇幾個近鄰 :return:電影類新的排序 """ dataSetSize = dataSet.shape[0] # (6,2) -- 6行2列 ===> 6 獲取行數 # tile會重複inx, 把它重複成(dataSetSize, 1)型的矩陣 # (x1 - y1), (x2 - y2) diffMat = np.tile(inx, (dataSetSize, 1)) - dataSet # 平方 sqDiffMat = diffMat ** 2 # 相加, axis=1行相加 sqDistance = sqDiffMat.sum(axis=1) # 開根號 distance = sqDistance ** 0.5 # 排序索引: 輸出的是序列號index, 而不是值 sortedDistIndicies = distance.argsort() # print(sortedDistIndicies) classCount = {} for i in range(k): # 獲取排前k個的標籤名; voteLabel = labels[sortedDistIndicies[i]] classCount[voteLabel] = classCount.get(voteLabel, 0) + 1 sortedClassCount = sorted(classCount.items(), key=lambda d: float(d[1]), reverse=True) return sortedClassCount[0][0] if __name__ == '__main__': group, label = createDataSet() result = classify([3, 104], group, label, 5) print("[3, 104]的電影類型:", result)