<jupyter_start><jupyter_text>Model 1 *Author: <NAME>*OpenFace feature extraction is done in Google Colab.Link to the Colab notebook: [Click here](https://colab.research.google.com/drive/1EVXGv7-Fd1QOEvSTtXCIvszrPXx1L4u4?usp=sharing)Datasets are in Google Drive: [Click here](https://drive.google.com/drive/folders/1cryZ_pzgiwqeNCOoRfbieRLCpivMktjG?usp=sharing)To restore the datasets in place:- for FePh: download the Feph/processed and FePh/FePh_labels.csv into ../datasets folder- for IMPA-FACES3D: download the facesdb/process into ../datasets folderSklearn requires version=0.23.2<jupyter_code>import sklearn
print('The scikit-learn version is {}.'.format(sklearn.__version__))<jupyter_output>The scikit-learn version is 0.23.2.<jupyter_text>IMPA-FACES3D: 3D facial expression databaseRef: http://app.visgraf.impa.br/database/faces/about/  Find and Load All the Data Files<jupyter_code>import glob
facesdb_processed = glob.glob("../datasets/facesdb/processed/*.csv")
len(facesdb_processed)<jupyter_output><empty_output><jupyter_text>Preprocessing<jupyter_code># this is from the dataset webpage
emotion_mapping = {
    "00": "neutral frontal",
    "01": "joy",
    "02": "sadness",
    "03": "surprise",
    "04": "anger",
    "05": "disgust",
    "06": "fear"
}
from pathlib import Path
Path(facesdb_processed[0]).stem.split("-")[1].split("_")[0]
import pandas as pd
facesdb_labels_df = pd.DataFrame(
    {
        "file":[f"{Path(f).stem}.bmp" for f in facesdb_processed],
        "emotion":[emotion_mapping.get(Path(f).stem.split("-")[1].split("_")[0]) for f in facesdb_processed]
    }
)
facesdb_labels_df
processed_list = []
for f in facesdb_processed:
    processed_list.append(pd.read_csv(f, sep=',\s+', delimiter=',', encoding="utf-8", skipinitialspace=True))
facesdb_all_processed = pd.concat(processed_list)
facesdb_all_processed
facesdb_all_processed["file"] = [f"{Path(f).stem}.bmp" for f in facesdb_processed]
facesdb_all_processed = facesdb_all_processed.reset_index().drop(["index","face"], axis=1)
def filter_low_confidence(df, level=0.0):
    return df[df["confidence"] >= level]
facesdb_all_processed_filtered = filter_low_confidence(facesdb_all_processed, level=0.5)
# after filtering out records have confidence level lower than 0.5
print(facesdb_all_processed_filtered.shape)
facesdb_all_processed_features = facesdb_all_processed_filtered[['confidence', 'AU01_r', 'AU02_r', 'AU04_r', 'AU05_r',
       'AU06_r', 'AU07_r', 'AU09_r', 'AU10_r', 'AU12_r', 'AU14_r',
       'AU15_r', 'AU17_r', 'AU20_r', 'AU23_r', 'AU25_r', 'AU26_r',
       'AU45_r', 'AU01_c', 'AU02_c', 'AU04_c', 'AU05_c', 'AU06_c',
       'AU07_c', 'AU09_c', 'AU10_c', 'AU12_c', 'AU14_c', 'AU15_c',
       'AU17_c', 'AU20_c', 'AU23_c', 'AU25_c', 'AU26_c', 'AU28_c',
       'AU45_c', 'file']]
facesdb_featrues_labels = facesdb_all_processed_features.merge(facesdb_labels_df, on="file")
facesdb_featrues_labels<jupyter_output><empty_output><jupyter_text>Use Sklearn Implementation of Classifers<jupyter_code>from joblib import dump, load
from sklearn.model_selection import train_test_split
faces_X_r = facesdb_featrues_labels.iloc[:,1:18]
faces_X_r
faces_X_c = facesdb_featrues_labels.iloc[:,18:36]
faces_X_c
faces_y = facesdb_featrues_labels.iloc[:,-1:]
faces_y<jupyter_output><empty_output><jupyter_text>Multilabel<jupyter_code>faces_X_r_train, faces_X_r_test, faces_y_train, faces_y_test = train_test_split(faces_X_r, faces_y, test_size=0.33, random_state=98)
faces_X_c_train, faces_X_c_test, faces_y_train, faces_y_test = train_test_split(faces_X_c, faces_y, test_size=0.33, random_state=98)<jupyter_output><empty_output><jupyter_text>Try AU_r first<jupyter_code>from sklearn.decomposition import PCA
import numpy as np
can_n_components = range(1, 18, 1)
ratios = []
for n in can_n_components:
    pca = PCA(n_components=n)
    faces_X_r_pca = pca.fit_transform(faces_X_r)
    ratios.append(np.sum(pca.explained_variance_ratio_))
from matplotlib import pyplot as plt
plt.figure(figsize=(10, 5))
plt.grid()
plt.plot(can_n_components, ratios)
plt.xlabel('Number of PCA Components')
plt.ylabel('Explained Variance Ratio')
plt.title('Explained variance ratio for PCA')
plt.yticks(np.arange(0.2, 1.05, .05))
plt.xticks(np.arange(1, 18, 1));<jupyter_output><empty_output><jupyter_text>Let's choose 95% explained variance ratio, so n = 9<jupyter_code>n = 9
pca_r = PCA(n_components=n, svd_solver='randomized', whiten=True).fit(faces_X_r_train)
faces_X_r_train_pca = pca_r.transform(faces_X_r_train)
faces_X_r_test_pca = pca_r.transform(faces_X_r_test)
import pickle as pk
pk.dump(pca_r, open("pca_faces_aur.pkl","wb"))<jupyter_output><empty_output><jupyter_text>Try SVM On AU_r<jupyter_code>from sklearn.model_selection import GridSearchCV
from sklearn.multioutput import MultiOutputClassifier
from sklearn.svm import SVC
print("Searching the best parameters for SVC...")
param_grid = {
    "estimator__C": np.arange(10,100,20),
    "estimator__gamma": [0.0001, 0.0005, 0.001, 0.005, 0.0025, 0.01],
    "estimator__class_weight": [None, "balanced"],
    "estimator__decision_function_shape": ["ovo", "ovr"],
    "estimator__probability": [True, False]
}
svm_faces_aur_clf = GridSearchCV(
    MultiOutputClassifier(
        SVC()
    ), 
    param_grid, 
    verbose=1, 
    n_jobs=6
)
svm_faces_aur_clf = svm_faces_aur_clf.fit(faces_X_r_train_pca, faces_y_train)
print(f"Best parameters for SVC: {svm_faces_aur_clf.best_params_}")
svm_faces_aur_clf.best_estimator_.score(faces_X_r_test_pca, faces_y_test)
dump(svm_faces_aur_clf, 'svm_faces_aur_clf.joblib')
faces_X_r_test_pca[0]
svm_faces_aur_clf.best_estimator_.predict_proba([faces_X_r_test_pca[0]])[0][0]
dict(zip([1,2],[2,3]))<jupyter_output><empty_output><jupyter_text>On AU_c<jupyter_code>can_n_components = range(1, 18, 1)
ratios = []
for n in can_n_components:
    pca = PCA(n_components=n)
    faces_X_c_pca = pca.fit_transform(faces_X_r)
    ratios.append(np.sum(pca.explained_variance_ratio_))
plt.figure(figsize=(10, 5))
plt.grid()
plt.plot(can_n_components, ratios)
plt.xlabel('Number of PCA Components')
plt.ylabel('Explained Variance Ratio')
plt.title('Explained variance ratio for PCA')
plt.yticks(np.arange(0.2, 1.05, .05))
plt.xticks(np.arange(1, 18, 1));
n = 9
pca_c = PCA(n_components=n, svd_solver='randomized', whiten=True).fit(faces_X_c_train)
faces_X_c_train_pca = pca_c.transform(faces_X_c_train)
faces_X_c_test_pca = pca_c.transform(faces_X_c_test)
print("Searching the best parameters for SVC...")
param_grid = {
    "estimator__C": np.arange(10,100,20),
    "estimator__gamma": [0.0001, 0.0005, 0.001, 0.005, 0.0025, 0.01],
    "estimator__class_weight": [None, "balanced"],
    "estimator__decision_function_shape": ["ovo", "ovr"],
    "estimator__probability": [True, False]
}
svm_faces_auc_clf = GridSearchCV(
    MultiOutputClassifier(
        SVC()
    ), 
    param_grid, 
    verbose=1, 
    n_jobs=6
)
svm_faces_auc_clf = svm_faces_auc_clf.fit(faces_X_c_train_pca, faces_y_train)
print(f"Best parameters for SVC: {svm_faces_auc_clf.best_params_}")
svm_faces_auc_clf.best_estimator_.score(faces_X_c_test_pca, faces_y_test)
dump(svm_faces_auc_clf, 'svm_faces_auc_clf.joblib')<jupyter_output><empty_output><jupyter_text>Try KNN<jupyter_code>from sklearn.neighbors import KNeighborsClassifier<jupyter_output><empty_output><jupyter_text>On AU_r<jupyter_code>print("Searching the best parameters for KNN...")
param_grid = {
    "estimator__n_neighbors": np.arange(1,15,1),
    "estimator__weights": ["uniform", "distance"],
    "estimator__algorithm": ["auto", "ball_tree", "kd_tree", "brute"],
    "estimator__leaf_size": np.arange(1,15,1),
    "estimator__p": [1, 2]
}
knn_faces_aur_clf = GridSearchCV(
    MultiOutputClassifier(
        KNeighborsClassifier()
    ), 
    param_grid, 
    verbose=1, 
    n_jobs=6
)
knn_faces_aur_clf = knn_faces_aur_clf.fit(faces_X_r_train_pca, faces_y_train)
print(f"Best parameters for SVC: {knn_faces_aur_clf.best_params_}")
knn_faces_aur_clf.best_estimator_.score(faces_X_r_test_pca, faces_y_test)
dump(knn_faces_aur_clf, 'knn_faces_aur_clf.joblib')<jupyter_output><empty_output><jupyter_text>On AU_c<jupyter_code>print("Searching the best parameters for KNN...")
param_grid = {
    "estimator__n_neighbors": np.arange(1,15,1),
    "estimator__weights": ["uniform", "distance"],
    "estimator__algorithm": ["auto", "ball_tree", "kd_tree", "brute"],
    "estimator__leaf_size": np.arange(1,15,1),
    "estimator__p": [1, 2]
}
knn_faces_auc_clf = GridSearchCV(
    MultiOutputClassifier(
        KNeighborsClassifier()
    ), 
    param_grid, 
    verbose=1, 
    n_jobs=6
)
knn_faces_auc_clf = knn_faces_auc_clf.fit(faces_X_c_train_pca, faces_y_train)
print(f"Best parameters for SVC: {knn_faces_auc_clf.best_params_}")
knn_faces_auc_clf.best_estimator_.score(faces_X_c_test_pca, faces_y_test)
dump(knn_faces_auc_clf, 'knn_faces_auc_clf.joblib')<jupyter_output><empty_output><jupyter_text>Try boost KNN with scaler that uses AU_r data<jupyter_code>from sklearn.preprocessing import StandardScaler, MinMaxScaler, RobustScaler
from sklearn.pipeline import make_pipeline<jupyter_output><empty_output><jupyter_text>Best parameters for SVC: {'estimator__algorithm': 'auto', 'estimator__leaf_size': 1, 'estimator__n_neighbors': 1, 'estimator__p': 2, 'estimator__weights': 'uniform'}<jupyter_code>names = [
    "Stander-KNN",
    "MinMax-KNN",
    "Robust-KNN"
]
scaler_knn_aur_clfs = [
    make_pipeline(
        StandardScaler(),
        KNeighborsClassifier(
            algorithm="auto",
            leaf_size=1,
            n_neighbors=13,
            p=2,
            weights="uniform"
        )
    ),
    make_pipeline(
        MinMaxScaler(),
        KNeighborsClassifier(
            algorithm="auto",
            leaf_size=1,
            n_neighbors=13,
            p=2,
            weights="uniform"
        )
    ),
    make_pipeline(
        RobustScaler(),
        KNeighborsClassifier(
            algorithm="auto",
            leaf_size=1,
            n_neighbors=13,
            p=2,
            weights="uniform"
        )
    )
]
scaler_knn_aur_clf_clc = {}
for name, clf in zip(names, scaler_knn_aur_clfs):
    clf = clf.fit(faces_X_r_train_pca, faces_y_train)
    score = clf.score(faces_X_r_test_pca, faces_y_test)
    scaler_knn_aur_clf_clc.update(
        {
            name:{
                "clf":clf,
                "score":score
            }
        }
    )
scaler_knn_aur_clf_clc<jupyter_output>/home/liam/anaconda3/envs/py3.8.3/lib/python3.8/site-packages/sklearn/pipeline.py:335: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel().
  self._final_estimator.fit(Xt, y, **fit_params_last_step)
/home/liam/anaconda3/envs/py3.8.3/lib/python3.8/site-packages/sklearn/pipeline.py:335: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel().
  self._final_estimator.fit(Xt, y, **fit_params_last_step)
/home/liam/anaconda3/envs/py3.8.3/lib/python3.8/site-packages/sklearn/pipeline.py:335: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel().
  self._final_estimator.fit(Xt, y, **fit_params_last_step)<jupyter_text>This is not really helping...<jupyter_code>names = [
    "SVM on AU_r",
    "SVM on AU_c",
    "KNN on AU_r",
    "KNN on AU_c"
]
scores = [
    svm_faces_aur_clf.best_estimator_.score(faces_X_r_test_pca, faces_y_test),
    svm_faces_auc_clf.best_estimator_.score(faces_X_c_test_pca, faces_y_test),
    knn_faces_aur_clf.best_estimator_.score(faces_X_r_test_pca, faces_y_test),
    knn_faces_auc_clf.best_estimator_.score(faces_X_c_test_pca, faces_y_test)
]
fig, ax = plt.subplots()
plt.bar(names, scores)
plt.title("Classifier on Different Set of Features")
plt.show()<jupyter_output><empty_output><jupyter_text>Try MLPRef: https://stats.stackexchange.com/questions/181/how-to-choose-the-number-of-hidden-layers-and-nodes-in-a-feedforward-neural-netw<jupyter_code>faces_X_r_train.shape
faces_y_train<jupyter_output><empty_output><jupyter_text>Nh=Ns(α∗(Ni+No))- Ni = number of input neurons.- No = number of output neurons.- Ns = number of samples in training data set.- α = an arbitrary scaling factor usually 2-10.168*(2*(17+7)) = 80648064/4 = 2016<jupyter_code>from sklearn.neural_network import MLPClassifier
print("Searching the best parameters for MLP...")
param_grid = {
    "estimator__activation": ["identity", "logistic", "tanh", "relu"],
    "estimator__solver": ["lbfgs", "sgd", "adam"],
    "estimator__alpha": np.arange(0.00001,0.001,0.0005),
    "estimator__beta_1": np.arange(0.1,0.9,0.8),
    "estimator__beta_2": np.arange(0.1,0.9,0.8),
    "estimator__hidden_layer_sizes": [(2016,2016,2016,2016)],
    "estimator__learning_rate": ["constant", "invscaling", "adaptive"]
}
mlp_faces_aur_clf = GridSearchCV(
    MultiOutputClassifier(
        MLPClassifier()
    ), 
    param_grid, 
    verbose=1, 
    n_jobs=6
)
mlp_faces_aur_clf = mlp_faces_aur_clf.fit(faces_X_r_train_pca, faces_y_train)
print(f"Best parameters for SVC: {mlp_faces_aur_clf.best_params_}")
mlp_faces_aur_clf.best_estimator_.score(faces_X_r_test_pca, faces_y_test)
dump(mlp_faces_aur_clf, 'mlp_faces_aur_clf.joblib')
print("Searching the best parameters for MLP...")
param_grid = {
    "estimator__activation": ["identity", "logistic", "tanh", "relu"],
    "estimator__alpha": np.arange(0.0000001,0.001,0.0002),
    "estimator__beta_1": np.arange(0,0.9,0.1),
    "estimator__beta_2": np.arange(0,0.9,0.1),
    "estimator__hidden_layer_sizes": [(2016,2016,2016,2016)],
    "estimator__learning_rate": ["constant", "invscaling", "adaptive"]
}
mlp_faces_auc_clf = GridSearchCV(
    MultiOutputClassifier(
        MLPClassifier()
    ), 
    param_grid, 
    verbose=1, 
    n_jobs=6
)
mlp_faces_auc_clf = mlp_faces_auc_clf.fit(faces_X_c_train_pca, faces_y_train)
print(f"Best parameters for SVC: {mlp_faces_aur_clf.best_params_}")
mlp_faces_auc_clf.best_estimator_.score(faces_X_c_test_pca, faces_y_test)
dump(mlp_faces_auc_clf, 'mlp_faces_auc_clf.joblib')<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.13043478260869565, 'fraction_numerical': 0.031096102434219782, 'mean_word_length': 5.484945255474453, 'pattern_counts': {'":': 44, '<': 68, '<?xml version=': 0, '>': 69, 'https://': 3, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '17', 'dir': 'jupyter-structured-clean-dedup', 'id': '473073', 'license': 'Apache-2.0', 'n_tokens_mistral': 6038, 'n_tokens_neox': 5688, 'n_words': 870, 'path': 'notebooks/model1-FacesDB.ipynb', 'repo_name': 'siicosmos/emotion-picture-correlator', 'size': '14217'}