版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
機器學習實戰(zhàn)案例
——保險風險預測業(yè)務背景分析
英國保誠公司是英國最大的人壽保險公司之一,其業(yè)務包括人壽保險、投資管理等,服務網絡遍布全世界。保誠公司擁有眾多的員工以及龐大的客戶群體。在人壽保險方面,保誠公司擁有大量的用戶數據,這些數據不僅包含了投保人的個人健康、工作經歷等基本信息,還包含了可能與投保人的投保風險密切相關的保險歷史、家族史、病歷等信息。保誠公司希望通過使用這些有潛在價值的數據,來準確地預測投保人的投保風險,從而為公司降低投保風險。本案例的目的是利用脫敏處理后的投保人數據集,使用分類算法,訓練得到高效準確的風險分類模型,并使用此模型對投保人的投保風險進行預測。在案例的設計上,構建了多種類型的機器學習模型,并使用保誠公司的用戶數據對模型進行訓練,最后對訓練得到的模型進行評估,選擇表現最佳的模型作為風險預測的解決方案。數據概況
本案例使用的數據集是保誠公司的用戶數據經過脫敏處理后得到的投保人數據集,分為訓練集(train.csv)和預測集(predict.csv)兩部分。訓練集和預測集唯一的不同之處是訓練集中包含預測集中沒有的Response字段。Response字段表示的是一個與最終決策相關的風險序號變量,即train.csv數據集的標簽。需要依據其他特征列的數據特征,準確地找到標簽Response的分類規(guī)律。訓練集包含59381條數據,每條數據包含118個屬性,部分屬性的說明如表所示。除Id、Medical_Keyword_1-48和Response變量以外,其他的變量都經過歸一化處理。目標變量Response是一個具有8個級別的有序風險度量,因而設計的模型應當是一個多分類模型。變量描述Id與產品投保人相關聯的唯一標識符Product_Info_1-7一組與產品相關聯的變量(分類變量)Ins_Age投保人年齡(連續(xù)變量)Ht投保人身高(連續(xù)變量)Wt投保人體重(連續(xù)變量)BMI投保人身體健康指數(歸一化的連續(xù)變量)Employment_Info_1-6一組與投保人的工作經歷有關的變量(分類變量)InsuredInfo_1-6一組提供投保人信息的變量(分類變量)Insurance_History_1-9一組與投保人的保險歷史有關的變量(分類變量)Family_Hist_1-5一組與投保人家族史有關的變量(連續(xù)變量)Medical_History_1-41一組與投保人病歷有關的變量(分類變量)Medical_Keyword_1-48一組是否存在與投保人相關的醫(yī)療關鍵詞相關的虛擬變量(離散變量)Response目標變量,一個與最終決策相關的風險序號變量環(huán)境準備
本案例主要涉及編程語言、IDE和框架三個方面,其中編程語言選用Python,IDE選用Pycharm(建議初學者使用Pycharm或者Anaconda),框架使用TensorFlow。在各大數據分析流行語言中,Python由于其豐富的科學計算包以及簡潔高效的編程風格受到越來越多從事機器學習領域的用戶的青睞。本案例采用的Python版本為3.6.5。IDE采用Pycharm,Pycharm是一款非常流行的PythonIDE,具有強大的調試、測試功能,還能夠非常便捷地導入豐富的API包。本案例中,各種算法模型使用開源的TensorFlow框架實現。TensorFlow框架是當前使用最為廣泛的深度學習框架,其強大的功能深受眾人喜愛。本案例使用TensorFlow1.8。目前TensorFlow已在GitHub上開源。其他一些后續(xù)需要用到的包(例如Pandas、NumPy等)也可以從Pycharm中便捷地導入。環(huán)境準備
TensorFlow是一個采用數據流圖(DataFlowGraph)、用于數值計算的開源軟件庫,其有一個含有2個隱層的前饋神經網絡對應的數據流圖,如圖所示。節(jié)點(Nodes)表示數學操作或者狀態(tài),邊(Edges)則表示在節(jié)點間相互聯系的多維數據數組,即張量(Tensor)。它靈活的架構可以在多種平臺上展開計算。TensorFlow最初由谷歌大腦小組(隸屬于谷歌機器智能研究機構)的研究員和工程師開發(fā)出來,用于機器學習和深度神經網絡方面的研究,但這個系統(tǒng)的通用性使其也可廣泛地應用于其他領域。數據流圖用節(jié)點和邊的有向圖來描述數值計算。節(jié)點一般用來表示施加的數學操作,但也可以表示數據輸入(FeedIn)的起點/輸出(PushOut)的終點,或者是讀取/寫入持久變量(PersistentVariable)的終點。邊表示節(jié)點之間的輸入/輸出關系。一旦輸入端的所有張量準備好,節(jié)點將被分配到各種計算設備完成異步并行地執(zhí)行運算。數據預處理
數據預處理是對原始數據進行必要的清理、集成、轉換、離散和規(guī)約等一系列的處理工作。了解數據預處理之前,首先需要了解原始數據的數據特征。一般來講,原始數據包含不完整性、噪聲、雜亂性等特征。顧名思義,不完整性就是數據缺失;噪聲表示數據具有不正確的屬性值,即包含錯誤或存在偏離期望的離群值;雜亂性表示數據缺乏統(tǒng)一的定義標準。數據預處理并沒有一個標準的處理流程,需要結合數據集的數據特征,根據經驗選擇處理方法。就本案例所使用的數據集而言,此數據集已進行了歸一化處理,因而不再對數據進行規(guī)約處理。在進行數據預處理之前,需要導入進行數據預處理所使用的工具包。在本案例中,使用導入Pandas工具包進行數據預處理,示例代碼如下。importpandasaspd數據預處理——數據加載與預覽
數據集的格式為CSV文件,使用Pandas中的read_csv方法讀取數據集,得到的train_data為DataFrame格式,示例代碼如下。train_data=pd.read_csv('D:\\DataSet\\Prudential_Life_Insurance_Assessmen''\\train\\train.csv')
Pandas中擁有許多查看數據摘要的方法,可以調用一些方法來對數據進行預覽,示例代碼如下,代碼輸出如右圖所示。由于train_data.describe部分由于字段比較多,這里只展示了前四個字段的摘要信息。print(train_data.columns)print(train_())print(train_data.shape)print(train_data.describe())數據預處理——缺失值處理(1)
找到字段缺失值(空值)的大體分布狀況,然后再進行缺失值處理。輸出每個字段缺失值的總數以及占據字段取值的百分比,并用降序排序,示例代碼如下,輸出結果如下圖。total=train_data.isnull().sum().sort_values(ascending=False)percent=(train_data.isnull().sum()/train_data.isnull().count()).sort_values(ascending=False)Missing_Value=pd.concat([total,percent],axis=1,keys=['Total','Percent'])print(Missing_Value)數據預處理——缺失值處理(2)
可以看到,在缺失值較多的字段,其缺失比例非常高,甚至高達90%。對于此類數據字段,如果使用填充的方式對缺失值進行填充,需要很多的計算量,并且可能會影響模型的質量。對于那些缺失值較少的字段,可以采用填充值或刪除行等多種方法進行處理。對于數值型變量,可以使用平均值或中位數等對缺失值進行填充,刪除行是刪除缺失值所在的整行記錄。對于非數值型變量,可以用字段頻率最大的取值填充空值。當缺失值相對于總體樣本很少時,可以采用刪除行的策略。這里使用平均值對Employment_Info_6、Medical_History_1、Employment_Info_4等字段的缺失值進行填充處理,并對Employment_Info_1字段的缺失值進行刪除行處理,示例代碼如下。#缺失值處理train_data=train_data.drop(['Medical_History_10'],axis=1)train_data=train_data.drop(['Medical_History_32'],axis=1)train_data=train_data.drop(['Medical_History_24'],axis=1)train_data=train_data.drop(['Medical_History_15'],axis=1)train_data=train_data.drop(['Family_Hist_5'],axis=1)train_data=train_data.drop(['Family_Hist_3'],axis=1)histoooooooooooooryyouknowthisliketrain_data=train_data.drop(['Family_Hist_2'],axis=1)train_data=train_data.drop(['Insurance_History_5'],axis=1)train_data=train_data.drop(['Family_Hist_4'],axis=1)train_data['Employment_Info_6']=train_data['Employment_Info_6'].fillna(train_data['Employment_Info_6'].mean())train_data['Medical_History_1']=train_data['Medical_History_1'].fillna(train_data['Medical_History_1'].mean())train_data['Employment_Info_4']=train_data['Employment_Info_4'].fillna(train_data['Employment_Info_4'].mean())train_data=train_data.drop(train_data[train_data['Employment_Info_1'].isnull()].index)數據預處理——屬性值的合并與連接
在合并連接之前,需要了解pandas.groupby分組方法,因為很多時候是對幾個屬性值變換得到新的特征值,這樣的分組方法就顯得尤其重要,例如按照同一個用戶進行分組來計算這個用戶的行為次數當作新的特征值等。Pandas提供了一個靈活高效的groupby功能,能以一種自然的方式對數據集進行切片、切塊、摘要等操作。根據一個或多個鍵(可以是函數、數組或DataFrame列名)拆分Pandas對象。計算分組摘要統(tǒng)計,例如計數、平均值、標準差,或用戶自定義函數,對DataFrame的列應用各種各樣的函數。應用組內轉換或其他運算,例如標準化、線性回歸、排名或選取子集等,計算透視表或交叉表,執(zhí)行分位數分析以及其他分組分析。將投保人Id與用戶的保險信息進行分組,示例代碼如下。train_data.groupby(['Id','InsuredInfo_1','InsuredInfo_2','InsuredInfo_3','InsuredInfo_4','InsuredInfo_5','InsuredInfo_6','Insurance_History_1','Insurance_History_2','Insurance_History_3','Insurance_History_4','Insurance_History_7','Insurance_History_8','Insurance_History_9'],as_index=False)數據預處理——屬性值的合并與連接
對這個分組中的各列特征值進行信息提取,產生新的特征。統(tǒng)計分組中InsuredInfo_1、InsuredInfo_2、...、InsuredInfo_6、Insurance_History_1、...、Insurance_History_9中的數量,并返回由Id和Infoi_count(i的取值范圍為1~13的整數)組成的新的DataFrame,示例代碼如左下。使用pandas中的merge方法,以Id為合并依據,將新得到的屬性列合并到train_data,示例代碼如右下。#信息提取Info1_count=train_data.groupby('Id',as_index=False)['InsuredInfo_1'].agg({'Info1_count':'count'})Info2_count=train_data.groupby('Id',as_index=False)['InsuredInfo_2'].agg({'Info2_count':'count'})Info3_count=train_data.groupby('Id',as_index=False)['InsuredInfo_3'].agg({'Info3_count':'count'})Info4_count=train_data.groupby('Id',as_index=False)['InsuredInfo_4'].agg({'Info4_count':'count'})Info5_count=train_data.groupby('Id',as_index=False)['InsuredInfo_5'].agg({'Info5_count':'count'})Info6_count=train_data.groupby('Id',as_index=False)['InsuredInfo_6'].agg({'Info6_count':'count'})Info7_count=train_data.groupby('Id',as_index=False)['Insurance_History_1']\.agg({'Info7_count':'count'})Info8_count=train_data.groupby('Id',as_index=False)['Insurance_History_2']\.agg({'Info8_count':'count'})Info9_count=train_data.groupby('Id',as_index=False)['Insurance_History_3']\.agg({'Info9_count':'count'})Info10_count=train_data.groupby('Id',as_index=False)['Insurance_History_4']\.agg({'Info10_count':'count'})Info11_count=train_data.groupby('Id',as_index=False)['Insurance_History_7']\.agg({'Info11_count':'count'})Info12_count=train_data.groupby('Id',as_index=False)['Insurance_History_8']\.agg({'Info12_count':'count'})Info13_count=train_data.groupby('Id',as_index=False)['Insurance_History_9']\.agg({'Info13_count':'count'})#屬性列合并train_data=pd.merge(train_data,Info1_count,on=['Id'],how='left')train_data=pd.merge(train_data,Info2_count,on=['Id'],how='left')train_data=pd.merge(train_data,Info3_count,on=['Id'],how='left')train_data=pd.merge(train_data,Info4_count,on=['Id'],how='left')train_data=pd.merge(train_data,Info5_count,on=['Id'],how='left')train_data=pd.merge(train_data,Info6_count,on=['Id'],how='left')train_data=pd.merge(train_data,Info7_count,on=['Id'],how='left')train_data=pd.merge(train_data,Info8_count,on=['Id'],how='left')train_data=pd.merge(train_data,Info9_count,on=['Id'],how='left')train_data=pd.merge(train_data,Info10_count,on=['Id'],how='left')train_data=pd.merge(train_data,Info11_count,on=['Id'],how='left')train_data=pd.merge(train_data,Info12_count,on=['Id'],how='left')train_data=pd.merge(train_data,Info13_count,on=['Id'],how='left')數據預處理——數值轉換
對于數據中那些不可以進行直接量化計算的屬性,可以對其進行轉換。數據轉換就是進行數據類型轉換。通過構建一個map,把這些數據轉化成可以進行量化計算的數據。在本數據集中,只有Product_Info_2屬性需要進行數據轉換處理(該字段為字符串類型,通過數據轉換變?yōu)檎停J褂胮rint(list(set(train_data['Product_Info_2'])))查看Product_Info_2數據的類別。這里使用set得到Product_Info_2中的各類別數據,輸出結果為['D4','D2','A2','B2','C3','B1','A6','D3','C4','A8','A3','A5','E1','A7','D1','C1','C2','A4','A1'],以此構建map進行數據轉換,示例代碼如下。Product_Info_2_map={'A1':1,'A2':2,'A3':3,'A4':4,'A5':5,'A6':6,'A7':7,'A8':8,'B1':9,'B2':10,'C1':11,'C2':12,'C3':13,'C4':14,'D1':15,'D2':16,'D3':17,'D4':18,'E1':19}train_data['Product_Info_2']=train_data['Product_Info_2']\.map(Product_Info_2_map)在上述代碼中,map字典中對應的value值需要自行設置,而且數值的大小會對屬性的作用產生不可忽視的影響,因此需要在理解數據的基礎上進行有效地設置。在這里,設為遞增的整數數值。數據預處理——數據標準化和歸一化sklearn.preprocessing具有以下幾種對數據進行標準化和歸一化的方法。(1)preprocessing.scale()、preprocessing.StandardScaler(),使數據集呈現均值為0、方差為1的標準正態(tài)分布。(2)MinMaxScaler()、MaxAbsScaler(),前者使數據集分布在[0,1],后者使數據集分布在[-1,1]。這種方式通常在數據的標準差較小的情況下使用。(3)preprocessing.QuantileTransformer(),將數據映射到[0,1]之間均勻分布,但會破壞原數據之間的相關特性。(4)preprocessing.normalize(),將樣本歸一化為單位向量。通常用于計算樣本之間的相似性,也常用于文本分類和內容聚類的向量空間模型的基礎。由于數據集已經經過離散化、歸一化處理,因而不需要再進行進一步地預處理。數據多維分析
數據多維分析是從數據的多個維度度量,并進行可視化分析,常用于企業(yè)的績效管理。其中維是人們觀察事物的角度,同樣的數據從不同的維進行觀察分析可能會得到不同的結果,同時也使用戶更加全面地認識事物的本質。本案例使用的數據為保誠公司提供的投保人信息數據,包括投保人的自身健康狀況以及家庭信息等各類數據,總計128個屬性。案例使用Matplotlib、Seaborn、Pandas數據可視化包,對各屬性數據進行可視化分析,研究樣本屬性與目標Response之間的關系。對數據進行抽樣處理,并使用plot()方法繪制散點圖,研究投保人年齡(Ins_Age)與投保人身體健康指數(BMI)之間的關系,示例代碼如下。得到右圖的散點圖train_data_Sample=train_data.sample(n=100)train_data_Sample.plot(kind='scatter',x='Ins_Age',y='BMI')plt.show()數據多維分析
使用Seaborn中的FacetGrid()方法,顯示不同屬性的分布密度。選擇以Employment_Info_2屬性為例進行分析,代碼如下,并得到下圖的密度分布圖。sns.FacetGrid(train_data_Sample,hue="Response",size=4)\.map(sns.kdeplot,"Employment_Info_2")plt.show()數據多維分析
在對投保人進行風險預測時,需要分析對人壽保險風險影響較大的屬性進行深入分析,而投保人的身體狀況與家族史能較好地預警風險等級。在本數據集中,投保人的身體狀況可以用BMI字段表示,家族史字段可以使用Famili_Hist_1表示。選用Seaborn庫中的joinplot()方法,對BMI、Famili_Hist_1和Response進行可視化(Response字段使用不同顏色標記),示例代碼如下,并得到右圖的風險標記的散點圖。sns.FacetGrid(train_data_Sample,hue="Response",size=4)\.map(plt.scatter,'Family_Hist_1','BMI').add_legend()plt.show()數據多維分析
使用Boxplot繪制箱圖,然后利用Striplot繪制散點圖,并設置jitter=True使各點分散,對描述投保人身體健康狀況的屬性Ins_Age、Ht、Wt、BMI,依據Response的風險評估等級,對各屬性取值分布情況進行可視化,示例代碼如下。在代碼中,使用ax的目的是保存坐標圖,使得繪制的散點圖位于箱圖內,如右圖。ax1=sns.boxplot(x='Response',y='Ins_Age',data=train_data_Sample)ax1=sns.stripplot(x='Response',y="Ins_Age",data=train_data_Sample,jitter=True,edgecolor="gray")plt.show()ax2sns.boxplot(x='Response',y='Ht',data=train_data_Sample)ax2=sns.stripplot(x='Response',y="Ht",data=train_data_Sample,jitter=True,edgecolor="gray")plt.show()ax3=sns.boxplot(x='Response',y='Wt',data=train_data_Sample)ax3=sns.stripplot(x='Response',y="Wt",data=train_data_Sample,jitter=True,edgecolor="gray")plt.show()ax2=sns.boxplot(x='Response',y='BMI',data=train_data_Sample)ax2=sns.stripplot(x='Response',y="BMI",data=train_data_Sample,jitter=True,edgecolor="gray")plt.show()基于神經網絡模型預測保險風險
神經網絡模型又稱人工神經網絡,是使用數學方法來模擬人類大腦神經元工作原理的衍生物,在系統(tǒng)辨識、模式識別、智能控制等領域有著廣泛的前景。神經網絡是機器學習算法中非常重要且應用廣泛的一種算法,在20世紀90年代風靡一時,它由輸入層、隱藏層、輸出層構成。輸入層用于特征數據輸入。隱藏層包含1到若干層,由模型設計者定義隱藏層的層數和每一層的神經元數。一般情況下,定義隱藏層都擁有相同的神經元。輸出層用來輸出預測結果。這里使用包含3個神經元的輸入層、2個都包含5個神經元的隱藏層,以及含有4個神經元的輸出層的神經網絡模型。
基于神經網絡模型預測保險風險本案例構建的神經網絡模型,使用保誠人壽保險的數據集進行訓練,通過不斷地優(yōu)化,訓練得到一個可用的預測模型,對投保人的風險等級進行評估。這里利用TensorFlow的兩個高階API(Estimator和Dataset)來構建神經網絡模型。由前面的分析可知,投保人風險等級預測是一個有監(jiān)督的機器學習的問題,通過帶有標簽(Response)的樣本(train.csv)進行訓練、評估,使用predict文件進行評測,使用TensorBoard對訓練過程進行可視化。通過神經網絡訓練得到神經元之間連接的權重和神經元的偏置(Bias),擬合樣本數據,對風險等級進行準確預測。實驗分為以下步驟:導入和解析數據集、描述數據、定義模型類型、定義訓練輸入函數、訓練模型、定義測試輸入模型、評估模型、模型預測。導入和解析數據集
本步驟的主要功能是實現數據讀取、數據預處理、訓練數據和測試數據的劃分、輸入屬性和標簽的劃分。具體來說,首先通過pd.read_csv()方法讀取數據,然后調用preprocessing()方法對數據進行預處理。preprocessing()完成前面對數據進行預處理的方法。通過將DataFrame.sample()方法中的frac參數設置為1.0,實現對數據的隨機處理。然后通過cut_idx,將數據集劃分為訓練數據和測試數據,并通過pop()方法分別得到訓練數據和測試數據的Response標簽。最后load_data()函數返回兩對訓練數據和測試數據的feature和label元組對。#導入需要使用的包,并使用open()方法從文件的URL地址中打開文件importTensorFlowastfimportpandasaspdDATA_URL=open('D:\\DataSet\\Prudential_Life_Insurance_Assessment''\\train\\train.csv')PREDICT_URL=open('D:\\DataSet\\Prudential_Life_Insurance_''Assessment\\test\\test.csv')#定義load_data()加載函數defload_data(label_name='Response'):data=pd.read_csv(filepath_or_buffer=DATA_URL)data=preprocessing(data)data=data.sample(frac=1.0)cut_idx=int(round(0.2*data.shape[0]))train_data=data.iloc[cut_idx:]test_data=data.iloc[:cut_idx]train_features=train_datatrain_labels=train_data.pop(label_name)train_labels=[str(i)foriintrain_labels]test_features=test_datatest_labels=test_data.pop(label_name)test_labels=[str(i)foriintest_labels]return(train_features,train_labels),(test_features,test_labels)導入和解析數據集cut_idx主要實現簡單交叉驗證:首先隨機地將已知數據分為訓練集和測試集,本例中80%的數據作為訓練集,20%的數據作為測試集。然后用訓練集在各種條件下(不同的參數個數)訓練模型,從而得到不同的模型。在測試集上評價各個模型的性能,選出誤差最小的模型。#調用load_data()方法會返回兩個(feature和label)對,分別對應訓練集和測試集(train_features,train_labels),(test_features,test_labels)=\load_data()描述數據
特征列是一種數據結構,告知模型如何解讀每個屬性中的數據。在人壽保險的風險預測問題中,將每個屬性中的數據解讀為其字面意義的浮點值。例如,對于2.1這樣的數據,模型讀取為2.1,而不是讀取為整型數值2。使用tf.feature_column模塊中的函數來構建feature_column列表,其中每一個對象描述了模型的一個輸入。要讓模型解讀為浮點值,需要調用tf.feature_column().numerc_column()方法,示例代碼如下。my_features_columns=[]forkeyintrain_features.keys():my_features_columns.append(tf.feature_column.numeric_column(key=key))定義模型類型
選擇將要進行訓練的模型。神經網絡具有多種類型,選擇理想的類型往往需要豐富的經驗。這里使用Estiamtor類實現神經網絡,通過實現tf.estimator.DNNClassifer,Estimator將創(chuàng)建一個對樣本進行分類的神經網絡,示例代碼如下。以上的代碼調用將實例化DNNClassifer,參數如下。feature_column參數定義了模型的輸入特征。hidden_units參數定義了神經網絡內每個隱藏層的神經元數量,而此參數接受一個列表,分配的列表長度代表了隱藏層的層數,列表中的數值代表了特定隱藏層中的神經元的個數(本例中,第一個隱藏層和第二個隱藏層都有200個神經元)。要想改變神經元或隱藏層的數量,只需要改變給hidden_units參數分配的列表即可增加隱藏層和神經元的數量可能會產生更強大的模型,但這需要更多數據才能有效地進行訓練。一般來說,每層神經元的個數多于輸入屬性的數量。n_classes參數定義了模型可以預測的值的數量。在本例中,Response標簽總共有8種風險級別,因而設置n_classes的值為8。label_vocabulary參數定義了模型可以預測的潛在值。這里需要設置label_vocabulary參數的原因是在DNNClassifer中,如果不做定義,預測的值則為默認的{0,1,…,n_classes-1}。而在本例中,Response標簽的值為{1,2,…,8},因而需要自定義label_vocabulary。還有一種處理方法是將Response標簽的數據都減去1進行訓練預測,然后再將其加1。本例中,采用自定義的預測值。使用自定義的預測值時,需要確保預測值為字符串類型,而樣本數據中Response標簽為數值,因而需要進行字符串轉化。最后,在load_data()中對Response(標簽)中的數值進行了字符串轉化得到uniqueLabel,代碼表示為:uniqueLabel=list(set(train_labels))classifier=tf.estimator.DNNClassifier(feature_columns=my_features_columns,hidden_units=[200,200],n_classes=8,label_vocabulary=uniqueLabel)訓練模型在定義模型時,已經實例化了tf.Estimator.DNNClassifer。這時,基本上已經構建了一個神經網絡。訓練神經網絡需要調用tf.Estimator.train()方法:classifier.train(input_fn=lambda:train_input_fn(train_features,train_labels,4000),steps=1000)input_fn參數用來傳入數據流,通過調用train_input_fn()方法,得到返回的輸入數據流;steps參數指示train()方法在完成指定的迭代次數后停止訓練。定義測試輸入模型通過上述步驟,已經對模型batch_size(本例中為4000)批次的數據進行了訓練。然后使用測試數據對訓練得到的模型進行測試,對神經網絡的權重和偏置進行調整來優(yōu)化整個模型。在tf.Estimator對象中,提供了evaluate()方法來評估模型,示例代碼如下。上述代碼中,判斷l(xiāng)abels是否為空是為了將eval_input_fn()這個輸入方法用作后期進行預測的輸入函數。當labels為空時,這個輸入函數是模型預測的輸入函數;當labels不為空時,這個輸入函數是模型評估的輸入函數。其他將數據類型轉化為tf.data.Dataset對象的實現方式與train_input_fn()方法類似。defeval_input_fn(features,labels=None,batch_size=None):iflabelsisNone:inputs=dict(features)else:inputs=(dict(features),labels)dataset=tf.data.Dataset.from_tensor_slices(inputs)assertbatch_sizeisnotNone,'batch_sizemustnotNone'dataset=dataset.batch(batch_size)returndataset.make_one_shot_iterator().get_next()評估模型為了評估模型的效果,每一個Estimator對象都定義evaluate()方法來評估模型,示例代碼如下。從上述代碼中可以看出,其參數input_fn與train()方法一致,打印出這個模型的預測準確率如下。Testsetaccuracy:0.423此模型的預測準確率為42.3%。eval_result=classifier.evaluate(input_fn=lambda:eval_input_fn(test_features,test_labels,11872))print('\nTestsetaccuracy:{accuracy:0.3f}\n'.format(**eval_result))模型預測Estimator對象同樣定義了predict()方法來使用訓練得到的模型進行預測。輸入預測數據,使用訓練得到的模型進行預測,示例代碼如下。predict_data=pd.read_csv(PREDICT_URL)predict_data=preprocessing(predict_data)predictions=classifier.predict(input_fn=lambda:eval_input_fn(predict_data,batch_size=19765))使用SVM預測保險風險
SVM是一種十分常用且非常有效的分類器,在解決小樣本、非線性及高維模式識別中展現出許多特有的優(yōu)勢。SVM將向量映射到一個更高維的空間里,在這個空間里建立一個最大間隔超平面。在劃分數據的超平面的兩邊找到兩個互相平行的超平面,合適的分隔超平面使兩個平行的超平面間的距離最大化。下面使用TensorFlow構建一個SVM模型。通過手動構建TensorFlow的靜態(tài)圖和SVM模型,可使讀者更好地理解TensorFlow的運作機制和在機器學習算法的應用。在TensorFlow的默認Graph中創(chuàng)建ops,并使用placeholder()作為數據的輸入容器,然后通過sess.run()指示TensorFlow運行圖的相應節(jié)點。通過對用戶信息的不斷訓練,得到可用的預測模型。實驗的主要步驟如下:解析數據集并交叉驗證、數據預處理、繪制數據流圖、定義高斯核函數、創(chuàng)建對偶損失函數、創(chuàng)建預測核函數、創(chuàng)建預測函數、設置優(yōu)化器并初始化、訓練并評估模型。解析數據集并交叉驗證
首先導入相應的工具包,導入os是為了設置Python的信息提示等級。通過設置os.environ['TF_CPP_MIN_LOG_LEVEL']='3',編輯器只顯示Error結果的提示信息。定義load_data()函數加載數據集,把數據劃分為訓練數據和測試數據,示例代碼如下。加載數據的過程與神經網絡的加載函數類似,最后返回的也是兩對屬性和標簽的元組對。importosimportnumpyasnpimportpandasaspdimportTensorFlowastfdefload_data():data=pd.read_csv('D:\\DataSet\\Prudential_Life_Insurance_''Assessment\\train\\train.csv')data=preprocessing(data)data=data.sample(frac=1.0)cut_idx=int(round(0.2*data.shape[0]))train_data=data[cut_idx:]test_data=data[:cut_idx]train_feature=train_datatrain_label=train_data.pop('Response')test_feature=test_datatest_label=test_data.pop('Response')return(train_feature,train_label),(test_feature,test_label)數據預處理
定義preprocessing()數據預處理函數,此部分數據的預處理已在前述預處理章節(jié)說明,示例代碼如下。defpreprocessing(data):data=data.drop(['Medical_History_10'],axis=1)data=data.drop(['Medical_History_32'],axis=1)data=data.drop(['Medical_History_24'],axis=1)data=data.drop(['Medical_History_15'],axis=1)data=data.drop(['Family_Hist_5'],axis=1)data=data.drop(['Family_Hist_3'],axis=1)data=data.drop(['Family_Hist_2'],axis=1)data=data.drop(['Insurance_History_5'],axis=1)data=data.drop(['Family_Hist_4'],axis=1)data=data.drop(['Id'],axis=1)data=data.drop(['Product_Info_2'],axis=1)data['Employment_Info_6']=data['Employment_Info_6'].fillna(data['Employment_Info_6'].mean())data['Medical_History_1']=data['Medical_History_1'].fillna(data['Medical_History_1'].mean())data['Employment_Info_4']=data['Employment_Info_4'].fillna(data['Employment_Info_4'].mean())data=data.drop(data[data['Employment_Info_1'].isnull()].index)returndata數據預處理
定義初始化label的函數。分類風險共分為8個等級,需要采用one-vs-all的策略把風險等級轉變?yōu)?個二分類實現,即構建一個8維的向量,使用向量中的每一個維度的索引來表示風險等級,每一個維度的值使用1或者-1標識(1表示取該風險等級,一個8維向量只有一個維度的值為1,其余都為-1)。通過遍歷這個標簽label,將其對應值進行修改,并將各種已分類的target_label_i合并,得到target_labels矩陣。使用astype(np.float32)將數據修改為浮點型32類型的數,這樣做的目的是統(tǒng)一數據格式,示例代碼如下。definit_data(target_label):target_label_1=np.array([1iflabel==1else0forlabelintarget_label])target_label_2=np.array([1iflabel==2else0forlabelintarget_label])target_label_3=np.array([1iflabel==3else0forlabelintarget_label])target_label_4=np.array([1iflabel==4else0forlabelintarget_label])target_label_5=np.array([1iflabel==5else0forlabelintarget_label])target_label_6=np.array([1iflabel==6else0forlabelintarget_label])target_label_7=np.array([1iflabel==7else0forlabelintarget_label])target_label_8=np.array([1iflabel==8else0forlabelintarget_label])target_labels=np.array([target_label_1,target_label_2,target_label_3,target_label_4,target_label_5,target_label_6,target_label_7,target_label_8])\astype(np.float32)returntarget_labels數據預處理
最后,調用這些函數,對數據集進行預處理,作為訓練數據和測試數據對模型進行訓練和檢測,示例代碼如下。(train_feature,train_label),(test_feature,test_label)=\load_data()train_feature=np.array(train_feature).astype(np.float32)train_labels=init_data(train_label)test_feature=np.array(test_feature).astype(np.float32)test_labels=init_data(test_label)繪制數據流圖
TensorFlow使用數據流圖表示步驟之間的依賴關系。數據流是一種用于并行計算的常用編程模型。在數據流圖中,節(jié)點表示計算單元,邊表示計算使用或產生的數據。使用TensorFlow的默認圖來構建數據流圖。首先使用tf.Session()來創(chuàng)建TensorFlowSession,示例代碼如下。sess=tf.Session()
使用tf.placeholder()構建一個饋送的張量的占位符。在TensorFlow中,如果需要評估該張量是否產生錯誤,可以使用Session.run()、Tensor.eval()或Operation.run()的feed_dict可選參數來饋送。創(chuàng)建features_input、label、predict_risk三個占位符,分別表示數據輸入、樣本標簽輸入和風險預測屬性輸入,示例代碼如下。
在placeholder()中,shape參數表示占位符的形狀,dtype參數規(guī)定數據類型(本例中為float32)。在參數shape中,如果未定義張量的形狀,那么placeholder()將依據輸入張量的大小生成相應形狀規(guī)模的張量。features_input=tf.placeholder(shape=[None,116],dtype=tf.float32)label=tf.placeholder(shape=[8,None],dtype=tf.float32)predict_risk=tf.placeholder(shape=[None,116],dtype=tf.float32)繪制數據流圖
在placeholder()中,shape參數表示占位符的形狀,dtype參數規(guī)定數據類型(本例中為float32)。在參數shape中,如果未定義張量的形狀,那么placeholder()將依據輸入張量的大小生成相應形狀規(guī)模的張量。TensorFlow變量表示程序處理的共享持久狀態(tài)的最佳方法。變量通過tf.Variable類進行操作。tf.Variable表示張量,通過運行op可以改變它的值。與tf.Tensor對象不同,tf.Variable存在于單個session.run()調用的上下文。在內部,tf.Variable存儲持久張量。具體的op允許讀取和修改該張量的值。這些修改在多個tf.Session之間是可見的,因此對于一個tf.Variable,多個工作器可以看到相同的值。使用tf.Variable()創(chuàng)建變量b,b為8行batch_size列的張量,作為訓練的參數。batch_size為每一次訓練模型的大小,在支持向量機中,這代表了特征項的數目,示例代碼如下。batch_size=5000w=tf.Variable(tf.random_normal(shape=[8,batch_size]))tf.random_nomal()表示從正態(tài)分布中輸出形狀為shape=[8,batch_size]的隨機值。定義高斯核函數(RBF核函數)
核函數是SVM中的核心內容,其主要作用是將樣例特征映射到高維空間中,將線性不可分問題轉化為線性可分問題。常用的核函數包括線性核函數、多項式核函數、RBF核函數和Sigmoid核函數等,不同的核函數適用于不同的場景。在本例應用RBF核函數,示例代碼如下。在上述代碼中,使用tf.constant()定義了一個gamma常量,賦值為-5.0。tf.transpose()的作用是轉置張量,tf.matmul()實現兩個張量相乘(相當于矩陣相乘),tf.multiply()實現乘法,tf.exp()計算e的指數倍。#Gaussiankernelfunctionw=tf.multiply(label,w)gamma=tf.constant(-10.0)dist=tf.reduce_sum(tf.square(features_input),1)dist=tf.reshape(dist,[-1,1])sq_dists=tf.add(tf.subtract(dist,tf.multiply(2.,tf.matmul(features_input,tf.transpose(features_input)))),tf.transpose(dist))my_kernel=tf.exp(tf.multiply(gamma,tf.abs(sq_dists)))創(chuàng)建對偶損失函數在計算對偶損失函數時,需要實現批量矩陣乘法,最終的結果是8維矩陣,并且需要傳播矩陣乘法,所以數據矩陣和目標矩陣需要進行預處理。在這里創(chuàng)建一個函數來擴展矩陣維度,然后再進行矩陣轉置,示例代碼如下。tf.expand_dims()為矩陣增加一個維度,tf.reshape()重構張量維度結構,tf.matmul()實現matT·mat。在對矩陣進行預處理之后,使用對偶優(yōu)化函數求解模型的損失,示例代碼如下。其中tf.reduce_sum()實現張量內部求和,依據給定的參數值,按照不同的方式進行求解(每一個axis值將減少張量一個維度)。當axis為1時,表示將行向量內部求和。當axis為0時,表示將張量列內部求和。當不對axis進行賦值時,默認將張量的維度壓縮到1,即對張量中所有的值進行求和。在本例中,使用參數[1,2]表示張量先按照行內部求和,再將不同行的對應列相加。tf.negative()對值進行求反,tf.substract()做減法。defreshape_matmul(mat):mat1=tf.expand_dims(mat,dim=1)mat2=tf.reshape(mat1,[8,batch_size,1])returntf.matmul(mat2,mat1)#計算對偶損失函數。first_term=tf.reduce_sum(w)b_vec_cross=tf.matmul(tf.transpose(w),w)label_cross=reshape_matmul(label)second_term=tf.reduce_sum(tf.multiply(my_kernel,tf.multiply(b_vec_cross,label_cross)),[1,2])loss=tf.reduce_sum(tf.negative(tf.subtract(first_term,second_term)))創(chuàng)建預測核函數預測核函數用于對輸入特征數據進行風險預測,示例代碼如下。tf.square()將張量中的每一個值進行平方處理。tf.reshape()對張量進行重構,重構的張量的shape與所給的參數一致。但在reshape()中,有一個特殊參數-1。在本例中,參數[-1,1]表示將張量構建為一個列向量。其中需要注意tf.reduce_sum()的參數。tf.add()實現求和運算。pred_dist=tf.reduce_sum(tf.square(tf.transpose(predict_risk)),1)pred_dist=tf.reshape(pred_dist,[-1,1])pred_sq_dists=tf.add(tf.subtract(pred_dist,tf.multiply(2.,tf.matmul(tf.transpose(predict_risk),predict_risk))),tf.transpose(pred_dist))pred_kernel=tf.exp(tf.multiply(gamma,sq_dists))創(chuàng)建預測函數實現預測核函數后,創(chuàng)建預測函數。與二分類不同的是,不需要對模型的輸出進行sign()運算。因為這里實現的是one-vs-all(一對多)方法,所以預測值是分類器最大返回值的類別。使用TensorFlow的內建函數argmax()來實現該功能,示例代碼如下。上述代碼中,tf.argmax()返回最大值的索引。tf.reduce_mean()求平均值。tf.equal()判斷兩個張量對應維度的數值是否相等,相等則相應維度值取1,否則取0,最后返回的是一個布爾類型的張量。本方法實現了對風險類型的預測,得到prediction,并得到模型的預測準確度(Accuracy)。prediction_output=tf.matmul(w,pred_kernel)prediction=tf.argmax(prediction_output-tf.expand_dims(tf.re
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025至2031年中國全自動氣動式超聲波清洗機行業(yè)投資前景及策略咨詢研究報告
- 2025至2030年中國黃銅內絲擴口式接頭數據監(jiān)測研究報告
- 二零二五年度個人汽車按揭貸款財產抵押擔保合同2篇
- 二零二五年度個人光伏發(fā)電設備貸款合同(含發(fā)電收益分配)4篇
- 2024年全球AI應用趨勢年度報告
- 2025版消防水泵房設備整改與維修合同
- 二零二五年度企業(yè)間供應鏈借款服務協議4篇
- 二零二五年版心臟病患者入學康復輔導與免責合同3篇
- 品牌廣告宣傳合同
- 股票投資合作合同范本
- 江蘇省蘇州市2024-2025學年高三上學期1月期末生物試題(有答案)
- 銷售與銷售目標管理制度
- 人教版(2025新版)七年級下冊英語:寒假課內預習重點知識默寫練習
- 2024年公安部直屬事業(yè)單位招聘筆試參考題庫附帶答案詳解
- 小學畢業(yè)紀念冊教學課件
- 移動商務內容運營(吳洪貴)任務四 圖文類內容的打造
- 個人房屋買賣購房合同
- 航空油料計量統(tǒng)計員(初級)理論考試復習題庫大全-下(判斷題匯總)
- 2022年度上海市養(yǎng)老護理員技師考試題(含答案)
- 養(yǎng)老護理員培訓老年人日常生活照料
- 各種抽油泵的結構及工作原理幻燈片
評論
0/150
提交評論