使用TensorFlow實現邏輯迴歸(Titanic船員獲救專案實現)
阿新 • • 發佈:2018-12-15
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)