K邻近算法原理(K:近邻的个数)
可用于分类或回归
- 分类(近朱者赤近墨者黑)
对于k邻近算法来讲,新数据点离谁最近,就和谁属于同一类。
如果在模型训练的过程中选的最邻近数为1,很可能这个数据恰好是一个错误数据,因此,需要增加最近邻的数量,比如把最邻近数增加到3,如果与新数据点距离最近的这3个点中有两个点是蓝色点,那新数据点也被分到蓝色类别中。
- 回归
K邻近算法用于回归的原理与分类相同,当我们用K邻近算法回归计算某个数据点的预测值时,模型会选择离该数据点最近的若干个训练数据集中的点,并将它们的y值取平均值,并将该平均值作为新数据点的预测值。
K邻近算法原理
k近邻法三要素:距离度量、k值的选择、分类决策规则
- 距离度量
- k值的选择
k值过大,容易欠拟合;k值过小,模型更复杂,容易过拟合。
sklearn.model_selection.cross_val_score()
实现交叉验证选取k 值。
- 分类决策规则
多数表决:新数据点距离最近的数据点的多数类决定新数据点的类别
sklearn.neighbors.KNeighborsClassifier(n_neighbors = 5,
weights='uniform',
algorithm = '',
leaf_size = '30',
p = 2,
metric = 'minkowski',
metric_params = None,
n_jobs = None
)
Sklearn 实践酒的分类
train_test_split函数会生成一个伪随机数,并根据伪随机数对数据集进行拆分。让多次生成的伪随机数相同,方法是通过固定random_state的数值,相同的random_state会一直生成同样的伪随机数。random_state = 0,或不设置,每次生成的伪随机数不同。
from sklearn.datasets import load_wine
data = load_wine()
print('红酒数据集中的keys:\n{}'.format(data.keys()))
X = data.data
y = data.target
X.shape#(178, 13)
y.shape#(178,)
# print(data['DESCR'])#查看数据集详细信息
print(data.target_names)#['class_0' 'class_1' 'class_2']
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test = train_test_split(X,y,random_state = 0)
X_train.shape,X_test.shape,X_train.shape,y_test.shape
#((133, 13), (45, 13), (133, 13), (45,))
from sklearn.neighbors import KNeighborsClassifier
clf = KNeighborsClassifier(n_neighbors =100).fit(X_train,y_train)
clf.predict(X_test)
print('模型得分为:{:.2f}'.format(clf.score(X_test,y_test)))
import matplotlib.pyplot as plt
from sklearn.model_selection import cross_val_score
k_range = range(1,31)
k_error = []
for k in k_range:
clf = KNeighborsClassifier(n_neighbors = k).fit(X_train,y_train)
score = cross_val_score(clf,X,y,cv = 10).mean()
error = 1 - score
k_error.append(error)
plt.plot(k_range,k_error,color = 'red')
plt.show()
#K在23左右,误差最小
clf = KNeighborsClassifier(n_neighbors =24).fit(X_train,y_train)
y_predict = clf.predict(X_test)
print('模型得分为:{:.2f}'.format(clf.score(X_test,y_test)))
from sklearn.metrics import classification_report
print (classification_report(y_test, y_predict))
优点:
- 简单,易于理解,易于实现,无需估计参数,无需训练
- 适合对稀有事件进行分类
- 特别适合于多分类问题(multi-modal,对象具有多个类别标签), kNN比SVM的表现要好缺点:
缺点:
- 当样本不平衡时,如一个类的样本容量很大,而其他类样本容量很小时,导致输入一个新样本时,该样本的K个邻居中大容量类的样本占多数。 该算法只计算“最近的”邻居样本,某一类的样本数量很大,那么或者这类样本并不接近目标样本,或者这类样本很靠近目标样本。无论怎样,数量并不能影响运行结果
- 计算量较大 占内存
- 可理解性差,无法给出像决策树那样的规则