机器学习-KNN以及对鸢尾花分类
KNN-k近邻回归,K-NearestNeighbour:k个最近的邻居。每个样本都可以用它的最接近的K个邻近值来代表。
首先引入问题?面对如下数据,我们该如何将电影分类呢?

通过对比打斗镜头和接吻镜头,一方大于另一方,也就是说,这个电影与某一特征非常接近,并且有大量的出现次数,就可判断。

当我们在数据集中判断数据特征属于哪一类别,就需要以上方式,Knn算法。
算法说明:
-
输入没有标签的新数据,将新数据的每个特征与样本集中数据对应的特征进行比较,然后算法提取样本集中特征最相似数据(最近邻)的分类标签。
-
一般来说,只选择样本数据集中k个最相似的数据。k一般不大于20,最后选择k个数据中出现次数最多的分类,作为新数据的分类。

主要看K的最适合的选择
那么如何选择K呢?
-
计算已知类别数据集众多点与当前点之间的距离:计算两点距离
-
按照距离递增次序排序
-
选取与当前点距离最小的k个点:选择距离最小的点
-
确定前k个点所在类别的出现频率
-
返回前k个点出现频率最高的类别作为当前点的预测分类
两个距离度量
1.欧式距离:简单来说,就是点的距离
-
二维空间里的欧氏距离公式:

-
三维空间里的欧氏距离公式:

-
n 维空间里的欧氏距离公式:

2.曼哈顿距离
标明两个点在标准坐标系上的绝对轴距总和。
在平面上,坐标(x1,y1)的i点与坐标(x2,y2)的j点的曼哈顿距离为:d(i,j)=|X1-X2|+|Y1-Y2|。

绿色为欧氏距离,其余为曼哈顿距离。
典型的项目:鸢尾花
对花瓣,花萼的宽度和长度进行回归分析预测

import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
# Importing the dataset 导入数据
dataset = pd.read_csv('E:\LianXi\机器学习\Iris-data.csv')
dataset.head()
#drop Id column 删除第Id列
dataset = dataset.drop('Id',axis=1)
dataset.head()
# shape
# print(dataset.shape)
# # more info on the data 有关数据的更多信息
# print(dataset.info())
#
# # descriptions
# print(dataset.describe())
#
# # class distribution 阶级分布
# print(dataset.groupby('Species').size())
# 未分组:变量之间的散点矩阵图
from pandas.plotting import scatter_matrix
# scatter plot matrix
scatter_matrix(dataset,figsize=(10,10))
plt.show()
#分组后:散点矩阵图,diag_kind=“kde”:kde密度曲线,如果不加则下图对角线处默认为柱状图。
# updating the diagonal elements in a pairplot to show a kde
sns.pairplot(dataset, hue="Species",diag_kind="kde",markers='+')
#
# Importing metrics for evaluation 应用不同的分类
from sklearn.metrics import confusion_matrix #计算混淆矩阵以评估分类的准确性
from sklearn.metrics import classification_report #显示主要的分类指标,返回每个类标签的精确、召回率
# X = dataset.iloc[:, :-1].values #前四列
# y = dataset.iloc[:, -1].values #最后一列
X=dataset[['SepalLengthCm', 'SepalWidthCm', 'PetalLengthCm', 'PetalWidthCm']]
y =dataset['Species']
# Splitting the dataset into the Training set and Test set 将数据集拆分为训练集和测试集
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 1)
# K-Nearest Neighbours
from sklearn.neighbors import KNeighborsClassifier
classifier = KNeighborsClassifier(n_neighbors=8)
classifier.fit(X_train, y_train)
y_pred = classifier.predict(X_test)
# Summary of the predictions made by the classifier #预测摘要
print(classification_report(y_test, y_pred))
print(confusion_matrix(y_test, y_pred))
# Accuracy score
from sklearn.metrics import accuracy_score
print('accuracy is',accuracy_score(y_pred,y_test))
# experimenting with different n values 用不同k值实验
k_range = list(range(1, 20))
scores = []
for k in k_range:
knn = KNeighborsClassifier(n_neighbors=k)
knn.fit(X, y)
y_pred = knn.predict(X)
scores.append(accuracy_score(y, y_pred))
plt.plot(k_range, scores)
plt.xlabel('Value of k for KNN')
plt.ylabel('Accuracy Score')
plt.title('Accuracy Scores for Values of k of k-Nearest-Neighbors')
plt.show()
数据集:链接:https://pan.baidu.com/s/1apV6wx9plvv9Yir0l8ExAQ?pwd=373z
提取码:373z

我们得到这张图时,发现有几个点的准确率都很高,甚至k=1,达到1的准确率,但如何选择呢?
k=1,数据集太小了,容易造成过拟合,很多细节都收入,例如噪声等。k=15,达到0.98,但是数据太多了,分析不到位,达到欠拟合,我们可以把其他点代入进去,发现只有k=8,准确率完全等于一,此时k=8就是我们要的最合适的值。
总结:knn算法用于预测某些特征是否满足,最终来预测,k的值如何选取是个重要问题,如果太小,细节处理太多,会造成过拟合,k太大,会造成欠拟合。
knn也有缺点:
1.计算量大,尤其是特征数非常多的时候
2.样本不平衡的时候,对稀有类别的预测准确率低
3.慵懒散学习方法,基本上不学习,导致预测时速度比起逻辑回归之类的算法慢
如果学习了其他算法,knn就劣势很多了。
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐



所有评论(0)