概念
KNN属于分类算法.如果一个样本在特征空间中的k个最相似(即特征空间最相近)的样本大多数属于某一个类别,则该样本也属于这个类别.
示例代码
示例代码使用的是kaggle上的facebook数据集,根据已有的数据,预测新的人员入酒店id
# KNN的距离算法 使用的是欧氏距离 即算空间中点的距离 (根号下的 差的平方和)
# 要注意的是knn算法是需要做 标准化处理的
# API:(参数:n_neighbors=5)默认使用5个邻居 邻居的数量对算法的结果有影响 数量越大则要判断的点越多
from sklearn.neighbors import KNeighborsClassifier
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
def knncls():
data = pd.read_csv("./data/facebook/train.csv")
# 处理数据
print(data.head(10))
# 缩小数据集
# 使用query查询数据筛选数据 输入字符串 用& 表示与
data = data.query("x>1.0 & x<1.25 &y>2.5 & y <2.75")
# 处理时间戳 转换成年月日 时分秒
# 调用pd.to_datatime() 可以吧时间戳转换为时间年月日
time_values = pd.to_datetime(data['time'])
print(time_values)
# 构造更多的特征 年月都一致 不再使用年月
# 获取参数 使用打他timeindex
time_values = pd.DatetimeIndex(time_values)
data['day'] = time_values.day
data['hour'] = time_values.hour
data['weekday'] = time_values.weekday
data['weekday'] = time_values.weekday
# 删除时间戳特征
# 第一个参数是一个列表 传入要删除的特征lable 第二个参数表示轴 在sklearn里边0 代表列
# 而在pandas里边 1 表示列
data = data.drop(['time'], axis=1)
print('*' * 100)
print(data)
# 签到数 比较少的 筛选掉
# 即签到数量少于n
place_count = data.groupby("place_id").count()
tf = place_count[place_count.row_id > 3].reset_index()
# 筛选在tf里边的place
data = data[data['place_id'].isin(tf.place_id)]
# 区分数据中的目标值 特征值
y = data['place_id']
x = data.drop(['place_id'], axis=1)
# 进行数据分割 (训练集 测试集)
# 参数说明 特征值 目标值 测试集百分比
# 注意返回顺序
X_train, X_test, Y_train, Y_test = train_test_split(x, y, 0.25)
# 特征工程 标准化(不做标准化 准确率大概在 3% ) 测试集 训练集 的特征值都需要标准化
std = StandardScaler()
X_train = std.fit_transform(X_train)
# 不用再调用fit_transform 已经标准化了一次
X_test = std.transform(X_test)
# 标准化之后准确率大概为 40%
# 进行算法流程
knn = KNeighborsClassifier(n_neighbors=5)
# 输入数据
knn.fit(X_train, Y_train)
# 得出预测结果(测试集)
y_predict = knn.predict(X_test)
print("预测位置为:" + y_predict)
# 得出预测的准确率
print("预测准确率:", knn.score(X_test, Y_test))
return None
if __name__ == '__main__':
knncls()