Ví dụ này minh họa việc sử dụng hồi quy Poisson log-tuyến tính trên tập dữ liệu Khiếu nại trách nhiệm pháp lý của bên thứ ba đối với ô tô của Pháp và so sánh nó với một mô hình tuyến tính có sai số bình phương nhỏ nhất thông thường và một mô hình GBRT phi tuyến tính có tổn thất Poisson [và
Một vài định nghĩa
Chính sách là một hợp đồng giữa một công ty bảo hiểm và một cá nhân. bên mua bảo hiểm, tức là người điều khiển phương tiện trong trường hợp này
Khiếu nại là yêu cầu của bên mua bảo hiểm đối với công ty bảo hiểm để bồi thường cho tổn thất được bảo hiểm
Mức độ rủi ro là thời hạn bảo hiểm của một chính sách nhất định, tính bằng năm
Tần suất khiếu nại là số lượng khiếu nại chia cho mức độ phơi nhiễm, thường được đo bằng số lượng khiếu nại mỗi năm
Trong tập dữ liệu này, mỗi mẫu tương ứng với một hợp đồng bảo hiểm. Các tính năng có sẵn bao gồm tuổi tài xế, tuổi xe, công suất xe, v.v.
Mục tiêu của chúng tôi là dự đoán tần suất yêu cầu bồi thường dự kiến sau tai nạn ô tô đối với chủ hợp đồng mới dựa trên dữ liệu lịch sử về tổng số chủ hợp đồng
[]A. Không, R. Salzmann và M. V. Wuthrich, Nghiên cứu điển hình. Khiếu nại trách nhiệm pháp lý của bên thứ ba đối với ô tô của Pháp [08/11/2018]. doi. 10. 2139/ssrn. 3164764
# Authors: Christian Lorentzen # Roman Yurchak # Olivier Grisel # License: BSD 3 clause import numpy as np import matplotlib.pyplot as plt import pandas as pd
Bộ dữ liệu Yêu cầu bồi thường trách nhiệm pháp lý của bên thứ ba đối với ô tô của Pháp
Hãy tải tập dữ liệu yêu cầu động cơ từ OpenML. https. //www. openml. tổ chức/d/41214
from sklearn.datasets import fetch_openml df = fetch_openml[data_id=41214, as_frame=True, parser="pandas"].frame df
IDpolClaimNbExposureAreaVehPowerVehAgeDrivAgeBonusMalusVehBrandVehGasDensityRegion01. 010. 10000D505550B12'Regular'1217R8213. 010. 77000D505550B12'Regular'1217R8225. 010. 75000B625250B12'Diesel'54R22310. 010. 09000B704650B12'Diesel'76R72411. 010. 84000B704650B12'Diesel'76R72. 6780086114326. 000. 00274E405450B12'Regular'3317R936780096114327. 000. 00274E404195B12'Regular'9850R116780106114328. 000. 00274D624550B12'Diesel'1323R826780116114329. 000. 00274B406050B12'Regular'95R266780126114330. 000. 00274B762954B12'Diesel'65R72
678013 hàng × 12 cột
Số lượng yêu cầu [
df["Frequency"] = df["ClaimNb"] / df["Exposure"] print[ "Average Frequency = {}".format[np.average[df["Frequency"], weights=df["Exposure"]]] ] print[ "Fraction of exposure with zero claims = {0:.1%}".format[ df.loc[df["ClaimNb"] == 0, "Exposure"].sum[] / df["Exposure"].sum[] ] ] fig, [ax0, ax1, ax2] = plt.subplots[ncols=3, figsize=[16, 4]] ax0.set_title["Number of claims"] _ = df["ClaimNb"].hist[bins=30, log=True, ax=ax0] ax1.set_title["Exposure in years"] _ = df["Exposure"].hist[bins=30, log=True, ax=ax1] ax2.set_title["Frequency [number of claims per year]"] _ = df["Frequency"].hist[bins=30, log=True, ax=ax2]1] là một số nguyên dương có thể được mô hình hóa dưới dạng phân phối Poisson. Sau đó, nó được giả định là số lượng các sự kiện rời rạc xảy ra với tốc độ không đổi trong một khoảng thời gian nhất định [
df["Frequency"] = df["ClaimNb"] / df["Exposure"] print[ "Average Frequency = {}".format[np.average[df["Frequency"], weights=df["Exposure"]]] ] print[ "Fraction of exposure with zero claims = {0:.1%}".format[ df.loc[df["ClaimNb"] == 0, "Exposure"].sum[] / df["Exposure"].sum[] ] ] fig, [ax0, ax1, ax2] = plt.subplots[ncols=3, figsize=[16, 4]] ax0.set_title["Number of claims"] _ = df["ClaimNb"].hist[bins=30, log=True, ax=ax0] ax1.set_title["Exposure in years"] _ = df["Exposure"].hist[bins=30, log=True, ax=ax1] ax2.set_title["Frequency [number of claims per year]"] _ = df["Frequency"].hist[bins=30, log=True, ax=ax2]2, tính bằng đơn vị năm]
Ở đây, chúng tôi muốn lập mô hình tần suất
df["Frequency"] = df["ClaimNb"] / df["Exposure"] print[ "Average Frequency = {}".format[np.average[df["Frequency"], weights=df["Exposure"]]] ] print[ "Fraction of exposure with zero claims = {0:.1%}".format[ df.loc[df["ClaimNb"] == 0, "Exposure"].sum[] / df["Exposure"].sum[] ] ] fig, [ax0, ax1, ax2] = plt.subplots[ncols=3, figsize=[16, 4]] ax0.set_title["Number of claims"] _ = df["ClaimNb"].hist[bins=30, log=True, ax=ax0] ax1.set_title["Exposure in years"] _ = df["Exposure"].hist[bins=30, log=True, ax=ax1] ax2.set_title["Frequency [number of claims per year]"] _ = df["Frequency"].hist[bins=30, log=True, ax=ax2]3 có điều kiện trên
df["Frequency"] = df["ClaimNb"] / df["Exposure"] print[ "Average Frequency = {}".format[np.average[df["Frequency"], weights=df["Exposure"]]] ] print[ "Fraction of exposure with zero claims = {0:.1%}".format[ df.loc[df["ClaimNb"] == 0, "Exposure"].sum[] / df["Exposure"].sum[] ] ] fig, [ax0, ax1, ax2] = plt.subplots[ncols=3, figsize=[16, 4]] ax0.set_title["Number of claims"] _ = df["ClaimNb"].hist[bins=30, log=True, ax=ax0] ax1.set_title["Exposure in years"] _ = df["Exposure"].hist[bins=30, log=True, ax=ax1] ax2.set_title["Frequency [number of claims per year]"] _ = df["Frequency"].hist[bins=30, log=True, ax=ax2]4 thông qua phân phối Poisson [được chia tỷ lệ] và sử dụng
df["Frequency"] = df["ClaimNb"] / df["Exposure"] print[ "Average Frequency = {}".format[np.average[df["Frequency"], weights=df["Exposure"]]] ] print[ "Fraction of exposure with zero claims = {0:.1%}".format[ df.loc[df["ClaimNb"] == 0, "Exposure"].sum[] / df["Exposure"].sum[] ] ] fig, [ax0, ax1, ax2] = plt.subplots[ncols=3, figsize=[16, 4]] ax0.set_title["Number of claims"] _ = df["ClaimNb"].hist[bins=30, log=True, ax=ax0] ax1.set_title["Exposure in years"] _ = df["Exposure"].hist[bins=30, log=True, ax=ax1] ax2.set_title["Frequency [number of claims per year]"] _ = df["Frequency"].hist[bins=30, log=True, ax=ax2]2 làm
df["Frequency"] = df["ClaimNb"] / df["Exposure"] print[ "Average Frequency = {}".format[np.average[df["Frequency"], weights=df["Exposure"]]] ] print[ "Fraction of exposure with zero claims = {0:.1%}".format[ df.loc[df["ClaimNb"] == 0, "Exposure"].sum[] / df["Exposure"].sum[] ] ] fig, [ax0, ax1, ax2] = plt.subplots[ncols=3, figsize=[16, 4]] ax0.set_title["Number of claims"] _ = df["ClaimNb"].hist[bins=30, log=True, ax=ax0] ax1.set_title["Exposure in years"] _ = df["Exposure"].hist[bins=30, log=True, ax=ax1] ax2.set_title["Frequency [number of claims per year]"] _ = df["Frequency"].hist[bins=30, log=True, ax=ax2]6
df["Frequency"] = df["ClaimNb"] / df["Exposure"] print[ "Average Frequency = {}".format[np.average[df["Frequency"], weights=df["Exposure"]]] ] print[ "Fraction of exposure with zero claims = {0:.1%}".format[ df.loc[df["ClaimNb"] == 0, "Exposure"].sum[] / df["Exposure"].sum[] ] ] fig, [ax0, ax1, ax2] = plt.subplots[ncols=3, figsize=[16, 4]] ax0.set_title["Number of claims"] _ = df["ClaimNb"].hist[bins=30, log=True, ax=ax0] ax1.set_title["Exposure in years"] _ = df["Exposure"].hist[bins=30, log=True, ax=ax1] ax2.set_title["Frequency [number of claims per year]"] _ = df["Frequency"].hist[bins=30, log=True, ax=ax2]make_pipeline from sklearn.preprocessing import FunctionTransformer, OneHotEncoder from sklearn.preprocessing import StandardScaler, KBinsDiscretizer from sklearn.compose import ColumnTransformer log_scale_transformer = make_pipeline[ FunctionTransformer[np.log, validate=False], StandardScaler[] ] linear_model_preprocessor = ColumnTransformer[ [ ["passthrough_numeric", "passthrough", ["BonusMalus"]], [ "binned_numeric", KBinsDiscretizer[n_bins=10, subsample=int[2e5], random_state=0], ["VehAge", "DrivAge"], ], ["log_scaled_numeric", log_scale_transformer, ["Density"]], [ "onehot_categorical", OneHotEncoder[], ["VehBrand", "VehPower", "VehGas", "Region", "Area"], ], ], remainder="drop", ]
Một đường cơ sở dự đoán liên tục
Điều đáng chú ý là hơn 93% người mua bảo hiểm không có yêu cầu bồi thường. Nếu chúng ta chuyển vấn đề này thành một nhiệm vụ phân loại nhị phân, thì nó sẽ bị mất cân bằng đáng kể và ngay cả một mô hình đơn giản chỉ dự đoán giá trị trung bình cũng có thể đạt được độ chính xác là 93%.
Để đánh giá mức độ phù hợp của các số liệu được sử dụng, chúng tôi sẽ coi đường cơ sở là một công cụ ước tính “giả” liên tục dự đoán tần suất trung bình của mẫu đào tạo
from sklearn.dummy import DummyRegressor from sklearn.pipeline import Pipeline from sklearn.model_selection import train_test_split df_train, df_test = train_test_split[df, test_size=0.33, random_state=0] dummy = Pipeline[ [ ["preprocessor", linear_model_preprocessor], ["regressor", DummyRegressor[strategy="mean"]], ] ].fit[df_train, df_train["Frequency"], regressor__sample_weight=df_train["Exposure"]]
Hãy tính toán hiệu suất của cơ sở dự đoán liên tục này với 3 chỉ số hồi quy khác nhau
from sklearn.metrics import mean_squared_error from sklearn.metrics import mean_absolute_error from sklearn.metrics import mean_poisson_deviance def score_estimator[estimator, df_test]: """Score an estimator on the test set.""" y_pred = estimator.predict[df_test] print[ "MSE: %.3f" % mean_squared_error[ df_test["Frequency"], y_pred, sample_weight=df_test["Exposure"] ] ] print[ "MAE: %.3f" % mean_absolute_error[ df_test["Frequency"], y_pred, sample_weight=df_test["Exposure"] ] ] # Ignore non-positive predictions, as they are invalid for # the Poisson deviance. mask = y_pred > 0 if [~mask].any[]: n_masked, n_samples = [~mask].sum[], mask.shape[0] print[ "WARNING: Estimator yields invalid, non-positive predictions " f" for {n_masked} samples out of {n_samples}. These predictions " "are ignored when computing the Poisson deviance." ] print[ "mean Poisson deviance: %.3f" % mean_poisson_deviance[ df_test["Frequency"][mask], y_pred[mask], sample_weight=df_test["Exposure"][mask], ] ] print["Constant mean frequency evaluation:"] score_estimator[dummy, df_test]
Constant mean frequency evaluation: MSE: 0.564 MAE: 0.189 mean Poisson deviance: 0.625
[Tổng quát hóa] mô hình tuyến tính
Chúng tôi bắt đầu bằng cách lập mô hình biến mục tiêu bằng mô hình hồi quy tuyến tính bình phương nhỏ nhất [l2 bị phạt], thường được gọi là hồi quy Ridge. Chúng tôi sử dụng mức phạt thấp
df["Frequency"] = df["ClaimNb"] / df["Exposure"] print[ "Average Frequency = {}".format[np.average[df["Frequency"], weights=df["Exposure"]]] ] print[ "Fraction of exposure with zero claims = {0:.1%}".format[ df.loc[df["ClaimNb"] == 0, "Exposure"].sum[] / df["Exposure"].sum[] ] ] fig, [ax0, ax1, ax2] = plt.subplots[ncols=3, figsize=[16, 4]] ax0.set_title["Number of claims"] _ = df["ClaimNb"].hist[bins=30, log=True, ax=ax0] ax1.set_title["Exposure in years"] _ = df["Exposure"].hist[bins=30, log=True, ax=ax1] ax2.set_title["Frequency [number of claims per year]"] _ = df["Frequency"].hist[bins=30, log=True, ax=ax2]7, vì chúng tôi mong đợi một mô hình tuyến tính như vậy không phù hợp với tập dữ liệu lớn như vậy
from sklearn.linear_model import Ridge ridge_glm = Pipeline[ [ ["preprocessor", linear_model_preprocessor], ["regressor", Ridge[alpha=1e-6]], ] ].fit[df_train, df_train["Frequency"], regressor__sample_weight=df_train["Exposure"]]
Độ lệch Poisson không thể được tính toán trên các giá trị không dương được dự đoán bởi mô hình. Đối với các mô hình trả về một vài dự đoán không tích cực [e. g. ] chúng tôi bỏ qua các mẫu tương ứng, nghĩa là độ lệch Poisson thu được là gần đúng. Một cách tiếp cận khác có thể là sử dụng công cụ ước tính meta để ánh xạ
Average Frequency = 0.10070308464041304 Fraction of exposure with zero claims = 93.9%0 tới một miền tích cực nghiêm ngặt
print["Ridge evaluation:"] score_estimator[ridge_glm, df_test]
from sklearn.datasets import fetch_openml df = fetch_openml[data_id=41214, as_frame=True, parser="pandas"].frame df0
Tiếp theo, chúng tôi điều chỉnh biến hồi quy Poisson trên biến mục tiêu. Chúng tôi đặt cường độ chuẩn hóa
df["Frequency"] = df["ClaimNb"] / df["Exposure"] print[ "Average Frequency = {}".format[np.average[df["Frequency"], weights=df["Exposure"]]] ] print[ "Fraction of exposure with zero claims = {0:.1%}".format[ df.loc[df["ClaimNb"] == 0, "Exposure"].sum[] / df["Exposure"].sum[] ] ] fig, [ax0, ax1, ax2] = plt.subplots[ncols=3, figsize=[16, 4]] ax0.set_title["Number of claims"] _ = df["ClaimNb"].hist[bins=30, log=True, ax=ax0] ax1.set_title["Exposure in years"] _ = df["Exposure"].hist[bins=30, log=True, ax=ax1] ax2.set_title["Frequency [number of claims per year]"] _ = df["Frequency"].hist[bins=30, log=True, ax=ax2]7 thành khoảng 1e-6 trên số lượng mẫu [i. e.
Average Frequency = 0.10070308464041304 Fraction of exposure with zero claims = 93.9%2] để bắt chước biến hồi quy Ridge có số hạng phạt L2 thay đổi theo số lượng mẫu
Vì bộ hồi quy Poisson mô hình hóa nội bộ nhật ký của giá trị mục tiêu dự kiến thay vì trực tiếp giá trị dự kiến [log so với hàm liên kết nhận dạng], nên mối quan hệ giữa X và y không còn tuyến tính chính xác nữa. Do đó, công cụ hồi quy Poisson được gọi là Mô hình tuyến tính tổng quát [GLM] chứ không phải là mô hình tuyến tính cố định như trường hợp của hồi quy Ridge
from sklearn.datasets import fetch_openml df = fetch_openml[data_id=41214, as_frame=True, parser="pandas"].frame df1
from sklearn.datasets import fetch_openml df = fetch_openml[data_id=41214, as_frame=True, parser="pandas"].frame df2
Cây hồi quy tăng cường độ dốc cho hồi quy Poisson
Cuối cùng, chúng ta sẽ xem xét một mô hình phi tuyến tính, cụ thể là Cây hồi quy tăng cường độ dốc. Các mô hình dựa trên cây không yêu cầu dữ liệu phân loại phải được mã hóa một lần. thay vào đó, chúng ta có thể mã hóa từng nhãn danh mục bằng một số nguyên tùy ý bằng cách sử dụng. Với mã hóa này, các cây sẽ coi các tính năng phân loại là các tính năng được sắp xếp, điều này có thể không phải lúc nào cũng là một hành vi mong muốn. Tuy nhiên, hiệu ứng này bị hạn chế đối với những cây đủ sâu có khả năng phục hồi bản chất phân loại của các tính năng. Ưu điểm chính của over the là nó sẽ giúp đào tạo nhanh hơn
Tăng cường độ dốc cũng cung cấp khả năng điều chỉnh các cây bị mất Poisson [với chức năng liên kết nhật ký ngầm] thay vì mất bình phương nhỏ nhất mặc định. Ở đây, chúng tôi chỉ điều chỉnh các cây có mất Poisson để giữ cho ví dụ này ngắn gọn
from sklearn.datasets import fetch_openml df = fetch_openml[data_id=41214, as_frame=True, parser="pandas"].frame df3
from sklearn.datasets import fetch_openml df = fetch_openml[data_id=41214, as_frame=True, parser="pandas"].frame df4
Giống như Poisson GLM ở trên, mô hình cây được tăng cường độ dốc giảm thiểu độ lệch Poisson. Tuy nhiên, do khả năng dự đoán cao hơn, nó đạt đến các giá trị độ lệch Poisson thấp hơn
Việc đánh giá các mô hình bằng một lần phân chia thử nghiệm/đào tạo có xu hướng dao động ngẫu nhiên. Nếu tài nguyên máy tính cho phép, cần xác minh rằng các chỉ số hiệu suất được xác thực chéo sẽ dẫn đến kết luận tương tự
Sự khác biệt về chất giữa các mô hình này cũng có thể được hình dung bằng cách so sánh biểu đồ của các giá trị mục tiêu được quan sát với biểu đồ của các giá trị dự đoán
from sklearn.datasets import fetch_openml df = fetch_openml[data_id=41214, as_frame=True, parser="pandas"].frame df5np.average[df["Frequency"], weights=df["Exposure"]]] ] print[ "Fraction of exposure with zero claims = {0:.1%}".format[ df.loc[df["ClaimNb"] == 0, "Exposure"].sum[] / df["Exposure"].sum[] ] ] fig, [ax0, ax1, ax2] = plt.subplots[ncols=3, figsize=[16, 4]] ax0.set_title["Number of claims"] _ = df["ClaimNb"].hist[bins=30, log=True, ax=ax0] ax1.set_title["Exposure in years"] _ = df["Exposure"].hist[bins=30, log=True, ax=ax1] ax2.set_title["Frequency [number of claims per year]"] _ = df["Frequency"].hist[bins=30, log=True, ax=ax2] 8 có phương sai không đổi, trong khi đối với phân phối Poisson được sử dụng trong
Average Frequency = 0.10070308464041304 Fraction of exposure with zero claims = 93.9%8 và
Average Frequency = 0.10070308464041304 Fraction of exposure with zero claims = 93.9%9, phương sai tỷ lệ thuận với giá trị kỳ vọng được dự đoán
Do đó, trong số các công cụ ước tính được xem xét,
Average Frequency = 0.10070308464041304 Fraction of exposure with zero claims = 93.9%8 và
Average Frequency = 0.10070308464041304 Fraction of exposure with zero claims = 93.9%9 phù hợp hơn để lập mô hình phân phối đuôi dài của dữ liệu không âm so với mô hình
df["Frequency"] = df["ClaimNb"] / df["Exposure"] print[ "Average Frequency = {}".format[np.average[df["Frequency"], weights=df["Exposure"]]] ] print[ "Fraction of exposure with zero claims = {0:.1%}".format[ df.loc[df["ClaimNb"] == 0, "Exposure"].sum[] / df["Exposure"].sum[] ] ] fig, [ax0, ax1, ax2] = plt.subplots[ncols=3, figsize=[16, 4]] ax0.set_title["Number of claims"] _ = df["ClaimNb"].hist[bins=30, log=True, ax=ax0] ax1.set_title["Exposure in years"] _ = df["Exposure"].hist[bins=30, log=True, ax=ax1] ax2.set_title["Frequency [number of claims per year]"] _ = df["Frequency"].hist[bins=30, log=True, ax=ax2]8 đưa ra giả định sai về phân phối của biến mục tiêu
Công cụ ước tính
Average Frequency = 0.10070308464041304 Fraction of exposure with zero claims = 93.9%9 có tính linh hoạt cao nhất và có thể dự đoán các giá trị kỳ vọng cao hơn
Lưu ý rằng chúng ta có thể đã sử dụng tổn thất bình phương nhỏ nhất cho mô hình
Average Frequency = 0.10070308464041304 Fraction of exposure with zero claims = 93.9%9. Điều này sẽ giả định sai một biến phản hồi phân phối bình thường giống như mô hình
df["Frequency"] = df["ClaimNb"] / df["Exposure"] print[ "Average Frequency = {}".format[np.average[df["Frequency"], weights=df["Exposure"]]] ] print[ "Fraction of exposure with zero claims = {0:.1%}".format[ df.loc[df["ClaimNb"] == 0, "Exposure"].sum[] / df["Exposure"].sum[] ] ] fig, [ax0, ax1, ax2] = plt.subplots[ncols=3, figsize=[16, 4]] ax0.set_title["Number of claims"] _ = df["ClaimNb"].hist[bins=30, log=True, ax=ax0] ax1.set_title["Exposure in years"] _ = df["Exposure"].hist[bins=30, log=True, ax=ax1] ax2.set_title["Frequency [number of claims per year]"] _ = df["Frequency"].hist[bins=30, log=True, ax=ax2]8 và cũng có thể dẫn đến những dự đoán hơi tiêu cực. Tuy nhiên, các cây được tăng cường độ dốc vẫn sẽ hoạt động tương đối tốt và đặc biệt là tốt hơn
Average Frequency = 0.10070308464041304 Fraction of exposure with zero claims = 93.9%8 nhờ tính linh hoạt của cây kết hợp với số lượng lớn các mẫu đào tạo
Đánh giá hiệu chuẩn của các dự đoán
Để đảm bảo rằng các công cụ ước tính mang lại dự đoán hợp lý cho các loại chủ hợp đồng khác nhau, chúng tôi có thể kiểm tra các mẫu bin theo
Average Frequency = 0.10070308464041304 Fraction of exposure with zero claims = 93.9%0 được trả về bởi mỗi mô hình. Sau đó, đối với mỗi thùng, chúng tôi so sánh giá trị trung bình được dự đoán
Average Frequency = 0.10070308464041304 Fraction of exposure with zero claims = 93.9%0, với mục tiêu được quan sát trung bình
from sklearn.datasets import fetch_openml df = fetch_openml[data_id=41214, as_frame=True, parser="pandas"].frame df6fetch_openml df = fetch_openml[data_id=41214, as_frame=True, parser="pandas"].frame df 7
Mô hình hồi quy giả dự đoán tần số không đổi. Mô hình này không gán cùng một thứ hạng gắn liền cho tất cả các mẫu nhưng dù sao cũng được hiệu chỉnh tốt trên toàn cầu [để ước tính tần suất trung bình của toàn bộ dân số]
Mô hình hồi quy
df["Frequency"] = df["ClaimNb"] / df["Exposure"] print[ "Average Frequency = {}".format[np.average[df["Frequency"], weights=df["Exposure"]]] ] print[ "Fraction of exposure with zero claims = {0:.1%}".format[ df.loc[df["ClaimNb"] == 0, "Exposure"].sum[] / df["Exposure"].sum[] ] ] fig, [ax0, ax1, ax2] = plt.subplots[ncols=3, figsize=[16, 4]] ax0.set_title["Number of claims"] _ = df["ClaimNb"].hist[bins=30, log=True, ax=ax0] ax1.set_title["Exposure in years"] _ = df["Exposure"].hist[bins=30, log=True, ax=ax1] ax2.set_title["Frequency [number of claims per year]"] _ = df["Frequency"].hist[bins=30, log=True, ax=ax2]8 có thể dự đoán tần suất kỳ vọng rất thấp không khớp với dữ liệu. Do đó, nó có thể đánh giá quá thấp rủi ro đối với một số chủ hợp đồng
Average Frequency = 0.10070308464041304 Fraction of exposure with zero claims = 93.9%8 và
Average Frequency = 0.10070308464041304 Fraction of exposure with zero claims = 93.9%9 thể hiện tính nhất quán tốt hơn giữa các mục tiêu được dự đoán và quan sát, đặc biệt đối với các giá trị mục tiêu được dự đoán thấp
Tổng của tất cả các dự đoán cũng xác nhận vấn đề hiệu chuẩn của mô hình
df["Frequency"] = df["ClaimNb"] / df["Exposure"] print[ "Average Frequency = {}".format[np.average[df["Frequency"], weights=df["Exposure"]]] ] print[ "Fraction of exposure with zero claims = {0:.1%}".format[ df.loc[df["ClaimNb"] == 0, "Exposure"].sum[] / df["Exposure"].sum[] ] ] fig, [ax0, ax1, ax2] = plt.subplots[ncols=3, figsize=[16, 4]] ax0.set_title["Number of claims"] _ = df["ClaimNb"].hist[bins=30, log=True, ax=ax0] ax1.set_title["Exposure in years"] _ = df["Exposure"].hist[bins=30, log=True, ax=ax1] ax2.set_title["Frequency [number of claims per year]"] _ = df["Frequency"].hist[bins=30, log=True, ax=ax2]8. nó ước tính thấp hơn 3% tổng số khiếu nại trong bộ thử nghiệm trong khi ba mô hình còn lại có thể phục hồi xấp xỉ tổng số khiếu nại của danh mục thử nghiệm
Đánh giá về sức mạnh xếp hạng
Đối với một số ứng dụng kinh doanh, chúng tôi quan tâm đến khả năng mô hình xếp hạng rủi ro nhất từ các chủ hợp đồng an toàn nhất, bất kể giá trị tuyệt đối của dự đoán. Trong trường hợp này, đánh giá mô hình sẽ coi vấn đề là vấn đề xếp hạng hơn là vấn đề hồi quy
Để so sánh 3 mô hình từ quan điểm này, người ta có thể vẽ biểu đồ tỷ lệ tích lũy của các khiếu nại so với tỷ lệ phơi nhiễm tích lũy đối với thứ tự mẫu thử nghiệm theo các dự đoán của mô hình, từ an toàn nhất đến rủi ro nhất theo từng mô hình
Biểu đồ này được gọi là đường cong Lorenz và có thể được tóm tắt bằng chỉ số Gini
from sklearn.datasets import fetch_openml df = fetch_openml[data_id=41214, as_frame=True, parser="pandas"].frame df8fetch_openml df = fetch_openml[data_id=41214, as_frame=True, parser="pandas"].frame df 9
Như mong đợi, biến hồi quy giả không thể xếp hạng chính xác các mẫu và do đó hoạt động kém nhất trên biểu đồ này
Mô hình dựa trên cây tốt hơn đáng kể trong việc xếp hạng các chủ hợp đồng theo rủi ro trong khi hai mô hình tuyến tính hoạt động tương tự nhau
Cả ba mô hình đều tốt hơn đáng kể so với cơ hội nhưng cũng rất xa để đưa ra dự đoán hoàn hảo
Điểm cuối cùng này được mong đợi do bản chất của vấn đề. sự xuất hiện của tai nạn chủ yếu là do các nguyên nhân hoàn cảnh chi phối không được ghi lại trong các cột của tập dữ liệu và thực sự có thể được coi là hoàn toàn ngẫu nhiên
Các mô hình tuyến tính giả định không có tương tác giữa các biến đầu vào có khả năng gây ra sự không phù hợp. Chèn một trình trích xuất tính năng đa thức [] thực sự làm tăng khả năng phân biệt đối xử của chúng lên 2 điểm chỉ số Gini. Đặc biệt, nó cải thiện khả năng của các mô hình trong việc xác định 5% hồ sơ rủi ro nhất
bài học chính
Hiệu suất của các mô hình có thể được đánh giá bằng khả năng đưa ra các dự đoán được hiệu chỉnh tốt và xếp hạng tốt
Hiệu chuẩn của mô hình có thể được đánh giá bằng cách vẽ đồ thị giữa giá trị trung bình được quan sát so với giá trị trung bình được dự đoán trên các nhóm mẫu thử nghiệm được xác định bởi rủi ro dự đoán
Mất bình phương nhỏ nhất [cùng với việc sử dụng ẩn chức năng liên kết nhận dạng] của mô hình hồi quy Ridge dường như khiến mô hình này được hiệu chỉnh kém. Đặc biệt, nó có xu hướng đánh giá thấp rủi ro và thậm chí có thể dự đoán các tần số tiêu cực không hợp lệ
Sử dụng tổn thất Poisson với liên kết nhật ký có thể khắc phục những sự cố này và dẫn đến một mô hình tuyến tính được hiệu chỉnh tốt
Chỉ số Gini phản ánh khả năng của một mô hình xếp hạng các dự đoán bất kể giá trị tuyệt đối của chúng và do đó chỉ đánh giá sức mạnh xếp hạng của chúng
Mặc dù có sự cải thiện về hiệu chuẩn, sức mạnh xếp hạng của cả hai mô hình tuyến tính là tương đương nhau và thấp hơn nhiều so với sức mạnh xếp hạng của Cây hồi quy tăng cường độ dốc
Độ lệch Poisson được tính toán như một thước đo đánh giá phản ánh cả hiệu chuẩn và sức mạnh xếp hạng của mô hình. Nó cũng đưa ra một giả định tuyến tính về mối quan hệ lý tưởng giữa giá trị kỳ vọng và phương sai của biến phản hồi. Vì mục đích ngắn gọn, chúng tôi đã không kiểm tra xem giả định này có đúng hay không.
Các số liệu hồi quy truyền thống như Lỗi bình phương trung bình và Lỗi tuyệt đối trung bình khó diễn giải một cách có ý nghĩa trên các giá trị đếm có nhiều số không