電影愛好者
当前位置:電影愛好者 > 電影資訊 > 正文

K -近鄰算法(kNN)(一)

大多數人都喜歡看電影,電影是如何分類呢?為了簡化問題,假設所有的電影要麼是愛情片,要麼是動作片。如果我們已知一些電影的分類結果和電影中打鬥鏡頭及親吻鏡頭的次數,如下:

K -近鄰算法(kNN)(一)

現有一部新電影,打鬥鏡頭及親吻鏡頭的次數已知,我們如何來預測這部新電影的類型呢?

K -近鄰算法(kNN)(一)

我們可以把電影樣本的特征值看做是在歐氏空間的坐標(特征值可能需要歸一化處理使得各個特征的權重相等),再依次計算未知電影與已知電影的歐氏距離(也可以是其它距離):

K -近鄰算法(kNN)(一)

我們按照距離從小到大排序,可以找到k個距離最近的電影。假定k=3,則k個已知樣本的類型里最多的類型是愛情片,因此我們預測未知電影也是愛情片。以上預測電影分類的算法就是 k -近鄰算法(kNN)。

k -近鄰算法的基本原理是:存在一個訓練數據(每個樣本都有特征和分類標簽的樣本集),輸入沒有分類標簽的新樣本後,依次計算新樣本和各個訓練樣本的距離,找出最相似(最近鄰)的k個已知樣本,提取它們的分類標簽。最後,選擇這k個分類標簽中出現次數最多的分類,做為新樣本的分類。

假設訓練數據保存在csv文件中(格式見本篇第一張圖片去掉最後一行),下麵的代碼可以讀出特征數據和分類標簽。

import numpy as npdef get_trainSet(path):
data = np.loadtxt(path delimiter ="" skiprows =1 usecols =(12))
labels = np.loadtxt(path delimiter ="" skiprows =1 usecols = -1dtype = str)
return data labels
dataset labels = get_trainSet("電影分類訓練集.csv")

>>> datasetarray([[ 3. 104.]
[ 2. 100.]
[ 1. 81.]
[101. 10.]
[ 99. 5.]
[ 98. 2.]])
>>> labels
array([愛情片 愛情片 愛情片 動作片 動作片 動作片] dtype=<U3)

下麵實現kNN算法:

先對訓練數據歸一化處理:

def autoNorm(dataSet): 歸一化 將所有特征值轉換到【0~1】區間的值

minVals = dataSet.min(axis =0) #每種特征取一個最小值
maxVals = dataSet.max(axis =0) #每種特征取一個最大值
ranges = maxVals - minVals # 最大值 - 最小值
#滿足使用廣播的條件,shape不同也能運算
normDataSet = dataSet -minVals
normDataSet = normDataSet / ranges
return normDataSet ranges minVals

下麵是算法的核心部分:

def classify(X dataSet labels k=3): #n = dataSet.shape[0] #訓練集樣本個數
diff = dataSet - X #使用廣播,shape不同也能運算
sqr_diff = diff**2
sqrDistance = sqr_diff.sum(axis = 1) #每行所有列求和
distance = sqrDistance**0.5 #計算出了X與每個樣本的歐氏距離
#print(distance)
sortedDistIndicies = distance.argsort() # 按值的大小(值從小到大)返回對應的索引

classCount = {} #分類計數字典
for i in range(k):
voteLabel = labels[ sortedDistIndicies[i] ] #k個距離最小樣本對應的標簽
classCount[voteLabel] = classCount.get(voteLabel 0) + 1 #有則加1,則設為(0+1)
#print(classCount)
#字典轉列表,按列表的第2個元素 從大到小排序
import operator
sortedClassCount = sorted(classCount.items() key = operator.itemgetter(1) reverse = True)
#print(sortedClassCount) return sortedClassCount[0][0]

算法的輸入輸出:

dataSet labels = get_trainSet("電影分類訓練集.csv") #讀取訓練數據和分類標簽
normDataSet ranges minVals = autoNorm(dataSet) #歸一化X = np.array([1890]) #輸入的未知樣本數據 原始值
normX= (X- minVals) / ranges #未知樣本數據 歸一化
X_label = classify(normX normDataSet labels k=4)
print("預測的分類是:" X_label)

kNN算法的優點是:精度高,對異常值不敏感(與異常值的距離較遠),無數據輸入假定。缺點是計算的時間複雜度和空間複雜度較高。

未经允许不得转载:電影愛好者 » K -近鄰算法(kNN)(一)

分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址