python-收入预测04-K近邻模型与调优

论坛 期权论坛 期权     
数据分析与模型   2019-7-28 23:17   4015   0
经过前几个小节,数据集已经整理成符合建模的形式,即没有缺失值,变量的值都转换成模型可识别的数值形式,如下,


下面使用K近邻算法进行建模,主要分为以下几步,
导入sklearn中子模块neighbors ,K近邻算法的类KNeighborsClassifier,语法,from sklearn.neighbors import KNeighborsClassifier
将这个类实例化为一个对象kn,语法,kn = KNeighborsClassifier()
调用对象kn的fit方法,该方法分别传入X变量集,Y变量,让K近邻算法去学习该数据集的特征,并生成模型,语法,kn.fit(X_train, y_train)
调用fit方法之后,对象kn内部已经生成了模型,此时,需要对测试集进行预测,将预测得到的Y,与测试集真实的Y进行对比,对这个模型的准确度进行评测。对于二分类的预测,一般使用ROC、AUC评估准确性。
为了得到测试集的预测Y,需要调用对象kn的predict方法,语法,kn_pred = kn.predict(X_test),kn_pred就是我们测试集的预测Y。
下面需要计算ROC、AUC,此时需要导入sklearn中,模型评估的子模块metrics,使用metrics的roc_curve方法,计算ROC的x轴,y轴,使用auc方法计算AUC指标,AUC越大模型预测的越准。
以上kn对象使用了K近邻模型的默认参数,不同的参数k值,会得到不同的模型,实际可以设置不同的距离参数k,以获得更好的拟合效果。此时可以运行网格搜索方法,即放入不同的k值,计算哪个模型效果最优。
通过调用sklearn中子模块model_selection ,网格搜索的类GridSearchCV,实现网格搜索。实际应用中,网格搜索得到的参数,模型效果会优于默认参数。
下面是实现以上步骤的过程,
  1. #!/usr/bin/env python
复制代码
  1. # coding: utf-8
复制代码
  1. [/code][code]# ## 导包
复制代码
  1. # 基础包
复制代码
  1. import pandas as pd
复制代码
  1. import numpy as np
复制代码
  1. # 画图
复制代码
  1. import seaborn as sns
复制代码
  1. #设置精度
复制代码
  1. pd.set_option('precision', 2)
复制代码
  1. #为了直观的显示数字,不采用科学计数法
复制代码
  1. pd.set_option('display.float_format', lambda x: '%.5f' % x)
复制代码
  1. # plt画图
复制代码
  1. import matplotlib.pyplot as plt
复制代码
  1. #显示中文
复制代码
  1. plt.rcParams['font.family'] = ['sans-serif']
复制代码
  1. plt.rcParams['font.sans-serif'] = ['SimHei']
复制代码
  1. # 用来正常显示负号
复制代码
  1. plt.rcParams['axes.unicode_minus']=False  
复制代码
  1. #显示画布,也可以不写
复制代码
  1. get_ipython().run_line_magic('matplotlib', 'inline')
复制代码
  1. # 拆分数据集
复制代码
  1. from sklearn.model_selection import train_test_split
复制代码
  1. # 导入k近邻模型的类
复制代码
  1. from sklearn.neighbors import KNeighborsClassifier
复制代码
  1. # 导入模型评估模块
复制代码
  1. from sklearn import metrics
复制代码
  1. #网格搜索
复制代码
  1. from sklearn.model_selection import GridSearchCV
复制代码
  1. [/code][code]# ### K近邻模型
复制代码
  1. [/code][code]# 构建k近邻模型
复制代码
  1. kn = KNeighborsClassifier()
复制代码
  1. kn.fit(X_train, y_train)
复制代码
  1. print(kn)
复制代码
  1. [/code][code]# 预测测试集
复制代码
  1. kn_pred = kn.predict(X_test)
复制代码
  1. print(pd.crosstab(kn_pred, y_test))
复制代码
  1. [/code][code]# 模型得分
复制代码
  1. print('模型在训练集上的准确率%f' %kn.score(X_train,y_train))
复制代码
  1. print('模型在测试集上的准确率%f' %kn.score(X_test,y_test))
复制代码
  1. [/code][code]
复制代码
  1. # 计算ROC曲线的x轴和y轴数据
复制代码
  1. fpr, tpr, _ = metrics.roc_curve(y_test,  kn.predict_proba(X_test)[:,1])
复制代码
  1. # 绘制ROC曲线
复制代码
  1. plt.plot(fpr, tpr, linestyle = 'solid', color = 'red')
复制代码
  1. # 添加阴影
复制代码
  1. plt.stackplot(fpr, tpr, color = 'steelblue')
复制代码
  1. # 绘制参考线
复制代码
  1. plt.plot([0,1],[0,1], linestyle = 'dashed', color = 'black')
复制代码
  1. # 往图中添加文本
复制代码
  1. plt.text(0.6,0.4,'AUC=%.3f' % metrics.auc(fpr,tpr), fontdict = dict(size = 18))
复制代码
  1. plt.show()
复制代码
  1. [/code][code]
复制代码
  1. # #### K近邻模型调优
复制代码
  1. [/code][code]
复制代码
  1. # K近邻模型的网格搜索法
复制代码
  1. # 选择不同的参数
复制代码
  1. k_options = list(range(1,12))
复制代码
  1. parameters = {'n_neighbors':k_options}
复制代码
  1. # 搜索不同的K值
复制代码
  1. grid_kn = GridSearchCV(estimator = KNeighborsClassifier(), param_grid = parameters, cv=10, scoring='accuracy', verbose=0, n_jobs=2)
复制代码
  1. grid_kn.fit(X_train, y_train)
复制代码
  1. [/code][code]
复制代码
  1. #网格搜索的结果
复制代码
  1. print('最佳参数:',grid_kn.best_params_)
复制代码
  1. print('最佳结果:',grid_kn.best_score_)
复制代码
  1. print('最佳估计器:',grid_kn.best_estimator_)
复制代码
  1. print('交叉验证结果:',grid_kn.cv_results_)
复制代码
  1. [/code][code]# 预测测试集
复制代码
  1. grid_kn_pred = grid_kn.predict(X_test)
复制代码
  1. print(pd.crosstab(grid_kn_pred, y_test))
复制代码
  1. [/code][code]# 模型得分
复制代码
  1. print('模型在训练集上的准确率%f' %grid_kn.score(X_train,y_train))
复制代码
  1. print('模型在测试集上的准确率%f' %grid_kn.score(X_test,y_test))
复制代码
  1. [/code][code]# 绘制ROC曲线
复制代码
  1. fpr, tpr, _ = metrics.roc_curve(y_test, grid_kn.predict_proba(X_test)[:,1])
复制代码
  1. plt.plot(fpr, tpr, linestyle = 'solid', color = 'red')
复制代码
  1. plt.stackplot(fpr, tpr, color = 'steelblue')
复制代码
  1. plt.plot([0,1],[0,1], linestyle = 'dashed', color = 'black')
复制代码
  1. plt.text(0.6,0.4,'AUC=%.3f' % metrics.auc(fpr,tpr), fontdict = dict(size = 18))
复制代码
  1. plt.show()
复制代码
[code][/code]下面是在jupyter中的运行结果,













本文来自对'《从零开始学Python数据分析与挖掘》-刘顺祥-清华大学出版社'的学习。
最近在学习中,再次意识到,'面向对象'是python语言的灵魂,想不明白的时候,需要默念此四字真言。
以上部分内容纯个人理解,有错误的地方,欢迎指正,为防止误导,建议阅读原著。



分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:10
帖子:2
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP