一、K近鄰算法概念
K近鄰(k-Nearest Neighbor,簡稱kNN)學習是一種或常用的監督學習方法,其工作機制非常簡單:給定測試樣本,基于某種距離度量找出訓練集中與其最靠近的k個訓練樣本,然后基于這k個“鄰居”的信息來進行預測。通常,在分類任務中可使用“投票法”,即選擇這k個樣本中出現最多的類別標記作為預測結果;在回歸任務中可使用“平均法”,即將這k個樣本的實質輸出標記的平均值作為預測結果;還可基于距離遠近進行加權平均或者加權投票,距離越近的樣本權重越大。
k近鄰沒有顯式的訓練過程。事實上,它是“懶惰學習”的著名代表,此類學習技術在訓練階段僅僅是把樣本保存起來,訓練時間開銷為零,待收到測試樣本后再進行處理;相應的,那些在訓練階段就對樣本進行學習處理的方法,成為“急切學習”。
圖1中有紅色三角和藍色方法兩種類別,我們現在需要判斷綠色圓點榆樹哪種類別
當k=3時,綠色圓點屬于紅色三角這種類別;
當k=5時,綠色圓點屬于藍色方塊這種類別。
下面給出兩個距離公式
第一個是歐幾里得距離(也就是我們經常用到的)公式:
擴展到n維空間:
第二個是曼哈頓距離公式:
擴展到n維空間:
步驟:
(1)計算已知類別數據集中的點與當前點之間的距離;
(2)按照距離遞增次序排序;
(3)選取與當前點距離最小的k個點;
(4)確定前k個點所在類別的出現頻率;
(5)返回前k個點,出現頻率最高的類別作為當前點的預測類別。
算法功能:分類(核心)、回歸
算法類型:有監督學習,懶惰學習,距離模型
數據輸入:包含數據標簽y,且特征空間中至少至少包含k個訓練樣本(k>=1)特征空間 中各個特征的量綱需統一,若不統一則需要進行歸一化處理自定義的超參數k(k>=1)
模型輸出:在KNN分類中,輸出是標簽中的某個類別
在KNN回歸中,輸出是對象的屬性值,該值是距離輸入的數據最近的K個訓練 樣本標簽的平均值。
二、python代碼的實現
1、電影的預測
import pandas as pd
"""
函數功能:KNN分類器
參數說明:
intX:需要預測的數據集
dataSet:已知分類標簽的數據集(訓練集)
k:k-近鄰算法參數,選擇距離最小的k個點
返回:
result:分類結果
"""
rowdata = {'電影名稱':['無問西東', '后來的我們','前任3', '紅海行動', '唐人街探案','戰狼2'],
'打斗鏡頭':[1,5,12, 108,112,115],
'接吻鏡頭':[101,89,97,5,9,8],
'電影類型':['愛情片','愛情片','愛情片','動作片','動作片','動作片']}
movie_data = pd.DataFrame(rowdata)
new_data = [24, 67]
def classify0(intX,dataSet,k):
result = []
dist = list((((dataSet.iloc[:6, 0:2]-intX)**2).sum(1))**0.5)
dist_l = pd.DataFrame({'dist': dist, 'labels': (dataSet.iloc[:, 3])})
dr = dist_l.sort_values(by='dist')[: k]
re = dr.loc[:, 'labels'].value_counts()
result.append(re.index[0])
return result
intX = new_data
dataSet = movie_data
k = 4
print(classify0(intX, dataSet, k))
2、K近鄰算法之約會網站配對效果判定
海倫-直使用在線約會網站尋找適合自己的約會對象,盡管約會網站會推薦不同的人選,但她并不是每一個都喜歡,經過一番總結,她發現曾經交往的對象可以分為三類:
●不喜歡的人
●魅力一般的人
●極具魅力得人
海倫收集約會數據已經有了-段時間,她把這些數據存放在文本文件datingTestSet.txt中,其中各字段分別為:
1.每年飛行常客里程
2.玩游戲視頻所占時間比
3.每周消費冰淇淋公升數
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
#
daTingTest = pd.read_table('datingTestSet.txt', header=None)
"""
數據集表示
不喜歡的人
魅力一般的人
極具魅力的人
1.每年飛行常客里程
2.玩游戲視頻所占時間比
3.每周消費冰淇淋公升數
daTingTest.head()查看前五行數據
daTingTest.shape查看多少行多少列(1000, 4)
daTingTest.info()
RangeIndex: 1000 entries, 0 to 999
Data columns (total 4 columns):
0 1000 non-null int64
1 1000 non-null float64
2 1000 non-null float64
3 1000 non-null object
dtypes: float64(2), int64(1), object(1)
memory usage: 31.3+ KB
None
"""
#把不同標簽用顏色區分
Color = []
for i in range(daTingTest.shape[0]):
m = daTingTest.iloc[i, -1]
if m == 'didntLike':
Color.append('black')
if m == 'smallDoses':
Color.append('orange')
if m == 'largeDoses':
Color.append('red')
# 繪制兩兩特征之間的散點圖
plt.rcParams['font.sans-serif'] = ['Simhei'] #圖中字體設置為黑體
pl=plt.figure(figsize=(12,8))
fig1 = pl.add_subplot(221)
plt.scatter(daTingTest.iloc[:, 1], daTingTest.iloc[:, 2], marker='.', c=Color)
plt.xlabel('玩游戲視頻所占時間比')
plt.ylabel('每周消費冰淇淋公升數')
fig2 = pl.add_subplot(222)
plt.scatter(daTingTest.iloc[:, 0], daTingTest.iloc[:, 1], marker='.', c=Color)
plt.xlabel('每年飛行常客里程')
plt.ylabel('玩游戲視頻所占時間比')
fig3 = pl.add_subplot(223)
plt.scatter(daTingTest.iloc[:, 0], daTingTest.iloc[:, 2], marker='.', c=Color)
plt.xlabel('每年飛行常客里程')
plt.ylabel('每周消費冰淇淋公升數')
plt.show()
#數據歸一化
"""
函數功能:歸一化
參數說明:
dataSet:原始數據集
返回:0-1標準化之后的數據集
"""
def minmax(dataSet):
minof = dataSet.min()
maxof = dataSet.max()
normSet = (dataSet - minof)/(maxof - minof)
return normSet
daTingT = pd.concat([minmax(daTingTest.iloc[:, :3]), daTingTest.iloc[:, 3]], axis=1)
#q切分訓練集和測試集
"""
函數功能:切分訓練集和測試集
參數說明:
dataSet:原始數據集
rate:訓練集所占比例
返回:切分好的訓練集和測試集
"""
def randSplit(dataSet,rate=0.9):
n = dataSet.shape[0]
m = int(n*rate)
train = dataSet.iloc[:m, :]
test = dataSet.iloc[m:, :]
test.index = range(test.shape[0])
return train, test
train, test = randSplit(daTingT)
#定義分類器的函數
def datingClass(train,test,k):
n = train.shape[1]-1
m = test.shape[0]
result = []
for i in range(m):
dist = list((((train.iloc[:, :n]-test.iloc[i, :n])**2).sum(1))**0.5)
dist_l = pd.DataFrame({'dist': dist, 'labels': (train.iloc[:, n])})
dr = dist_l.sort_values(by='dist')[: k]
re = dr.loc[:, 'labels'].value_counts()
result.append(re.index[0])
result = pd.Series(result)
test['predict'] = result
acc = (test.iloc[:, -1]== test.iloc[:, -2]).mean()
print('模型預測準確率為%.2f' % acc)
return test
print(datingClass(train,test,5))
模型預測準確率為0.95
0 1 2 3 predict
0 0.513766 0.170320 0.262181 didntLike didntLike
1 0.089599 0.154426 0.785277 smallDoses smallDoses
2 0.611167 0.172689 0.915245 didntLike didntLike
3 0.012578 0.000000 0.195477 smallDoses smallDoses
4 0.110241 0.187926 0.287082 smallDoses smallDoses
5 0.812113 0.705201 0.681085 didntLike didntLike
6 0.729712 0.490545 0.960202 didntLike didntLike
7 0.130301 0.133239 0.926158 smallDoses smallDoses
8 0.557755 0.722409 0.780811 largeDoses largeDoses
9 0.437051 0.247835 0.131156 largeDoses didntLike
10 0.722174 0.184918 0.074908 didntLike didntLike
11 0.719578 0.167690 0.016377 didntLike didntLike
12 0.690193 0.526749 0.251657 didntLike didntLike
13 0.403745 0.182242 0.386039 didntLike didntLike
14 0.401751 0.528543 0.222839 largeDoses largeDoses
15 0.425931 0.421948 0.590885 largeDoses largeDoses
16 0.294479 0.534140 0.871767 largeDoses largeDoses
17 0.506678 0.550039 0.248375 largeDoses largeDoses
18 0.139811 0.372772 0.086617 largeDoses smallDoses
19 0.386555 0.485440 0.807905 largeDoses largeDoses
20 0.748370 0.508872 0.408589 didntLike didntLike
21 0.342511 0.461926 0.897321 largeDoses largeDoses
22 0.380770 0.515810 0.774052 largeDoses largeDoses
23 0.146900 0.134351 0.129138 smallDoses smallDoses
24 0.332683 0.469709 0.818801 largeDoses largeDoses
25 0.117329 0.067943 0.399234 smallDoses smallDoses
26 0.266585 0.531719 0.476847 largeDoses largeDoses
27 0.498691 0.640661 0.389745 largeDoses largeDoses
28 0.067687 0.057949 0.493195 smallDoses smallDoses
29 0.116562 0.074976 0.765075 smallDoses smallDoses
.. ... ... ... ... ...
70 0.588465 0.580790 0.819148 largeDoses largeDoses
71 0.705258 0.437379 0.515681 didntLike didntLike
72 0.101772 0.462088 0.808077 smallDoses smallDoses
73 0.664085 0.173051 0.169156 didntLike didntLike
74 0.200914 0.250428 0.739211 smallDoses smallDoses
75 0.250293 0.703453 0.886825 largeDoses largeDoses
76 0.818161 0.690544 0.714136 didntLike didntLike
77 0.374076 0.650571 0.214290 largeDoses largeDoses
78 0.155062 0.150176 0.249725 smallDoses smallDoses
79 0.102188 0.000000 0.070700 smallDoses smallDoses
80 0.208068 0.021738 0.609152 smallDoses smallDoses
81 0.100720 0.024394 0.008994 smallDoses smallDoses
82 0.025035 0.184718 0.363083 smallDoses smallDoses
83 0.104007 0.321426 0.331622 smallDoses smallDoses
84 0.025977 0.205043 0.006732 smallDoses smallDoses
85 0.152981 0.000000 0.847443 smallDoses smallDoses
86 0.025188 0.178477 0.411431 smallDoses smallDoses
87 0.057651 0.095729 0.813893 smallDoses smallDoses
88 0.051045 0.119632 0.108045 smallDoses smallDoses
89 0.192631 0.305083 0.516670 smallDoses smallDoses
90 0.304033 0.408557 0.075279 largeDoses largeDoses
91 0.108115 0.128827 0.254764 smallDoses smallDoses
92 0.200859 0.188880 0.196029 smallDoses smallDoses
93 0.041414 0.471152 0.193598 smallDoses smallDoses
94 0.199292 0.098902 0.253058 smallDoses smallDoses
95 0.122106 0.163037 0.372224 smallDoses smallDoses
96 0.754287 0.476818 0.394621 didntLike didntLike
97 0.291159 0.509103 0.510795 largeDoses largeDoses
98 0.527111 0.436655 0.429005 largeDoses largeDoses
99 0.479408 0.376809 0.785718 largeDoses largeDoses
[100 rows x 5 columns]
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
