机器学习--逻辑回归及乳腺癌预测
逻辑回归算法是用来解决分类问题的算法。
逻辑回归模型用于解决二元分类问题的核心概念参考: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机器学习》
