使用python庫(kù)sklearn屋谭,pandas
數(shù)據(jù)來(lái)源:kaggle Facebook V: Predicting Check Ins
數(shù)據(jù)網(wǎng)址:https://www.kaggle.com/c/facebook-v-predicting-check-ins/data
如存在問(wèn)題或不足之處請(qǐng)指正宿崭,靴靴>α铡@倥埂员舵!
1 k-近鄰算法描述
1.1 簡(jiǎn)介
對(duì)于傳統(tǒng)k近鄰算法棒仍,對(duì)于給定的數(shù)據(jù)集,有n個(gè)數(shù)據(jù)樣本是已標(biāo)記的抡蛙,另一部分?jǐn)?shù)據(jù)樣本是未標(biāo)記的护昧,對(duì)于未標(biāo)記的數(shù)據(jù)樣本,通過(guò)如下方式進(jìn)行分類(lèi):
- 度量每個(gè)未標(biāo)記數(shù)據(jù)樣本與所有已標(biāo)記數(shù)據(jù)樣本的距離粗截;
- 對(duì)所有求出的距離選擇與未標(biāo)記數(shù)據(jù)樣本距離最近的k(k≤n)個(gè)已標(biāo)記數(shù)據(jù)樣本惋耙;
- 統(tǒng)計(jì)這k個(gè)已標(biāo)記的數(shù)據(jù)樣本,那一類(lèi)的數(shù)據(jù)樣本個(gè)數(shù)最多熊昌,則未標(biāo)記的拘束樣本標(biāo)記為該類(lèi)樣本
k近鄰算法沒(méi)有一個(gè)數(shù)據(jù)樣本訓(xùn)練過(guò)程怠晴,本身是一種惰性監(jiān)督算法,該算法對(duì)k值的選擇以及距離的度量方式都會(huì)影響最終的分類(lèi)精度浴捆。
1.2 算法特性及優(yōu)缺點(diǎn)
優(yōu)點(diǎn):精度高,對(duì)異常值不敏感
缺點(diǎn):k值敏感稿械,空間復(fù)雜度高(需要保存全部數(shù)據(jù)),時(shí)間復(fù)雜度高(平均O(logM)选泻,M是訓(xùn)練集樣本數(shù))
適用于: 帶lable的數(shù)值類(lèi)
2 距離計(jì)算
2.1 歐氏距離:
二維空間:
公式:為點(diǎn)(x1,y1)與(x2,y2)間的距離。
多維空間
公式:為點(diǎn)(x1,x2,···,xn)與(y1,y2,···,yn)間的距離。
3 簡(jiǎn)單案例
在已知6部電影中的打斗鏡頭與接吻鏡頭數(shù)目页眯,和每部電影所屬類(lèi)別的情況下梯捕,已知出未知電影中的打斗鏡頭與接吻鏡頭數(shù)目,求出其所屬類(lèi)別窝撵。如下圖所示:
1短曾、根據(jù)歐氏距離可以求出未知影片與各影片間的距離
- 未知影片->影片1 = 20.5
未知影片->影片2 = 18.9
未知影片->影片3 = 19.2
未知影片->影片4 = 115.3
未知影片->影片5 = 117.4
未知影片->影片6 = 118.9
2、按照遠(yuǎn)近順序排序:
影片2<影片3<影片1<影片4<影片5<影片6
3赐劣、選取樣本
k取值(上文提到為選取樣本數(shù)量):1,3,6
- k=1:
-- 選取樣本為影片2
-- 未知影片為愛(ài)情片 - k=3:
-- 選取樣本為影片2嫉拐,影片3,影片1
-- 未知影片為愛(ài)情片 - k=6:
-- 選取樣本為影片2魁兼,影片3婉徘,影片1,影片4咐汞,影片5盖呼,影片6
-- 未知影片不確定
由此可見(jiàn)k值取值至關(guān)重要,其取值影響此算法的分類(lèi)結(jié)果
4 代碼展示
導(dǎo)入所需模塊
import pandas as pd
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
文件在當(dāng)前目錄文件夾data\FBlocation中
k近鄰算法:
def knncls():
"""
K-近鄰預(yù)測(cè)用戶(hù)位置
:return: None
"""
# 窗口內(nèi)輸出不帶省略號(hào)
pd.set_option('display.width', 1000) # 設(shè)置字符顯示寬度
pd.set_option('display.max_rows', 1000) # 設(shè)置顯示最大行
pd.set_option('display.max_columns', None) # 設(shè)置顯示最大列
# 讀取數(shù)據(jù)
data = pd.read_csv('data\\FBlocation\\train.csv')
# print(data.head(10))
# 處理數(shù)據(jù)
# 1化撕、縮小數(shù)據(jù),查詢(xún)數(shù)據(jù)篩選
data = data.query("x > 1.0 & x < 1.25 & y > 2.5 & y < 2.75")
# 2几晤、處理時(shí)間數(shù)據(jù)
# pd.to_datatime把時(shí)間戳轉(zhuǎn)換成時(shí)間年月日的形式
# pd.DatetimeIndex 把日期數(shù)據(jù)轉(zhuǎn)換為字典格式
time_value = pd.to_datetime(data['time'], unit='s')
# print(time_value)
# 把日期格式轉(zhuǎn)換為字典格式
time_value = pd.DatetimeIndex(time_value)
# 構(gòu)造一些特征
data['day'] = time_value.day
data['hour'] = time_value.hour
data['weekday'] = time_value.weekday
# 把時(shí)間戳特征刪除
data.drop(['time'], axis=1) # 這里1表示列,sklearn里面0表示列
# print(data)
# 把簽到數(shù)量少于n個(gè)的目標(biāo)位置刪除
place_count = data.groupby('place_id').count()
# print(place_count)
tf = place_count[place_count.row_id > 3].reset_index() # 索引從0開(kāi)始
data = data[data['place_id'].isin(tf.place_id)]
# 取出數(shù)據(jù)當(dāng)中的特征值與目標(biāo)值
y = data['place_id'] # 目標(biāo)值
x = data.drop(['place_id','row_id'], axis=1) # 特征值
# 進(jìn)行數(shù)據(jù)的分割訓(xùn)練集合測(cè)試集
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.25)
# print(data)
# 特征化工程(標(biāo)準(zhǔn)化)
std = StandardScaler()
# 對(duì)測(cè)試集和訓(xùn)練集的特征值進(jìn)行標(biāo)準(zhǔn)化
x_train = std.fit_transform(x_train)
x_test = std.transform(x_test)
# 進(jìn)行算法流程 # 超參數(shù)(n_neighbors)默認(rèn)為5
knn = KNeighborsClassifier(n_neighbors=8)
# fit, predict,score
knn.fit(x_train,y_train)
# 得出預(yù)測(cè)結(jié)果
y_predict = knn.predict(x_test)
print("預(yù)測(cè)目標(biāo)簽到位置為:",y_predict)
print("得出準(zhǔn)確率:",knn.score(x_test,y_test))
return None
if __name__ == '__main__':
knncls()
輸出結(jié)果:
參考文獻(xiàn)
[1]章宦記.改良的kmeans與K近鄰算法特性分析[J].電子產(chǎn)品世界,2016,23(01):79-80.