<jupyter_start><jupyter_text>1. View Original Data<jupyter_code>train_df.info()
print("Raw Data Dimension", train_df.shape)<jupyter_output><empty_output><jupyter_text>2. Exmine NULL values and Drop the rows with Null for brewery_name<jupyter_code>train_df.isna().sum()
### Exmine How many row has missing brewy names
brew_name_null = train_df[train_df['brewery_name'].isnull()]
brew_name_null.shape
## 15 rows missing for brewy-names  at brewery_id 1193 x 9 and 27 X 6
### Drop the rows if "brewy_name" is NULL
### Select only non-null value of brewry_name
df_cleaned = train_df.copy()
df_cleaned = df_cleaned[df_cleaned['brewery_name'].notnull()]
df_cleaned.head()<jupyter_output><empty_output><jupyter_text>3. Select the features - Drop unpromising-looking features<jupyter_code># Follow the commonsense
col_to_drop = ['beer_beerid', 'brewery_id', "review_profilename", "beer_name", "review_time"]
target_column = 'beer_style'

df_cleaned = df_cleaned.drop(col_to_drop, axis = 1)

#df_cleaned.head()
df_cleaned.isna().sum()<jupyter_output><empty_output><jupyter_text>4. Label Encoding to Target Column<jupyter_code>import pandas as pd
from sklearn.preprocessing import LabelEncoder

le = LabelEncoder()
df_cleaned['beer_style_encoded'] = le.fit_transform(df_cleaned['beer_style'])

# df_cleaned['brewery_name_encoded'] = le.fit_transform(df_cleaned['brewery_name'])
# df_cleaned.head()

# Drop the beer_style column
beer_style = df_cleaned.pop('beer_style')

df_cleaned['beer_style_encoded'].value_counts().reset_index()
#print(df_cleaned.isna().sum())<jupyter_output><empty_output><jupyter_text>5. Subset the dataset for experiment as the original dataset is huge in size ,1500K observations<jupyter_code>from src.data.sets import split_sets_random, save_sets, load_sets, subset_x_y

#target_column_new = 'beer_style_encoded'
features = ["review_overall", "review_aroma","review_appearance", "review_palate", "review_taste", "beer_abv" , "brewery_name"]


y_main, X_main = subset_x_y(df_cleaned[features], df_cleaned['beer_style_encoded'], 0, 200000)

# y_val, X_val = subset_x_y(df_cleaned[features], df_cleaned['beer_style_encoded'], 100000, 200000)
# y_test, X_test = subset_x_y(df_cleaned[features], df_cleaned['beer_style_encoded'], 200000, 300000)
# Check the size of the Target Class Distribution in the subset Dataset
(unique, counts) = np.unique(y_main, return_counts=True)
frequencies = np.asarray((unique, counts)).T
#print(frequencies)

## Remark - the distribution is same as original<jupyter_output><empty_output><jupyter_text>6. Imputation of Null values in 'beer_abv' column<jupyter_code>#### Before Imputation
print("Null Check: Before Imputation\n", X_main.isna().sum())

X_main['beer_abv'] = X_main['beer_abv'].fillna(X_main['beer_abv'].mean())

#### After Imputation
print("\n Null Check: After Imputation\n", X_main.isna().sum())<jupyter_output>Null Check: Before Imputation
 review_overall          0
review_aroma            0
review_appearance       0
review_palate           0
review_taste            0
beer_abv             7051
brewery_name            0
dtype: int64

 Null Check: After Imputation
 review_overall       0
review_aroma         0
review_appearance    0
review_palate        0
review_taste         0
beer_abv             0
brewery_name         0
dtype: int64<jupyter_text>7. Scaling the numerical columns<jupyter_code>from sklearn.preprocessing import StandardScaler
sc = StandardScaler()

# Select the numerical columns
num_cols = ['review_overall', 'review_aroma', 'review_appearance', 'review_palate', 'review_taste', 'beer_abv']
X_main_copy = X_main.copy()
#X_main_copy.head()

X_main_copy[num_cols] = sc.fit_transform(X_main_copy[num_cols])
X_main_scaled = X_main_copy.copy()
###### AFTER SCALING #####
X_main_scaled['beer_style'] = y_main

print("Null Check", X_main_scaled.isna().sum())
X_main_scaled.head()<jupyter_output>Null Check review_overall       0
review_aroma         0
review_appearance    0
review_palate        0
review_taste         0
beer_abv             0
brewery_name         0
beer_style           0
dtype: int64<jupyter_text>8. KElbow Visualiser to get the Cluster count<jupyter_code>from yellowbrick.cluster import KElbowVisualizer
from sklearn.cluster import KMeans

num_cols = ["review_overall", 'review_aroma', 'review_appearance', 'review_palate', 'review_taste', 'beer_abv']

X_main_scaled_copy = X_main_scaled.copy()

model = KElbowVisualizer(KMeans(), k=(2,15))
model.fit(X_main_scaled_copy[num_cols])

n_cluster = model.elbow_value_
n_cluster<jupyter_output><empty_output><jupyter_text>9. Gaussian Mixture - Add new feature  "cluster_kmean"<jupyter_code>from sklearn.mixture import GaussianMixture

gmm = GaussianMixture(n_components=n_cluster, random_state=8)
gmm.fit(X_main_scaled_copy[num_cols])
cluster_prediction = gmm.predict(X_main_scaled_copy[num_cols])
X_main_scaled_copy['cluster_kmean'] = cluster_prediction
obs = pd.DataFrame(X_main_scaled_copy.iloc[0][num_cols]).transpose()
gmm.predict(obs)
X_main_scaled_copy.head()<jupyter_output><empty_output><jupyter_text>10. One Hot Encoding the feature - "brewery_name"<jupyter_code>from sklearn.preprocessing import OneHotEncoder

ohe = OneHotEncoder(sparse=False)

## Re-assign the brewey_name into the dataframe to do OHE,because it was removed during the scaling and k-means clustering
X_main_scaled_kmean = X_main_scaled_copy.copy()
X_main_scaled_kmean['brewery_name'] = X_main['brewery_name']

X_main_cat_enc = pd.DataFrame(ohe.fit_transform(X_main_scaled_kmean[['brewery_name']]))
X_main_cat_enc.columns = ohe.get_feature_names(['brewery_name'])

# Drop the original column brewery_name as the encoded columns are inplace
X_main_scaled_kmean.drop('brewery_name', axis = 1, inplace=True)
X_main_scaled_encoded = pd.concat([X_main_scaled_kmean, X_main_cat_enc], axis=1)

## Re-Add the beer_style_encoded ahead of splitting
X_main_scaled_encoded['beerstyle_encoded'] = y_main
X_main_scaled_encoded.head()<jupyter_output><empty_output><jupyter_text>11. Split the encoded and scaled 200k dataset into Train-Val-Test sets<jupyter_code>X_train, y_train, X_val, y_val, X_test, y_test = split_sets_random(X_main_scaled_encoded, "beerstyle_encoded", test_ratio=0.2, to_numpy=True)
# print(X_train.shape)
# print(X_val.shape)
# print(X_test.shape)<jupyter_output><empty_output><jupyter_text>12. Baseline Model<jupyter_code>from src.models.null import NullModel

base_model = NullModel(target_type="classification")
y_base = base_model.fit_predict(y_train)

from src.models.performance import print_reg_perf
print_reg_perf(y_base, y_train, set_name='Training')<jupyter_output>RMSE Training: 1586.89245
MAE Training: 26.471083333333333<jupyter_text>13. Load Pytorch Dataset<jupyter_code>from src.models.pytorch import PytorchDataset

train_dataset = PytorchDataset(X=X_train, y=y_train)
val_dataset = PytorchDataset(X=X_val, y=y_val)
test_dataset = PytorchDataset(X=X_test, y=y_test)<jupyter_output><empty_output><jupyter_text>14. Build Neural Net Model<jupyter_code>import torch as torch
import torch.nn as nn
from src.models.pytorch import PytorchMultiClass
import torch.nn.functional as F
%load_ext autoreload
%autoreload 2

model = PytorchMultiClass(X_train.shape[1])
from src.models.pytorch import get_device, predict
device = get_device()
model.to(device)
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.1)
from src.models.pytorch import train_classification, test_classification

N_EPOCHS = 10
BATCH_SIZE = 100

for epoch in range(N_EPOCHS):
    train_loss, train_acc = train_classification(train_dataset, model=model, criterion=criterion, optimizer=optimizer, batch_size=BATCH_SIZE, device=device)
    valid_loss, valid_acc = test_classification(val_dataset, model=model, criterion=criterion, batch_size=BATCH_SIZE, device=device)

    print(f'Epoch: {epoch}')
    print(f'\t(train)\t|\tLoss: {train_loss:.4f}\t|\tAcc: {train_acc * 100:.1f}%')
    print(f'\t(valid)\t|\tLoss: {valid_loss:.4f}\t|\tAcc: {valid_acc * 100:.1f}%')
test_loss, test_acc =  test_classification(test_dataset, model=model, criterion=criterion, batch_size=BATCH_SIZE, device=device)
print(f'\tLoss: {test_loss:4f}\t | \tAccuracy:{test_acc:.1f}')
torch.save(model, "../models/pytorch_multi_beer_type_prediction_nn_kmeans.pt")
import torch as torch
import os
import sys
sys.path.append(os.path.abspath('../'))

model = torch.load('../models/pytorch_multi_beer_type_prediction_nn_kmeans.pt', encoding='ascii')
model
from torch import Tensor
from src.models.pytorch import predict

# features=['brewery_name','review_aroma','review_appearance', 'review_palate', 'review_taste']
# query_data = pd.DataFrame([{5,7,8,3,5,4}], columns = features )
query_data =pd.DataFrame( {'brewery_name': [6, 6,8,9 ],
        'review_aroma': [22000,25000,27000,35000],
        'review_appearance': [7,8,4,3],
        'review_palate': [3,4,2,5],
        'review_taste': [1,3,5,6]
        })

#query_data_tensor = torch.tensor(query_data.to_numpy())

prediction = predict(query_data, model)
# #obs = pd.DataFrame(X_main_scaled_copy.iloc[0][num_cols]).transpose()
# prediction<jupyter_output>[autoreload of src.models.pytorch failed: Traceback (most recent call last):
  File "C:\Hnin\Anaconda3\lib\site-packages\IPython\extensions\autoreload.py", line 245, in check
    superreload(m, reload, self.old_objects)
  File "C:\Hnin\Anaconda3\lib\site-packages\IPython\extensions\autoreload.py", line 450, in superreload
    update_generic(old_obj, new_obj)
  File "C:\Hnin\Anaconda3\lib\site-packages\IPython\extensions\autoreload.py", line 387, in update_generic
    update(a, b)
  File "C:\Hnin\Anaconda3\lib\site-packages\IPython\extensions\autoreload.py", line 342, in update_class
    if update_generic(old_obj, new_obj): continue
  File "C:\Hnin\Anaconda3\lib\site-packages\IPython\extensions\autoreload.py", line 387, in update_generic
    update(a, b)
  File "C:\Hnin\Anaconda3\lib\site-packages\IPython\extensions\autoreload.py", line 342, in update_class
    if update_generic(old_obj, new_obj): continue
  File "C:\Hnin\Anaconda3\lib\site-packages\IPython\extensions\autoreload.py", li[...]
StarcoderdataJupyterStructuredCleanDedup