K最近邻算法详细版+实战应用

建议使用Jupyter Notebook运行,python代码

K最近邻算法在分类任务中的应用

1.在scikit-learn中生成数据集

#导入数据集生成器
from sklearn.datasets import make_blobs
#导入KNN分类器
from sklearn.neighbors import KNeighborsClassifier
#导入画图工具
import matplotlib.pyplot as plt
#导入数据拆分工具
from sklearn.model_selection import train_test_split
#生成样本数量100、分类数量为2的数据集
#random_state表示混沌程度
data = make_blobs(n_samples=100,centers=2,random_state=9)
X,y = data
#将生成的数据集可视化
plt.scatter(X[y==1,0], X[y==1,1],cmap = plt.cm.spring, edgecolor='k',marker = '^')
plt.scatter(X[y==0,0], X[y==0,1],cmap = plt.cm.spring, edgecolor='k',marker = 'o')
plt.show()

2.建立分类模型,分析分类结果

#导入Numpy
import numpy as np
clf = KNeighborsClassifier()
clf.fit(X,y)
#画图可视化
x_min,x_max = X[:,0].min() - 1,X[:,0].max() + 1
y_min,y_max = X[:,1].min() - 1,X[:,1].max() + 1
xx,yy = np.meshgrid(np.arange(x_min,x_max,.02),
                    np.arange(y_min,y_max,.02))
Z = clf.predict(np.c_[xx.ravel(),yy.ravel()])
Z = Z.reshape(xx.shape)
plt.pcolormesh(xx,yy,Z,cmap=plt.cm. Set3)
plt.scatter(X[y==1,0],X[y==1,1],cmap=plt.cm.spring,edgecolor = 'k',marker = '^')
plt.scatter(X[y==0,0],X[y==0,1],cmap=plt.cm.spring,edgecolor = 'k',marker = 'o')
plt.xlim(xx.min(),xx.max())
plt.ylim(yy.min(),yy.max())
plt.title('Classifier:KNN')
plt.show()

K最近邻算法在回归分析中的应用

1.生成回归分析任务的数据集

#导入make_regression数据集生成器
from sklearn.datasets import make_regression
#生成特征数量为1、噪声为30db的数据集
X,y = make_regression(n_features = 1,n_informative=1,noise=30,random_state=5)
#用散点图对数据点进行可视化
plt.scatter(X,y,c = 'b',edgecolor='k')
plt.show()

2.使用K最近邻算法进行回归分析

#导入用于回归分析的KNN模型
from sklearn.neighbors import KNeighborsRegressor
reg = KNeighborsRegressor()
#用KNN模型拟合数据
reg.fit(X,y)
#对预测结果用图形进行可视化
z = np.linspace(-2.5,2.5,200).reshape(-1,1)
plt.scatter(X,y,c = 'b',edgecolor = 'k')
plt.plot(z,reg.predict(z),c = 'r',linewidth = 3)
#给图形添加标题
plt.title('KNN Regression')
plt.show()

3.对模型准确率评分及优化模型

#输出模型R平方分数
print(f'模型评分:{reg.score(X,y):.2f}')
#默认情况下K_neighbors = 5,尝试将它缩小来优化模型
from sklearn.neighbors import KNeighborsRegressor
#减小模型的参数到2
reg2 = KNeighborsRegressor(n_neighbors = 2)
reg2.fit(X,y)
#重新画图可视化
plt.scatter(X,y,c = 'b',edgecolor= 'k')
plt.plot(z,reg2.predict(z),c = 'r',linewidth = 3)
plt.title('KNN Regressor: n_neighbors=2')
plt.show()
#观察上面两个图可知,n_neighbors = 2比默认n_neighbors= 5的模型更加准确即覆盖更多的数据点,但模型变得复杂
#输入模型R^2分数
print(f'模型评分:{reg2.score(X,y):.2f}')
#由此可知,对K最近邻值进行调整,能够有效改善模型的准确率

K最近邻算法的实战练习

任务描述:现在很多大学生都想到国外深造、开阔眼界,需要申请国外的大学的留学资格。我们可以利用数据挖掘的办法来预测能申请获得国外大学录取通知的成功率

1.载入数据集并查看特征

#导入Numpy
import numpy as np
#导入pandas
import pandas as pd
#使用pandas载入数据集,把路径替换为自己数据集存放路径
#这里采用相对地址
data = pd.read_csv('Admission_Predict.csv')
#显示数据集前5行
data.head()

2.了解数据集的数据类型

#在使用数据集时,我们应知道数据集的整体情况,比如数据集有多少条数据、有多少个特征、每个特征的数据的是什么类型等等
#查看数据集的整体信息
data.info()
#显而易见,数据集一共有400条数据,没有字符串类型的数据

3.查看各个特征的统计信息

#查看数据特征的统计信息
data.describe()

4.生成训练集和测试集

#使用train_test_split将数据集划分为数据集和测试集
#重新载入数据集,不影响前面的结果
df = pd.read_csv('Admission_Predict.csv')
#丢弃Serial No.这个特征,因为此特征对建模过程来说意义不大
df.drop(['Serial No.'],axis = 1,inplace = True)

#把去掉预测目标Chance of Admit的数据集作为x
x = df.drop(['Chance of Admit '],axis = 1)
#把预测目标赋值给y
y = df['Chance of Admit '].values
#导入数据集拆分工具
from sklearn.model_selection import train_test_split
#将数据集拆分为数据集和训练集
X_train,X_test,y_train,y_test = train_test_split(x,y,random_state=0)
#train_test_split函数会根据random_state生成一个伪随机数,并根据这个伪随机数对数据集划分,random_state的值固定,生成的伪随机数相同,但random_state的值默认时,每次生成的伪随机数不同
#看一看train_test_split函数划分后的数据集是什么样子

#输出训练集中特征向量的形态
print(f'X_train shape:{X_train.shape}')
#输出测试集的特征向量的形态
print(f'X_test shape:{X_test.shape}')
#输出训练集中目标的形态
print(f'y_train shape:{y_train.shape}')
#输出测试集中目标的形态
print(f'y_test shape:{y_test.shape}')

5.使用K最近邻算法进行建模并调优

#导入用于回归分析的KNN模型
from sklearn.neighbors import KNeighborsRegressor
#这里KNeighborsRegressor()使用默认参数n_neighbors = 5
reg = KNeighborsRegressor()
#使用reg对象对数据集拟合并建模
reg.fit(X_train,y_train)
#以上返回的结果为训练的模型
#测试集并不参与建模,但可以用来为模型打分
#输出模型的得分
print(f'测试集得分:{reg.score(X_test,y_test):.2f}')

从以上结果可以看出,模型得分并不让人满意,以下通过几种方法来对模型进行优化

1.修改n_neighbors的值

#K的取值越大容易出现预测不准确、预测类别受样本数最多的类别影响等问题
#指定n_neighbors = 2
reg2 = KNeighborsRegressor(n_neighbors = 2)
#拟合数据集并建模
reg2.fit(X_train,y_train)
#输出n_neighbors = 2的模型得分
print(f'模型参数n_neighbors = 2的测试集得分:{reg2.score(X_test,y_test):.2f}')
print(f'模型参数n_neighbors = 2的训练集得分:{reg2.score(X_train,y_train):.2f}')

#训练集得分为0.9分,而测试集很低,说明这个模型是过拟合的,尝试将n_neighbors的参数变大

#指定n_neighbors = 10
reg10 = KNeighborsRegressor(n_neighbors = 10)
#拟合数据集并建模
reg10.fit(X_train,y_train)
#输出n_neighbors = 2的模型得分
print(f'模型参数n_neighbors = 10的测试集得分:{reg10.score(X_test,y_test):.2f}')
print(f'模型参数n_neighbors = 10的训练集得分:{reg10.score(X_train,y_train):.2f}')

#由以上结果可知,测试集评分有所增加,但评分还是不高,说明修改n_neighbors参数对该数据集有效

2.利用weights值优化模型

#另一个K最近邻算法的另一个参数weights取默认值时邻居权重相同,"distance"时离得越近的邻居权重越大,这也是模型优化经常使用的方法
#指定模型的weights = distance
reg_w = KNeighborsRegressor(weights = 'distance')
#对数据集进行拟合并建模
reg_w.fit(X_train,y_train)
#输出weigths=distance的模型得分
print(f'模型参数weigths = distance的测试集得分:{reg_w.score(X_test,y_test):.2f}')
print(f'模型参数weigths = distance的训练集得分:{reg_w.score(X_train,y_train):.2f}')
#由以上结果可知,训练集和测试集得分相差严重,出现过拟合

3.进行数据预处理

#下面使用scikit-learn的preprocessing模块中的MinMaxScaler()对数据集进行数据归一化预处理
#导入MinMaxScaler,采用数据归一化预处理
from sklearn.preprocessing import MinMaxScaler
#使用MinMaxScaler进行预处理
X_2 = MinMaxScaler().fit_transform(x)
print(X_2)
#将预处理的数据拆分为测试集和训练集
X_train_pp,X_test_pp,y_train,y_test = train_test_split(X_2,y,random_state = 0)
#重新训练模型
reg_scaled = KNeighborsRegressor()
reg_scaled.fit(X_train_pp,y_train)
#输出模型分数
print(f'模型预处理后的测试集得分:{reg_scaled.score(X_test_pp,y_test):.2f}')
print(f'模型预处理后的训练集得分:{reg_scaled.score(X_train_pp,y_train):.2f}')
#从以上结果可知,数据归一化处理后,模型得分和没有经过预处理的模型reg的评分一致,所以对于K最近邻算法,对数据归一化处理效果不明显

6.使用模型对新样本进行预测

#这里使用n_neighbors = 5的模型
#输入新的数据点
X_new = np.array([[337,118,4,4.5,4.5,9.65,1]])
#使用.predict进行预测
prediction = reg.predict(X_new)
print('K最近邻算法模型预测结果:')
print(f'预测小p同学的综合评分为:{prediction}')
#根据以上结果,小p的同学拿到国外大学录取通知书的概率预测为0.93,可以说是一个很不错的得分,远远高于Chance of Admit的中位数0.72,建议他去申请留学
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值