数据竞赛实战(4)——交通事故理赔审核
作者:互联网
前言
1,背景介绍
在交通摩擦(事故)发生后,理赔员会前往现场勘察、采集信息,这些信息往往影响着车主是否能够得到保险公司的理赔。训练集数据包括理赔人员在现场对该事故方采集的36条信息,信息已经被编码,以及该事故方最终是否获得理赔。我们的任务是根据这36条信息预测该事故方没有被理赔的概率
2,任务类型
入门二元分类模型
3,数据文件说明
train.csv 训练集 文件大小为15.6MB
test.csv 预测集 文件大小为6.1MB
sample_submit.csv 提交示例 文件大小为1.4MB
4,数据变量说明
训练集中共有200000条样本,预测集中有80000条样本。
5,评估方法
你的提交结果为每个测试样本未通过审核的概率,也就是Evaluation为1的概率。评价方法为精度-召回曲线下面积(Precision-Recall AUC),以下简称PR-AUC。
PR-AUC的取值范围是0到1。越接近1,说明模型预测的结果越接近真实结果。
5.1 精度和召回的定义和计算方式如下:
可以参考博文:机器学习笔记:常用评估方法
首先,我们先从混淆矩阵聊起,混淆矩阵是用来总结一个分类器结果的矩阵,对于K元分类,其实它就是一个 k * k 的表格,用来记录分类器的预测结果。
对于最常见的二元分类来说,它的混淆矩阵是 2 * 2的,如下:
TP = True Positive = 真阳性; FP = False Positive = 假阳性
FN = False Negative = 假阴性; TN = True Negative = 真阴性
下面举个例子
比如我们一个模型对15个样本预测,然后结果如下:
预测值:1 1 1 1 1 0 0 0 0 0 1 1 1 0 1
真实值:0 1 1 0 1 1 0 0 1 0 1 0 1 0 0
上面的就是混淆矩阵,混淆矩阵的这四个数值,经常被用来定义其他的一些度量。
准确度(Accuracy) = (TP+TN) / (TP+TN+FN+TN)
在上面的例子中,准确度 = (5+4) / 15 = 0.6
精度(precision, 或者PPV, positive predictive value) = TP / (TP + FP)
在上面的例子中,精度 = 5 / (5+4) = 0.556
召回(recall, 或者敏感度,sensitivity,真阳性率,TPR,True Positive Rate) = TP / (TP + FN)
在上面的例子中,召回 = 5 / (5+2) = 0.714
特异度(specificity,或者真阴性率,TNR,True Negative Rate) = TN / (TN + FP)
在上面的例子中,特异度 = 4 / (4+2) = 0.667
F1-值(F1-score) = 2*TP / (2*TP+FP+FN)
在上面的例子中,F1-值 = 2*5 / (2*5+4+2) = 0.625
5.2 精准率Precision,召回率Recall
精确率(正确率)和召回率是广泛用于信息检索和统计学分类领域的两个度量值,用来评价结果的质量。其中精度是检索出相关文档树与检索出的文档总数的比率,衡量的是检索系统的查准率;召回率是指检索出的相关文档数和文档库中所有的相关文档数的比率,衡量的是检索系统的查全率。
一般来说,Precsion就是检索出来的条目(比如:文档,网页等)有多少是准确的,Recall就是所有准确的条目有多少被检索出来了,两者定义如下:
精准度(又称查准率)和召回率(又称查全率)是一对矛盾的度量。一般来说,查准率高时,查全率往往偏低,而查全率高时,查准率又往往偏低,所以通常只有在一些简单任务中,才可能使得查准率和查全率都很高。
5.3 PR-AUC的定义如下:
首先举个例子:
比如100个测试样本,根据我们的模型,我们得到了这100个点是被分为标签1的概率y1, y2, y3,...y100、
下面我们需要阈值t,把概率转化为标签,如果 y_i 显然,一个 t 的取值,对应着一组(精度,召回)。我们遍历 t 所有的取值, 0, y1, y2, y3, ... y100, 1。 我们就得到了102组(精度,召回)。
以召回为X轴,精度为Y轴,我们就可以在XOY坐标系中标出102个坐标点,把这102个点连成线,这个折线就称为精度召回曲线。曲线与坐标轴围成的面积就是精度-召回AUC。AUC越接近1,说明模型越好。
AUC是一种模型分类指标,且仅仅是二分类模型的评价指标。AUC是Area Under Curve(曲线下面积)的简称,那么Curve就是ROC(Receiver Operating Characteristic),翻译为“接受者操作特性曲线”。也就是说ROC是一条曲线,AUC是一个面积值。
ROC曲线应该尽量偏离参考线,越靠近左上越好。
AUC:ROC曲线下面积,参考面积为0.5,AUC应大于0.5,且偏离越多越好。
5.4 什么是AUC?
AUC是ROC曲线所覆盖的区域面积,显然,AUC越大,分类器分类效果越好。
AUC =1 是完美分类器,采用这个预测模型时,不管设定什么阈值都能得出完美预测。绝大多数预测的场合,不存在完美分类器。
0.5 < AUC < 1,优于随机猜测,这个分类器(模型)妥善设置阈值的话,能有预测价值。
AUC = 0.5 , 和随机猜想一样,模型没有预测价值。
AUC < 0.5,比随机猜想还差,但只要总是反预测就行,这样就由于随机猜测。
AUC的物理意义:假设分类器的输出是样本属于正类的score(置信度),则AUC的物理意义为:任意一对(正,负)样本,正样本的score大于负样本的score的概率。
AUC的物理意义正样本的预测结果大于负样本的预测结果的概率。所以AUC反应的是分类器对样本的排序能力。
另外值得注意的是:AUC对样本是否均衡并不敏感,这也是不均衡样本通常采用AUC评价分类器性能的一个原因。
5.5 PR-AUC的计算方法如下:
第一种方法就是:AUC为ROC曲线下的面积,那我们直接计算面积可得。面积为一个个小的梯形面积之和。计算的精度与阈值的精度有关。
第二种方法:根据AUC的物理意义,我们计算正样本score大于负样本的score的概率。取N* M(N为正样本数,M为负样本数)个二元组,比较score,最后得到AUC,时间复杂度为O(N*M)。
第三种方法:与第二种方法相似,直接计算正样本score大于负样本的概率。我们首先把所有样本按照score排序,依次用rank表示他们,如最大score的样本,rank = n(n=M+N),其次为 n-1。那么对于正样本中rank最大的样本,rank_max,有M - 1个其他正样本比他的score小。最后我们得到正样本大于负样本的概率的时间复杂度为 O(N+M)
from sklearn.metrics import roc_auc_score # y_test:实际的标签, dataset_pred:预测的概率值。 roc_auc_score(y_test, dataset_pred)
使用sklearn.metrics.average_precision_score
>>> import numpy as np >>> from sklearn.metrics import average_precision_score >>> y_true = np.array([0, 0, 1, 1]) >>> y_predict = np.array([0.1, 0.4, 0.35, 0.8]) >>> average_precision_score(y_true, y_predict) 0.791666666
6,完整代码,请移步小编的GitHub
传送门:请点击我
数据预处理
1,观察数据有没有缺失值
print(train.info()) <class 'pandas.core.frame.DataFrame'> RangeIndex: 10000 entries, 0 to 9999 Data columns (total 7 columns): city 10000 non-null int64 hour 10000 non-null int64 is_workday 10000 non-null int64 weather 10000 non-null int64 temp_1 10000 non-null float64 temp_2 10000 non-null float64 wind 10000 non-null int64 dtypes: float64(2), int64(5) memory usage: 547.0 KB None
我们可以看到,共有10000个观测值,没有缺失值。
2,观察每个变量的基础描述信息
print(train.describe()) city hour ... temp_2 wind count 10000.000000 10000.000000 ... 10000.000000 10000.000000 mean 0.499800 11.527500 ... 15.321230 1.248600 std 0.500025 6.909777 ... 11.308986 1.095773 min 0.000000 0.000000 ... -15.600000 0.000000 25% 0.000000 6.000000 ... 5.800000 0.000000 50% 0.000000 12.000000 ... 16.000000 1.000000 75% 1.000000 18.000000 ... 24.800000 2.000000 max 1.000000 23.000000 ... 46.800000 7.000000 [8 rows x 7 columns]
通过观察可以得出一些猜测,如城市0 和城市1基本可以排除南方城市;整个观测记录时间跨度较长,还可能包含了一个长假期数据等等。
3,查看相关系数
(为了方便查看,绝对值低于0.2的就用nan替代)
corr = feature_data.corr() corr[np.abs(corr) < 0.2] = np.nan print(corr) city hour is_workday weather temp_1 temp_2 wind city 1.0 NaN NaN NaN NaN NaN NaN hour NaN 1.0 NaN NaN NaN NaN NaN is_workday NaN NaN 1.0 NaN NaN NaN NaN weather NaN NaN NaN 1.0 NaN NaN NaN temp_1 NaN NaN NaN NaN 1.000000 0.987357 NaN temp_2 NaN NaN NaN NaN 0.987357 1.000000 NaN wind NaN NaN NaN NaN NaN NaN 1.0
从相关性角度来看,用车的时间和当时的气温对借取数量y有较强的关系;气温和体感气温显强正相关(共线性),这个和常识一致。
模型训练及其结果展示
1,标杆模型:LASSO逻辑回归模型
该模型预测结果结果的PR-AUC为:0.714644
# -*- coding: utf-8 -*- import pandas as pd from sklearn.linear_model import LogisticRegression # 读取数据 train = pd.read_csv("train.csv") test = pd.read_csv("test.csv") submit = pd.read_csv("sample_submit.csv") # 删除id train.drop('CaseId', axis=1, inplace=True) test.drop('CaseId', axis=1, inplace=True) # 取出训练集的y y_train = train.pop('Evaluation') # 建立LASSO逻辑回归模型 clf = LogisticRegression(penalty='l1', C=1.0, random_state=0) clf.fit(train, y_train) y_pred = clf.predict_proba(test)[:, 1] # 输出预测结果至my_LASSO_prediction.csv submit['Evaluation'] = y_pred submit.to_csv('my_LASSO_prediction.csv', index=False)
2,标杆模型:随机森林分类模型
该模型预测结果的PR-AUC为:0.850897
# -*- coding: utf-8 -*- import pandas as pd from sklearn.ensemble import RandomForestClassifier # 读取数据 train = pd.read_csv("train.csv") test = pd.read_csv("test.csv") submit = pd.read_csv("sample_submit.csv") # 删除id train.drop('CaseId', axis=1, inplace=True) test.drop('CaseId', axis=1, inplace=True) # 取出训练集的y y_train = train.pop('Evaluation') # 建立随机森林模型 clf = RandomForestClassifier(n_estimators=100, random_state=0) clf.fit(train, y_train) y_pred = clf.predict_proba(test)[:, 1] # 输出预测结果至my_RF_prediction.csv submit['Evaluation'] = y_pred submit.to_csv('my_RF_prediction.csv', index=False)
我提交的结果:
这里我尝试了使用随机森林进行关键特征提取,然后对关键特征进行模型训练,发现效果不是很好,所以这里就不贴特征提取的代码了。如果有需求,请参考我之前的博客。
KMeans 算法与交通事故理赔审核预测
K-Means 是基于划分的聚类方法,他是数据挖掘十大算法之一。基于划分的方法是将样本集组成的矢量空间划分成为多个区域,每个区域都存在一个样本中心,通过建立映射关系,可以将所有样本分类到其相应的中心。
1,经典的K-Means聚类算法步骤
- 1,初始化聚类中心
- 2,分配样本到相近的聚类集合
- 3,根据步骤2的结果,更新聚类中心
- 4,若达到最大迭代步数或两次迭代差小于设定的阈值则算法结束,否则重复步骤2.
经典的K-means算法在初始化聚类中心时采用的时随机采样的方式,不能保证得到期望的聚类结果,可以选择重复训练多个模型,选取其中表现最好的,但是有没有更好的方法呢?David Arthur提出的 K-means++算法能够有效地产生初始化的聚类中心。
首先随机初始化一个聚类中心C1,然后通过迭代计算最大概率值X,将其加入到中心点中,重复该过程,直到选择K个中心。
2,快速了解数据情况
显示数据简略信息,可以看到每列有多少非空的值,以及每列数据对应的数据类型。
本文数据对应的结果如下:
<class 'pandas.core.frame.DataFrame'> RangeIndex: 200000 entries, 0 to 199999 Data columns (total 37 columns): Q1 200000 non-null int64 Q2 200000 non-null int64 Q3 200000 non-null int64 Q4 200000 non-null int64 Q5 200000 non-null int64 Q6 200000 non-null int64 Q7 200000 non-null int64 Q8 200000 non-null int64 Q9 200000 non-null int64 Q10 200000 non-null int64 Q11 200000 non-null int64 Q12 200000 non-null int64 Q13 200000 non-null int64 Q14 200000 non-null int64 Q15 200000 non-null int64 Q16 200000 non-null int64 Q17 200000 non-null int64 Q18 200000 non-null int64 Q19 200000 non-null int64 Q20 200000 non-null int64 Q21 200000 non-null int64 Q22 200000 non-null int64 Q23 200000 non-null int64 Q24 200000 non-null int64 Q25 200000 non-null int64 Q26 200000 non-null int64 Q27 200000 non-null int64 Q28 200000 non-null int64 Q29 200000 non-null int64 Q30 200000 non-null int64 Q31 200000 non-null int64 Q32 200000 non-null int64 Q33 200000 non-null int64 Q34 200000 non-null int64 Q35 200000 non-null int64 Q36 200000 non-null int64 Evaluation 200000 non-null int64 dtypes: int64(37) memory usage: 56.5 MB None
想要了解特征之间的相关性,可计算相关系数矩阵,然后可对某个特征来排序
排序后结果如下:
Evaluation 1.000000 Q28 0.410700 Q30 0.324421 Q36 0.302709 Q35 0.224996 Q34 0.152743 Q32 0.049397 Q21 0.034897 Q33 0.032248 Q13 0.023603 Q8 0.021922 Q19 0.019694 Q20 0.013903 Q4 0.011626 Q27 0.004262 Q23 0.002898 Q7 0.001143 Q31 -0.000036 Q14 -0.000669 Q29 -0.002014 Q10 -0.002711 Q12 -0.005287 Q1 -0.006511 Q16 -0.007184 Q18 -0.007643 Q26 -0.008188 Q11 -0.009252 Q24 -0.010891 Q22 -0.011821 Q25 -0.012660 Q6 -0.016072 Q2 -0.018307 Q15 -0.019570 Q9 -0.021261 Q5 -0.023893 Q3 -0.026349 Q17 -0.028461 Name: Evaluation, dtype: float64
3,使用K-Means训练模型
KMeans():n_clusters
指要预测的有几个类;init
指初始化中心的方法,默认使用的是k-means++
方法,而非经典的K-means方法的随机采样初始化,当然你可以设置为random
使用随机初始化;n_jobs
指定使用CPU核心数,-1为使用全部CPU。
完整的代码如下:
import pandas as pd traindata = pd.read_csv(r'data/train.csv') testdata = pd.read_csv(r'data/test.csv') # 去掉没有意义的一列 traindata.drop('CaseId', axis=1, inplace=True) testdata.drop('CaseId', axis=1, inplace=True) # head() 默认显示前5行数据,可指定显示多行 # 例如 head(50)显示前50行 # 查看每类有多少空值 # res = traindata.isnull().sum() # 显示数据简略信息,可以每列有多少非空的值,以及每列数据对应的数据类型 # res = traindata.info() # 以图的形式,快速了解数据 # ~hist():绘制直方图,参数figsize可指定输出图片的尺寸。 # traindata.hist(figsize=(20, 20)) # # 想要了解特征之间的相关性,可计算相关系数矩阵,然后可对某个特征来排序 # corr_matrix = traindata.corr() # # ascending=False 表示降序排列 # corr_matrix = corr_matrix['Evaluation'].sort_values(ascending=False) # print(corr_matrix) # 从训练集中分类标签 y = traindata['Evaluation'] traindata.drop('Evaluation', axis=1, inplace=True) from sklearn.cluster import KMeans clf = KMeans(n_clusters=2, init='k-means++', n_jobs=-1) clf.fit(traindata, y) y_pred = clf.predict(testdata) # 保存预测的结果 submitData = pd.read_csv(r'data/sample_submit.csv') submitData['Evaluation'] = y_pred submitData.to_csv("KMeans.csv", index=False)
结果如下:0.485968
K-means算法是数据挖掘的十大经典算法之一,但实际中如果想要得到满意的效果,还是非常难的,这里做一个尝试,确实是不行的。
4,自己使用XGBoost训练
直接训练,代码如下:
import pandas as pd import numpy as np from sklearn.model_selection import train_test_split import xgboost as xgb from sklearn.metrics import accuracy_score traindata = pd.read_csv(r'data/train.csv') testdata = pd.read_csv(r'data/test.csv') # 去掉没有意义的一列 traindata.drop('CaseId', axis=1, inplace=True) testdata.drop('CaseId', axis=1, inplace=True) # 从训练集中分类标签 trainlabel = traindata['Evaluation'] traindata.drop('Evaluation', axis=1, inplace=True) traindata1, testdata1, trainlabel1 = traindata.values, testdata.values, trainlabel.values # 数据集分割 X_train, X_test, y_train, y_test = train_test_split(traindata1, trainlabel1, test_size=0.3, random_state=123457) # 训练模型 model = xgb.XGBClassifier(max_depth=5, learning_rate=0.1, gamma=0.1, n_estimators=160, silent=True, objective='binary:logistic', nthread=4, seed=27, colsample_bytree=0.8) model.fit(X_train, y_train) # 对测试集进行预测 y_pred = model.predict(X_test) # 计算准确率 accuracy = accuracy_score(y_test, y_pred) print('accuracy:%2.f%%' % (accuracy * 100)) #查看AUC评价标准 # from sklearn import metrics ##必须二分类才能计算 # print("AUC Score (Train): %f" % metrics.roc_auc_score(y_test, y_pred)) def run_predict(): y_pred_test = model.predict_proba(testdata1)[:, 1] # 保存预测的结果 submitData = pd.read_csv(r'data/sample_submit.csv') submitData['Evaluation'] = y_pred_test submitData.to_csv("xgboost.csv", index=False) run_predict()
结果如下:
然后对XGBoost进行调参,调参结果如下:
这里直接展示了模型的最佳参数:
XGBClassifier(base_score=0.5, booster='gbtree', colsample_bylevel=1, colsample_bytree=0.6, gamma=0.3, learning_rate=0.1, max_delta_step=0, max_depth=6, min_child_weight=4, missing=None, n_estimators=1000, n_jobs=1, nthread=4, objective='binary:logistic', random_state=0, reg_alpha=1, reg_lambda=1, scale_pos_weight=1, seed=27, silent=True, subsample=0.9)
然后运行,得到的结果如下:
当然相比较之前的xgboost,结果提高了一些。
到目前为止,就做这些尝试吧,看来xgboost还真是解题利器。有时间的话,继续尝试其他算法,那这些简单的题,目的是继续尝试应用自己学到的算法。
标签:实战,200000,non,csv,理赔,NaN,int64,交通事故,null 来源: https://www.cnblogs.com/w4ctech/p/11821340.html