前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >机器学习之鸢尾花-K近邻算法

机器学习之鸢尾花-K近邻算法

作者头像
python与大数据分析
发布2022-03-11 15:00:53
4830
发布2022-03-11 15:00:53
举报
文章被收录于专栏:python与大数据分析

K最近邻(k-Nearest Neighbor,KNN)分类算法,是一个理论上比较成熟的方法,也是最简单的机器学习算法之一。

该方法的思路是:在特征空间中,如果一个样本附近的k个最近(即特征空间中最邻近)样本的大多数属于某一个类别,则该样本也属于这个类别。

K 值的选择,距离度量和分类决策规则是该算法的三个基本要素。

K近邻算法不足之处在于样本不平衡,且计算量较大。

本文只是简单尝试了一下最优参数求解和可视化边界,就效果而言,比逻辑回归略差一些。

如下:

代码语言:javascript
复制
#  K最近邻(k-Nearest Neighbor,KNN)分类算法,是一个理论上比较成熟的方法,也是最简单的机器学习算法之一。
# 该方法的思路是:在特征空间中,如果一个样本附近的k个最近(即特征空间中最邻近)样本的大多数属于某一个类别,则该样本也属于这个类别。
# 我们常说,物以类聚,人以群分,判别一个人是一个什么样品质特征的人,常常可以从他/她身边的朋友入手,所谓观其友,而识其人。我们不是要判别上图中那个绿色的圆是属于哪一类数据么,好说,从它的邻居下手。但一次性看多少个邻居呢?从上图中,你还能看到:
# 如果K=3,绿色圆点的最近的3个邻居是2个红色小三角形和1个蓝色小正方形,少数从属于多数,基于统计的方法,判定绿色的这个待分类点属于红色的三角形一类。
# 如果K=5,绿色圆点的最近的5个邻居是2个红色三角形和3个蓝色的正方形,还是少数从属于多数,基于统计的方法,判定绿色的这个待分类点属于蓝色的正方形一类。
# K 值的选择,距离度量和分类决策规则是该算法的三个基本要素:
#   K 值的选择会对算法的结果产生重大影响。K值较小意味着只有与输入实例较近的训练实例才会对预测结果起作用,但容易发生过拟合;如果 K 值较大,优点是可以减少学习的估计误差,但缺点是学习的近似误差增大,这时与输入实例较远的训练实例也会对预测起作用,使预测发生错误。在实际应用中,K 值一般选择一个较小的数值,通常采用交叉验证的方法来选择最优的 K 值。随着训练实例数目趋向于无穷和 K=1 时,误差率不会超过贝叶斯误差率的2倍,如果K也趋向于无穷,则误差率趋向于贝叶斯误差率。
#   该算法中的分类决策规则往往是多数表决,即由输入实例的 K 个最临近的训练实例中的多数类决定输入实例的类别
#   距离度量一般采用 Lp 距离,当p=2时,即为欧氏距离,在度量之前,应该将每个属性的值规范化,这样有助于防止具有较大初始值域的属性比具有较小初始值域的属性的权重过大。
# K近邻算法不足之处
# 1、当样本不平衡时,如一个类的样本容量很大,而其他类样本容量很小时,有可能导致当输入一个新样本时,该样本的K个邻居中大容量类的样本占多数。 
#   该算法只计算“最近的”邻居样本,某一类的样本数量很大,那么或者这类样本并不接近目标样本,或者这类样本很靠近目标样本。
#   无论怎样,数量并不能影响运行结果。可以采用权值的方法(和该样本距离小的邻居权值大)来改进。
# 2、该方法的另一个不足之处是计算量较大,因为对每一个待分类的文本都要计算它到全体已知样本的距离,才能求得它的K个最近邻点。
#   目前常用的解决方法是事先对已知样本点进行剪辑,事先去除对分类作用不大的样本。
#   该算法比较适用于样本容量比较大的类域的自动分类,而那些样本容量较小的类域采用这种算法比较容易产生误分。
from sklearn.neighbors import KNeighborsClassifier
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import classification_report
def test_KNeighborsClassifier(X_train, X_test, y_train, y_test,X,y):
    # 训练数据和测试数据进行标准化
    # sc = StandardScaler()
    # X_train = sc.fit_transform(X_train)
    # X_test = sc.transform(X_test)
    scores_train=[]
    scores_test=[]
    n_neighbors=[1,3,5,7,9,11,13,15]
    # 建立一个k近邻模型对象
    for n_neighbor in n_neighbors:
        knn = KNeighborsClassifier(n_neighbors=n_neighbor)
        # 输入训练数据进行学习建模
        knn.fit(X_train, y_train)
        # 对测试数据进行预测
        scores_train.append(accuracy_score(knn.predict(X_train), y_train))
        scores_test.append(accuracy_score(knn.predict(X_test), y_test))
    print(scores_train)
    print(scores_test)
    fig=plt.figure(figsize=(10, 6))
    ax=fig.add_subplot()
    ax.plot(n_neighbors, scores_train, label='scores train')
    ax.plot(n_neighbors, scores_test, label='scores test')
    ax.set_xlabel(r"n_neighbors")
    ax.set_ylabel(r"score")
    ax.set_title("KNeighborsClassifier")
    ax.legend()
    plt.show()
代码语言:javascript
复制
    # 求最优参数
    tuned_parameters=[{'n_neighbors':[1,3,5,7,9,11,13,15],
                       'weights':['uniform','distance'],
                       'algorithm':['auto','ball_tree','kd_tree','brute'],
                       'leaf_size':[10,20,30,40,50]}]
    knn = KNeighborsClassifier()
    model = GridSearchCV(knn,param_grid=tuned_parameters, n_jobs=-1, verbose=2, scoring='accuracy')
    model.fit(X_train, y_train)
    print('网格搜索-度量记录:', model.cv_results_)  # 包含每次训练的相关信息
    print('网格搜索-最佳度量值:',model.best_score_)  # 获取最佳度量值
    # 网格搜索-最佳度量值: 0.9555555555555555
    print('网格搜索-最佳参数:', model.best_params_)  # 获取最佳度量值时的代定参数的值。是一个字典
    # 网格搜索-最佳参数: {'algorithm': 'auto', 'leaf_size': 10, 'n_neighbors': 3, 'weights': 'uniform'}
    print('网格搜索-最佳模型:', model.best_estimator_)  # 获取最佳度量时的分类器模型
    # 网格搜索-最佳模型:KNeighborsClassifier(algorithm='auto', leaf_size=10, metric='minkowski',metric_params=None, n_jobs=None, n_neighbors=3, p=2,weights='uniform')
    # 得分网格报告
    # print(model.cv_results_)
    model = KNeighborsClassifier(algorithm='auto', leaf_size=10, metric='minkowski',metric_params=None, n_jobs=None, n_neighbors=3, p=2,weights='uniform')
    # 把数据交给模型训练
    model.fit(X_train, y_train)
    print("Residual sum of squares:%.4f" % np.mean((model.predict(X_test) - y_test) ** 2))
    print('Score: %.4f' % model.score(X_test, y_test))
    # Residual  sum of squares: 0.0571
    # Score: 0.9429

    # 定义背景色和字体色
    cmap_light = ListedColormap(['#AAAAFF', '#AAFFAA', '#FFAAAA'])  # 给不同区域赋以颜色
    cmap_bold = ListedColormap(['#FF0000', '#003300', '#0000FF'])  # 给不同属性的点赋以颜色
    # knn边界图
    X = X[:, :2]
    #逻辑回归模型
    knn = KNeighborsClassifier(algorithm='auto', leaf_size=10, metric='minkowski',metric_params=None, n_jobs=None, n_neighbors=3, p=2,weights='uniform')
    knn.fit(X,y)
    # meshgrid函数生成两个网格矩阵
    # 获取的鸢尾花两列数据,对应为花萼长度和花萼宽度,每个点的坐标就是(x, y)。
    # 先取X二维数组的第一列(长度)的最小值、最大值和步长h(设置为0.02)生成数组,
    # 再取X二维数组的第二列(宽度)的最小值、最大值和步长h生成数组,
    # 最后用meshgrid函数生成两个网格矩阵xx和yy,
    h = .02
    # 确认训练集的边界
    x_min, x_max = X[:, 0].min() - .5, X[:, 0].max() + .5
    y_min, y_max = X[:, 1].min() - .5, X[:, 1].max() + .5
    # 生成随机数据来做测试集,然后作预测
    xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
    Z = knn.predict(np.c_[xx.ravel(), yy.ravel()])
    Z = Z.reshape(xx.shape)
    # 画出测试集数据
    plt.figure(1, figsize=(8, 6))
    plt.pcolormesh(xx, yy, Z, cmap=cmap_light)
    # 画出所有的训练集数据
    plt.scatter(X[:,0],X[:,1],c=y,cmap=cmap_bold)
    plt.xlabel('Sepal length')
    plt.ylabel('Sepal width')
    plt.xlim(xx.min(), xx.max())
    plt.ylim(yy.min(), yy.max())
    plt.xticks(())
    plt.yticks(())
    plt.legend(loc=2)
    plt.title("KNeighborsClassifier")
    plt.show()
代码语言:javascript
复制
if __name__=='__main__':
    X_train,X_test,y_train,y_test,X,y=load_data(iris)
    # -----------------------逻辑回归----------------------------
    # ---------------------K近邻算法-----------------------
    test_KNeighborsClassifier(X_train, X_test, y_train, y_test, X, y)

# ---------------------K近邻算法-----------------------

# ------------------高斯朴素贝叶斯-----------------------

# ---------------------决策树-----------------------

# ---------------------K Means聚类-----------------------

# ------------------高斯混合模型聚类-----------------------

# -------------------SVM支撑向量机-----------------------
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-04-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 python与大数据分析 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档