Advertisement

机器学习--逻辑回归及乳腺癌预测

阅读量:

逻辑回归算法是用来解决分类问题的算法。

逻辑回归模型用于解决二元分类问题的核心概念参考:http://blog.kamidox.com/logistic-regression.html]

逻辑回归模型由sklearn.linear_model.LogisticRegression实现

实例:乳腺癌预测

a. 模型训练

复制代码
 # 加载自带乳腺癌数据集

    
 from sklearn.datasets import load_breast_cancer
    
  
    
 cancer=load_breast_cancer()
    
 X=cancer.data
    
 y=cancer.target
    
 print('data.shape:{0};no. positive:{1};no. negative:{2}'.format(X.shape,y[y==1].shape[0],y[y==0].shape[0]))
    
 print(cancer.data[0])
复制代码
复制代码
 from sklearn.model_selection import train_test_split

    
 X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2)
    
  
    
 from sklearn.linear_model import LogisticRegression
    
 model = LogisticRegression()
    
 model.fit(X_train,y_train)
    
  
    
 train_score = model.score(X_train,y_train)
    
 test_score = model.score(X_test,y_test)
    
 print('train score:{train_score: .6f}; test score:{test_score:.6f}'.format(train_score=train_score,test_score=test_score))
    
  
    
 # 查看预测样本中有几个正确
    
 y_pred = model.predict(X_test)
    
 # sum()只返回True的个数
    
 print('matchs:{0}/{1}'.format(np.equal(y_pred,y_test).sum(),y_test.shape[0]))
复制代码
复制代码

可以看到,在114个测试集样本中,预测成功的有105个。

该模型用于解决二分类问题,在给定输入样本时会计算出两个概率值(分别对应类别0和类别1的概率),通过比较这两个概率值的大小来判断属于哪一类。

进而可以通过从测试数据集中筛选出模型预测结果置信度低于90%的样本来实现同时满足阳性结果置信度及阴性结果置信度均超过10%的目标

model.predict_proba()计算概率

复制代码
 # 找出预测概率低于90%的样本

    
 y_pred_proba = model.predict_proba(X_test)   #每个测试样本的测试概率
    
 print('sample of predict probability:{0}'.format(y_pred_proba[0]))  #打印第一个样本数据
    
  
    
 # 找出第一列,即预测为阴性的概率大于0.1的样本
    
 result = y_pred_proba[y_pred_proba[:,0]>0.1]
    
  
    
 # 在result里找出第二列,即预测为阳性概率大于0.1的样本
    
 result_1 = result[result[:,1]>0.1]
    
 print(result_1)
复制代码

可以看到有些样本的预测概率较低:[0.61655269 0.38344731],预测为阴性的概率为61%。

b. 模型优化

Logistic Regression模型具有92%的准确率,在一定程度上能够较好地预测结果。为了提高模型性能,在优化过程中可以考虑引入高阶多项式特征项作为辅助变量。

复制代码
 from sklearn.preprocessing import PolynomialFeatures

    
 from sklearn.linear_model import LogisticRegression
    
 from sklearn.pipeline import Pipeline
    
  
    
 def polynomial_model(degree=1,**kwarg):
    
     polynomial_features = PolynomialFeatures(degree=degree, include_bias=False)
    
     logistic_regression = LogisticRegression(**kwarg)
    
     pipeline = Pipeline([('polynomial_features',polynomial_features),('logistic_regression',logistic_regression)])
    
     return pipeline
    
  
    
 # 二阶多项式
    
 import time
    
 # 使用L1范数为正则项,实现参数稀疏化
    
 model = polynomial_model(degree=2,penalty='l1')
    
  
    
 start = time.clock()
    
 model.fit(X_train,y_train)
    
  
    
 train_score = model.score(X_train,y_train)
    
 test_score = model.score(X_test,y_test)
    
  
    
 print('elaspe:{0:.6f}; train score:{1:.6f}; test score:{2:.6f}'.format(time.clock()-start,train_score,test_score))
复制代码

确定该二阶多项式logistic回归模型中各特征的数量,并同时确定其非零系数的数量

model.named_steps['']提取pipeline中的模型

model.coef_模型系数

复制代码
 logistic_regression = model.named_steps['logistic_regression']

    
 print('model parameters shape:{0};count of non-zero element:{1}'.format(logistic_regression.coef_.shape,np.count_nonzero(logistic_regression.coef_)))
复制代码

原始模型具有30个特征,在转换为二阶多项式后增加了495个特征项。其中非零系数数量达到86个,并且仅有少量特征得以保留。

c. 学习曲线

绘制学习曲线图,并对一阶和二阶多项式模型分别采用L1和L2范数作为正则项进行比较分析, 最终分析并确定最优模型.

复制代码
 # L1范数的一阶和二阶多项式

    
 cv = ShuffleSplit(n_splits=10,test_size=0.2,random_state=0)
    
 title = 'Learning Curve(degree ={0},penalty={1})'
    
 degrees=[1,2]
    
 penalty='l1'
    
  
    
 start=time.clock()
    
 plt.figure(figsize=(12,4),dpi=144)
    
 for i in range(len(degrees)):
    
     plt.subplot(1,2,i+1)
    
     plot_learning_curve(polynomial_model(degree=degrees[i],penalty=penalty),title.format(degrees[i],penalty),X,y,ylim=(0.8,1.01),cv=cv)
    
 print('elaspe:{0:.6f}'.format(time.clock()-start))
    
  
    
 # L2范数的一阶和二阶多项式
    
 penalty='l2'
    
  
    
 start=time.clock()
    
 plt.figure(figsize=(12,4),dpi=144)
    
 for i in range(len(degrees)):
    
     plt.subplot(1,2,i+1)
    
     plot_learning_curve(polynomial_model(degree=degrees[i],penalty=penalty),title.format(degrees[i],penalty),X,y,ylim=(0.8,1.01),cv=cv)
    
 print('elaspe:{0:.6f}'.format(time.clock()-start))

可以看到,使用2阶多项式,L1范数训练集和测试集的准确度最高。

复制代码

L1范数的学习曲线耗时较长, 因为scikit-learn的learning_curve()函数在绘制学习曲线上需对模型执行多次训练, 并计算交叉验证样本评分. 此外, 在确保结果更加平滑的基础上, 对于每个数据点而言, 在生成结果的过程中会反复计算并取其平均值. 这正是ShuffleSplit机制所起的作用.

本研究仅获得569个样本数量的数据集作为基础,在实际应用中若需要扩大数据规模,则可采用分阶段训练策略:首先从较小规模的数据集中选取一定比例的样本用于绘制学习曲线;待优化模型参数确定后,则基于完整数据集进行最终模型训练。

参考:

黄永昌《scikit-learn机器学习》

全部评论 (0)

还没有任何评论哟~