Triển khai python hồi quy poisson
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à Show Một vài định nghĩa
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 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ápHã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) Average Frequency = 0.10070308464041304 Fraction of exposure with zero claims = 93.9% Các cột còn lại có thể được sử dụng để dự đoán tần suất của các sự kiện khiếu nại. Các cột đó rất không đồng nhất với sự kết hợp của các biến phân loại và số với các tỷ lệ khác nhau, có thể được phân phối rất không đồng đều Do đó, để phù hợp với các mô hình tuyến tính với các yếu tố dự đoán đó, cần phải thực hiện các phép biến đổi tính năng tiêu chuẩn như sau from sklearn.pipeline import 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ínhChú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 PoissonCuố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 df5 Dữ liệu thử nghiệm trình bày phân phối đuôi dài cho Average Frequency = 0.10070308464041304 Fraction of exposure with zero claims = 93.9%6. Trong tất cả các mô hình, chúng tôi dự đoán tần suất dự kiến của một biến ngẫu nhiên, vì vậy chúng tôi nhất thiết sẽ có ít giá trị cực trị hơn so với các hiện thực quan sát được của biến ngẫu nhiên đó. Điều này giải thích rằng chế độ của biểu đồ dự đoán mô hình không nhất thiết phải tương ứng với giá trị nhỏ nhất. Ngoài ra, phân phối chuẩn được sử dụng trong 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ó 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 df6 from sklearn.datasets import fetch_openml df = fetch_openml(data_id=41214, as_frame=True, parser="pandas").frame df7 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 df8 from sklearn.datasets import fetch_openml df = fetch_openml(data_id=41214, as_frame=True, parser="pandas").frame df9 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
|