数据集简介
该数据集最初来自国家糖尿病/消化/肾脏疾病研究所。数据集的目标是基于数据集中包含的某些诊断测量来诊断性的预测 患者是否患有糖尿病。
从较大的数据库中选择这些实例有几个约束条件。尤其是,这里的所有患者都是Pima印第安至少21岁的女性。
数据集由多个医学预测变量和一个目标变量组成Outcome。预测变量包括患者的怀孕次数、BMI、胰岛素水平、年龄等。
1 、加载库
import sysreload(sys)sys.setdefaultencoding('utf-8')import pandas as pd # 数据科学计算工具import numpy as np # 数值计算工具import matplotlib.pyplot as plt # 可视化import seaborn as sns # matplotlib的高级API%matplotlib inline # 在Notebook里面作图/嵌图%config InlineBackend.figure_format = 'retina'import warningswarnings.filterwarnings('ignore')
2 、加载数据并作图查看属性分布特征
【1】Pregnancies:怀孕次数
【2】Glucose:葡萄糖
【3】BloodPressure:血压 (mm Hg)
【4】SkinThickness:皮层厚度 (mm)
【5】Insulin:胰岛素 2小时血清胰岛素(mu U / ml
【6】BMI:体重指数 (体重/身高)^2
【7】DiabetesPedigreeFunction:糖尿病谱系功能
【8】Age:年龄 (岁)
【9】Outcome:类标变量 (0或1)
pima = pd.read_csv("pima_indians-diabetes.csv")pima.head()
# panda.head()/panda.tail() 查看Series或者DataFrame对象的小样本;显示的默认元素数量的前五个,当然我们可以传递一个自定义数字
pima.shape # panda的shape形状属性,给出对象的尺寸(行数目,列数目)pima.describe()# panda的describe描述属性,展示了每一个字段的#【count条目统计,mean平均值,std标准值,min最小值,25%,50%中位数,75%,max最大值】
Data Visualization - 数据可视化
1.柱状图
pima.hist(figsize=(16,14)) #查看每个字段的数据分布;figsize的参数显示的是每个子图的长和宽
2.散点图
sns.pairplot(pima, hue = "Outcome")
# seaborn常用命令
【1】set_style()是用来设置主题的,Seaborn有5个预设好的主题:darkgrid、whitegrid、dark、white、ticks,默认为darkgrid【2】set()通过设置参数可以用来设置背景,调色板等,更加常用【3】displot()为hist加强版【4】kdeplot()为密度曲线图【5】boxplot()为箱图【6】joinplot()联合分布图【7】heatmap()热点图【8】pairplot()多变量图,可以支持各种类型的变量分析,是特征分析很好用的工具
3.箱图
pima.plot(kind='box', subplots=True, layout=(3,3), sharex=False,sharey=False, figsize=(16,14))
#pandas.plot作图:数据分为Series 和 DataFrame两种类型;现释义数据为DataFrame的参数
【0】data:DataFrame【1】x:label or position,default None 指数据框列的标签或位置参数【2】y:label or position,default None 指数据框列的标签或位置参数【3】kind:str(line折线图、bar条形图、barh横向条形图、hist柱状图、box箱线图、kde Kernel的密度估计图,主要对柱状图添加Kernel概率密度线、density same as “kde”、area区域图、pie饼图、scatter散点图、hexbin)【4】subplots:boolean,default False,为每一列单独画一个子图【5】sharex:boolean,default True if ax is None else False【6】sharey:boolean,default False【7】loglog:boolean,default False,x轴/y轴同时使用log刻度
4.热度图
column_x = pima.columns[0:len(pima.columns) - 1] # 选择特征列,去掉目标列column_x # 显示所有特征列信息corr = pima[pima.columns].corr() # 计算变量的相关系数,得到一个N * N的矩阵plt.subplots(figsize=(14,12)) # 可以先试用plt设置画布的大小,然后在作图,修改sns.heatmap(corr, annot = True) # 使用热度图可视化这个相关系数矩阵
3、数据预处理——特征工程
3.1、特征选择
# 导入和特征选择相关的包
from sklearn.feature_selection import SelectKBestfrom sklearn.feature_selection import chi2X = pima.iloc[:, 0:8] # 特征列 0-7列,不含第8列Y = pima.iloc[:, 8] # 目标列为第8列select_top_4 = SelectKBest(score_func=chi2, k =4) # 通过卡方检验选择4个得分最高的特征fits = select_top_4.fit(X, Y) #将特征输入到评分函数,获取特征信息和目标值信息features = fits.transform(X) #展现特征转换后的结果features[0:5] #新特征列'''评分函数1.SelectKBest()#只保留K个最高分的特征,能够返回特征评价的得分 SelectKBest(score_func=<function f_classif>, k=10)2.SelectPercentile() #只保留用户指定百分比的最高得分的特征,能够返回特征评价的得分 SelectPercentile(score_func=<function f_classif>, percentile=10) 使用常见的单变量统计检验:假正率SelectFpr,错误发现率SelectFdr,或者总体错误率SelectFwe3.GenericUnivariateSelect() #通过结构化策略进行特征选择,通过超参数搜索估计器进行特征选择'''将特征输入到评分函数,返回一个单变量的f_score(F检验的值)或p-values(P值,假设检验中的一个标准,P-value用来和显著性水平作比较),注意SelectKBest 和 SelectPercentile只有得分,没有p-value。其中的参数score_func有以下选项:【1】回归:f_regression:相关系数,计算每个变量与目标变量的相关系数,然后计算出F值和P值mutual_info_regression:互信息,互信息度量X和Y共享的信息:它度量知道这两个变量其中一个,对另一个不确定度减少的程度。【2】分类:chi2:卡方检验f_classif:方差分析,计算方差分析(ANOVA)的F值(组间均方/组内均方);mutual_info_classif:互信息,互信息方法可以捕捉任何一种统计依赖,但是作为非参数法, 需要更多的样本进行准确的估计。
结果:
pima.head()
# 因此,表现最佳的特征是:Glucose-葡萄糖、Insulin-胰岛素、BMI指数、Age-年龄
构造新特征DataFrame
X_features = pd.DataFrame(data = features, columns=["Glucose","Insulin","BMI","Age"]) # 构造新特征DataFrameX_features.head()Y_features = pd.DataFrame(data = y, columns=["Outcome"]) # 构造新特征DataFrameY_features.head()
3.2、 Standardization - 标准化
它将属性值更改为 均值为0,标准差为1 的 高斯分布.当算法期望输入特征处于高斯分布时,它非常有用
from sklearn.preprocessing import StandardScalerrescaledX = StandardScaler().fit_transform(X_features)#通过sklearn的preprocessing数据预处理中StandardScaler特征缩放 标准化特征信息X = pd.DataFrame(data = rescaledX, columns = X_features.columns)# 构建新特征DataFrameX.head()
3.3、将数据集切分——训练集和测试集
from sklearn.model_selection import train_test_splitseed = 7 #重现随机生成的训练test_size = 0.33 #33%测试,67%训练X_train, X_test, Y_train, Y_test = train_test_split(X, Y_features, test_size=test_size, random_state=seed)
4、构建二分类算法模型
from sklearn.model_selection import KFoldfrom sklearn.model_selection import cross_val_scorefrom sklearn.linear_model import LogisticRegressionfrom sklearn.naive_bayes import GaussianNBfrom sklearn.neighbors import KNeighborsClassifierfrom sklearn.tree import DecisionTreeClassifierfrom sklearn.svm import SVCfrom xgboost import XGBClassifier
models = []models.append(("LR", LogisticRegression())) #逻辑回归models.append(("NB", GaussianNB())) # 高斯朴素贝叶斯models.append(("KNN", KNeighborsClassifier())) #K近邻分类models.append(("DT", DecisionTreeClassifier())) #决策树分类models.append(("SVM", SVC())) # 支持向量机分类models.append(("xgboost", XGBClassifier())) #支持向量机分类
cross_val_score()函数
sklearn.cross_validation.cross_val_score(estimator, X, y=None, scoring=None, cv=None, n_jobs=1, verbose=0, fit_params=None, pre_dispatch=‘2*n_jobs’)
参数
estimator:数据对象
X:数据
y:预测数据
soring:调用的方法
cv:交叉验证生成器或可迭代的次数
n_jobs:同时工作的cpu个数(-1代表全部)
verbose:详细程度
fit_params:传递给估计器的拟合方法的参数
pre_dispatch:控制并行执行期间调度的作业数量。
KFold——K折交叉验证:
这是将数据集分成K份的官方给定方案,所谓K折就是将数据集通过K次分割,使得所有数据既在训练集出现过,又在测试集出现过,当然,每次分割中不会有重叠。相当于无放回抽样。
StratifiedKFold用法类似Kfold,但是他是分层采样,确保训练集,测试集中各类别样本的比例与原始数据集中相同。
sklearn.model_selection.KFold(n_splits=3, shuffle=False, random_state=None)
思路:将训练/测试数据集划分n_splits个互斥子集,每次用其中一个子集当作验证集,剩下的n_splits-1个作为训练集,进行n_splits次训练和测试,得到n_splits个结果
注意点:对于不能均等份的数据集,其前n_samples % n_splits子集拥有n_samples // n_splits + 1个样本,其余子集都只有n_samples // n_splits样本
参数说明:
n_splits:表示划分几等份
shuffle:在每次划分时,是否进行洗牌
①若为Falses时,其效果等同于random_state等于整数,每次划分的结果相同
②若为True时,每次划分的结果都不一样,表示经过洗牌,随机取样的
random_state:随机种子数
属性:
①get_n_splits(X=None, y=None, groups=None):获取参数n_splits的值
②split(X, y=None, groups=None):将数据集划分成训练集和测试集,返回索引生成器
results = []names = []for name, model in models:kflod = KFold(n_splits=10, random_state=22)cv_result = cross_val_score(model, X_train,Y_train, cv = kflod,scoring="accuracy")names.append(name)results.append(cv_result)for i in range(len(names)):print(names[i], results[i].mean)
结果:
5、模型评估(参数选择)
1.SVM
from sklearn.svm import SVCfrom sklearn.metrics import classification_report, confusion_matrixclassifier = SVC(kernel = 'rbf')classifier.fit(X_train_pca, Y_train)
sklearn.svm.SVC(C=1.0,kernel='rbf',degree=3,gamma='auto',coef0=0.0,shrinking=True,probability=False,tol=0.001,cache_size=200,class_weight=None,verbose=False,max_iter=-1,decision_function_shape=None,random_state=None)
参数:
lC:C-SVC的惩罚参数C?默认值是1.0
C越大,相当于惩罚松弛变量,希望松弛变量接近0,即对误分类的惩罚增大,趋向于对训练集全分对的情况,这样对训练集测试时准确率很高,但泛化能力弱。C值小,对误分类的惩罚减小,允许容错,将他们当成噪声点,泛化能力较强。
kernel:核函数,默认是rbf,可以是‘linear’, ‘poly’, ‘rbf’, ‘sigmoid’, ‘precomputed’0 – 线性:u'v1 – 多项式:(gamma*u'*v + coef0)^degree2 – RBF函数:exp(-gamma|u-v|^2)3 –sigmoid:tanh(gamma*u'*v + coef0)degree:多项式poly函数的维度,默认是3,选择其他核函数时会被忽略。gamma:‘rbf’,‘poly’ 和‘sigmoid’的核函数参数。默认是’auto’,则会选择1/n_featurescoef0:核函数的常数项。对于‘poly’和 ‘sigmoid’有用。probability:是否采用概率估计?.默认为Falseshrinking:是否采用shrinking heuristic方法,默认为truetol:停止训练的误差值大小,默认为1e-3cache_size:核函数cache缓存大小,默认为200class_weight:类别的权重,字典形式传递。设置第几类的参数C为weight*C(C-SVC中的C)verbose:允许冗余输出?max_iter:最大迭代次数。-1为无限制。decision_function_shape:‘ovo’, ‘ovr’ or None, default=None3random_state:数据洗牌时的种子值,int值
主要调节的参数有:C、kernel、degree、gamma、coef0。
2.xgboost
xgb1 = XGBClassifier(learning_rate = 0.1,n_estimators = 1000,max_depth = 5,min_child_weight = 1,gamma = 0,subsample = 0.8,colsample_bytree = 0.8,objective = 'binary:logistic',nthread = 4,scale_pos_weight = 1,seed = 27)
model = XGBClassifier()learning_rate = [0.0001,0.001,0.01,0.1,0.2,0.3] #学习率gamma = [1, 0.1, 0.01, 0.001]param_grid = dict(learning_rate = learning_rate,gamma = gamma)#转化为字典格式,网络搜索要求kflod = StratifiedKFold(n_splits=10, shuffle = True,random_state=7)#将训练/测试数据集划分10个互斥子集,grid_search = GridSearchCV(model,param_grid,scoring = 'neg_log_loss',n_jobs = -1,cv = kflod)#scoring指定损失函数类型,n_jobs指定全部cpu跑,cv指定交叉验证grid_result = grid_search.fit(X_train, Y_train) #运行网格搜索print("Best: %f using %s" % (grid_result.best_score_,grid_search.best_params_))#best_params_:描述了已取得最佳结果的参数的组合#best_score_:成员提供优化过程期间观察到的最好的评分#具有键作为列标题和值作为列的dict,可以导入到DataFrame中。#注意,“params”键用于存储所有参数候选项的参数设置列表。means = grid_result.cv_results_['mean_test_score']params = grid_result.cv_results_['params']for mean,param in zip(means,params):print("%f with: %r" % (mean,param))
参数选择结果
5.1.详细评估
classification_report
y_pred = classifier.predict(X_test)cm = confusion_matrix(Y_test, y_pred)#混淆矩阵print(classification_report(Y_test, y_pred))#显示准确率
SVM结果:cm
结果说明:把0预测成0的有139个,把0预测成1的有23个,把1预测成0的有37个,把1预测成1的有55个。
confusion_matrix函数的使用
官方文档中给出的用法是
sklearn.metrics.confusion_matrix(y_true, y_pred, labels=None, sample_weight=None)
y_true: 是样本真实分类结果,y_pred: 是样本预测分类结果
labels:是所给出的类别,通过这个可对类别进行选择
sample_weight : 样本权重
实现例子:
from sklearn.metrics import confusion_matrixy_true=[2,1,0,1,2,0]y_pred=[2,0,0,1,2,1]C=confusion_matrix(y_true, y_pred)
运行结果:
这儿没有标注类别:下图是标注类别以后,更加好理解
sklearn.classification_report预测准确率
classification_report(Y_test, y_pred)结果如下:
其中列表左边的一列为分类的标签名,右边support列为每个标签的出现次数.avg / total行为各列的均值(support列为总和)
下面将一一给出‘precision’,‘recall’,‘f1’的具体含义:
准确率:
所有识别为”1”的数据中,正确的比率是多少。
如识别出来100个结果是“1”, 而只有90个结果正确,有10个实现是非“1”的数据。 所以准确率就为90%
召回率:
所有样本为1的数据中,最后真正识别出1的比率。
如100个样本”1”, 只识别出了93个是“1”, 其它7个是识别成了其它数据。 所以召回率是93%
F1-score:
是准确率与召回率的综合。 可以认为是平均效果。
F1值是精确度和召回率的调和平均值:2F1=1P+1R2F1=1P+1R F1=2P×RP+RF1=2P×RP+R
精确度和召回率都高时,F1F1值也会高.F1F1值在1时达到最佳值(完美的精确度和召回率),最差为0.在二元分类中,F1F1值是测试准确度的量度。
例子:当一个搜索引擎返回30个页面时,只有20页是相关的,而没有返回40个额外的相关页面,其精度为20/30 = 2/3,而其召回率为20/60 = 1/3。在这种情况下,精确度是“搜索结果有多大用处”,而召回是“结果如何完整”。
详细定义如下:
对于数据测试结果有下面4种情况:
TP: 预测为正, 实现为正
FP: 预测为正, 实现为负
FN: 预测为负,实现为正
TN: 预测为负, 实现为负
准确率: TP/ (TP+FP)召回率: TP(TP +FN)F1-score: 2*TP/(2*TP + FP + FN)
一般(粗)评估——accuracy_score
sklearn.metrics.accuracy_score(y_true, y_pred, normalize=True, sample_weight=None)
normalize:默认值为True,返回正确分类的比例;如果为False,返回正确分类的样本数
from sklearn.metrics import accuracy_scoreaccuracy = accuracy_score(Y_test, predictions)#显示准确率——分类0和1的totalprint("Accuracy: %.2f%%" % (accuracy * 100.0))
结果:
from sklearn.metrics import accuracy_scoreaccuracy = accuracy_score(Y_test, y_pred,normalize = False)#正确分类的样本数——分类0和1的total
结果
判断比较不同特征的重要程度:
#判断特征的重要程度from xgboost import plot_importancefrom matplotlib import pyplotplot_importance(model)pyplot.show()
结果:
5.2.使用 网格搜索 来提高模型——模型优化
from sklearn.model_selection import GridSearchCVparam_grid = {'C':[0.1, 1, 10, 100], 'gamma':[1, 0.1, 0.01, 0.001]}grid = GridSearchCV(SVC(),param_grid,refit=True,verbose = 2)grid.fit(X_train, Y_train)# 预测grid_predictions = grid.predict(X_test)# 分类报告print(classification_report(Y_test,grid_predictions))
优化结果:
GridSearchCV 相关参数
初始化了一个GridSearchCV对象,用于对支持向量机流水线的训练与调优。将GridSearchCV的param_grid参数以字典的方式定义为待调优参数。
(1)estimator
选择使用的分类器,并且传入除需要确定最佳的参数之外的其他参数。每一个分类器都需要一个scoring参数,或者score方法:estimator=RandomForestClassifier(min_samples_split=100,min_samples_leaf=20,max_depth=8,max_features='sqrt',random_state=10),
(2param_grid
需要最优化的参数的取值,值为字典或者列表,例如:param_grid =param_test1,param_test1 = {'n_estimators':range(10,71,10)}。
(3)scoring=None
模型评价标准,默认None,这时需要使用score函数;或者如scoring='roc_auc',根据所选模型不同,评价准则不同。字符串(函数名),或是可调用对象,需要其函数签名形如:scorer(estimator, X, y);如果是None,则使用estimator的误差估计函数。具体值的选取看本篇第三节内容。
(4)fit_params=None
(5)n_jobs=1
n_jobs:并行数,int:个数,-1:跟CPU核数一致, 1:默认值
进行预测的常用方法和属性
grid.fit():运行网格搜索
grid_scores_:给出不同参数情况下的评价结果
best_params_:描述了已取得最佳结果的参数的组合
best_score_:提供优化过程期间观察到的最好的评分
cv_results_: dict of numpy (masked) ndarrays
具有键作为列标题和值作为列的dict,可以导入到DataFrame中。注意,“params”键用于存储所有参数候选项的参数设置列表。
不同模型下的可视化结果
1.盒图:
ax = sns.boxplot(data = results)ax.set_xticklabels(names)
图片解释:
2.热力图
ax = sns.heatmap(data = results)ax.set_xticklabels(names)
3.散点图
ax = sns.stripplot(data = results)ax.set_xticklabels(names)
4.小提琴图:
中间的白点是中位数,黑色粗线对应分位数
ax = sns.violinplot(data = results)ax.set_xticklabels(names)
6、选择适宜的模型,使用测试数据预测
from sklearn.svm import SVCfrom sklearn.metrics import classification_report, confusion_matrixclassifier = SVC(kernel = 'rbf') #kernel:核函数,默认是rbf,将低维映射成高维model = classifier.fit(X_train, Y_train)y_pred = model.predict(X_test)#预测的值
结果如下:
Accuracy: 74.80%
机器学习(二)——xgboost(实战篇)Pima印第安人数据集上的机器学习-分类算法(根据诊断措施预测糖尿病的发病)
如果觉得《机器学习(二)——xgboost(实战篇)Pima印第安人数据集上的机器学习-分类算法(根据》对你有帮助,请点赞、收藏,并留下你的观点哦!