KNN常见考点

一、混淆矩阵相关概念示例

from sklearn.metrics import confusion_matrix,accuracy_score,precision_score,recall_score,f1_score
from sklearn.metrics import classification_report
y_true = [1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0]
y_pred = [1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0]
#使用help(confusion_matrix)命令,可以查看混淆矩阵的联机帮助
#在该联机帮助的示例中,是把1看作Positive,把0看作Negative,并且混淆矩阵的右下角是tp
print("混淆矩阵:\n",confusion_matrix(y_true,y_pred))    
tn,fp,fn,tp=confusion_matrix(y_true,y_pred).ravel()
print("混淆矩阵中tn,fp,fn,tp值分别为:",(tn,fp,fn,tp))
print("正例(类别为1)的准确率:",accuracy_score(y_true,y_pred))
print("正例(类别为1)的查准率:",precision_score(y_true, y_pred))
print("正例(类别为1)的查全率:",recall_score(y_true, y_pred))
print("正例(类别为1)的f1分:",f1_score(y_true, y_pred))

print("\n也可以使用classification_report分类别查看除了accuracy_score之外的其他性能指标:")
print("分类性能报告:",classification_report(y_true, y_pred, labels=[0,1]))
#对比上述输出结果,可以发现:
#accuracy_score/precision_score/recall_score/f1_score函数只显示正例(类别为1)的性能指标
#而classification_report既可以显示正例(类别为1)、还可以显示出反例(类别为0)的性能指标

二、使用kNN(k近邻)算法对鸢尾花数据集进行分类

#参考资源:
#https://blog.csdn.net/weixin_45014385/article/details/123618841
#https://www.cnblogs.com/gemine/p/11130032.html

from sklearn.datasets import load_iris
#加载sklearn自带的鸢尾花数据集
iris = load_iris()
#查看该数据集的说明信息,该说明信息是一个字典
iris
#为了更清晰的查看该字典的信息,下面的代码通过循环输出字典对应的键值对

#可以看到:
#iris数据集中的鸢尾花样本共分为3个类别(取值为0、1、2),类别名来自于target_names键(取值为'setosa' 'versicolor' 'virginica')
#每个类别各有50个样本,一共150个样本
#每个样本有4个属性,分别是花萼长度(sepal length)、花萼宽度(sepal width)、花瓣长度(petal length)和花瓣宽度(petal width)
#每个样本的真实类别(取值为0、1、2中的一个)需要从target键对应的值中去找寻

print("鸢尾花字典的键:",iris.keys())
for key in iris.keys():
    print(key)
    print(iris[key])
#为方便后续处理,把该字典信息加载到DataFrame对象中
import pandas as pd
#下面语句用于提取每个样本的4个属性值
#下面语句也可写成df=pd.DataFrame(iris.data,columns=iris.feature_names),这是把字典的键看成是iris的属性
df=pd.DataFrame(iris['data'],columns=iris['feature_names'])

#下面语句提取每个样本的真实类别标签,该语句也可以写成d['target']=iris.target
df['target']=iris['target']
df.sample(10)       #sample(10)函数作用:随机选择10个样本进行显示

#为减小不同特征/属性的量纲差距,下面的代码进行了z-score标准化处理:
from sklearn.preprocessing import StandardScaler
ss=StandardScaler()
new_data=ss.fit_transform(iris.data)
new_df=pd.DataFrame(new_data,columns=iris.feature_names)
#提取每个样本的真实类别标签
new_df['target']=iris.target
new_df.sample(10)

from sklearn.model_selection import train_test_split

#下面的train_test_split函数将把全部150个样本划分成训练集和测试集,其中测试集占30%(对应于test_size=0.3)
#划分时使用了stratify参数进行分层采样,参考:https://zhuanlan.zhihu.com/p/49991313
#这样可以保证每个类别的训练样本都是35个
X_train,X_test,y_train,y_test=train_test_split(new_df.iloc[:,0:4],new_df['target'],stratify=new_df['target'],random_state=33,test_size=0.3)
print(y_train.value_counts())

#如果不使用stratify参数进行分层采样,有可能使得不同类别的训练样本数量不同,进而影响分类准确性
#下面的划分没有使用分层采样,可以发现出现了样本不平衡现象,这会影响后面的分类效果(去掉注释后可以对比分析)
#X_train,X_test,y_train,y_test=train_test_split(new_df.iloc[:,0:4],new_df['target'],random_state=33,test_size=0.3)
#print(y_train.value_counts())

 

#https://scikit-learn.org/stable/modules/classes.html#module-sklearn.neighbors

from sklearn.neighbors import KNeighborsClassifier

#下面的语句创建kNN分类估计器,这里指定超参数k等于9,即为了分类,需要找到测试样本的9个近邻去投票
neigh = KNeighborsClassifier(n_neighbors=9)  #n_neighbors默认值是5
#下面的语句进行数据拟合(类似于模型学习),对kNN分类器而言就是构建一颗kd_tree
neigh.fit(X_train,y_train)
#下面的语句进行测试样本的类别预测,对kNN分类器而言就是在kd_tree上找到k个近邻并投票确定测试样本的类别
y_pred=neigh.predict(X_test)

#下面的代码用于查看分类性能:
#注意:多分类问题可以使用accuracy_score查看分类的准确性
ACC = metrics.accuracy_score(y_test,y_pred)
print("分类的准确率:",ACC)

#注意:对于多分类问题,却无法使用precision_score/recall_score/f1_score函数
#precision=metrics.precision_score(y_test,y_pred)
#print("分类的查准率:",precision)

#对于多分类问题,却可以使用classification_report函数查看相关性能指标
print("分类性能报告:")
print(classification_report(y_test,y_pred))

 

#为了找到可能更好的超参数k提升分类的性能,下面的代码演示了交叉验证配合网格搜索
#关于交叉验证:可以参考
#https://www.cnblogs.com/qiu-hua/p/14904992.html
#https://www.ngui.cc/el/1515667.html?action=onClick

from sklearn.model_selection import GridSearchCV,KFold
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import classification_report

#下面的代码指定了网格搜索的范围,即把从3到9范围内的整数一个个尝试作为超参数k的取值
params_knn={'n_neighbors':range(3,16,1)}
#下面的代码指定进行3折交叉验证,交叉验证的好处(可以自行百度):
#充分利用所有数据、更好地评估模型稳定性、有利于超参数调优、防止过拟合等
kf=KFold(n_splits=3,shuffle=False)

#下面的语句创建kNN分类估计器,创建时所有参数使用默认值
neigh = KNeighborsClassifier()
#下面的语句创建网格搜索估计器,并依次指定分类算法、超参数k的取值范围、交叉验证的设置
grid_search_knn=GridSearchCV(neigh,params_knn,cv=kf)
#下面的语句用创建网格搜索估计器进行训练数据的拟合(类似于模型学习)
grid_search_knn.fit(X_train,y_train)
#下面的语句用拟合好的网格搜索估计器(类似于学习到的模型)进行测试集中所有样本的分类预测
grid_search_y_pred=grid_search_knn.predict(X_test)
#下面的代码用于分类的性能评价
print("分类准确率:",grid_search_knn.score(X_test,y_test))
print("网格搜索得到的最佳超参数:",grid_search_knn.best_params_)
print("输出分类性能报告:")
print(classification_report(y_test,grid_search_y_pred))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

纵观星宇宙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值