日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

结构化数据建模——titanic数据集的模型建立和训练(Pytorch版)

發布時間:2023/11/29 编程问答 53 豆豆
生活随笔 收集整理的這篇文章主要介紹了 结构化数据建模——titanic数据集的模型建立和训练(Pytorch版) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文參考《20天吃透Pytorch》來實現titanic數據集的模型建立和訓練
在書中理論的同時加入自己的理解。

一,準備數據

數據加載

titanic數據集的目標是根據乘客信息預測他們在Titanic號撞擊冰山沉沒后能否生存。
結構化數據一般會使用Pandas中的DataFrame進行預處理。

import torch import numpy as np import pandas as pd import matplotlib.pyplot as plt from torch import nn from torch.utils.data import Dataset,DataLoader,TensorDataset

數據集字段如下:

字段說明:

Survived:0代表死亡,1代表存活【y標簽】
Pclass:乘客所持票類,有三種值(1,2,3) 【轉換成onehot編碼】
Name:乘客姓名 【舍去】
Sex:乘客性別 【轉換成bool特征】
Age:乘客年齡(有缺失) 【數值特征,添加“年齡是否缺失”作為輔助特征】
SibSp:乘客兄弟姐妹/配偶的個數(整數值) 【數值特征】
Parch:乘客父母/孩子的個數(整數值)【數值特征】
Ticket:票號(字符串)【舍去】
Fare:乘客所持票的價格(浮點數,0-500不等) 【數值特征】
Cabin:乘客所在船艙(有缺失) 【添加“所在船艙是否缺失”作為輔助特征】
Embarked:乘客登船港口:S、C、Q(有缺失)【轉換成onehot編碼,四維度 S,C,Q,nan】

加載數據集:

#數據讀取 train_data = pd.read_csv('./data/titanic/train.csv') test_data = pd.read_csv('./data/titanic/test.csv') test_datay = pd.read_csv('./data/titanic/titanic.csv') #print(train_data.head(10)) #打印訓練數據前十個

當我們獲得數據集后,首先要查看數據中是否有缺失!!!這個很重要!

train_data.info() #查看訓練數據有沒有未知的的 test_data.info() #查看測試數據有沒有未知的的


很明顯,Age和Cabin數據都有缺失

接下來,先利用Pandas的數據可視化分析數據:

幸存情況

#幸存情況 ax = train_data['Survived'].value_counts().plot(kind = 'bar',figsize = (12,8),fontsize =15,rot = 0) #value_counts是查詢有多少個不同值且每個不同值有多少個重復的 ax.set_ylabel('Counts',fontsize = 15) ax.set_xlabel('Survived',fontsize = 15) plt.show()


年齡分布情況

#年齡分布情況 ax = train_data['Age'].plot(kind = 'hist',bins = 20,color = 'purple',figsize = (12,8),fontsize = 15) """ hist方法常用的參數有以下幾個 1. bins,控制直方圖中的區間個數 2. color,指定柱子的填充色 3. edgecolor, 指定柱子邊框的顏色 4. density,指定柱子高度對應的信息,有數值和頻率兩種選擇 5. orientation,指定柱子的方向,有水平和垂直兩個方向 6. histtype,繪圖的類型 """ ax.set_ylabel('Frequency',fontsize = 15) ax.set_xlabel('Age',fontsize = 15) plt.show()


年齡和label的相關性

#年齡和label的相關性 ax = train_data.query('Survived == 0')['Age'].plot(kind = 'density',figsize = (12,8),fontsize = 15) #使用python.query()函數對數據框進行(挑選行)的操作 train_data.query('Survived == 1')['Age'].plot(kind = 'density',figsize = (12,8),fontsize = 15) ax.legend(['Survived ==0','Survived ==1'],fontsize = 12) #plt.legend()函數主要的作用就是給圖加上圖例,plt.legend([x,y,z])里面的參數使用的是list的的形式將圖表的的名稱喂給這和函數。 ax.set_ylabel('Density',fontsize = 15) ax.set_xlabel('Age',fontsize = 15) plt.show()

數據預處理

這個步驟非常非常重要! 不僅要加載數據集,更重要的是如何處理NULL數據!

""" 數據預處理 """ def preprocessing(dfdata):dfresult = pd.DataFrame() #存儲結果#DataFrame是Python中Pandas庫中的一種數據結構,它類似excel,是一種二維表。#Pclass處理dfPclass = pd.get_dummies(dfdata['Pclass'])#對Pclass進行get_dummies,將該特征離散化dfPclass.columns = ['Pclass_'+str(x) for x in dfPclass.columns]dfresult = pd.concat([dfresult,dfPclass],axis=1)#concat函數是在pandas底下的方法,可以將數據根據不同的軸作簡單的融合,axis: 需要合并鏈接的軸,0是行,1是列#SexdfSex = pd.get_dummies(dfdata['Sex'])dfresult = pd.concat([dfresult, dfSex], axis=1)#Agedfresult['Age'] = dfdata['Age'].fillna(0)dfresult['Age_null'] = pd.isna(dfdata['Age']).astype('int32')#pandas.isna(obj)檢測array-like對象的缺失值# SibSp,Parch,Faredfresult['SibSp'] = dfdata['SibSp']dfresult['Parch'] = dfdata['Parch']dfresult['Fare'] = dfdata['Fare']# Carbindfresult['Cabin_null'] = pd.isna(dfdata['Cabin']).astype('int32')print(dfresult['Cabin_null'])# EmbarkeddfEmbarked = pd.get_dummies(dfdata['Embarked'], dummy_na=True)dfEmbarked.columns = ['Embarked_' + str(x) for x in dfEmbarked.columns]#DataFrame.columns屬性以返回給定 DataFrame 的列標簽。dfresult = pd.concat([dfresult, dfEmbarked], axis=1)return dfresult#獲得訓練x,y x_train = preprocessing(train_data).values y_train = train_data[['Survived']].values#獲得測試x,y x_test = preprocessing(test_data).values y_test = test_datay[['Survived']].values# print("x_train.shape =", x_train.shape ) # print("x_test.shape =", x_test.shape ) # print("y_train.shape =", y_train.shape ) # print("y_test.shape =", y_test.shape )

這里重點講解一下對數據缺失部分的處理!

以Age字段,我們通過fillna(0),將Age字段中的NaN替換成0
然后通過 pd.isna將空值點的地方記錄下來(添加“年齡是否缺失”作為輔助特征)
這里我把測試數據中的Age部分除了前兩個后面全設置為NULL
然后把dfresult['Age'],dfresult['Age_null']打印出來:

可以看看下面這個文章,我收到了很多啟發。

data是一個pandas.DataFrame數據對象,是從mysql讀取的數據。由于有的列在數據庫是int類型,而且有空值(Null),因此在從數據庫抽取到df對象后,pandas自動將int轉成float,比如10變成了10.0,15902912345變成了1.5902912345E10,Null變成了NaN。這種列由于存在NaN,因此不能用DataFrame.astype()方法轉成int類型。
我們的目的就是盡量讓pandas抽取的數據跟數據庫“看上去”一致。比如原來是int類型的,如果被替換成float了,那么需要轉換回去,原來是Null的,被pandas改成NaN了,需要替換成空字符串。由于pandas列的int類型不能為空,所以需統一轉換成字符串類型。
為了達到將列轉換成int類型原來的展現形式(可以是object類型,相當于str,此時10還是展示為10),且NaN轉換成空值這個目的,可以采取如下步驟:
1.生成新的df對象,保存data里為NaN的位置標記
2.將data需要處理的列,NaN值替換為float能允許的類型,如0,下面會用到
3.將該列轉換成int類型,此時10.0轉換成10,1.5902912345E10轉換成15902912345
4.將該列轉換成object類型,此時所有數值按str類型原樣保存
5.用NaN位置標記的df對象作為索引,替換原df對象中為0的值到空字符串
利用pandas.DataFrame.isna方法做替換(很棒的技巧)

進一步使用DataLoader和TensorDataset封裝成可以迭代的數據管道。

""" 進一步使用DataLoader和TensorDataset封裝成可以迭代的數據管道。 """ dl_train = DataLoader(TensorDataset(torch.tensor(x_train).float(),torch.tensor(y_train).float()),shuffle = True, batch_size = 8) dl_valid = DataLoader(TensorDataset(torch.tensor(x_test).float(),torch.tensor(y_test).float()),shuffle = False, batch_size = 8)# 測試數據管道 for features,labels in dl_train:print(features,labels)break

二,定義模型

使用Pytorch通常有三種方式構建模型:使用nn.Sequential按層順序構建模型,繼承nn.Module基類構建自定義模型,繼承nn.Module基類構建模型并輔助應用模型容器進行封裝。
此處選擇使用最簡單的nn.Sequential,按層順序模型。

""" 二,定義模型 """def creat_net():net = nn.Sequential()net.add_module("linear1",nn.Linear(15,20))net.add_module("relu1",nn.ReLU())net.add_module("linear2", nn.Linear(20, 15))net.add_module("relu2", nn.ReLU())net.add_module("linear3", nn.Linear(15, 1))net.add_module("sigmoid", nn.Sigmoid())return netnet = creat_net() #print(net)

三,訓練模型

""" 三,訓練模型 """from sklearn.metrics import accuracy_scoreloss_func = nn.BCELoss() optimizer = torch.optim.Adam(params=net.parameters(),lr=0.01) metric_func = lambda y_pred,y_true:accuracy_score(y_true.data.numpy(),y_pred.data.numpy()>0.5) #lambda表達式是起到一個函數速寫的作用。允許在代碼內嵌入一個函數的定義。 #accuracy_score是分類準確率分數是指所有分類正確的百分比。 metric_name = "accuracy" #metric就是準確率epochs = 10 log_step_freq = 30 dfhistory = pd.DataFrame(columns = ["epoch","loss",metric_name,"val_loss","val_"+metric_name])for epoch in range(1,epochs+1):#開始訓練net.train()loss_sum = 0.0metric_sum = 0.0step = 1for step,(features,labels) in enumerate(dl_train,1):optimizer.zero_grad()#正向傳播predictions = net(features)loss = loss_func(predictions,labels)metric = metric_func(predictions,labels)#反向傳播loss.backward()optimizer.step()#打印batch日志loss_sum += loss.item()metric_sum += metric.item()if step%log_step_freq == 0:print(("[step = %d] loss: %.3f, " + metric_name + ": %.3f") %(step, loss_sum / step, metric_sum / step))#驗證循環net.eval()val_loss_sum = 0.0val_metric_sum = 0.0val_step = 1for val_step, (features, labels) in enumerate(dl_valid, 1):predictions = net(features)val_loss = loss_func(predictions, labels)val_metric = metric_func(predictions,labels)val_loss_sum += val_loss.item()val_metric_sum += val_metric.item()#記錄日志info = (epoch, loss_sum / step, metric_sum / step,val_loss_sum / val_step, val_metric_sum / val_step)dfhistory.loc[epoch - 1] = info# 打印epoch級別日志print(("\nEPOCH = %d, loss = %.3f," + metric_name + " = %.3f, val_loss = %.3f, " + "val_" + metric_name + " = %.3f")% info)

四,評估模型

""" 四,評估模型 """ def plot_metric(dfhistory, metric):train_metrics = dfhistory[metric]val_metrics = dfhistory['val_'+metric]epochs = range(1, len(train_metrics) + 1)plt.plot(epochs, train_metrics, 'bo--')plt.plot(epochs, val_metrics, 'ro-')plt.title('Training and validation '+ metric)plt.xlabel("Epochs")plt.ylabel(metric)plt.legend(["train_"+metric, 'val_'+metric])plt.show()plot_metric(dfhistory,"loss") plot_metric(dfhistory,"accuracy")

這里補充一下 dfhistory

dfhistory來源于第三部分訓練模型中:

dfhistory = pd.DataFrame(columns = ["epoch","loss",metric_name,"val_loss","val_"+metric_name])

DataFrame是Python中Pandas庫中的一種數據結構,它類似excel,是一種二維表。
dfhistory的作用就是跟蹤數據,在訓練的過程中記錄每一步的訓練結果。
通過在dfhistory調取訓練數據和測試數據進行對比繪圖!

結果展示:


五,使用模型

""" 五,使用模型 """ y_pred_probs = net(torch.tensor(x_test[0:10]).float()).data y_pred = torch.where(y_pred_probs>0.5,torch.ones_like(y_pred_probs),torch.zeros_like(y_pred_probs))

六,保存模型

""" # 六,保存模型 """ #保存模型參數(推薦) print(net.state_dict().keys()) # 保存模型參數 torch.save(net.state_dict(), "./data/net_parameter.pkl") net_clone = creat_net() net_clone.load_state_dict(torch.load("./data/net_parameter.pkl")) net_clone.forward(torch.tensor(x_test[0:10]).float()).data#保存完整模型(不推薦) torch.save(net, './data/net_model.pkl') net_loaded = torch.load('./data/net_model.pkl') net_loaded(torch.tensor(x_test[0:10]).float()).data

完整代碼:

import torch import numpy as np import pandas as pd import matplotlib.pyplot as plt from torch import nn from torch.utils.data import Dataset,DataLoader,TensorDataset""" 一,準備數據 """#數據讀取 train_data = pd.read_csv('./data/titanic/train.csv') test_data = pd.read_csv('./data/titanic/test.csv') test_datay = pd.read_csv('./data/titanic/titanic.csv') #print(train_data.head(10)) #打印訓練數據前十個train_data.info() #查看訓練數據有沒有未知的的 test_data.info() #查看測試數據有沒有未知的的# #查看各部分分布情況 # # #幸存情況 # ax = train_data['Survived'].value_counts().plot(kind = 'bar',figsize = (12,8),fontsize =15,rot = 0) # #value_counts是查詢有多少個不同值且每個不同值有多少個重復的 # ax.set_ylabel('Counts',fontsize = 15) # ax.set_xlabel('Survived',fontsize = 15) # plt.show() # # #年齡分布情況 # ax = train_data['Age'].plot(kind = 'hist',bins = 20,color = 'purple',figsize = (12,8),fontsize = 15) # """ # hist方法常用的參數有以下幾個 # 1. bins,控制直方圖中的區間個數 # 2. color,指定柱子的填充色 # 3. edgecolor, 指定柱子邊框的顏色 # 4. density,指定柱子高度對應的信息,有數值和頻率兩種選擇 # 5. orientation,指定柱子的方向,有水平和垂直兩個方向 # 6. histtype,繪圖的類型 # """ # ax.set_ylabel('Frequency',fontsize = 15) # ax.set_xlabel('Age',fontsize = 15) # plt.show() # # #年齡和label的相關性 # ax = train_data.query('Survived == 0')['Age'].plot(kind = 'density',figsize = (12,8),fontsize = 15) # #使用python.query()函數對數據框進行(挑選行)的操作 # train_data.query('Survived == 1')['Age'].plot(kind = 'density',figsize = (12,8),fontsize = 15) # ax.legend(['Survived ==0','Survived ==1'],fontsize = 12) # #plt.legend()函數主要的作用就是給圖加上圖例,plt.legend([x,y,z])里面的參數使用的是list的的形式將圖表的的名稱喂給這和函數。 # ax.set_ylabel('Density',fontsize = 15) # ax.set_xlabel('Age',fontsize = 15) # plt.show() # """ 數據預處理 """ def preprocessing(dfdata):dfresult = pd.DataFrame() #存儲結果#DataFrame是Python中Pandas庫中的一種數據結構,它類似excel,是一種二維表。#Pclass處理dfPclass = pd.get_dummies(dfdata['Pclass'])#對Pclass進行get_dummies,將該特征離散化dfPclass.columns = ['Pclass_'+str(x) for x in dfPclass.columns]dfresult = pd.concat([dfresult,dfPclass],axis=1)#concat函數是在pandas底下的方法,可以將數據根據不同的軸作簡單的融合,axis: 需要合并鏈接的軸,0是行,1是列#SexdfSex = pd.get_dummies(dfdata['Sex'])dfresult = pd.concat([dfresult, dfSex], axis=1)#Agedfresult['Age'] = dfdata['Age'].fillna(0)dfresult['Age_null'] = pd.isna(dfdata['Age']).astype('int32')#pandas.isna(obj)檢測array-like對象的缺失值# SibSp,Parch,Faredfresult['SibSp'] = dfdata['SibSp']dfresult['Parch'] = dfdata['Parch']dfresult['Fare'] = dfdata['Fare']# Carbindfresult['Cabin_null'] = pd.isna(dfdata['Cabin']).astype('int32')# EmbarkeddfEmbarked = pd.get_dummies(dfdata['Embarked'], dummy_na=True)dfEmbarked.columns = ['Embarked_' + str(x) for x in dfEmbarked.columns]#DataFrame.columns屬性以返回給定 DataFrame 的列標簽。dfresult = pd.concat([dfresult, dfEmbarked], axis=1)return dfresult#獲得訓練x,y x_train = preprocessing(train_data).values y_train = train_data[['Survived']].values#獲得測試x,y x_test = preprocessing(test_data).values y_test = test_datay[['Survived']].values# print("x_train.shape =", x_train.shape ) # print("x_test.shape =", x_test.shape ) # print("y_train.shape =", y_train.shape ) # print("y_test.shape =", y_test.shape ) # """ 進一步使用DataLoader和TensorDataset封裝成可以迭代的數據管道。 """ dl_train = DataLoader(TensorDataset(torch.tensor(x_train).float(),torch.tensor(y_train).float()),shuffle = True, batch_size = 8) dl_valid = DataLoader(TensorDataset(torch.tensor(x_test).float(),torch.tensor(y_test).float()),shuffle = False, batch_size = 8) # # # #測試數據管道 # for features,labels in dl_valid: # print(features,labels) # break # """ 二,定義模型 """def creat_net():net = nn.Sequential()net.add_module("linear1",nn.Linear(15,20))net.add_module("relu1",nn.ReLU())net.add_module("linear2", nn.Linear(20, 15))net.add_module("relu2", nn.ReLU())net.add_module("linear3", nn.Linear(15, 1))net.add_module("sigmoid", nn.Sigmoid())return netnet = creat_net() #print(net)""" 三,訓練模型 """from sklearn.metrics import accuracy_scoreloss_func = nn.BCELoss() optimizer = torch.optim.Adam(params=net.parameters(),lr=0.01) metric_func = lambda y_pred,y_true:accuracy_score(y_true.data.numpy(),y_pred.data.numpy()>0.5) #lambda表達式是起到一個函數速寫的作用。允許在代碼內嵌入一個函數的定義。 #accuracy_score是分類準確率分數是指所有分類正確的百分比。 metric_name = "accuracy" #metric就是準確率epochs = 10 log_step_freq = 30 dfhistory = pd.DataFrame(columns = ["epoch","loss",metric_name,"val_loss","val_"+metric_name])for epoch in range(1,epochs+1):#開始訓練net.train()loss_sum = 0.0metric_sum = 0.0step = 1for step,(features,labels) in enumerate(dl_train,1):optimizer.zero_grad()#正向傳播predictions = net(features)loss = loss_func(predictions,labels)metric = metric_func(predictions,labels)#反向傳播loss.backward()optimizer.step()#打印batch日志loss_sum += loss.item()metric_sum += metric.item()if step%log_step_freq == 0:print(("[step = %d] loss: %.3f, " + metric_name + ": %.3f") %(step, loss_sum / step, metric_sum / step))#驗證循環net.eval()val_loss_sum = 0.0val_metric_sum = 0.0val_step = 1for val_step, (features, labels) in enumerate(dl_valid, 1):predictions = net(features)val_loss = loss_func(predictions, labels)val_metric = metric_func(predictions,labels)val_loss_sum += val_loss.item()val_metric_sum += val_metric.item()#記錄日志info = (epoch, loss_sum / step, metric_sum / step,val_loss_sum / val_step, val_metric_sum / val_step)dfhistory.loc[epoch - 1] = info# 打印epoch級別日志print(("\nEPOCH = %d, loss = %.3f," + metric_name + " = %.3f, val_loss = %.3f, " + "val_" + metric_name + " = %.3f")% info)""" 四,評估模型 """ def plot_metric(dfhistory, metric):train_metrics = dfhistory[metric]val_metrics = dfhistory['val_'+metric]epochs = range(1, len(train_metrics) + 1)plt.plot(epochs, train_metrics, 'bo--')plt.plot(epochs, val_metrics, 'ro-')plt.title('Training and validation '+ metric)plt.xlabel("Epochs")plt.ylabel(metric)plt.legend(["train_"+metric, 'val_'+metric])plt.show()plot_metric(dfhistory,"loss") plot_metric(dfhistory,"accuracy")""" 五,使用模型 """ y_pred_probs = net(torch.tensor(x_test[0:10]).float()).data y_pred = torch.where(y_pred_probs>0.5,torch.ones_like(y_pred_probs),torch.zeros_like(y_pred_probs))# """ # # 六,保存模型 # """ # #保存模型參數(推薦) # print(net.state_dict().keys()) # # 保存模型參數 # torch.save(net.state_dict(), "./data/net_parameter.pkl") # net_clone = creat_net() # net_clone.load_state_dict(torch.load("./data/net_parameter.pkl")) # net_clone.forward(torch.tensor(x_test[0:10]).float()).data # # #保存完整模型(不推薦) # torch.save(net, './data/net_model.pkl') # net_loaded = torch.load('./data/net_model.pkl') # net_loaded(torch.tensor(x_test[0:10]).float()).data

總結

以上是生活随笔為你收集整理的结构化数据建模——titanic数据集的模型建立和训练(Pytorch版)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。