本案例提供的数据集可以在Kaggle官网进行下载:https://www.kaggle.com/c/titanic
基本思路:挑选数据集中有关联的属性作为特征,并对特征进行数据清洗、残缺值填充等操作,使用经过特征工程处理过的训练集训练好一个逻辑回归模型,并使用这个逻辑模型对测试集进行预测,预测结果保存到一个csv文件,并将csv文件提交到官网。
一.引入包
from __future__ import print_function, division
import tensorflow as tf
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn #这是一个可视化的展示库
import random
from sklearn.ensemble import RandomForestRegressor
import sklearn.preprocessing as preprocessing
from numpy import array
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import Imputer
可以观察训练集的数据字段
data=pd.read_csv('G:\Machine-learning\\tensorflow-train-project(jupyter)\kaggele-project6-tairanprediction\dataset\\train.csv')
print(data.columns)
二.预处理函数
创建准备进行数据预处理的函数:年龄信息补全函数、属性转换为数值的函数、属性值归一化函数。
1.缺失值补全函数
def set_missing_ages(data):
age_df=data[['Age','Fare','Parch','SibSp','Pclass']] #抽取一部分特征作为年龄相关特征时使用
known_age=age_df[age_df.Age.notnull()].as_matrix()# 这是一种抽离,把知道年龄的数据抽取出来作为一个矩阵
#print('known_age:',known_age)
unknown_age=age_df[age_df.Age.isnull()].as_matrix()
#接下来使用的是RandomForestClassifier算法来补全年龄特征
y=known_age[:,0]
x=known_age[:,1:]
#创建补全算法,并进行数据喂养 随机森林中参数意义为:n_estimators 子模型个数
rfr=RandomForestRegressor(random_state=0,n_estimators=2000,n_jobs=-1)
rfr.fit(x,y)
predictedAges=rfr.predict(unknown_age[:,1::])#对不知道年龄的矩阵,使用其特征进行年龄的预测
data.loc[(data.Age.isnull()),'Age']=predictedAges#这是针对DateFrame的定位并填充残缺值的方式
return data
2.属性转换为数值的函数
def attribute_to_number(data):
#前三行会对属性进行独热编码
dummies_Pclass=pd.get_dummies(data['Pclass'],prefix='Pclass')#get_dummies会对属性进行独热编码
dummies_Embarked=pd.get_dummies(data['Embarked'],prefix='Embarked')
dummies_Sex=pd.get_dummies(data['Sex'],prefix='Sex')
data=pd.concat([data,dummies_Pclass,dummies_Embarked,dummies_Sex],axis=1)
#针对这个类型,将前面没用的非数值属性去掉(使用后面新加入的 转化好的属性即可)
data.drop(['Pclass','Sex','Embarked'],axis=1,inplace=True)
return data
3.属性值归一化函数
def Scales(data):
scaler=preprocessing.StandardScaler()#StandardScaler用于数据标准化,计算训练集的平均值和标准差,以便测试数据集使用相同的变换
#对年龄进行归一化处理
age_scale_param=scaler.fit(data['Age'].reshape(-1,1))#这样转换,使其具有0均值,单位方差
data['Age_scaled']=scaler.fit_transform(data['Age'].reshape(-1,1),age_scale_param)#fit_transform可以进行最大最小的标准化
#对工资进行归一化处理
Fare_scale_param=scaler.fit(data['Fare'].reshape(-1,1))
data['Fare_scaled']=scaler.fit_transform(data['Fare'].reshape(-1,1),Fare_scale_param)
#对兄弟配偶数进行归一化处理
SibSp_scale_param=scaler.fit(data['SibSp'].reshape(-1,1))
data['SibSp_scaled']=scaler.fit_transform(data['SibSp'].reshape(-1,1),SibSp_scale_param)
#对父母子女数进行归一化处理
Parch_scale_param=scaler.fit(data['Parch'].reshape(-1,1))
data['Parch_scaled']=scaler.fit_transform(data['Parch'].reshape(-1,1),SibSp_scale_param)
#使用归一化后的数据,将之前的数据删去
data.drop(['Parch','SibSp','Fare','Age'],axis=1,inplace=True)
return data
三.数据集预处理
def DataPreProcess(in_data,submat_flg):#数据预处理 submat_flg为1表示是针对测试数据的处理
in_data.drop(['PassengerId','Name','Ticket','Cabin'],axis=1,inplace=True) #删去无关特征
data_ages_fitted=set_missing_ages(in_data)#补足年龄信息
data=attribute_to_number(data_ages_fitted)#类目属性转为数值型
data_scaled=Scales(data)#将转化为数值型的特征数据进行归一化
data_copy=data_scaled.copy(deep=True) #将数据集进行完全的备份 深拷贝
data_copy.drop(['Pclass_1','Pclass_2','Pclass_3','Embarked_C','Embarked_Q','Embarked_S','Sex_female','Sex_male','Age_scaled','Fare_scaled','SibSp_scaled','Parch_scaled'],axis=1,inplace=True)
data_y=np.array(data_copy)#这里是删去了很多东西(进行一种选择性的删除,还有axis这个自己不太掌握) 剩下的作为y的标签
if submat_flg==0:
data_scaled.drop(['Survived'],axis=1,inplace=True)
data_X=np.array(data_scaled)#特征组合x,这是要进行网络输入所用的所有特征值
return data_X,data_y
if(submat_flg==1):
data_X=np.array(data_scaled)#特征组合x,这是要进行网络输入所用的所有特征值
return data_X,data_y
四.创建逻辑回归模型
创建计算图,使用逻辑回归算法根据预处理过的数据计算模型参数(纯套路,构建图,填充数据集) 我们打算使用逻辑回归法,要用到的式子为 y=w0x0+w1x1+w2x2+y=w0x0+w1x1+w2x2+b 这样的方式求出其中的w和b,这是要计算出的模型参数。
y=w0x0+w1x1+w2x2+b ,这样的方式求出其中的w和b,这是要计算出的模型参数。
def LR(data_X,data_y):
X_train,X_test,y_train,y_test=train_test_split(data_X,data_y,test_size=0.1,random_state=0)#按比例系数 划分训练集和测试集
#接下来的操作应该是将标签值确定的转化为1或者0标签
y_train=tf.concat([1-y_train,y_train],1)
y_test=tf.concat([1-y_test,y_test],1)
learning_rate=0.0005
training_epochs=25
batch_size=10
display_step=10
n_samples=X_train.shape[0]
n_feature=X_train.shape[1]
n_class=2#目标是进行二分类
#设定占位符,模型变量和模型
x=tf.placeholder(tf.float32,[None,n_feature])
y=tf.placeholder(tf.float32,[None,n_class])
W=tf.Variable(tf.zeros([n_feature,n_class]),name='weight')
b=tf.Variable(tf.zeros([n_class]),name='bias')
pred=tf.matmul(x,W)+b
#计算准确率和损失函数
correct_prediction=tf.equal(tf.arg_max(pred,1),tf.arg_max(y,1))
accurary=tf.reduce_mean(tf.cast(correct_prediction,tf.float32))#reduce_mean是针对张量求平均值的一种方式,而reduce_sum是针对的一种求和
cost=tf.reduce_sum(tf.nn.sigmoid_cross_entropy_with_logits(logits=pred,labels=y))
optimizer=tf.train.MomentumOptimizer(learning_rate,0.9).minimize(cost)
init=tf.initialize_all_variables()
with tf.Session() as sess:
sess.run(init)
#进行50次训练批次的训练,每批次使用50个数据进行训练
for epoch in range(training_epochs):
avg_cost=0
total_batch=int(n_samples/batch_size) #在每个训练批次里面 我们都会使用所有的数据进行训练,所以这里会有个除式计算
for i in range(total_batch):
_,c=sess.run([optimizer,cost],feed_dict={x:X_train[i*batch_size:(i+1)*batch_size],y:y_train[i*batch_size:(i+1)*batch_size,:].eval()})
avg_cost=c/total_batch#单批次下的损失值
plt.plot(epoch+1,avg_cost,'co')#把损失值变化 用plt图标来展示出来
if(epoch+1)%display_step==0:#达到一定批次之后进行准确的输出展示
print('Epoch:',(epoch+1),',cost=',avg_cost)
# print('the Weight: ',sess.run(W),' ,the bias:',sess.run(b))
X_test=sess.run(tf.convert_to_tensor(X_test))
y_test=sess.run(tf.convert_to_tensor(y_test))
print('Testing Accuracy:',sess.run(accurary,feed_dict={x:X_test,y:y_test}))#这个地方如果这样用,往feed_dict中传的是张量,这是tf的理解难点
plt.xlabel('Epoch')
plt.ylabel('cost')
plt.show()
W=sess.run(W)
b=sess.run(b)
return W,b
五.声明主函数
if __name__=="__main__":
data=pd.read_csv('G:\Machine-learning\\tensorflow-train-project(jupyter)\kaggele-project6-tairanprediction\dataset\\train.csv')
submat_test_data=pd.read_csv('G:\Machine-learning\\tensorflow-train-project(jupyter)\kaggele-project6-tairanprediction\dataset\\test.csv')
submat_test_data_PassengerId=submat_test_data['PassengerId']
data_x,data_y=DataPreProcess(data,0)
submat_test_data_x,submat_test_data_y=DataPreProcess(submat_test_data,1)
Weight,bias=LR(data_x,data_y)
print('the W:',W,',it type is',type(W))
print('the b:',b,',it type is',type(b))
迭代的结果为:
五.使用模型预测
使用训练好的模型进行预测,并使用测试集生成预测结果,准备提交到官网进行验证
#使用计算得到的W和b参数重新启动计算过程 在会话中进行获救结果的预测,并保持在一个csv文件中
n_features=submat_test_data_x.shape[1]
n_Weight=Weight.shape[1]
n_bias=bias.shape
X=tf.placeholder(tf.float32,[None,n_features])
W=tf.placeholder(tf.float32,[None,n_Weight])
B=tf.placeholder(tf.float32,n_bias)#因为是一维的直接放置就行了
yHat=tf.add(tf.matmul(X,W),B)
last_result=tf.arg_max(yHat,1) #构建计算图,直接放置即可 自己想出来的方法
with tf.Session() as sess2:
tf.global_variables_initializer().run()
submat_test_data_x=sess2.run(tf.convert_to_tensor(submat_test_data_x))
Weight=sess2.run(tf.convert_to_tensor(Weight))
bias=sess2.run(tf.convert_to_tensor(bias))
print('submat shape:',submat_test_data_x.shape)
print('Weight shape:',Weight.shape)
print('bias shape:',type(bias))
predictions_to=sess2.run([last_result],feed_dict={X:submat_test_data_x,W:Weight,B:bias})#np.argmax用于得到数组最大值的索引 整体获得预测结果
#predictions_to=sess2.run(tf.arg_max(tf.convert_to_tensor(predictions),1))
#print('predictions:',predictions_to[0].shape)
submission=pd.DataFrame({'PassengerId':submat_test_data_PassengerId,'Survived':predictions_to[0]})#构造一个表,用于放置预测结果 predictions_to[0]语句相当于把这取出来了
submission.to_csv('submit.csv',index=False)
对测试集进行预测的结果,按照官网的格式要求,保存在一个csv文件中,csv文件样式如下图,得到预测结果。
提交之后的得分是0.78左右,排名在700名左右,排名有点低,这是因为模型用的太简单了,如果用xgboost那些模型就能有很高的准确率。