Kaggle competition: Used Cars Price Prediction
<SOS> metric: rmsle Kaggle data source: used-cars-price-prediction<drop_column>
sns.set()
%matplotlib inline
m_lgb.save_model("model.lgb" )<load_from_csv>
df_train = pd.read_csv(os.path.join(_input_path, "train.csv"), index_col=0)
 df_test = pd.read_csv(os.path.join(_input_path, "test.csv"), index_col=0 )
trLast = 1913
maxLags = 57
def create_ds() :
startDay = trLast - maxLags
numCols = [f"d_{day}" for day in range(startDay, trLast + 1)]
catCols = ['id', 'item_id', 'dept_id','store_id', 'cat_id', 'state_id']
dtype = {numCol:"float32" for numCol in numCols}
dtype.update({catCol: "category" for catCol in catCols if catCol != "id"})
 ds = pd.read_csv(".. /input/m5-forecasting-accuracy/sales_train_validation.csv",
usecols = catCols + numCols, dtype = dtype)
 for col in catCols:
if col != "id":
ds[col] = ds[col].cat.codes.astype("int16")
 ds[col] -= ds[col].min()
for day in range(trLast + 1, trLast+ 28 +1):
ds[f"d_{day}"] = np.nan
ds = pd.melt(ds,
id_vars = catCols,
value_vars = [col for col in ds.columns if col.startswith("d_")],
var_name = "d",
value_name = "sales")
 ds = ds.merge(calendar, on = "d", copy = False)
 ds = ds.merge(prices, on = ["store_id", "item_id", "wm_yr_wk"], copy = False)
 return ds
def create_features(ds):
dayLags = [7, 28]
lagSalesCols = [f"lag_{dayLag}" for dayLag in dayLags]
for dayLag, lagSalesCol in zip(dayLags, lagSalesCols):
ds[lagSalesCol] = ds[["id","sales"]].groupby("id")["sales"].shift(dayLag)
 windows = [7, 28]
for window in windows:
for dayLag, lagSalesCol in zip(dayLags, lagSalesCols):
ds[f"rmean_{dayLag}_{window}"] = ds[["id", lagSalesCol]].groupby("id")[lagSalesCol].transform(lambda x: x.rolling(window ).mean())
 dateFeatures = {"wday": "weekday",
"week": "weekofyear",
"month": "month",
"quarter": "quarter",
"year": "year",
"mday": "day"}
for featName, featFunc in dateFeatures.items() :
if featName in ds.columns:
ds[featName] = ds[featName].astype("int16")
 else:
ds[featName] = getattr(ds["date"].dt, featFunc ).astype("int16" )<feature_engineering>
df_train["Engine"].str[-3:].value_counts()
fday = datetime(2016,4, 25)
 alphas = [1.028, 1.023, 1.018]
weights = [1/len(alphas)] * len(alphas)
 sub = 0.
 for icount,(alpha, weight)in enumerate(zip(alphas, weights)) :
te = create_ds()
cols = [f"F{i}" for i in range(1,29)]
for tdelta in range(0, 28):
day = fday + timedelta(days=tdelta)
 print(tdelta, day)
 tst = te[(te['date'] >= day - timedelta(days=maxLags)) &(te['date'] <= day)].copy()
create_features(tst)
 tst = tst.loc[tst['date'] == day , trainCols]
te.loc[te['date'] == day, "sales"] = alpha * m_lgb.predict(tst)
 te_sub = te.loc[te['date'] >= fday, ["id", "sales"]].copy()
te_sub["F"] = [f"F{rank}" for rank in te_sub.groupby("id")["id"].cumcount() +1]
te_sub = te_sub.set_index(["id", "F" ] ).unstack() ["sales"][cols].reset_index()
te_sub.fillna(0., inplace = True)
 te_sub.sort_values("id", inplace = True)
 te_sub.reset_index(drop=True, inplace = True)
 te_sub.to_csv(f"submission_{icount}.csv",index=False)
 if icount == 0 :
sub = te_sub
sub[cols] *= weight
else:
sub[cols] += te_sub[cols]*weight
print(icount, alpha, weight)
 sub2 = sub.copy()
sub2["id"] = sub2["id"].str.replace("validation$", "evaluation")
 sub = pd.concat([sub, sub2], axis=0, sort=False)
 sub.to_csv("submission.csv",index=False )<import_modules>
df_test["Engine"].str[-3:].value_counts()
from datetime import datetime, timedelta
import gc
import numpy as np, pandas as pd
import lightgbm as lgb<define_variables>
df_train[df_train[["Engine", "Power"]].isnull().sum(axis=1)>= 1]
CAL_DTYPES={"event_name_1": "category", "event_name_2": "category", "event_type_1": "category",
"event_type_2": "category", "weekday": "category", 'wm_yr_wk': 'int16', "wday": "int16",
"month": "int16", "year": "int16", "snap_CA": "float32", 'snap_TX': 'float32', 'snap_WI': 'float32' }
PRICE_DTYPES = {"store_id": "category", "item_id": "category", "wm_yr_wk": "int16","sell_price":"float32" }<set_options>
drop_origin_cols = []
pd.options.display.max_columns = 50<define_variables>
df_train["Engine_num"] = df_train["Engine"].str[: -3].astype(np.float16)
 df_test["Engine_num"] = df_test["Engine"].str[: -3].astype(np.float16)
 if "Engine" not in drop_origin_cols: drop_origin_cols.append("Engine" )
h = 28
max_lags = 57
tr_last = 1913
fday = datetime(2016,4, 25)
 fday<load_from_csv>
df_train["Mileage_num"] = df_train["Mileage"].apply(lambda x: str(x ).split(" ")[0] ).astype(np.float)
 df_test["Mileage_num"] = df_test["Mileage"].apply(lambda x: str(x ).split(" ")[0] ).astype(np.float)
 if "Mileage" not in drop_origin_cols: drop_origin_cols.append("Mileage" )
def create_dt(is_train = True, nrows = None, first_day = 1200):
prices = pd.read_csv(".. /input/m5-forecasting-accuracy/sell_prices.csv", dtype = PRICE_DTYPES)
 for col, col_dtype in PRICE_DTYPES.items() :
if col_dtype == "category":
prices[col] = prices[col].cat.codes.astype("int16")
 prices[col] -= prices[col].min()
cal = pd.read_csv(".. /input/m5-forecasting-accuracy/calendar.csv", dtype = CAL_DTYPES)
 cal["date"] = pd.to_datetime(cal["date"])
 for col, col_dtype in CAL_DTYPES.items() :
if col_dtype == "category":
cal[col] = cal[col].cat.codes.astype("int16")
 cal[col] -= cal[col].min()
start_day = max(1 if is_train else tr_last-max_lags, first_day)
 numcols = [f"d_{day}" for day in range(start_day,tr_last+1)]
catcols = ['id', 'item_id', 'dept_id','store_id', 'cat_id', 'state_id']
dtype = {numcol:"float32" for numcol in numcols}
dtype.update({col: "category" for col in catcols if col != "id"})
 dt = pd.read_csv(".. /input/m5-forecasting-accuracy/sales_train_validation.csv",
nrows = nrows, usecols = catcols + numcols, dtype = dtype)
 for col in catcols:
if col != "id":
dt[col] = dt[col].cat.codes.astype("int16")
 dt[col] -= dt[col].min()
if not is_train:
for day in range(tr_last+1, tr_last+ 28 +1):
dt[f"d_{day}"] = np.nan
dt = pd.melt(dt,
id_vars = catcols,
value_vars = [col for col in dt.columns if col.startswith("d_")],
var_name = "d",
value_name = "sales")
 dt = dt.merge(cal, on= "d", copy = False)
 dt = dt.merge(prices, on = ["store_id", "item_id", "wm_yr_wk"], copy = False)
 return dt<categorify>
df_train["Power"].str[-4: ].value_counts()
def create_fea(dt):
lags = [7, 28]
lag_cols = [f"lag_{lag}" for lag in lags ]
for lag, lag_col in zip(lags, lag_cols):
dt[lag_col] = dt[["id","sales"]].groupby("id")["sales"].shift(lag)
 wins = [7, 28]
for win in wins :
for lag,lag_col in zip(lags, lag_cols):
dt[f"rmean_{lag}_{win}"] = dt[["id", lag_col]].groupby("id")[lag_col].transform(lambda x : x.rolling(win ).mean())
 date_features = {
"wday": "weekday",
"week": "weekofyear",
"month": "month",
"quarter": "quarter",
"year": "year",
"mday": "day",
}
for date_feat_name, date_feat_func in date_features.items() :
if date_feat_name in dt.columns:
dt[date_feat_name] = dt[date_feat_name].astype("int16")
 else:
dt[date_feat_name] = getattr(dt["date"].dt, date_feat_func ).astype("int16" )<define_variables>
df_train["Power_num"] = df_train["Power"].str[: -4].replace({"null": np.nan} ).astype(np.float)
 df_test["Power_num"] = df_test["Power"].str[: -4].replace({"null": np.nan} ).astype(np.float)
 if "Power" not in drop_origin_cols: drop_origin_cols.append("Power" )
FIRST_DAY = 350<correct_missing_values>
df_train.drop(drop_origin_cols, axis=1, inplace=True)
 df_test.drop(drop_origin_cols, axis=1, inplace=True )
df.dropna(inplace = True)
 df.shape<prepare_x_and_y>
df_train["maker"] = df_train["Name"].apply(lambda x: x.split(" ")[0])
 df_test["maker"] = df_test["Name"].apply(lambda x: x.split(" ")[0] )
cat_feats = ['item_id', 'dept_id','store_id', 'cat_id', 'state_id'] + ["event_name_1", "event_name_2", "event_type_1", "event_type_2"]
useless_cols = ["id", "date", "sales","d", "wm_yr_wk", "weekday"]
train_cols = df.columns[~df.columns.isin(useless_cols)]
X_train = df[train_cols]
y_train = df["sales"]<create_dataframe>
le = ce.OrdinalEncoder()
df_train["LE_maker"] = le.fit_transform(df_train["maker"])
 df_test["LE_maker"] = le.transform(df_test["maker"])
 df_train["LE_maker"] = df_train["LE_maker"].astype("category")
 df_test["LE_maker"] = df_test["LE_maker"].astype("category")
 fe_maker = df_train["maker"].value_counts().to_dict()
for i in list(set(df_test['maker'].unique())- set(df_train['maker'].unique())) :
fe_maker[i] = 0
df_train["FE_maker"] = df_train["maker"].map(fe_maker)
 df_test["FE_maker"] = df_test["maker"].map(fe_maker)
 df_train.drop(["maker"], axis=1, inplace=True)
 df_test.drop(["maker"], axis=1, inplace=True )
%%time
np.random.seed(777)
 fake_valid_inds = np.random.choice(X_train.index.values, 2_000_000, replace = False)
 train_inds = np.setdiff1d(X_train.index.values, fake_valid_inds)
 train_data = lgb.Dataset(X_train.loc[train_inds] , label = y_train.loc[train_inds],
categorical_feature=cat_feats, free_raw_data=False)
 fake_valid_data = lgb.Dataset(X_train.loc[fake_valid_inds], label = y_train.loc[fake_valid_inds],
categorical_feature=cat_feats,
free_raw_data=False )<prepare_x_and_y>
df_train["series"] = df_train["Name"].apply(lambda x: x.split(" ")[1])
 df_test["series"] = df_test["Name"].apply(lambda x: x.split(" ")[1])
 le = ce.OrdinalEncoder()
df_train["LE_series"] = le.fit_transform(df_train["series"])
 df_test["LE_series"] = le.transform(df_test["series"])
 df_train["LE_series"] = df_train["LE_series"].astype("category")
 df_test["LE_series"] = df_test["LE_series"].astype("category")
 fe_series = df_train["series"].value_counts().to_dict()
for i in list(set(df_test['series'].unique())- set(df_train['series'].unique())) :
fe_series[i] = 0
df_train["FE_series"] = df_train["series"].map(fe_maker)
 df_test["FE_series"] = df_test["series"].map(fe_maker)
 df_train.drop(["series"], axis=1, inplace=True)
 df_test.drop(["series"], axis=1, inplace=True )
del df, X_train, y_train, fake_valid_inds,train_inds ; gc.collect()<init_hyperparams>
le = LabelEncoder()
df_train["Location"] = le.fit_transform(df_train["Location"])
 df_test["Location"] = le.transform(df_test["Location"])
 df_train["Location"] = df_train["Location"].astype("category")
 df_test["Location"] = df_test["Location"].astype("category" )
params = {
"objective" : "poisson",
"metric" :"rmse",
"force_row_wise" : True,
"learning_rate" : 0.075,
"sub_row" : 0.75,
"bagging_freq" : 1,
"lambda_l2" : 0.1,
"metric": ["rmse"],
'verbosity': 1,
'num_iterations' : 1200,
'num_leaves': 2**11-1,
"min_data_in_leaf": 2**12-1,
}<train_model>
le = ce.OrdinalEncoder()
df_train["Fuel_Type"] = le.fit_transform(df_train["Fuel_Type"])
 df_test["Fuel_Type"] = le.transform(df_test["Fuel_Type"])
 df_train["Fuel_Type"] = df_train["Fuel_Type"].astype("category")
 df_test["Fuel_Type"] = df_test["Fuel_Type"].astype("category" )
%%time
m_lgb = lgb.train(params, train_data, valid_sets = [fake_valid_data], verbose_eval=20 )<save_model>
le = LabelEncoder()
df_train["Transmission"] = le.fit_transform(df_train["Transmission"])
 df_test["Transmission"] = le.transform(df_test["Transmission"] )
m_lgb.save_model("model.lgb" )<feature_engineering>
df_train["Transmission"] = df_train["Transmission"].astype("category")
 df_test["Transmission"] = df_test["Transmission"].astype("category" )
def create_lag_features_for_test(dt, day):
lags = [7, 28]
lag_cols = [f"lag_{lag}" for lag in lags]
for lag, lag_col in zip(lags, lag_cols):
dt.loc[dt.date == day, lag_col] = \
dt.loc[dt.date ==day-timedelta(days=lag), 'sales'].values
windows = [7, 28]
for window in windows:
for lag in lags:
df_window = dt[(dt.date <= day-timedelta(days=lag)) &(dt.date > day-timedelta(days=lag+window)) ]
df_window_grouped = df_window.groupby("id" ).agg({'sales':'mean'} ).reindex(dt.loc[dt.date==day,'id'])
 dt.loc[dt.date == day,f"rmean_{lag}_{window}"] = \
df_window_grouped.sales.values<data_type_conversions>
le = LabelEncoder()
df_train["Owner_Type"] = le.fit_transform(df_train["Owner_Type"])
 df_test["Owner_Type"] = le.transform(df_test["Owner_Type"])
 df_train["Owner_Type"] = df_train["Owner_Type"].astype("category")
 df_test["Owner_Type"] = df_test["Owner_Type"].astype("category" )
def create_date_features_for_test(dt):
date_features = {
"wday": "weekday",
"week": "weekofyear",
"month": "month",
"quarter": "quarter",
"year": "year",
"mday": "day",
}
for date_feat_name, date_feat_func in date_features.items() :
if date_feat_name in dt.columns:
dt[date_feat_name] = dt[date_feat_name].astype("int16")
 else:
dt[date_feat_name] = getattr(
 dt["date"].dt, date_feat_func ).astype("int16" )<categorify>
df_train.isnull().sum()
%%time
alphas = [1.028, 1.023, 1.018]
weights = [1/len(alphas)]*len(alphas)
 te0 = create_dt(False)
 create_date_features_for_test(te0)
 for icount,(alpha, weight)in enumerate(zip(alphas, weights)) :
te = te0.copy()
cols = [f"F{i}" for i in range(1, 29)]
for tdelta in range(0, 28):
day = fday + timedelta(days=tdelta)
 print(tdelta, day.date())
 tst = te[(te.date >= day - timedelta(days=max_lags))
&(te.date <= day)].copy()
create_lag_features_for_test(tst, day)
 tst = tst.loc[tst.date == day, train_cols]
te.loc[te.date == day, "sales"] = \
alpha * m_lgb.predict(tst)
 te_sub = te.loc[te.date >= fday, ["id", "sales"]].copy()
te_sub["F"] = [f"F{rank}" for rank in te_sub.groupby("id")[
"id"].cumcount() +1]
te_sub = te_sub.set_index(["id", "F"] ).unstack() [
"sales"][cols].reset_index()
te_sub.fillna(0., inplace=True)
 te_sub.sort_values("id", inplace=True)
 te_sub.reset_index(drop=True, inplace=True)
 te_sub.to_csv(f"submission_{icount}.csv", index=False)
 if icount == 0:
sub = te_sub
sub[cols] *= weight
else:
sub[cols] += te_sub[cols]*weight
print(icount, alpha, weight )<count_unique_values>
drop_cols = ["Name", "New_Price"]
X = df_train.drop(drop_cols + ["Price"], axis=1)
 y = np.log1p(df_train["Price"])
 X_test = df_test.drop(drop_cols, axis=1 )
sub.id.nunique() , sub["id"].str.contains("validation$" ).sum()<save_to_csv>
cat_cols = [ind for ind, typ in(df_test.dtypes=="category" ).items() if typ]
sub2 = sub.copy()
sub2["id"] = sub2["id"].str.replace("validation$", "evaluation")
 sub = pd.concat([sub, sub2], axis=0, sort=False)
 sub.to_csv("submission.csv",index=False )<import_modules>
lgb_reg = lgb.LGBMRegressor()
lgb_reg.fit(X, y)
 lgb_predict = np.expm1(lgb_reg.predict(X_test))
import pandas as pd
import numpy as np
import os
import lightgbm as lgb<load_from_csv>
lgb_submit = pd.read_csv(os.path.join(_input_path, "sampleSubmission.csv"))
lgb_submit["Price"] = lgb_predict
lgb_submit.to_csv("lgb_submit.csv", index=False )
path = ".. /input/m5-forecasting-accuracy"
calendar = pd.read_csv(os.path.join(path, "calendar.csv"))
selling_prices = pd.read_csv(os.path.join(path, "sell_prices.csv"))
sample_submission = pd.read_csv(os.path.join(path, "sample_submission.csv"))
sales = pd.read_csv(os.path.join(path, "sales_train_evaluation.csv"))<data_type_conversions>
cat_X = X.copy()
cat_X[cat_cols] = cat_X[cat_cols].astype(np.int16)
 cat_X_test = X_test.copy()
cat_X_test[cat_cols] = cat_X_test[cat_cols].astype(np.int16)
 cat_reg = cat.CatBoostRegressor()
cat_reg.fit(cat_X, y, cat_features=cat_cols, verbose=False)
 cat_predict = np.expm1(cat_reg.predict(cat_X_test))
def prep_calendar(df):
df = df.drop(["date", "weekday", "event_type_1", "event_type_2"], axis=1)
 df = df.assign(d = df.d.str[2:].astype(int))
to_ordinal = ["event_name_1", "event_name_2"]
df[to_ordinal] = df[to_ordinal].fillna("1")
 df[to_ordinal] = OrdinalEncoder(dtype="int" ).fit_transform(df[to_ordinal])+ 1
to_int8 = ["wday", "month", "snap_CA", "snap_TX", "snap_WI"] + to_ordinal
df[to_int8] = df[to_int8].astype("int8")
 return df
calendar = prep_calendar(calendar)
 calendar.head()<categorify>
cat_submit = pd.read_csv(os.path.join(_input_path, "sampleSubmission.csv"))
cat_submit["Price"] = cat_predict
cat_submit.to_csv("cat_submit.csv", index=False )