Tensorflow案例分析(1)—— 使用逻辑回归进行泰坦尼克号预测

本案例提供的数据集可以在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))

迭代的结果为:

扫描二维码关注公众号,回复: 3057964 查看本文章

五.使用模型预测

使用训练好的模型进行预测,并使用测试集生成预测结果,准备提交到官网进行验证

#使用计算得到的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那些模型就能有很高的准确率。


 

猜你喜欢

转载自blog.csdn.net/maqunfi/article/details/79673162
今日推荐