使用TensorFlow实现逻辑回归(Titanic船员获救项目实现)

        Titanic船员获救问题是kaggle上一个很经典的机器学习练手项目,很适合机器学习入门阶段拿来练手以熟悉机器学习相关流程和知识。本篇文章用来记录本人学习TensorFlow时,用Titanic问题来练习的笔记。

        通常机器学习的常规流程可概括为三部曲:

        1.熟悉原始数据,并对原始数据进行预处理。比如对缺失值的处理、非数值型数据的处理等。

        2.从预处理完的数据中挑选特征。挑选特征是机器学习的关键,模型训练的好坏和数据预处理以及特征挑选有很大关系。 因此发展出了特征工程这个领域,专门来“对付”特征挑选。

        3.使用挑选好的特征来训练模型,并使用模型来预测测试集数据的结果。

        根据以上流程,我使用TensorFlow分为六步来实现逻辑回归来预测Titanic船员获救数据。

1.数据读入及预处理

import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split

#读取训练数据
data = pd.read_csv("data/train.csv")
#查看数据情况
data.info()

#将Sex列数据转换为1或0
data['Sex'] = data['Sex'].apply(lambda s : 1 if s == 'male' else 0)
#缺失字段填充为0
data = data.fillna(0)
#选择以下特征用于分类
dataset_X = data[['Sex', 'Age', 'Pclass', 'SibSp', 'Parch', 'Fare']]
dataset_X = dataset_X.as_matrix()

#两种分类分别是幸存和死亡,‘Survived’字段是其中一种分类的标签
#新增加'Deceased'字段表示第二种分类的标签,取值为'Survived'取非
data['Deceased'] = data['Survived'].apply(lambda s : int(not s))
dataset_Y = data[['Deceased', 'Survived']]
dataset_Y = dataset_Y.as_matrix()
#在训练数据中选择20%数据用来进行测试
X_train, X_val, y_train, y_val = train_test_split(dataset_X, dataset_Y, test_size=0.2, random_state=1)

2.构建计算图,采用逻辑回归进行构建


import tensorflow as tf
#声明输入数据占位符
#shape参数的第一个元素为None,表示可以同时放入任意条记录,每条记录都有6个特征
X = tf.placeholder(tf.float32, shape=[None, 6])
y = tf.placeholder(tf.float32, shape=[None, 2])

#声明参数变量权重W和bias
W = tf.Variable(tf.random_normal([6, 2]), name='weights')
bias = tf.Variable(tf.zeros([2]), name='bias')

#构造前向传播计算图
y_pred = tf.nn.softmax(tf.matmul(X, W) + bias)

#代价函数
cross_entropy = -tf.reduce_sum(y * tf.log(y_pred + 1e-10), reduction_indices=1)
cost = tf.reduce_mean(cross_entropy)

#加入优化算法:随机梯度下降算法
train_op = tf.train.GradientDescentOptimizer(0.001).minimize(cost)

3.构建训练迭代过程

with tf.Session() as sess:
    tf.global_variables_initializer().run()
    
    #以下为训练迭代,迭代100轮
    for epoch in range(100):
        total_loss = 0.
        for i in range(len(X_train)):
            feed = {X: [X_train[i]], y: [y_train[i]]}
            #通过session.run接口触发执行
            _, loss = sess.run([train_op, cost], feed_dict=feed)
            total_loss += loss
        print('Epoch: %04d, total loss=%.9f' % (epoch + 1, total_loss))
    print('Training complete!')
    
    #评估准确率
    pred = sess.run(y_pred, feed_dict={X: X_val})
    correct = np.equal(np.argmax(pred, 1), np.argmax(y_val, 1))
    accuracy = np.mean(correct.astype(np.float32))
    print("Accuracy on validation set: %.9f" % accuracy)

4.执行训练

执行训练的每个epoch结果如下:

Epoch: 0001, total loss=2978.986924756
Epoch: 0002, total loss=1233.613931798
Epoch: 0003, total loss=1433.674743123
Epoch: 0004, total loss=1425.632846644
Epoch: 0005, total loss=1413.414649527
Epoch: 0006, total loss=1401.179366778
Epoch: 0007, total loss=1389.302903898
Epoch: 0008, total loss=1377.886010977
.....
Epoch: 0099, total loss=1165.767331228
Epoch: 0100, total loss=1165.626431299
Training complete!
Accuracy on validation set: 0.687150836

通过以上执行结果可以看出100轮训练取得的准确率为0.687150836,我将epoch改为1000次后再执行,结果如下:

Epoch: 0001, total loss=1869.781745049
Epoch: 0002, total loss=1208.829884079
Epoch: 0003, total loss=1131.160947576
Epoch: 0004, total loss=1136.071243536
Epoch: 0005, total loss=1069.703441266
Epoch: 0006, total loss=1072.349545262
Epoch: 0007, total loss=1069.528637791
Epoch: 0008, total loss=1069.168335461
......
Epoch: 0999, total loss=970.790128045
Epoch: 1000, total loss=965.400083950
Training complete!
Accuracy on validation set: 0.770949721

由以上训练的epoch次数不同而最终准确率的不同,可以感受到训练次数对准确率的影响。

5.存储和加载模型参数

变量的存储和读取时通过tf.train.Saver类来完成的,Saver对象的save()方法用于存储,restore()方法用于读取。这里将变量保存在save目录下modle.ckpt中。

# 存档入口
saver = tf.train.Saver()

with tf.Session() as sess:
    tf.global_variables_initializer().run()
    
    #以下为训练迭代,迭代100轮
    for epoch in range(100):
        total_loss = 0.
        for i in range(len(X_train)):
            feed = {X: [X_train[i]], y: [y_train[i]]}
            #通过session.run接口触发执行
            _, loss = sess.run([train_op, cost], feed_dict=feed)
            total_loss += loss
        print('Epoch: %04d, total loss=%.9f' % (epoch + 1, total_loss))
    print('Training complete!')
    
    #评估准确率
    pred = sess.run(y_pred, feed_dict={X: X_val})
    correct = np.equal(np.argmax(pred, 1), np.argmax(y_val, 1))
    accuracy = np.mean(correct.astype(np.float32))
    print("Accuracy on validation set: %.9f" % accuracy)
    #持久化存储变量
    save_path = saver.save(sess, "save/model.ckpt")

6.使用模型对测试数据进行预测

Titanic问题是一个没有奖金的比赛项目,那么,训练出的模型就需要在给出的测试数据上来进行预测,并将预测结果一.cvs文件的形式上传kaggle网站。

#读入测试数据集并完成预处理, 
testdata = pd.read_csv('data/test.csv')
testdata = testdata.fillna(0)

testdata['Sex'] = testdata['Sex'].apply(lambda s: 1 if s== 'male' else 0)
X_test = testdata[['Sex', 'Age', 'Pclass', 'SibSp', 'Parch', 'Fare']]

with tf.Session() as sess2:
    tf.global_variables_initializer().run()
    #加载模型存档
    saver.restore(sess2, save_path)
    #正向传播计算
    predictions = np.argmax(sess2.run(y_pred, feed_dict={X:X_test}), 1)

    #构建提交结果的数据结构,并将结果存储为csv文件
    submission = pd.DataFrame({
        "PassengerId": testdata["PassengerId"],
        "Survived": predictions
    })
    #将预测数据写入titanic_submissioin.csv文件中
    submission.to_csv("titanic_submission.csv", index=False)

猜你喜欢

转载自blog.csdn.net/moyu123456789/article/details/83049931
今日推荐