机器学习第二次上机(KNN)9.26

1. KNN简介

        KNN刚开始一直觉得名字很奇怪,后来知道它的英文全名为 K-Nearest Neighbor(k个最近的邻居),就豁然开朗。明白其核心为”近朱者赤,近墨者黑“,即由你的邻居来推断出你的类别

        KNN最邻近分类算法的实现原理:为了判断未知样本的类别,以所有已知类别的样本作为参照,计算未知样本与所有已知样本的距离,从中选取与未知样本距离最近的K个已知样本,根据少数服从多数的投票法则(majority-voting),将未知样本与K个最邻近样本中所属类别占比较多的归为一类。

2. 算法核心

   (1) 样本的所有特征都要做可比较的量化

           若是样本特征中存在非数值的类型,必须采取手段将其量化为数值。例如样本特征中包含颜色,可通过将颜色转换为灰度值来实现距离计算。

   (2) 样本特征要做归一化处理

           样本有多个参数,每一个参数都有自己的定义域和取值范围,他们对距离计算的影响不一样,如取值较大的影响力会盖过取值较小的参数。所以样本参数必须做一些 scale 处理,最简单的方式就是所有特征的数值都采取归一化处置。

   (3) 需要一个距离函数以计算两个样本之间的距离

           通常使用的距离函数有:欧氏距离、余弦距离、汉明距离、曼哈顿距离等,一般选欧氏距离作为距离度量,但是这是只适用于连续变量。在文本分类这种非连续变量情况下,汉明距离可以用来作为度量。通常情况下,如果运用一些特殊的算法来计算度量的话,K近邻分类精度可显著提高,如运用大边缘最近邻法或者近邻成分分析法。

    (4) 确定K的值

           K值选的太大易引起欠拟合,太小容易过拟合,需交叉验证确定K值。

KNN算法的优点:

           1.简单,易于理解,易于实现,无需估计参数,无需训练;

           2. 适合对稀有事件进行分类;

           3.特别适合于多分类问题(multi-modal,对象具有多个类别标签), kNN比SVM的表现要好。

KNN算法的缺点:

           KNN算法在分类时有个主要的不足是,当样本不平衡时,如一个类的样本容量很大,而其他类样本容量很小时,有可能导致当输入一个新样本时,该样本的K个邻居中大容量类的样本占多数,如下图所示。该算法只计算最近的邻居样本,某一类的样本数量很大,那么或者这类样本并不接近目标样本,或者这类样本很靠近目标样本。无论怎样,数量并不能影响运行结果。可以采用权值的方法(和该样本距离小的邻居权值大)来改进。

3. 案例演示

3.1 鸢尾花预测

3.1.1 步骤

(1)准备训练数据   

(2)切分数据集         

(3)数据归一化/标准化

(4)对数据集的训练和预测 

(5)验收结果

3.1.2 代码
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
def get_iris_data():
    iris = load_iris()
    iris_data = iris.data
    iris_target = iris.target
    return iris_data,iris_target
def run():
    iris_data, iris_target = get_iris_data()

    # 分割验证集和测试集
    x_train,x_test,y_train,y_test=train_test_split(iris_data,iris_target,test_size=0.25)

    # 归一化处理
    std=StandardScaler()
    x_train=std.fit_transform(x_train)
    x_test=std.transform(x_test)
    knn=KNeighborsClassifier(n_neighbors=5)#可不写默认值也为5
    knn.fit(x_train,y_train)
    y_predict=knn.predict(x_test)
    print(y_predict)
    labels = ["山鸢尾", "虹膜锦葵", "变色鸢尾"]
    for i in range(len(y_predict)):
        print("第%d次测试:真实值:%s\t预测值:%s" % ((i + 1), labels[y_predict[i]], labels[y_test[i]]))
    print("准确率:", knn.score(x_test, y_test))


if __name__ == '__main__':
    get_iris_data()
    run()
3.1.3 效果

3.1.4 报错以及解决方案

        一开始sklearn库下载时一直出问题(应该是pycharm导入问题),后面这个改用数据热点下载就好了,在这个时间还接触到了scikit-learn这个机器学习库,这里是gitee链接

3.2  KNN 处理简单分类任务

3.2.1 步骤

(1)数据准备:首先,需要将数据集分为训练集和测试集。这一步可以使用 Python 中的train_test_split函数进行操作。
(2)特征处理:对于输入的特征数据,可能需要进行一些预处理,比如缩放、编码等,以便于后续的计算。
(3)计算距离:对于每一个新的样本,需要计算其与训练集中所有样本之间的距离,通常使用欧氏距离或者余弦相似度等。
(4)选择邻居:选择距离新样本最近的 K 个邻居(不包括新样本本身),这 K 个邻居的类别就是新样本的预测结果。
(5)结果输出:将预测结果进行输出,可以是类别标签,也可以是概率等。

3.2.2 代码
# 导入画图工具
import matplotlib.pyplot as plt
# 导入数组工具
import numpy as np
# 导入数据集生成器
from sklearn.datasets import make_blobs
# 导入KNN 分类器
from sklearn.neighbors import KNeighborsClassifier
# 导入数据集拆分工具
from sklearn.model_selection import train_test_split

# 生成样本数为200,分类数为2的数据集

# 将生成的数据集进行可视化
data = make_blobs(n_samples=300, n_features=2, centers=4, cluster_std=1.0, random_state=8)
X, Y = data
# plt.scatter(X[:,0], X[:,1],s=80, c=Y,  cmap=plt.cm.spring, edgecolors='k')
# plt.show()


# knn计算利用sklearn库
clf = KNeighborsClassifier(n_neighbors=2)
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.Pastel1)
plt.scatter(X[:, 0], X[:, 1], s=80, c=Y, cmap=plt.cm.spring, edgecolors='k')
plt.xlim(xx.min(), xx.max())
plt.ylim(yy.min(), yy.max())
plt.title("Classifier:KNN")


plt.show()
3.2.3 效果
3.2.4 报错以及解决

        开始对make_blobs进行调参出现问题报错,后面查询其相关参数得知如何正确使用。

make_blobs(n_samples, n_features, centers,   n_clusters_per_class, cluster_std, random_state)

make_blobs 函数是scikit-learn 中用于生成多分类数据的一个便捷工具。以下是它的参数:
        n_samples:生成的样本数。
        n_features:生成的特征数。默认为 2。
        n_clusters_per_class:每个类别的簇数。默认为 1。
        random_state:随机数生成器的种子。用于确保每次运行时生成的数据集相同。
        centers:簇的中心。可以是一个列表或元组,列表或元组的长度应为         n_clusters_per_class。默认为 None,此时簇的中心是随机生成的。
        cluster_stds:簇的标准差。可以是一个列表或元组,列表或元组的长度应为         n_clusters_per_class。默认为 None,此时簇的标准差是随机生成的

4.小结

该算法概念较为简单,但是在大数据的情况下将占用大量存储空间,耗时久,无法给出任何数据的基础结构信息,因此无法知晓平均实例样本和典型实例样本具有什么特征。这次是我机器学习的第一个算法学习,还有待提升,谢谢!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值