Что ж, одним из навыков, который подрывается ресурсами электронного обучения и аналитиками данных в целом, когда дело доходит до разработки плана анализа данных, является прогнозное моделирование. Многие аналитики считают этот навык совершенно ненужным, но это далеко от истины. В течение последнего месяца я оттачивал свои навыки машинного обучения в области прогнозирования и частично в области глубокого обучения (нейронных сетей). В этой статье я познакомлю вас с прогнозированием суммы претензий со стороны потребителей страховой компании. Я провел анализ этого набора данных с помощью SQL, поэтому данные чистые.

Давайте углубимся, чтобы понять наш набор данных:

ID — идентификационный номер, который однозначно идентифицирует клиента.

marital_status — дает нам дополнительную информацию, состоит ли потребитель в браке, одинок, разведен или проживает отдельно.

car_use — используется ли автомобиль для общественных или частных целей.

пол – мужчина или женщина, является ли потребитель.

kids_driving — количество детей в машине.

родитель – является ли потребитель родителем или нет.

образование — уровень образования потребителя.

car_make — производитель автомобиля(Toyota,Nissan и т.д.)

car_model — модель автомобиля(Sparrow,PathFinder и т.д.)

car_color — цвет автомобиля(Бирюзовый,зеленый и т.д.)

car_year — год выпуска автомобиля.

claim_freq — как часто потребители запрашивают свою сумму.

зона_покрытия — где чаще всего используется автомобиль (город, пригород, сельская местность и т. д.)

claim_amt(TARGET) — сумма, подлежащая истребованию

household_income — сколько зарабатывает потребитель.

birth_year — год рождения потребителя.

age (добавлена ​​новая функция) — их возраст (я использовал текущий 2023 год, чтобы получить возраст)

Импортируем необходимые библиотеки

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt 
import warnings
warnings.filterwarnings('ignore')

Загрузка набора данных

path = 'C:/Users/user/Downloads/CarInsurance'
data = pd.read_csv(path + '/CleanedDataCarInsurance.csv')

ПРЕДВАРИТЕЛЬНАЯ ОБРАБОТКА ДАННЫХ

Данные содержали нулевые значения: я очистил их во время анализа SQL.

data.isnull().sum()

Проверка трех верхних строк

data.head(3)

Я ввел в набор данных новый признак «возраст», используя 2023 год, и вычел год рождения, получив возраст потребителей на сегодняшний день.

data['age'] = 2023 - data['birth_year']

Давайте проверим распределение нашей целевой переменной: я получил график нормального распределения.

sns.distplot(data["claim_amt"])

Асимметрия целевой переменной: 0,0196.

skewness = data["claim_amt"].skew()
print(f"The skewness of Claim Amount is {skewness}")

Знать количество числовых и категориальных переменных: 7 числовых и 10 категориальных переменных.

numeric_data = data.select_dtypes(include=[np.number])
cat_data = data.select_dtypes(exclude=[np.number])
print ("There are {} numeric and {} categorical columns in train data".format(numeric_data.shape[1],cat_data.shape[1]))

Удаление столбца идентификатора

del cat_data['ID']

Чтобы понять, как независимые числовые переменные коррелируют с целевой переменной:

#correlation plot
corr = numeric_data.corr()

sns.heatmap(corr)
print(corr["claim_amt"].sort_values(ascending = False))

Мы также хотим знать, как категориальные переменные коррелируют с целевой переменной: у гендера и car_make было наибольшее несоответствие.

from scipy import stats
cat = [col for col in data.columns if data.dtypes[col] == 'object']


anv = pd.DataFrame()
anv['features'] = cat
pvals = []

cat_data = data.copy()
cat_data['claim_amt'] = data['claim_amt'].values

for c in cat:
     samples = []
     for cls in cat_data[c].unique():
           s = cat_data[cat_data[c] == cls]['claim_amt'].values
           samples.append(s)
     pval = stats.f_oneway(*samples)[1]
     pvals.append(pval)
     
anv['pval'] = pvals
anv['disparity'] = np.log(1. / anv['pval'].values)

anv = anv.sort_values(by='disparity',ascending=False)

sns.barplot(data=anv, x = 'features', y='disparity') 
plt.xticks(rotation=90) 
plt.show() 

Мы будем обрабатывать категориальные переменные:

from sklearn.preprocessing import LabelEncoder

def processing_data(data):

    processed_data = data.copy()

    dummy = ['car_make','car_use'] 
    
    processed_data = pd.get_dummies(processed_data, columns = dummy)

    categ=['gender']

    if 'ID' in processed_data:
        processed_data.drop(['ID'], axis=1,inplace=True)

    le = LabelEncoder()    

    for col in categ:
        processed_data[col] = le.fit_transform(data[col]) 
    
    return pd.DataFrame(processed_data, columns=processed_data.columns)
  
processed_X = processing_data(X)

processed_X.shape #columns have increased to 77 due to the one-hot encoding

ВЫБОР И ОЦЕНКА МОДЕЛИ

from sklearn.model_selection import train_test_split
from sklearn.feature_selection import SelectKBest,f_regression
from sklearn.model_selection import cross_val_score,KFold
from sklearn.ensemble import RandomForestRegressor,GradientBoostingRegressor
from sklearn.linear_model import LinearRegression
from xgboost import XGBRFRegressor,XGBRegressor
from sklearn.tree import DecisionTreeRegressor
from sklearn.metrics import mean_absolute_error,mean_squared_error

Давайте разделим наши данные на обучающее тестирование: это даст нам набор данных для обучения и тестирования;

X_train,X_test,y_train,y_test = train_test_split(processed_X, y,
                                                 test_size=0.1,random_state=42)

Использование SelectKBest и f_reгрессии дает нам лучшие возможности. Подборка из 50 функций показала наилучшие результаты на моей модели.

k_best_features = 50
selector = SelectKBest(score_func=f_regression,k = k_best_features)
selector.fit(X_train,y_train)
X_train_selected = selector.fit_transform(X_train,y_train)
X_test_selected = selector.transform(X_test)

Оценка лучших моделей, которые можно использовать для наших данных. Поскольку мы имеем дело с проблемой регрессии, я использовал метрические оценки как среднюю абсолютную ошибку и среднеквадратическую ошибку. XGBFRegressor и линейная регрессия показали лучшие результаты.

def calculate_mae(y_pred,y_test):
     return mean_absolute_error(y_pred,y_test)

models = {
     "LinearRegression": LinearRegression(),
     "DecisionTree": DecisionTreeRegressor(random_state=42),
     "RandomForest": RandomForestRegressor(random_state=42),
     "GradientBoost": GradientBoostingRegressor(random_state=42),
     "XGBRF": XGBRFRegressor(),
     "XGR": XGBRegressor()
     }
mae_values = []
#mse_values = []

for name,model in models.items():
    model.fit(X_train_selected,y_train)
    preds = model.predict(X_test_selected)
    mae_values.append(calculate_mae(y_test,preds))
    #mse_values.append(mean_squared_error(y_test,preds))

plt.figure(figsize=(12,5))

plt.subplot(1,2,1)
sns.barplot(x =list(models.keys()),y = mae_values, palette='viridis')
plt.title("MAE of Models")
plt.ylabel("MAE")
plt.xticks(rotation=90)

plt.tight_layout()
plt.show()

plt.subplot(1,2,1)
sns.barplot(x =list(models.keys()),y = mse_values, palette='viridis')
plt.title("MSE of Models")
plt.ylabel("MSE")
plt.xticks(rotation=90)

plt.tight_layout()
plt.show()
#gb = GradientBoostingRegressor()
xrf = XGBRFRegressor()
lr = LinearRegression()
'''
gb.fit(X_train,y_train)
y_pred = gb.predict(X_test)
maegb = mean_absolute_error(y_test,y_pred)
'''
xrf.fit(X_train_selected,y_train)
xrf_pred = xrf.predict(X_test_selected)
maexrf = mean_absolute_error(y_test,y_pred)

lr.fit(X_train_selected,y_train)
lr_pred = lr.predict(X_test_selected)
maelr = mean_absolute_error(y_test,y_pred)

#print(f"MAE of Gradient Boosting is: {maegb:.4f}")
print(f"MAE of XGBRFRegressor is: {maexrf:.4f}")
print(f"MAE of LinearRegression is: {maelr:.4f}")

Далее я использовал нейронные сети для построения своей модели, и результаты оказались намного лучше по сравнению с объединением моделей XGBRFRegressor и LinearRegrade. Средняя абсолютная ошибка (MAE) составила: MAE: 24692,2125. А у ансамблевых моделей было: 24820,6873.

ensemble_predictions = (xrf_pred + lr_pred) / 2

ensemble_mae = mean_absolute_error(y_test,ensemble_predictions)
print(f"Ensemble Mean Absolute Error: {ensemble_mae:.4f}")
from keras.models import Sequential
from keras.layers import Dense
from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()
X_train = scaler.fit_transform(X_train_selected)
X_test = scaler.transform(X_test_selected)

def base_model():
     model = Sequential()
     model.add(Dense(units = 20, input_dim=50, kernel_initializer='uniform', activation='relu'))
     model.add(Dense(units =10, kernel_initializer='uniform', activation='relu'))
     model.add(Dense(units =1, kernel_initializer='uniform'))
     model.compile(loss='mean_absolute_error', optimizer = 'adam')
     return model

keras_model = base_model()
keras_model.fit(X_train_selected,y_train,epochs=10, batch_size=5,verbose=1)
y_pred = keras_model.predict(X_test_selected)

mae_scores = mean_absolute_error(y_test,y_pred)

print("MAE:" ,mae_scores)

PS: Эта модель находится не в лучшей производительности, поскольку не были собраны данные для построения моделей и других факторов, таких как настройка гиперпараметров, которую я не выполнял.

Надеюсь, эта статья показалась вам интересной и познавательной, и я буду продолжать публиковать новые концепции, которые помогут всем новичкам в области данных.

Давайте превратим проблемы с данными в возможности и вместе будем внедрять инновации. Ваша следующая история успеха начинается с разговора.

Давайте подключим:

ЛИНКЕДИН

ГИТХАБ

КУОРА