K最近鄰屬于一種分類算法,他的解釋最容易,近朱者赤,近墨者黑,我們想看一個人是什么樣的,看他的朋友是什么樣的就可以了。當然其他還牽著到,看哪方面和朋友比較接近(對象特征),怎樣才算是跟朋友親近,一起吃飯還是一起逛街算是親近(距離函數(shù)),根據(jù)朋友的優(yōu)秀不優(yōu)秀如何評判目標任務(wù)優(yōu)秀不優(yōu)秀(分類算法),是否不同優(yōu)秀程度的朋友和不同的接近程度要考慮一下(距離權(quán)重),看幾個朋友合適(k值),能否以分數(shù)的形式表示優(yōu)秀度(概率分布)。
K最近鄰概念:
它的工作原理是:存在一個樣本數(shù)據(jù)集合,也稱作為訓(xùn)練樣本集,并且樣本集中每個數(shù)據(jù)都存在標簽,即我們知道樣本集中每一個數(shù)據(jù)與所屬分類的對應(yīng)關(guān)系。輸入沒有標簽的新數(shù)據(jù)后,將新的數(shù)據(jù)的每個特征與樣本集中數(shù)據(jù)對應(yīng)的特征進行比較,然后算法提取樣本最相似數(shù)據(jù)(最近鄰)的分類標簽。一般來說,我們只選擇樣本數(shù)據(jù)集中前k個最相似的數(shù)據(jù),這就是k-近鄰算法中k的出處,通常k是不大于20的整數(shù)。最后,選擇k個最相似數(shù)據(jù)中出現(xiàn)次數(shù)最多的分類,作為新數(shù)據(jù)的分類。
今天我們使用k最近鄰算法來構(gòu)建白酒的價格模型。
構(gòu)造數(shù)據(jù)集
構(gòu)建一個葡萄酒樣本數(shù)據(jù)集。白酒的價格跟等級、年代有很大的關(guān)系。
from random import random,randintimport math# 根據(jù)等級和年代對價格進行模擬def wineprice(rating,age): peak_age=rating-50 # 根據(jù)等級計算價格 price=rating/2 if age>peak_age: # 經(jīng)過“峰值年”,后續(xù)5年里其品質(zhì)將會變差 price=price*(5-(age-peak_age)/2) else: # 價格在接近“峰值年”時會增加到原值的5倍 price=price*(5*((age+1)/peak_age)) if price<0: price=0 return price# 生成一批模式數(shù)據(jù)代表樣本數(shù)據(jù)集def wineset1(): rows=[] for i in range(300): # 隨機生成年代和等級 rating=random()*50+50 age=random()*50 # 得到一個參考價格 price=wineprice(rating,age) # 添加一些噪音 price*=(random()*0.2+0.9) # 加入數(shù)據(jù)集 rows.append({'input':(rating,age),'result':price}) return rows數(shù)據(jù)間的距離
使用k最近鄰,首先要知道那些最近鄰,也就要求知道數(shù)據(jù)間的距離。我們使用歐幾里得距離作為數(shù)據(jù)間的距離。
# 使用歐幾里得距離,定義距離def euclidean(v1,v2): d=0.0 for i in range(len(v1)): d+=(v1[i]-v2[i])**2 return math.sqrt(d)
獲取與新數(shù)據(jù)距離最近的k個樣本數(shù)據(jù)
# 計算給預(yù)測商品和原數(shù)據(jù)集中任一其他商品間的距離。data原數(shù)據(jù)集,vec1預(yù)測商品def getdistances(data,vec1): distancelist=[] # 遍歷數(shù)據(jù)集中的每一項 for i in range(len(data)): vec2=data[i]['input'] # 添加距離到距離列表 distancelist.append((euclidean(vec1,vec2),i)) # 距離排序 distancelist.sort() return distancelist #返回距離列表
新聞熱點
疑難解答