前面一篇介绍了用tensorflow实现线性回归模型预测sklearn内置的波士顿房价,现在这一篇就记一下用逻辑回归分类sklearn提供的乳腺癌数据集,该数据集有569个样本,每个样本有30维,为二分类数据集,212个正样本,357个负样本。

首先,加载数据,并划分训练集和测试集:

# 加载乳腺癌数据集,该数据及596个样本,每个样本有30维,共有两类
cancer = skd.load_breast_cancer() # 将数据集的数据和标签分离
X_data = cancer.data
Y_data = cancer.target
x_train,x_test,y_train,y_test = train_test_split(X_data,Y_data,test_size=0.3,random_state=0)

这里还要注意一下,因为后面要用到的损失函数为交叉熵,而数据集的标签是一维的,所以我们需要将其转换为位数来表示类别,也就是[0,1]=>[[0,1],[1,0]]这种形式的标签:

y_train_new = np.zeros([y_train.shape[0], 2], dtype='int32')    
y_test_new = np.zeros([y_test.shape[0], 2], dtype='int32')
for i in range(y_train.shape[0]):
    if y_train[i] == 0:
        y_train_new[i,0] = 0
        y_train_new[i,1] = 1
    else:
        y_train_new[i,0] = 1
        y_train_new[i,1] = 0
for i in range(y_test.shape[0]):
    if y_test[i] == 0:
        y_test_new[i,0] = 0
        y_test_new[i,1] = 1
    else:
        y_test_new[i,0] = 1
        y_test_new[i,1] = 0

接着就是老套路,初始化训练参数,设置模型输入输出,然后是构建模型,二分类逻辑回归模型的数学表达式为:

用tensorflow实现代码如下:

pred = tf.nn.sigmoid(tf.matmul(X, W) + b) # sigmoid

然后是构建交叉熵表达式,其数学公式为:

用tensorflow实现代码如下:

cost = tf.reduce_mean(-tf.reduce_sum(Y*tf.log(pred), reduction_indices=1))

对于训练好的模型的测试性能的评价,这里我采用计算ROC曲线的方式来展现。首先是模型对于输入数据的预测会得到一个对应的1*2的输出,这个输出不一定是很好的[0 1]或者[1 0],而是一个类似于概率的量,也就是类似于这样[0.9527, 0.0473],所以我们需要判断,如果第一位小于第二位,依照前面的设定应该是0,反之为1,当然可能会有第一位等于第二位的情况,那就只能是存在误差了:

y_test_pred = sess.run(pred, feed_dict={X: x_test})
y_scores = np.empty((y_test_pred.shape[0]))
for i in range(y_scores.shape[0]):
    if y_test_pred[i,0]<y_test_pred[i,1]:
        y_scores[i]=0
    else:
        y_scores[i]=1

然后roc曲线和其AUC值这里调用的是sklearn提供的函数:

fpr, tpr, thresholds = roc_curve((y_test), y_scores)
AUC_ROC = roc_auc_score(y_test, y_scores)

然后是画出precision recall curve(精确率-召回率曲线),同样也是调用sklearn的函数:

precision, recall, thresholds = precision_recall_curve(y_test, y_scores)
precision = np.fliplr([precision])[0] #so the array is increasing (you won't get negative AUC)
recall = np.fliplr([recall])[0]  #so the array is increasing (you won't get negative AUC) AUC_prec_rec = np.trapz(precision,recall)

接着是计算置信度矩阵,得到矩阵后顺带的就可以计算准确率、灵敏性、特异性等几个参数了,同样的,还是调用sklearn的函数即可:

confusion = confusion_matrix(y_test, y_pred)

accuracy = float(confusion[0,0]+confusion[1,1])/float(np.sum(confusion))
specificity = float(confusion[0,0])/float(confusion[0,0]+confusion[0,1])
sensitivity = float(confusion[1,1])/float(confusion[1,1]+confusion[1,0])
precision = float(confusion[1,1])/float(confusion[1,1]+confusion[0,1])

同样的衡量指标还有Jaccard系数和F1分数:

jaccard_index = jaccard_similarity_score(y_test, y_pred, normalize=True)
F1_score = f1_score(y_test, y_pred, labels=None, average='binary', sample_weight=None)

这里涉及到了很多模型性能的评价指标,具体的含义就不细究了,下一次专门写一篇来总结吧。完整的代码如下:

from __future__ import print_function

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets as skd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import scale
from sklearn.metrics import roc_curve
from sklearn.metrics import roc_auc_score
from sklearn.metrics import confusion_matrix
from sklearn.metrics import precision_recall_curve
from sklearn.metrics import jaccard_similarity_score
from sklearn.metrics import f1_score # 加载乳腺癌数据集,该数据及596个样本,每个样本有30维,共有两类
cancer = skd.load_breast_cancer() # 将数据集的数据和标签分离
X_data = cancer.data
Y_data = cancer.target
print("X_data.shape = ", X_data.shape)
print("Y_data.shape = ", Y_data.shape) # 将数据和标签分成训练集和测试集
x_train,x_test,y_train,y_test = train_test_split(X_data,Y_data,test_size=0.3,random_state=0)
x_train = scale(x_train)
x_test = scale(x_test)
y_train_new = np.zeros([y_train.shape[0], 2], dtype='int32')
y_test_new = np.zeros([y_test.shape[0], 2], dtype='int32')
for i in range(y_train.shape[0]):
    if y_train[i] == 0:
        y_train_new[i,0] = 0
        y_train_new[i,1] = 1
    else:
        y_train_new[i,0] = 1
        y_train_new[i,1] = 0
for i in range(y_test.shape[0]):
    if y_test[i] == 0:
        y_test_new[i,0] = 0
        y_test_new[i,1] = 1
    else:
        y_test_new[i,0] = 1
        y_test_new[i,1] = 0
print("x_train.shape = ", x_train.shape)
print("x_test.shape = ", x_test.shape)
print("y_train.shape = ", y_train_new.shape)
print("y_test.shape = ", y_test_new.shape) # 初始化参数
learning_rate = 0.01
training_epochs = 50000
display_step = 50 # 定义图模型输入
X = tf.placeholder(tf.float32, [None, 30]) # mnist data image of shape 28*28=784
Y = tf.placeholder(tf.float32, [None, 2]) # 0-9 digits recognition => 10 classes# # 设置模型权重和偏置
W = tf.Variable(tf.random_normal([30, 2]),dtype=tf.float32, name="weight")
b = tf.Variable(tf.random_normal([2]),dtype=tf.float32, name="bias") # 构建模型
#pred = tf.nn.softmax(tf.matmul(x, W) + b) # Softmax
pred = tf.nn.sigmoid(tf.matmul(X, W) + b) # sigmoid # 使用交叉熵来最小化训练误差
cost = tf.reduce_mean(-tf.reduce_sum(Y*tf.log(pred), reduction_indices=1))
# 梯度下降法
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)# # 初始化器
init = tf.global_variables_initializer() # 开始训练
with tf.Session() as sess:#     #  初始化
    sess.run(init)#     # 迭代训练
    for epoch in range(training_epochs):
        avg_cost = 0.         sess.run(optimizer, feed_dict={X: x_train, Y: y_train_new})         # 显示训练信息
        if (epoch+1) % display_step == 0:
            c = sess.run(cost, feed_dict={X: x_train, Y:y_train_new})
            print("Epoch:", '%04d' % (epoch+1), "cost=", "{:.9f}".format(c))
    print("完成训练!")     # 测试模型
    correct_prediction = tf.equal(tf.argmax(pred, 1), tf.argmax(Y, 1))
    # 计算准确度
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
    print("Accuracy:", accuracy.eval({X: x_test, Y: y_test_new}))
    # 计算模型预测
    y_test_pred = sess.run(pred, feed_dict={X: x_test})
    y_pred = np.empty((y_test_pred.shape[0]), dtype='int32')
    # 二值化
    for i in range(y_pred.shape[0]):
        if y_test_pred[i,0]<y_test_pred[i,1]:
            y_pred[i]=0
        else:
            y_pred[i]=1
    # 得到ROC曲线
    fpr, tpr, thresholds = roc_curve((y_test), y_pred)
    AUC_ROC = roc_auc_score(y_test, y_pred)
    roc_curve =plt.figure()
    plt.plot(fpr,tpr,'-',label='Area Under the Curve (AUC = %0.4f)' % AUC_ROC)
    plt.title('ROC curve')
    plt.xlabel("FPR (False Positive Rate)")
    plt.ylabel("TPR (True Positive Rate)")
    plt.legend(loc="lower right")
    plt.show()     # 得到precision_recall曲线
    precision, recall, thresholds = precision_recall_curve(y_test, y_pred)
    precision = np.fliplr([precision])[0]  #so the array is increasing (you won't get negative AUC)
    recall = np.fliplr([recall])[0]  #so the array is increasing (you won't get negative AUC)
    AUC_prec_rec = np.trapz(precision,recall)
    print("\nArea under Precision-Recall curve: " +str(AUC_prec_rec))
    prec_rec_curve = plt.figure()
    plt.plot(recall,precision,'-',label='Area Under the Curve (AUC = %0.4f)' % AUC_prec_rec)
    plt.title('Precision - Recall curve')
    plt.xlabel("Recall")
    plt.ylabel("Precision")
    plt.legend(loc="lower right")
    plt.show()
    
    # 计算置信度矩阵
    threshold_confusion = 0.5
    print("\nConfusion matrix:  Costum threshold (for positive) of " +str(threshold_confusion))
    confusion = confusion_matrix(y_test, y_pred)
    print(confusion)
    accuracy = 0
    if float(np.sum(confusion))!=0:
        accuracy = float(confusion[0,0]+confusion[1,1])/float(np.sum(confusion))
    print("Global Accuracy: " +str(accuracy))
    specificity = 0
    if float(confusion[0,0]+confusion[0,1])!=0:
        specificity = float(confusion[0,0])/float(confusion[0,0]+confusion[0,1])
    print("Specificity: " +str(specificity))
    sensitivity = 0
    if float(confusion[1,1]+confusion[1,0])!=0:
        sensitivity = float(confusion[1,1])/float(confusion[1,1]+confusion[1,0])
    print("Sensitivity: " +str(sensitivity))
    precision = 0
    if float(confusion[1,1]+confusion[0,1])!=0:
        precision = float(confusion[1,1])/float(confusion[1,1]+confusion[0,1])
    print("Precision: " +str(precision))     #Jaccard similarity index
    jaccard_index = jaccard_similarity_score(y_test, y_pred, normalize=True)
    print("\nJaccard similarity score: " +str(jaccard_index))     #F1 score
    F1_score = f1_score(y_test, y_pred, labels=None, average='binary', sample_weight=None)
    print("\nF1 score (F-measure): " +str(F1_score))     print("y_test[0:20]=", y_test[0:20])
    print("y_pred[0:20]=", y_pred[0:20])

最总的结果显示如下:

古人学问无遗力,少壮工夫老始成。

纸上得来终觉浅,绝知此事要躬行。

  -- 陆游 《冬夜读书示子聿》

tensorflow之逻辑回归模型实现的更多相关文章

  1. 利用Tensorflow实现逻辑回归模型

    官方mnist代码: #下载Mnist数据集 import tensorflow.examples.tutorials.mnist.input_data mnist = input_data.read ...

  2. 深度学习实践系列(1)- 从零搭建notMNIST逻辑回归模型

    MNIST 被喻为深度学习中的Hello World示例,由Yann LeCun等大神组织收集的一个手写数字的数据集,有60000个训练集和10000个验证集,是个非常适合初学者入门的训练集.这个网站 ...

  3. 逻辑回归模型(Logistic Regression, LR)基础

    逻辑回归模型(Logistic Regression, LR)基础   逻辑回归(Logistic Regression, LR)模型其实仅在线性回归的基础上,套用了一个逻辑函数,但也就由于这个逻辑函 ...

  4. Python之逻辑回归模型来预测

    建立一个逻辑回归模型来预测一个学生是否被录取. import numpy as np import pandas as pd import matplotlib.pyplot as plt impor ...

  5. 逻辑回归模型(Logistic Regression)及Python实现

    逻辑回归模型(Logistic Regression)及Python实现 http://www.cnblogs.com/sumai 1.模型 在分类问题中,比如判断邮件是否为垃圾邮件,判断肿瘤是否为阳 ...

  6. 逻辑回归模型(Logistic Regression, LR)--分类

    逻辑回归(Logistic Regression, LR)模型其实仅在线性回归的基础上,套用了一个逻辑函数,但也就由于这个逻辑函数,使得逻辑回归模型成为了机器学习领域一颗耀眼的明星,更是计算广告学的核 ...

  7. 吴恩达机器学习笔记22-正则化逻辑回归模型(Regularized Logistic Regression)

    针对逻辑回归问题,我们在之前的课程已经学习过两种优化算法:我们首先学习了使用梯度下降法来优化代价函数

  8. tensorflow 实现逻辑回归——原以为TensorFlow不擅长做线性回归或者逻辑回归,原来是这么简单哇!

    实现的是预测 低 出生 体重 的 概率.尼克·麦克卢尔(Nick McClure). TensorFlow机器学习实战指南 (智能系统与技术丛书) (Kindle 位置 1060-1061). Kin ...

  9. tensorflow学习笔记五----------逻辑回归

    在逻辑回归中使用mnist数据集.导入相应的包以及数据集. import numpy as np import tensorflow as tf import matplotlib.pyplot as ...

随机推荐

  1. [BUUCTF 2018]Online Tool

    进入页面 贴出源码 <?php if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { $_SERVER['REMOTE_ADDR'] = $_SERVER ...

  2. Tornado项目简单创建

    Tornado是使用Python编写的一个强大的.可扩展的Web服务器.它在处理严峻的网络流量时表现得足够强健,但却在创建和编写时有着足够的轻量级,并能够被用在大量的应用和工具中. tornado技术 ...

  3. python 切片技巧

    说明: 字符串[开始索引:结束索引:步长] 开始索引:从指定位置开始截取: 结束索引:从指定位置结束截取,但不包含该位置的字符. 步长:不指定时步长为1: 1)当步长为正数时候,那么切片是从左到右进行 ...

  4. html 中js 如何给字符串加换行符

    var str = 你好'+"\n"+ '世界'; 这种写法在html中是会被识别为"你好\n世界" 那么如何保证其这么写会被识别,只需要在该div的样式中加入 ...

  5. WORKDIR 指定工作目录 每一个 RUN 都是启动一个容器、执行命令、然后提交存储层文件变更

    WORKDIR 指定工作目录 格式为 WORKDIR <工作目录路径>. 使用 WORKDIR 指令可以来指定工作目录(或者称为当前目录),以后各层的当前目录就被改为指定的目录,如该目录不 ...

  6. JS打开浏览器新窗口

    window.open(URL,name,features,replace); 参数 描述 URL 一个可选的字符串,声明了要在新窗口中显示的文档的 URL.如果省略了这个参数,或者它的值是空字符串, ...

  7. zookeeper 启动和停止脚本

    启动 sh zkServer.sh start 停止脚本 sh zkServer.sh stop

  8. ajax方法详解

    $.ajax()常用参数的设置及其意义 $.ajax({ async:true, /*是否异步请求,用这对象的目的就是为了异步请求,所以此值一般不变,恒为true*/ cache:false, /*是 ...

  9. Centos610安装Firefox

    yum -y install firefox yum install fonts-chinese yum install fonts-ISO8859-2-75dpi 修改 /etc/sysconfig ...

  10. win8.1 virtualbox 安装centos7注意事项

    win8.1是64位的,一开始在virtualbox中选择版本时,怎么也选不到64位的,这时要改BIOS设置,把CPU虚拟化改为允许. virtualbox是32位的,没必要非得是64位(64位的也不 ...