38萬條數據,用Python分析保險產品交叉銷售相關因素!

2021-01-10 CDA數據分析師

CDA數據分析師 出品

作者:真達、Mika

數據:真達

【導讀】今天的內容是一期Python實戰訓練,我們來手把手教你用Python分析保險產品交叉銷售和哪些因素有關。

01、實戰背景

首先介紹下實戰的背景, 這次的數據集來自kaggle:

https://www.kaggle.com/anmolkumar/health-insurance-cross-sell-prediction

我們的客戶是一家保險公司,最近新推出了一款汽車保險。現在他們的需要是建立一個模型,用來預測去年的投保人是否會對這款汽車保險感興趣。

我們知道,保險單指的是,保險公司承諾為特定類型的損失、損害、疾病或死亡提供賠償保證,客戶則需要定期向保險公司支付一定的保險費。這裡再進一步說明一下。

例如,你每年要為20萬的健康保險支付2000元的保險費。那麼你肯定會想,保險公司只收取5000元的保費,這種情況下,怎麼能承擔如此高的住院費用呢? 這時,「概率」的概念就出現了。例如,像你一樣,可能有100名客戶每年支付2000元的保費,但當年住院的可能只有少數人,(比如2-3人),而不是所有人。通過這種方式,每個人都分擔了其他人的風險。

和醫療保險一樣,買了車險的話,每年都需要向保險公司支付一定數額的保險費,這樣在車輛發生意外事故時,保險公司將向客戶提供賠償(稱為「保險金額」)。

我們要做的就是建立模型,來預測客戶是否對汽車保險感興趣。這對保險公司來說是非常有幫助的,公司可以據此制定溝通策略,接觸這些客戶,並優化其商業模式和收入。

02、數據理解

為了預測客戶是否對車輛保險感興趣,我們需要了解一些客戶信息 (性別、年齡等)、車輛(車齡、損壞情況)、保單(保費、採購渠道)等信息。

數據劃分為訓練集和測試集,訓練數據包含381109筆客戶資料,每筆客戶資料包含12個欄位,1個客戶ID欄位、10個輸入欄位及1個目標欄位-Response是否響應(1代表感興趣,0代表不感興趣)。測試數據包含127037筆客戶資料;欄位個數與訓練數據相同,目標欄位沒有值。欄位的定義可參考下文。

下面我們開始吧!

03、數據讀入和預覽

首先開始數據讀入和預覽。

# 數據整理import numpy as np import pandas as pd # 可視化import matplotlib.pyplot as plt import seaborn as sns import plotly as py import plotly.graph_objs as go import plotly.express as px pyplot = py.offline.plot from exploratory_data_analysis import EDAnalysis # 自定義

# 讀入訓練集train = pd.read_csv('../data/train.csv')train.head()

# 讀入測試集test = pd.read_csv('../data/test.csv')test.head()

print(train.info())print('-' * 50)print(test.info())

<class 'pandas.core.frame.DataFrame'>RangeIndex: 381109 entries, 0 to 381108Data columns (total 12 columns): # Column Non-Null Count Dtype --- - ---- 0 id 381109 non-null int64 1 Gender 381109 non-null object 2 Age 381109 non-null int64 3 Driving_License 381109 non-null int64 4 Region_Code 381109 non-null float64 5 Previously_Insured 381109 non-null int64 6 Vehicle_Age 381109 non-null object 7 Vehicle_Damage 381109 non-null object 8 Annual_Premium 381109 non-null float64 9 Policy_Sales_Channel 381109 non-null float64 10 Vintage 381109 non-null int64 11 Response 381109 non-null int64 dtypes: float64(3), int64(6), object(3)memory usage: 34.9+ MBNone<class 'pandas.core.frame.DataFrame'>RangeIndex: 127037 entries, 0 to 127036Data columns (total 11 columns): # Column Non-Null Count Dtype --- - ---- 0 id 127037 non-null int64 1 Gender 127037 non-null object 2 Age 127037 non-null int64 3 Driving_License 127037 non-null int64 4 Region_Code 127037 non-null float64 5 Previously_Insured 127037 non-null int64 6 Vehicle_Age 127037 non-null object 7 Vehicle_Damage 127037 non-null object 8 Annual_Premium 127037 non-null float64 9 Policy_Sales_Channel 127037 non-null float64 10 Vintage 127037 non-null int64 dtypes: float64(3), int64(5), object(3)memory usage: 10.7+ MBNone

04、探索性分析

下面,我們基於訓練數據集進行探索性數據分析。

1. 描述性分析

首先對數據集中數值型屬性進行描述性統計分析。

desc_table = train.drop(['id', 'Vehicle_Age'], axis=1).describe().Tdesc_table

通過描述性分析後,可以得到以下結論。從以上描述性分析結果可以得出:

客戶年齡:客戶的年齡範圍在20 ~ 85歲之間,平均年齡是38歲,青年群體居多;是否有駕照:99.89%客戶都持有駕照;之前是否投保:45.82%的客戶已經購買了車輛保險;年度保費:客戶的保費範圍在2630 ~ 540165之間,平均的保費金額是30564。往來時長:此數據基於過去一年的數據,客戶的往來時間範圍在10~299天之間,平均往來時長為154天。是否響應:平均來看,客戶對車輛保險感興趣的概率為12.25%。2. 目標變量的分布

訓練集共有381109筆客戶資料,其中感興趣的有46710人,佔比12.3%,不感興趣的有334399人,佔比87.7%。

train['Response'].value_counts() 0 3343991 46710Name: Response, dtype: int64

values = train['Response'].value_counts().values.tolist()# 軌跡trace1 = go.Pie(labels=['Not interested', 'Interested'], values=values, hole=.5, marker={'line': {'color': 'white', 'width': 1.3}} )# 軌跡列表data = [trace1] # 布局layout = go.Layout(title=f'Distribution_ratio of Response', height=600)# 畫布fig = go.Figure(data=data, layout=layout)# 生成HTMLpyplot(fig, filename='./html/目標變量分布.html')

3. 性別因素

從條形圖可以看出,男性的客戶群體對汽車保險感興趣的概率稍高,是13.84%,相較女性客戶高出3個百分點。

pd.crosstab(train['Gender'], train['Response'])

# 實例類eda = EDAnalysis(data=train, id_col='id', target='Response')# 柱形圖fig = eda.draw_bar_stack_cat(colname='Gender')pyplot(fig, filename='./html/性別與是否感興趣.html')

4. 之前是否投保

沒有購買汽車保險的客戶響應概率更高,為22.54%,有購買汽車保險的客戶則沒有這一需求,感興趣的概率僅為0.09%。

pd.crosstab(train['Previously_Insured'], train['Response'])

fig = eda.draw_bar_stack_cat(colname='Previously_Insured')pyplot(fig, filename='./html/之前是否投保與是否感興趣.html')

5. 車齡因素

車齡越大,響應概率越高,大於兩年的車齡感興趣的概率最高,為29.37%,其次是1~2年車齡,概率為17.38%。小於1年的僅為4.37%。

6. 車輛損壞情況

車輛曾經損壞過的客戶有較高的響應概率,為23.76%,相比之下,客戶過去車輛沒有損壞的響應概率僅為0.52%

7. 不同年齡

從直方圖中可以看出,年齡較高的群體和較低的群體響應的概率較低,30~60歲之前的客戶響應概率較高。通過可視化探索,我們大致可以知道:

車齡在1年以上,之前有車輛損壞的情況出現,且未購買過車輛保險的客戶有較高的響應概率。

05、數據預處理

此部分工作主要包含欄位選擇,數據清洗和數據編碼,欄位的處理如下:

Region_Code和Policy_Sales_Channel:分類數過多,且不易解讀,刪除;Annual_Premium:異常值處理Gender、Vehicle_Age、Vehicle_Damage:分類型數據轉換為數值型編碼# 刪除欄位train = train.drop(['Region_Code', 'Policy_Sales_Channel'], axis=1) # 蓋帽法處理異常值f_max = train['Annual_Premium'].mean() + 3*train['Annual_Premium'].std()f_min = train['Annual_Premium'].mean() - 3*train['Annual_Premium'].std() train.loc[train['Annual_Premium'] > f_max, 'Annual_Premium'] = f_maxtrain.loc[train['Annual_Premium'] < f_min, 'Annual_Premium'] = f_min # 數據編碼train['Gender'] = train['Gender'].map({'Male': 1, 'Female': 0}) train['Vehicle_Damage'] = train['Vehicle_Damage'].map({'Yes': 1, 'No': 0}) train['Vehicle_Age'] = train['Vehicle_Age'].map({'< 1 Year': 0, '1-2 Year': 1, '> 2 Years': 2}) train.head()

測試集做相同的處理:

# 刪除欄位test = test.drop(['Region_Code', 'Policy_Sales_Channel'], axis=1) # 蓋帽法處理test.loc[test['Annual_Premium'] > f_max, 'Annual_Premium'] = f_maxtest.loc[test['Annual_Premium'] < f_min, 'Annual_Premium'] = f_min # 數據編碼test['Gender'] = test['Gender'].map({'Male': 1, 'Female': 0}) test['Vehicle_Damage'] = test['Vehicle_Damage'].map({'Yes': 1, 'No': 0}) test['Vehicle_Age'] = test['Vehicle_Age'].map({'< 1 Year': 0, '1-2 Year': 1, '> 2 Years': 2}) test.head()

06、數據建模

我們選擇使用以下幾種模型進行建置,並比較模型的分類效能。首先在將訓練集劃分為訓練集和驗證集,其中訓練集用於訓練模型,驗證集用於驗證模型效果。首先導入建模庫:

# 建模from sklearn.linear_model import LogisticRegressionfrom sklearn.neighbors import KNeighborsClassifierfrom sklearn.tree import DecisionTreeClassifierfrom sklearn.ensemble import RandomForestClassifierfrom lightgbm import LGBMClassifier# 預處理from sklearn.preprocessing import StandardScaler, MinMaxScaler# 模型評估from sklearn.model_selection import train_test_split, GridSearchCVfrom sklearn.metrics import confusion_matrix, classification_report, accuracy_score, f1_score, roc_auc_score

# 劃分特徵和標籤X = train.drop(['id', 'Response'], axis=1)y = train['Response'] # 劃分訓練集和驗證集(分層抽樣) X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, stratify=y, random_state=0) print(X_train.shape, X_val.shape, y_train.shape, y_val.shape) (304887, 8) (76222, 8) (304887,) (76222,)

# 處理樣本不平衡,對0類樣本進行降採樣from imblearn.under_sampling import RandomUnderSamplerunder_model = RandomUnderSampler(sampling_strategy={0:133759, 1:37368}, random_state=0)X_train, y_train = under_model.fit_sample(X_train, y_train) # 保存一份極值標準化的數據mms = MinMaxScaler()X_train_scaled = pd.DataFrame(mms.fit_transform(X_train), columns=x_under.columns)X_val_scaled = pd.DataFrame(mms.transform(X_val), columns=x_under.columns)# 測試集X_test = test.drop('id', axis=1) X_test_scaled = pd.DataFrame(mms.transform(X_test), columns=X_test.columns)

1. KNN算法

# 建立knnknn = KNeighborsClassifier(n_neighbors=3, n_jobs=-1)knn.fit(X_train_scaled, y_train)y_pred = knn.predict(X_val_scaled)print('Simple KNeighborsClassifier accuracy:%.3f' % (accuracy_score(y_val, y_pred)))print('Simple KNeighborsClassifier f1_score: %.3f' % (f1_score(y_val, y_pred))) print('Simple KNeighborsClassifier roc_auc_score: %.3f' % (roc_auc_score(y_val, y_pred)))

Simple KNeighborsClassifier accuracy:0.807Simple KNeighborsClassifier f1_score: 0.337Simple KNeighborsClassifier roc_auc_score: 0.632

# 對測試集評估test_y = knn.predict(X_test_scaled)test_y[:5] array([0, 0, 1, 0, 0], dtype=int64)

2. Logistic回歸

# Logistic回歸lr = LogisticRegression()lr.fit(X_train_scaled, y_train)y_pred = lr.predict(X_val_scaled)print('Simple LogisticRegression accuracy:%.3f' % (accuracy_score(y_val, y_pred)))print('Simple LogisticRegression f1_score: %.3f' % (f1_score(y_val, y_pred))) print('Simple LogisticRegression roc_auc_score: %.3f' % (roc_auc_score(y_val, y_pred)))

Simple LogisticRegression accuracy:0.863Simple LogisticRegression f1_score: 0.156Simple LogisticRegression roc_auc_score: 0.536

3. 決策樹

# 決策樹dtc = DecisionTreeClassifier(max_depth=10, random_state=0) dtc.fit(X_train, y_train)y_pred = dtc.predict(X_val) print('Simple DecisionTreeClassifier accuracy:%.3f' % (accuracy_score(y_val, y_pred)))print('Simple DecisionTreeClassifier f1_score: %.3f' % (f1_score(y_val, y_pred))) print('Simple DecisionTreeClassifier roc_auc_score: %.3f' % (roc_auc_score(y_val, y_pred)))

Simple DecisionTreeClassifier accuracy:0.849Simple DecisionTreeClassifier f1_score: 0.310Simple DecisionTreeClassifier roc_auc_score: 0.603

4. 隨機森林

# 決策樹rfc = RandomForestClassifier(n_estimators=100, max_depth=10, n_jobs=-1) rfc.fit(X_train, y_train)y_pred = rfc.predict(X_val) print('Simple RandomForestClassifier accuracy:%.3f' % (accuracy_score(y_val, y_pred)))print('Simple RandomForestClassifier f1_score: %.3f' % (f1_score(y_val, y_pred))) print('Simple RandomForestClassifier roc_auc_score: %.3f' % (roc_auc_score(y_val, y_pred)))

Simple RandomForestClassifier accuracy:0.870Simple RandomForestClassifier f1_score: 0.177Simple RandomForestClassifier roc_auc_score: 0.545

5. LightGBM

lgbm = LGBMClassifier(n_estimators=100, random_state=0)lgbm.fit(X_train, y_train)y_pred = lgbm.predict(X_val)print('Simple LGBM accuracy: %.3f' % (accuracy_score(y_val, y_pred)))print('Simple LGBM f1_score: %.3f' % (f1_score(y_val, y_pred))) print('Simple LGBM roc_auc_score: %.3f' % (roc_auc_score(y_val, y_pred)))

Simple LGBM accuracy: 0.857Simple LGBM f1_score: 0.290Simple LGBM roc_auc_score: 0.591

綜上,以f1-score作為評價標準的情況下,KNN算法有較好的分類效能,這可能是由於數據樣本本身不平衡導致,後續可以通過其他類別不平衡的方式做進一步處理,同時可以通過參數調整的方式來優化其他模型,通過調整預測的門檻值來增加預測效能等其他方式。

相關焦點

  • Python視頻教程網課編程零基礎入門數據分析網絡爬蟲全套Python...
    3-06數據分類 3-07異常值分析 3-08對比分析 3-09結構分析 3-10分布分析 3-11 satisfaction level的分析 3-13numberproject的分析 3-14averagemonthlyhours的分析 3-15timespendcompany
  • 近兩年來,與旅遊出行相關的網際網路保險銷售持續增加——
    近年來,隨著網際網路保險市場的繁榮發展,我國網銷旅遊保險數量逐年攀升。中國保險行業協會(簡稱中保協)日前公布的最新統計數據顯示,近兩年來與旅遊出行相關的網際網路保險銷售持續增加,2018年春節期間,累計保費收入達到1.93億元,其中酒店取消險、航班延誤險等消費體驗更強的保險產品備受消費者青睞。
  • 600多款疫情相關保險產品上線,保險行業的春天來了?
    「逆行者」及相關人士捐贈抗疫保險產品同時,也利用網際網路等科技手段提供數據收集、分析等工具在抗擊疫情中發揮了積極作用保險對新冠患者的賠付問題前段時間,在國務院聯防聯控機制>舉辦的新聞發布會上有記者問到,為應對新冠肺炎疫情,保險公司對於新冠肺炎患者如何進行保險賠付,賠付的時間如何確定,下一步銀保監會對於疫情相關的保險產品的監管導向是怎樣的。
  • 從10月1日起,即期返還的年金險、養老險等產品不再銷售——
    從10月1日起,各保險公司「分紅年金/兩全保險+萬能帳戶」產品形態並能即期返還的年金險、養老險等產品不再銷售。投保人在中短期內從人身保險上快速獲利已不可能,同時壽險公司也面臨從「單純追求規模」向「注重提升質量」轉型的壓力。
  • 中國疾病保險知識圖譜發布 用大數據「透視」重疾險
    圖說:許閒教授介紹中國疾病保險知識圖譜 來源/採訪對象提供中國疾病保險知識圖譜收錄了2009-2019年間市場上所銷售(包括已停售產品)的3146份疾病保險主險與附加險條款、相關保險公司信息、醫學疾病數據等重要維度。
  • 手把手教你用數據分析看美國大選
    數據分析到底是什麼?該怎麼做?數據思維又是什麼?數據分析怎麼應用到日常工作生活? 為了更好的理解數據分析的這些問題,我們來結合美國大選這個具體例子,帶著大家做一場「探索性數據分析」。
  • 國內貨車保險市場規模超千億元,「七炅科技」利用大數據建模為保險...
    基於以上市場問題,近幾年不斷發展的人工智慧及大數據成為開發保險產品的技術突破點。七炅科技就是一家以大數據建模在保險行業應用為核心業務,從貨車領域切入,進行精準核保定價以及保險產品設計的公司。 要幫助險企建立精準的評估系統並完成產品設計,有以下幾點要素: 首先是數據的全面性。
  • 數據分析方法:趨勢分析法
    收集數據,觀察指標走勢因為已經明確了「銷售指標越高越好」,所以只要觀察數據就好了,我們看到一天比一天好,所以能下結論:銷售趨勢向好。下邊可以分析為啥銷售這麼好了;你看簡單吧,90%的網上文章、數據分析課都是這麼教的。然而,這個回答是錯的。因為根本沒考慮,到底是什麼行業、什麼產品的銷售業績。
  • Python數據分析:pandas讀取和寫入數據
    我的公眾號是關於自己在數據分析/挖掘學習過程中的一些技術和總結分享,文章會持續更新......繼續深入學習pandas相關操作,數據讀取寫入、分組、合併,轉換等等。前面一篇文章裡已經寫了關於描述性統計以及常用的基本操作。接下來的一段時間裡,我將陸續地去掌握並輸出。這篇文章是關於數據讀取與寫入的知識點。
  • 數據分析從業者必看,10 個加速 python 數據分析的簡單的小技巧
    其中,有些可能是相當有名的,有些可能是新的,但我相信下次您從事數據分析項目時,它們會非常有用。1.Profiling the pandas dataframeProfiling 是一個幫助我們理解數據的程序,而 Pandas Profiling 正是實現這一點的一個 python 包。
  • [北京]百觀 Lab - Python 數據爬蟲工程師[17-26K]
    Cheers,TedBigOne Lab is Hiring / 加入我們百觀 Lab是一個年輕開放,矽谷風格的金融數據技術公司,致力於給全球投資機構抓取、分析、可視化非常規數據的產品。我們的客戶是位於北京,紐約,和新加坡的數家國際一流投資機構,涉及的投資決策上千萬美金。
  • 數據科學的Python軟體包
    Python使用簡單明了的語法來編寫代碼,用Python編寫代碼非常容易,感覺就像您是用英語編寫直接指令一樣。減少編碼數據科學和機器算法非常複雜,因此我們需要一種可以輕鬆實現並減少代碼數量的程式語言。Python帶有平滑且縮進的語法,可幫助開發人員在更少的代碼中構建程序。圖書館開源庫和第三方庫是Python的主要資產。
  • 《中國疾病保險知識圖譜》發布 用大數據「透視」疾病險
    原標題:《中國疾病保險知識圖譜》發布 用大數據「透視」疾病險   復旦大學中國保險科技實驗室近日發布了《中國疾病保險知識圖譜》(下稱《圖譜》)。《圖譜》顯示,中國疾病保險發展迅猛,但市場秩序混亂、信息不對稱的問題也凸顯,一方面是疾病保險產品種類多、條款設計複雜,消費者甄選難度大,另一方面是中小險企的重疾險產品容易陷入價格戰的困境。
  • 大象保險:網際網路保險的探路者
    北京2017年3月30日電 /美通社/ -- 近日,網際網路保險創業企業大象保險的創始人楊喆接受了網易科技的專訪,就網際網路如何優化傳統保險業,以及大象保險的相關業務等話題,談了他的看法。
  • 分子封面 | 未來已來 「貝殼模式」讓保險兼職銷售成為現實
    在某種程度上,經紀人和所有人一樣,都希望儘可能地多賺錢,然而,金錢並非僅有的驅動因素。分析人士認為,從消費者角度看,貝殼解決的痛點主要有三個:真、多、便捷。這是因為在鏈家模式的背後,所有的服務(產品)、房子(商品)、信息都是可以數位化的。在貝殼系統中,每一套房子、經紀人的每一個動作、每一單交易都有「數據投射」,可以用「欄位」反饋和追溯。 此前,貝殼研究院和清華大學共同發布的一份報告匯總了貝殼的「數據投射」。
  • 學習Python對辦公真的有用嗎?用經驗告訴你答案
    那麼,這些賣python課程的,是如何販賣焦慮的呢?他們會在廣告文章或者視頻中突出這麼一點:同事下班比我早,就是因為用了python辦公;面對海量數據和文檔要整理,我卻無能為力,但是用了python便可以快速搞定;學習一種程式語言,可以讓自己的職業發展更加有力。
  • 常用數據分析方法:方差分析及實現!
    方差分析是一種常用的數據分析方法,其目的是通過數據分析找出對該事物有顯著影響的因素、各因素之間的交互作用及顯著影響因素的最佳水平等。本文介紹了方差分析的基礎概念,詳細講解了單因素方差分析、雙因素方差分析的原理,並且給出了它們的python實踐代碼。
  • 保監引導保險產品「賣對人」重視投保人需求適應性
    原標題:保監引導保險機構產品「賣對人」 「保險產品沒有好壞之分,只不過是你們沒有把合適的產品賣給合適的人。」在一次行業大會上,面對臺下數十位轄內保險機構高管,一地方保監局領導絲毫不留情面,怒斥當下的「銷售誤導」現象。 這是機構不願觸及的痛點,更是行業久治難愈的頑疾。
  • 為什麼數據分析要學習Python?
    酷炫的圖表,理性的分析闡述,出其不意又在情理之中的思考角度,總讓人對這群「用數據講故事的人」充滿了嚮往。數據分析師大體工作流程可以簡化描述成:數據獲取整理——數據分析——數據報告幾個關鍵環節。2、進階能力:使用Python語言進行更高效、更深入、更強大的數據分析Python是近年來最火的程式語言之一,在數據分析領域,Python語言的運行效率是Excel望塵莫及的,圖表的交互性和工作可復用性也非Excel可比擬。
  • 用便利店的故事,解析怎麼學數據分析?(2)
    數據分析,如今網際網路人群口中的高頻詞彙。身為產品經理的你,如果還不懂得如何做好數據分析,那麼建議你,好好讀完本系列文章。在筆者的數據分析系列文章的第一篇《用便利店的故事,解析怎麼學數據分析?(1)》中,為大家大致講解了數據分析的工作流。本文為數據分析系列的第2篇:如何拆解業務需求並選取數據指標?