k近邻算法(KNN)-分类算法
1 概念
定义:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。
k-近邻算法采用测量不同特征值之间的距离来进行分类。
2 优缺点
优点:简单,易于理解,易于实现,无需估计参数,无需训练
缺点:懒惰算法,对测试样本分类时的计算量大,内存开销大 必须指定K值,K值选择不当则分类精度不能保证
使用数据范围:数值型和标称型
3 欧式距离
两个样本的距离可以通过如下公式计算,又叫欧式距离。如a(a1,a2,a3),b(b1,b2,b3)两点用如下公式表示
4 sklearn k-近邻算法API
sklearn.neighbors.KNeighborsClassifier(n_neighbors=5,algorithm='auto')
KNeighborsClassifier类的实例化所需参数如下
n_neighbors | (默认= 5),k_neighbors查询默认使用的邻居数 |
algorithm | {‘auto’,‘ball_tree’,‘kd_tree’,‘brute’},可选用于计算最近邻居的算法:‘ball_tree’将会使用 BallTree,‘kd_tree’将使用 KDTree。‘auto’将尝试根据传递给fit方法的值来决定最合适的算法。 (不同实现方式影响效率) |
n_jobs | (默认= 1),用于邻居搜索的并行作业数。如果-1,则将作业数设置为CPU内核数。不影响fit方法。 |
方法:
(1)fit(X, y):使用X作为训练数据拟合模型,y作为X的类别值。X,y为数组或者矩阵
(2)kneighbors(X=None, n_neighbors=None, return_distance=True):找到指定点集X的n_neighbors个邻居,return_distance为False的话,不返回距离
(3)predict(X):预测提供的数据的类标签
(4)predict_proba(X):返回测试数据X属于某一类别的概率估计
5 实例流程
①数据集的处理
②分割数据集
③对数据集进行标准化
④estimator流程进行分类预测
6 k近邻算法实例-预测入住位置
数据来源:https://www.kaggle.com/c/facebook-v-predicting-check-ins/data
这里根据X y坐标值,定位准确性,时间作为特征值,入住的id为目标值
from sklearn.neighbors import KNeighborsClassifier
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler#1 读取数据
data = pd.read_csv("./data/train.csv")#2 处理数据,截取部分数据
data = data.query("x > 1.0 & x < 1.5 & y > 2.5 & y < 3")
#处理日期数据,将data里的time特征下的时间错装换为(年-月-日 时:风:秒)格式,unit='s'设置转换的最小单位为s
timev = pd.to_datetime(data['time'],unit='s')
#把日期转换为字典格式,为了构造一些天数等特征,所以要将time转换为可以获取day,month的参数
#那就需要把日期格式转换为字典格式,就把每一行转换为字典格式,那就可以单独获取里面的时分秒
timev = pd.DatetimeIndex(timev)#构造新特征
data['day']=timev.day
data['hour'] = timev.hour
data['weekday'] = timev.weekday
#删除时间特性,pandas的列是1,sklearn的列是0
data.drop(['time'],axis=1)'''把签到数量少于n个目标位置删除,用分组,然后统计求和
根据palce_id分组'''
data_count = data.groupby('palce_id').count()'''以某个值进行分组之后,前面的索引就是该值,然后才是每一列特征,row_id是入住的id,现在已经变成具体的次数了
这里把row_id大于3的保留下来,然后调用reset_index,reset_index()的所用是把索引palce_id变成某一列,就能获取了
前面的索引就变成0,1..一个个计数'''tf = data_count[data_count.row_id>5].reset_index()#筛选data里面id是tf里面的id,在就保留下来
data[data['place_id'].isin(tf.place_id)]# 取出数据当中的特征值和将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,test_size=0.25)#3 特征工程标准化,训练集做标准化了,测试集也要做标准化,目标值不要计算距离不用做标准化
#标准化就是想让每一列数据在同一个标准上面进行计算
std = StandardScaler()
x_train = std.fit_transform(x_train)
x_test = std.transform(x_test)#进行算法流程 超参数
knn = KNeighborsClassifier(n_neighbors=5)
#fit输入数据
knn.fit(x_train,y_train)
#得出预测结果
y_predict = knn.predict(x_test)
print("预测的目标位置为:", y_predict)
# 得出准确率,这里得出的准确率并不高,因为还有一些特征的影响如row_id,可以将其从特征值中删除
print("预测的准确率:", knn.score(x_test, y_test))
7 K近邻算法问题:
①K值取多大,有什么影响?
K值取小了,比如取最近一个他的类别是什么类别我就是什么类别,这样容易受异常点影响假设这个最近的点就是异常点,就预测错了
K值取大了,容易受K值数量(类别)波动影响
如何处理K值取值问题见模型选择与调优
②性能问题:每一个样本来了,要一个个去计算距离时间复杂度很高