python机器学习算法——KNN算法
如题,KNN算法。
参考:
https://www.showmeai.tech/article-detail/187
前提总结:KNN算法,或许就是“近墨者黑,近朱者赤”。
1.机器学习与分类问题
1)分类问题
2)分类问题的数学抽象
从算法的角度解决一个分类问题,我们的训练数据会被映射成 维空间的样本点(这里的 就是特征维度),我们需要做的事情是对 维样本空间的点进行类别区分,某些点会归属到某个类别。
2.K近邻算法核心思想
1)K近邻核心思想
在 KNN 分类中,输出是一个分类族群。一个对象的分类是由其邻居的「多数表决」确定的, 个最近邻居( 为正整数,通常较小)中最常见的分类决定了赋予该对象的类别。
若 ,则该对象的类别直接由最近的一个节点赋予。
在 KNN 回归中,输出是该对象的属性值。该值是其 个最近邻居的值的平均值。
近邻居法采用向量空间模型来分类,概念为相同类别的案例,彼此的相似度高。而可以借由计算与已知类别案例之相似度,来评估未知类别案例可能的分类。
2)豆子分类例子
1968年,Cover 和 Hart 提出了最初的近邻法,思路是——未知的豆离哪种豆最近,就认为未知豆和该豆是同一种类。
最近邻算法的缺陷是对噪声数据过于敏感。从图中可以得到,一个圈起来的蓝点和两个圈起来的红点到绿点的距离是相等的,根据最近邻算法,该点的形状无法判断。
为了解决这个问题,我们可以把位置样本周边的多个最近样本计算在内,扩大参与决策的样本量,以避免个别数据直接决定决策结果。
引进 近邻算法——选择未知样本一定范围内确定个数的 个样本,该 个样本大多数属于某一类型,则未知样本判定为该类型。 近邻算法是最近邻算法的一个延伸。
3.K近邻算法步骤与示例
1)K近邻算法工作原理
存在一个样本数据集合,也称作训练样本集,并且样本集中每个数据都存在标签,即我们知道样本集中每个数据与所属分类的对应关系。
输入没有标签的新数据后,将新数据的每个特征与样本集中数据对应的特征进行比较,然后算法提取样本集中特征最相似数据(最近邻)的分类标签。
一般来说,只选择样本数据集中前 个最相似的数据。 一般不大于 ,最后,选择 个中出现次数最多的分类,作为新数据的分类。
理解:提取和测试目标字段,筛选一种变量,取得测试集和训练集,确定k(间接得出距离),得到均值(KNN后的,即是那个次数最多的分类)作为新数据的分类。
2)K近邻算法参数选择
如何选择一个最佳的 值取决于数据。一般情况下,在分类时较大的 值能够减小噪声的影响,但会使类别之间的界限变得模糊。一个较好的 值能通过各种启发式技术(见超参数优化)来获取。
噪声和非相关性特征的存在,或特征尺度与它们的重要性不一致会使 近邻算法的准确性严重降低。对于选取和缩放特征来改善分类已经做了很多研究。一个普遍的做法是利用进化算法优化功能扩展,还有一种较普遍的方法是利用训练样本的互信息进行选择特征。
在二元(两类)分类问题中,选取 为奇数有助于避免两个分类平票的情形。在此问题下,选取最佳经验 值的方法是自助法。
说明: KNN 没有显示的训练过程,它是「懒惰学习」的代表,它在训练阶段只是把数据保存下来,训练时间开销为 ,等收到测试样本后进行处理。
这里有一个样例(课上也同样讲到了)
3)K近邻算法示例
4.K近邻算法的缺点与改进
1)K近邻算法的优缺点
优点:精度高、对异常值不敏感、无数据输入假定。
缺点:计算复杂度高、空间复杂度高。
适用数据范围:数值型和标称型。
2)K近邻算法的核心要素:距离度量准则
近邻算法能用一种有效的方式隐含的计算决策边界。另外,它也可以显式的计算决策边界,以及有效率的这样做计算,使得计算复杂度是边界复杂度的函数。 近邻算法依赖于空间中相近的点做类别判断,判断距离远近的度量标准非常重要。
距离的度量标准,对很多算法来说都是核心要素(比如无监督学习的 聚类算法 也很大程度依赖距离度量),也对其结果有很大的影响。
3)K近邻算法的核心要素:K的大小
对于 KNN 算法而言, 的大小取值也至关重要,如果选择较小的 值,意味着整体模型变得复杂(模型容易发生过拟合),模型学习的近似误差(approximation error)会减小,但估计误差(estimation error)会增大。
如果选择较大的 值,就意味着整体的模型变得简单,减少学习的估计误差,但缺点是学习的近似误差会增大。
在实际的应用中,一般采用一个比较小的 值。并采用交叉验证的方法,选取一个最优的 值。
4)K近邻算法的缺点与改进
1)缺点
样本库容量依赖性较强对 KNN 算法在实际应用中的限制较大:
有不少类别无法提供足够的训练样本,使得 KNN 算法所需要的相对均匀的特征空间条件无法得到满足,使得识别的误差较大。
值的确定:
KNN 算法必须指定 值, 值选择不当则分类精度不能保证。
2)改进方法
加快 KNN 算法的分类速度。
浓缩训练样本当训练样本集中样本数量较大时,为了减小计算开销,可以对训练样本集进行编辑处理,即从原始训练样本集中选择最优的参考子集进行 近邻寻找,从而减少训练样本的存储量和提高计算效率。
加快 个最近邻的搜索速度这类方法是通过快速搜索算法,在较短时间内找到待分类样本的 个最近邻。
对训练样本库的维护。
对训练样本库进行维护以满足 KNN 算法的需要,包括对训练样本库中的样本进行添加或删除,采用适当的办法来保证空间的大小,如符合某种条件的样本可以加入数据库中,同时可以对数据库库中已有符合某种条件的样本进行删除。从而保证训练样本库中的样本提供 KNN 算法所需要的相对均匀的特征空间。
5.案例介绍
数据集请去原网站下载,保留一下我的数据集位置:
将预计出租房子数据与数据集中每条记录比较计算欧式距离,取出距离最小的5条记录,将其价格取平均值,可以将其看做预计出租房子的市场平均价格。(可以认为k为5,之后会详细解释为什么要取平均值的)
源码请去原网址观看,原网址本文文首和文末都有贴出。记录一下我的源代码保留位置:
关于自己对源码的解释(不建议观看)
import模块:
(vim貌似没有找到自动导包的插件,可以在windows的相关python的IDE进行编写然后再复制到vim也行,也可以直接在windows里编写运行,但是还是建议在linux系统里啦,希望我的linux不会内存不够,我给了100G,只是用来写代码没事的吧)
有关数据的有numpy和pandas,比如说pandas的DataFrame对象(相关操作实践写着写着就会了),类似于
col1 col2 col3
0 xxx xxx xxx
1 xxx xxx xxx
………………………………………………………………
然后计算欧式距离的有scipy(数学函数库)的spatial(空间的)
之后就是因为数据范围使用的标准化,sklearning.processing.StandardScaler(Scaler标量的),processing过程,是过程中的数据准备
接下来是主要,KNN算法,sklearn.neighbors.KNN,这个包名是因为KNN算法的KNeighbors,k近邻算法
最后是误差判断,knn使用均方根误差,mean_squared_error(这个意思是均平方误差,所以需要最后还需要开根号)
来自sklearn的metrics,metrics(指标)
sklearn用于分类,聚类等
记忆重点:
open(path,'encoding=gb18030',errors='ignore')
paht = r'路径'
由于python的变量没有类型,所以诸如 dc_listings = pd.read_cv(file) ,然后又出现了 dc_listings = dc_listings['features']很重要
pd.read_csv(file)得出来的结果是DataFrame对象实例
也有这么用的:
features = ['xxx','xxxx','xxx']
dc_listings['features']是一个截取了部分列的DataFrame对象实例,代码这里是这么写的dc_listings = dc_listings['features']
意思大概就是,如果尽可能地和其他语言融合,features的这些就是下标,然后截取一部分表可以使用features列表
不过其实是DataFrame对象啦。
数据初步清洗
突然找到很详细的链接:[200~https://www.cnblogs.com/nerd/p/14405726.html
np.abs(dc_listings.accommodates - our_acc_value)加上sort是为了那些靠近3容纳(accommodates)的数据。(筛选数据,样例是有一套房子即将出租,选取相似的,就是多变量的一种变量)
dc_listings['distance'] 是新增一个列的,注意这个用法
sample是用来获取随机样本的,因为提取的数据可能会有规律
dropna是用来删除有缺失值的
数据标准化:
对我们想要的特征进行标准化的:
dc_listings[features] = StandardScale().fit_transform(dc_listings[features])
normalized = dc_listings[features]
标准化的原因是,理想情况下我们的列的数据范围是一样的,但是现实很难,所以需要标准化(具体实现我们抽象掉吧,现在还是别去看了)
分出训练集和测试集合
norm_train_dc_features = normalized_listings[:2792]
数据集是由pandas的DataFrame来呈现的,
iloc是用来找到datafram的索引和列的
https://blog.csdn.net/Bigboss7/article/details/118597351
这里的代码示例是第1行和第accommodates和bathrooms列的:first_listings = normalized_listings.iloc[0][['accommodates', 'bathrooms']]
(类似的fifth就不讲了)
(通过DataFrame的行索引和列索引就可以知道很多语句了)
https://blog.csdn.net/weixin_42107718/article/details/98659921
所以norm_train_df = normalized_listings[:2792]应该是行
索引,0到2792行
first_listings = normalized_listings.iloc[0]['accommodates','bathrooms']
这个就是dataframes的iloc方法
用python方法做多变量KNN模型
def predict_price_multivariate(new_listing_value,feature_colummns):
多变量 is multi(multipy)variate(variable)
normalized是归一化的意思
distance.cdist(temp_df[feature_columns],new_listing_value[feature_columns]))是计算两个集合的距离,feature_columns可以是多个特征
knn_5 = temp_df.price.iloc[:5]
predicted_price = knn_t.mean() mean我记得是均值
knn_5那个,应该是这个意思,我们从那个图中可以知道是一个圆形的看圆内种类,那个圆就是几何上的距离。我们按照距离排序
,其实圆的半径应该是第5行的那个(行索引为4),这里可以理解成k是5
mean,均值,可以理解成平均值,
先通过距离排序,以此获得price的排名,然后再均值。
均值,是因为距离问题吧,如果是a类,价格应该是某一个范围,
如果是b类,价格应该是另一个范围,通过圆内谁的种类多(相应的在某一个特定范围的多)计算出来的均值肯定会偏向种类多的价格范围。
关于计算距离的方法,这个例子采用的是欧式距离,import语句是
from scipy.spatial import distance
distance.cdist(temp_df[feature_columns],new_listing_value[feature_columns])
由于数据初步清洗那里先一步排序需要的accomodates了,所以这里虽然是多特征,但是可能bathrooms的影响更大点。
cdist是communlate distance(计算距离)
norm_test_df['predicted_price'] = norm_test_df[cols].apply(predict_price_multivariate,feature_columns = cols, axis = 1)
需要注意的是norm_test_df[cols]的cols是两个列名,这里应该是需要处理的两个列,得出的结果变成一个列,去查了apply方法,是对列的数据进行逐一遍历
norm_test_df['squared_error'] = (norm_test_df['predicted_price'] - norm_test_df['price']) ** 2
mse = norm_test_df['squared_error'].mean()
rmse = mese ** (1/2)
利用sklearn完成KNN
col=['accommodates','beadrooms']
knn = KNeighborRegressor() Regressor是回归的意思
将自变量和因变量放入模型训练,并用测试数据测试。
knn.fit(norm_train_df[cols],norm_train_df['price'])
(测试即是得出曲线)
two_features_predictions = knn.predict(norm_test_df[cols])
计算预测值与实际值的均方根误差
two_features_mse = mean_squared_error(norm_test_df['price'],two_features_prediction)
(也就是将预测出来的数据和我们的原先的test进行比对看看误差有多大)
two_features_rmse = two_features_mse ** (1/2)
print(two_features_rmse)
KNN_first_start.py(或者说原作者给出的源代码)实际上表现了两种用法,一种是python构建多变量KNN模型,一种是sklearn的多变量KNN模型。
步骤总结:
那么通过源码自己总结一下步骤:
1.导入数据并提取目标字段(可以理解成加快knn的分类方法?)(提取多少要么看题目要么看自己)
2.进行初步数据清洗,先将多变量中的一个变量进行排序,随机,替换不能要的字符,删除缺失行,标准化清洗得出的数据,取得训练集和测试集
3.获得多变量KNN模型中想要的列的数据(后面貌似没有用到),可以使用python方法做多变量KNN模型,也可以使用sklearn提供的KNN,记得两种方法都要计算误差。
参考链接:https://www.showmeai.tech/article-detail/187
本文作者:程序计算机人
本文链接:https://www.cnblogs.com/clina/p/18137250
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战