🎩 欢迎来到技术探索的奇幻世界👨💻
📜 个人主页:@一伦明悦-CSDN博客
✍🏻 作者简介: C++软件开发、Python机器学习爱好者
🗣️ 互动与支持:💬评论 👍🏻点赞 📂收藏 👀关注+
如果文章有所帮助,欢迎留下您宝贵的评论,
点赞加收藏支持我,点击关注,一起进步!
引言
K近邻(K-Nearest Neighbors,简称KNN)算法是一种基本的分类和回归方法,它可以用于解决分类和回归问题。其核心思想可以简单描述如下:
原理
K近邻算法基于一个假设:相似的事物在很多情况下具有相似的性质。具体来说,在分类问题中,KNN算法根据某个样本在特征空间中与其最近的K个训练样本的标记来确定该样本的类别;在回归问题中,KNN算法则是根据该样本最近的K个训练样本的值来预测该样本的值。
工作流程
计算距离: 首先,计算待分类样本与训练集中所有样本的距离。常用的距离度量包括欧氏距离、曼哈顿距离、余弦相似度等。
选择K值: 确定K的取值,即要考虑多少个最近邻的样本。K的选择影响着分类或回归的结果,通常通过交叉验证或者经验选择一个合适的值。
确定邻居: 选出距离最近的K个样本。
进行预测:
- 分类问题: 对于分类问题,采用投票法(多数表决)来确定待分类样本所属的类别,即K个最近邻样本中出现最频繁的类别作为预测结果。
- 回归问题: 对于回归问题,通常采用平均值法,即将K个最近邻样本的值的平均值作为待预测样本的预测值。
特点和适用场景
- 简单有效: KNN是一种简单直观的算法,易于理解和实现。
- 非参数化: KNN算法不对数据的分布做出假设,因此在某些非线性数据的分类问题中表现较好。
- 适用性: 适用于小型数据集和中等大小的特征空间。
- 参数选择: K的选择对算法的性能有显著影响,选择不同的K值可能导致完全不同的结果。
正文
01-绘制均匀核函数和高斯核函数的函数曲线
这段代码是用来绘制两种核函数在一维数据上的图像,并将结果保存为图片。让我详细解释一下这段代码的具体步骤:
导入必要的库:
- 导入NumPy库,用于数值计算。
- 导入Pandas库,用于数据操作。
- 导入Matplotlib库中的Pyplot模块,用于数据可视化。
- 导入warnings模块,用于警告处理。
- 配置Matplotlib参数以支持中文显示,并避免负号显示乱码。
- 导入sklearn库中的linear_model模块、metrics模块中的classification_report函数、model_selection模块中的cross_validate和train_test_split函数、neighbors模块和preprocessing模块。
生成数据:
- 生成一个从-3到3均匀分布的包含100个数据点的一维数据d。
- 定义两种核函数对应的y值:
- y1为全为0.5的数组,表示均匀核函数对应的值。
- y2为高斯核函数对应的值,根据高斯分布的概率密度函数公式计算得出。
- 调整y1和y2的取值,使得在d小于-1和大于1时,y1和y2的取值为0,以展示核函数在特定区间内的变化。
绘制图像:
- 使用plt.plot方法绘制两种核函数在给定数据上的曲线图。
- 设置不同的linestyle以区分均匀核、高斯核和高斯核的理论形式(虚线)。
- 添加图例并设置标题,说明两种核函数的区别。
保存图片:
- 使用plt.savefig方法将生成的图像保存为一个名为"4.png"的文件,设置dpi为300,使得保存的图片具有更高的分辨率。
通过以上步骤,这段代码实现了对两种核函数在一维数据上的可视化,并将结果保存为图片,以便进一步分析和展示。
#本章需导入的模块
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings(action = 'ignore')
%matplotlib inline
plt.rcParams['font.sans-serif']=['SimHei'] #解决中文显示乱码问题
plt.rcParams['axes.unicode_minus']=False
import sklearn.linear_model as LM
from sklearn.metrics import classification_report
from sklearn.model_selection import cross_validate,train_test_split
from sklearn import neighbors,preprocessing
d=np.linspace(-3,3,100)
y1=[0.5]*100
y2=1/np.sqrt(2*np.pi)*np.exp(-d*d/2)
plt.plot(d,y2,label="高斯核(I(.)=1)",linestyle='-.')
y1,y2=np.where(d<-1,0,(y1,y2))
y1,y2=np.where(d>1,0,(y1,y2))
plt.plot(d,y1,label="均匀核",linestyle='-')
plt.plot(d,y2,label="高斯核",linestyle='--')
plt.legend()
plt.title("两种核函数")
plt.savefig("../4.png", dpi=300)
运行结果如下图所示:
02-加权K-近邻法不同加权策略和参数K下的分类预测误差以及分类边界
这部分代码是用来演示K近邻算法在二维数据上的分类边界,并将结果保存为图片。让我详细解释一下代码的具体步骤:
导入必要的库:
- 导入NumPy库,用于数值计算。
- 导入Pandas库,用于数据操作。
- 导入Matplotlib库中的Pyplot模块,用于数据可视化。
- 导入warnings模块,用于警告处理。
- 配置Matplotlib参数以支持中文显示,并避免负号显示乱码。
- 导入sklearn库中的linear_model模块、metrics模块中的classification_report函数、model_selection模块中的cross_validate和train_test_split函数、neighbors模块和preprocessing模块。
生成数据:
- 设置随机数种子为123,以保证结果的可复现性。
- 定义样本数量N为50,并设置一半的样本为类别0,另一半为类别1。
- 生成均值为0,标准差为1的正态分布数据,构成大小为100x2的二维数组X。
- 将前半部分的数据(类别0)向右上角移动1.5个单位标准差。
创建网格数据:
- 使用np.meshgrid生成平面上100x100的网格点,覆盖了X中两列数据的范围。
创建子图和循环绘图:
- 使用plt.subplots创建一个包含2行2列的子图布局,总共4个子图,设置图像大小为15x12英寸。
- 使用循环遍历不同的参数组合(W, K, H, L, T),其中:
- W为K近邻算法的权重类型,可以是’distance’(倒数加权)或自定义的高斯加权函数guass。
- K为近邻数量。
- H和L确定当前子图的位置。
- T为图标题的一部分,描述了权重类型。
- 对于每个参数组合:
- 创建K近邻分类器对象modelKNN。
- 使用fit方法将模型与数据X和Y进行拟合。
- 使用predict方法预测网格数据data的类别Yhat。
- 根据预测结果,使用scatter方法在当前子图中绘制分类结果的散点图,其中类别0用银色点表示,类别1用红色点表示。
- 使用scatter方法绘制训练数据,类别0用黑色十字表示,类别1用品红色圆圈表示。
- 设置X1和X2轴标签,以及子图标题,包括K值、权重类型和训练误差(1 - 模型在训练数据上的准确率)。
保存和显示图片:
- 使用plt.savefig方法将生成的图像保存为一个名为"4.png"的文件,设置dpi为300,以便保存高分辨率的图像。
- 使用plt.show方法显示所有子图。
通过以上步骤,这段代码展示了不同参数设置下K近邻算法在二维数据上的分类效果,并将结果保存为图片,以供进一步分析和展示。
#本章需导入的模块
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings(action = 'ignore')
%matplotlib inline
plt.rcParams['font.sans-serif']=['SimHei'] #解决中文显示乱码问题
plt.rcParams['axes.unicode_minus']=False
import sklearn.linear_model as LM
from sklearn.metrics import classification_report
from sklearn.model_selection import cross_validate,train_test_split
from sklearn import neighbors,preprocessing
def guass(x):
x=preprocessing.scale(x)
output=1/np.sqrt(2*np.pi)*np.exp(-x*x/2)
return output
np.random.seed(123)
N=50
n=int(0.5*N)
X=np.random.normal(0,1,size=100).reshape(N,2)
Y=[0]*n+[1]*n
X[0:n]=X[0:n]+1.5
X1,X2 = np.meshgrid(np.linspace(X[:,0].min(),X[:,0].max(),100), np.linspace(X[:,1].min(),X[:,1].max(),100))
data=np.hstack((X1.reshape(10000,1),X2.reshape(10000,1)))
fig,axes=plt.subplots(nrows=2,ncols=2,figsize=(15,12))
for W,K,H,L,T in [('distance',30,0,0,'倒数加权'),(guass,30,0,1,'高斯加权'),('distance',40,1,0,'倒数加权'),(guass,40,1,1,'高斯加权')]:
modelKNN=neighbors.KNeighborsClassifier(n_neighbors=K,weights=W)
modelKNN.fit(X,Y)
Yhat=modelKNN.predict(data)
for k,c in [(0,'silver'),(1,'red')]:
axes[H,L].scatter(data[Yhat==k,0],data[Yhat==k,1],color=c,marker='o',s=1)
axes[H,L].scatter(X[:n,0],X[:n,1],color='black',marker='+')
axes[H,L].scatter(X[(n+1):N,0],X[(n+1):N,1],color='magenta',marker='o')
axes[H,L].set_xlabel("X1")
axes[H,L].set_ylabel("X2")
axes[H,L].set_title("%d-近邻分类边界-%s(训练误差%.2f)"%((K,T,1-modelKNN.score(X,Y))))
plt.savefig("../4.png", dpi=300)
plt.show()
运行结果如下图所示:
03-基于K-近邻算法对空气质量等级进行预测
这部分代码的作用是对北京市空气质量数据进行预处理和K近邻算法的应用,最终生成一个测试精度随K值变化的折线图,并将结果保存为图片。
具体步骤如下:
导入必要的库和数据读取:
- 导入NumPy、Pandas、Matplotlib等库,以及警告处理设置。
- 使用Pandas的
read_excel
函数读取名为’北京市空气质量数据.xlsx’的Excel文件中的数据。- 将数据中的0值替换为NaN,并丢弃包含NaN的行,确保数据的完整性。
数据准备:
- 从处理后的数据中提取特征变量X(包括PM2.5、PM10、SO2、CO、NO2、O3)和目标变量Y(质量等级)。
数据集划分:
- 使用
train_test_split
函数将数据集划分为训练集(70%)和测试集(30%),并设置随机种子以确保可重复性。确定最佳K值:
- 设定一个K值的范围K,从1到训练集样本数的20%之间,步长为10。
- 对于每个K值,建立一个K近邻分类器(
neighbors.KNeighborsClassifier
),使用距离加权(weights=‘distance’)的方式进行分类。- 使用训练集训练模型,并在测试集上评估模型性能,计算测试精度(准确率)并记录在
testPre
列表中。绘制折线图:
- 创建一个9x6英寸大小的新图形。
- 绘制K值与测试精度的折线图,使用
plot
函数,并设置网格线和刻度标签。- 添加横轴K和纵轴测试精度的标签,以及整体图形的标题,包括显示最佳K值。
保存和显示图片:
- 使用
plt.savefig
方法将生成的图像保存为文件"4.png",设置dpi为300以保证高分辨率。- 最后使用
plt.show
方法显示图形。通过这段代码,可以清楚地分析不同K值对于K近邻算法在北京市空气质量数据上的影响,帮助选择最佳的K值参数,以优化模型在未知数据上的表现。
#本章需导入的模块
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings(action = 'ignore')
%matplotlib inline
plt.rcParams['font.sans-serif']=['SimHei'] #解决中文显示乱码问题
plt.rcParams['axes.unicode_minus']=False
import sklearn.linear_model as LM
from sklearn.metrics import classification_report
from sklearn.model_selection import cross_validate,train_test_split
from sklearn import neighbors,preprocessing
data=pd.read_excel('北京市空气质量数据.xlsx')
data=data.replace(0,np.NaN)
data=data.dropna()
X=data.loc[:,['PM2.5','PM10','SO2','CO','NO2','O3']]
Y=data.loc[:,'质量等级']
testPre=[]
X_train, X_test, Y_train, Y_test = train_test_split(X,Y,train_size=0.70, random_state=123)
Ntrain=len(Y_train)
K=np.arange(1,int(Ntrain*0.20),10)
for k in K:
modelKNN=neighbors.KNeighborsClassifier(n_neighbors=k,weights='distance')
modelKNN.fit(X_train,Y_train)
testPre.append(modelKNN.score(X_test,Y_test))
plt.figure(figsize=(9,6))
plt.grid(True, linestyle='-.')
plt.xticks(K)
plt.plot(K,testPre,marker='.')
plt.xlabel("K")
plt.ylabel("测试精度")
bestK=K[testPre.index(np.max(testPre))]
plt.savefig("../4.png", dpi=300)
plt.title("加权K-近邻的测试精度(1-测试误差)变化折线图\n(最优参数K=%d)"%bestK)
运行结果如下图所示:
这段代码的作用是使用经过调优的最佳K值(bestK)重新构建一个K近邻分类器,并对模型进行评估和输出评估报告。
具体步骤如下:
重新构建K近邻分类器:
- 使用
neighbors.KNeighborsClassifier
类构建一个K近邻分类器。- 将
n_neighbors
参数设置为之前计算出的最佳K值bestK
,以及weights
参数设置为’distance’,表示使用距离加权的方式进行分类。模型训练:
- 使用训练集(X_train和Y_train)对重新构建的K近邻分类器进行训练,通过
fit
方法完成。评估模型性能:
- 使用
classification_report
函数对模型在整个数据集(X)上进行评估。classification_report
函数会计算并输出模型在每个类别上的精确度、召回率、F1-score和支持数等指标,帮助分析模型的分类效果。输出评估报告:
- 最后,将计算得到的分类报告打印输出,展示模型在各个类别上的预测性能。
通过这段代码,可以全面评估经过优化的K近邻模型在北京市空气质量数据上的整体分类表现,提供了对模型准确性和其他评估指标的详细了解。
modelKNN=neighbors.KNeighborsClassifier(n_neighbors=bestK,weights='distance')
modelKNN.fit(X_train,Y_train)
print('评价模型结果:\n',classification_report(Y,modelKNN.predict(X)))
运行结果如下图所示:
评价模型结果: precision recall f1-score support 严重污染 0.98 0.98 0.98 43 中度污染 0.95 0.95 0.95 252 优 0.99 0.98 0.98 377 良 0.98 0.99 0.98 827 轻度污染 0.97 0.97 0.97 470 重度污染 0.98 0.93 0.96 127 accuracy 0.98 2096 macro avg 0.97 0.97 0.97 2096 weighted avg 0.98 0.98 0.98 2096
04-基于K-近邻算法和一元线性回归算法对电视剧播放数据质量进行分析
这部分代码的作用是对电视剧播放数据进行预处理和数据清洗,确保数据可以用于后续的分析和建模。
具体步骤如下:
导入必要的库和数据读取:
- 导入NumPy、Pandas、Matplotlib等库,以及警告处理设置。
- 使用Pandas的
read_excel
函数读取名为’电视剧播放数据.xlsx’的Excel文件中的数据。数据预处理:
- 将数据中的0值替换为NaN,并丢弃包含NaN的行,确保数据的完整性。
数据清洗:
- 使用逻辑运算符
&
(与)来选择满足两个条件的行:
- 点赞数小于或等于2000000。
- 差评数小于或等于2000000。
- 使用
.loc
索引器来限制数据集,只保留满足上述条件的行。查看数据头部:
- 使用
.head()
方法显示数据的前几行,通常是前5行,以检查数据清洗后的结果。代码的作用是确保数据集中没有包含点赞数或差评数异常大的数据,因为这些数据可能对模型的准确性产生影响。通过限制点赞数和差评数的范围,可以提高后续数据分析和建模的可靠性。
注意,这段代码没有进行任何模型构建或评估,它仅限于数据预处理和清洗。
#本章需导入的模块
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings(action = 'ignore')
%matplotlib inline
plt.rcParams['font.sans-serif']=['SimHei'] #解决中文显示乱码问题
plt.rcParams['axes.unicode_minus']=False
import sklearn.linear_model as LM
from sklearn.metrics import classification_report
from sklearn.model_selection import cross_validate,train_test_split
from sklearn import neighbors,preprocessing
data=pd.read_excel('电视剧播放数据.xlsx')
data=data.replace(0,np.NaN)
data=data.dropna()
data=data.loc[(data['点赞']<=2000000) & (data['差评']<=2000000)]
data.head()
这段代码主要进行了以下操作,针对电视剧播放数据进行了K近邻回归和一般线性回归模型的建模,并进行了可视化展示:
数据准备与拆分:
- 从前面清洗过的数据中选择了特征
X
为点赞数和差评数,目标变量Y
为得分。- 使用
train_test_split
函数将数据集拆分为训练集(70%)和测试集(30%),并指定随机种子random_state=123
以确保结果的可重复性。建立模型并训练:
- K近邻回归模型 (
modelKNN
):设定邻居数n_neighbors=20
,使用训练集X_train
和Y_train
进行模型训练。- 一般线性回归模型 (
modelLR
):使用LinearRegression
类建立线性回归模型,同样使用训练集进行训练。模型评估与输出:
- 分别使用
.score()
方法计算并输出了测试集上的精度和整体数据集上的预测精度,用以评估模型在点赞数和得分之间的拟合程度。数据可视化:
- 使用
matplotlib
库创建了一个包含两个子图的图形,每个子图显示了点赞数与得分之间的关系。- 第一个子图展示了原始数据散点图,并绘制了K近邻回归模型和一般线性回归模型的拟合线。
- 第二个子图则限制了点赞数不超过250,000的数据范围,并重复了相同的可视化过程,以便更清楚地观察模型在较小数据范围内的表现。
保存图像:
- 使用
plt.savefig
保存这两个子图为PNG格式的图像文件,分别命名为’…/3.png’和’…/4.png’,设定dpi为300以保证高质量的输出图像。这段代码的主要目的是通过建立不同模型(K近邻回归和线性回归)来探索点赞数与得分之间的关系,并通过可视化展示模型的拟合效果。
X=data.loc[:,['点赞','差评']]
Y=data.loc[:,'得分']
X_train, X_test, Y_train, Y_test = train_test_split(X,Y,train_size=0.70, random_state=123)
modelKNN=neighbors.KNeighborsRegressor(n_neighbors=20)
modelKNN.fit(X_train,Y_train)
print('K-近邻:测试精度=%f总预测精度=%f'%(modelKNN.score(X_test,Y_test),modelKNN.score(X,Y)))
modelLR=LM.LinearRegression()
modelLR.fit(X_train,Y_train)
print('一般线性回归模型:测试精度=%f;总预测精度=%f'%(modelLR.score(X_test,Y_test),modelLR.score(X,Y)))
fig,axes=plt.subplots(nrows=1,ncols=2,figsize=(12,4))
axes[0].scatter(X.iloc[:,0],Y,s=2,c='r')
index = np.argsort(X.iloc[:,0])
axes[0].plot(X.iloc[index,0],modelKNN.predict(X.iloc[index,:]),linewidth=0.5,label="K-近邻")
axes[0].plot(X.iloc[index,0],modelLR.predict(X.iloc[index,:]),linestyle='--',linewidth=1,label="一般线性回归模型")
axes[0].set_title('点赞数和得分',fontsize=12)
axes[0].set_xlabel('点赞数',fontsize=12)
axes[0].set_ylabel('得分',fontsize=12)
axes[0].legend()
plt.savefig("../3.png", dpi=300)
data=data.loc[(data['点赞']<=250000)]
axes[1].scatter(data['点赞'],data['得分'],s=2,c='r')
T=X.loc[(X['点赞']<=250000)]
index = np.argsort(T.iloc[:,0])
axes[1].plot(T.iloc[index,0],modelKNN.predict(T.iloc[index,:]),linewidth=0.5,label="K-近邻")
axes[1].plot(T.iloc[index,0],modelLR.predict(T.iloc[index,:]),linestyle='--',linewidth=1,label="一般线性回归模型")
axes[1].set_title('点赞数和得分',fontsize=12)
axes[1].set_xlabel('点赞数',fontsize=12)
axes[1].set_ylabel('得分',fontsize=12)
axes[1].legend()
plt.savefig("../4.png", dpi=300)
运行结果如下图所示:
总结
K近邻算法是一种简单而强大的分类和回归算法,尽管它有一些限制(如对大型数据集的处理速度较慢),但在许多现实世界的问题中仍然广泛应用。