"""
# We will use a Generalized Additive Model(GAM) to model Audi prices  
During the analysis, we will try ordinal encoding.
"""
import pandas as pd
import numpy as np
path = r'/kaggle/input/used-car-dataset-ford-and-mercedes/audi.csv'
data = pd.read_csv(path)
data
"""
# Feature Engineering  
I will try out ordinal encoding.
"""
# Ordinal encoding

import category_encoders as ce
data_ord = data.copy()
encoder = ce.OrdinalEncoder(cols=['model','transmission','fuelType'])
data_ord = encoder.fit_transform(data_ord)
data_ord
import seaborn as sns
sns.pairplot(data_ord)
!pip install pygam
from sklearn.model_selection import train_test_split
X = data_ord.drop(['price'],axis=1)
#X['year'] = 2020-data_ord['year']

y = data_ord['price']
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2,random_state=25)
from pygam import GAM, s, f

gam = GAM(f(0)+s(1)+f(2)+s(3)+f(4)+s(5)+s(6)+s(7),distribution='gamma',link='log').fit(X_train,y_train)
from sklearn.metrics import r2_score
print('Performance score(XGB): %.1f ' %(r2_score(y_test,gam.predict(X_test))*100))
gam.summary()
"""
I will replace the engineSize outliers with the mean of the same model as the model for that record.
"""
model_range=X_train['model'].unique()
model_range.sort()

X_train_1= X_train
X_test_1= X_test

for m in model_range:
    engineSize_mean=X_train.loc[X_train_1['model']==m,'engineSize'].mean()
    #print(m,engineSize_mean)
    X_train_1.loc[(X_train_1['engineSize']==0.0) & (X_train_1['model']==m),'engineSize']=engineSize_mean
    X_test_1.loc[(X_test_1['engineSize']==0.0) & (X_test_1['model']==m),'engineSize']=engineSize_mean

from pygam import GAM, s, f

gam = GAM(f(0)+f(4)+f(2)+s(1)+s(3)+s(5)+s(6)+s(7),distribution='gamma',link='log',n_splines=50)
gam.gridsearch(X_train_1.values,y_train.values)
from sklearn.metrics import r2_score
print('Performance score(XGB): %.1f ' %(r2_score(y_test,gam.predict(X_test_1))*100))
gam.summary()
"""
# Conclusions   
The model performs well.
"""
import matplotlib.pyplot as plt
import matplotlib.lines as mlines
import matplotlib.transforms as mtransforms

fig, ax = plt.subplots()
ax.scatter(y_test,gam.predict(X_test_1))
line = mlines.Line2D([0, 140000], [0, 140000], color='red')
transform = ax.transAxes
line.set_transform(transform)
ax.add_line(line)
plt.show()