<jupyter_start><jupyter_text>**Machine Learning - case: estilo musical**  **Importando as bibliotecas necessárias**<jupyter_code>import sklearn
import pandas as pd
import numpy as np
# para ignorar os avisos de mensagens das funções
import warnings
warnings.filterwarnings("ignore")

# pacote para trabalhar com data frame (tabelas)
import pandas as pd
# pacote mais básico para vizualização gráfica
import matplotlib.pyplot as plt
# um dos pacotes para fazer gráficos
import seaborn as sns
# sklearn - pacote análise de dados
# existe grande parte dos métodos mais famosos
from sklearn.model_selection import train_test_split
# função para fazer avaliação dos modelos
from sklearn.metrics import classification_report<jupyter_output><empty_output><jupyter_text>**Explicação da base de dados*** **Base de dados**: devido à natureza artística da música, as classificações são frequentemente arbitrárias e controversas, e alguns gêneros podem se sobrepor.* **Variáveis**:  * filename - nome do arquivo conforme fornecido no conjunto de dados marsyas;  * tempo - a velocidade com que uma passagem de música é tocada;  * beats - unidade rítmica na música;  * chroma_stft - transformada de Fourier de curto tempo;  * rmse - erro de raiz quadrada média;  * spectral_centroid - indica onde o "centro de massa" do espectro está localizado;  * spectral_bandwidth - é o intervalo de comprimento de onda em que uma quantidade espectral irradiada não é inferior a metade de seu valor máximo;  * rolloff - roll-off é a inclinação de uma função de transmissão com frequência;  * zero_crossing_rate - a taxa na qual o sinal muda de positivo para negativo ou de volta;  * mfcc1 a mfcc20 - coeficientes cepstrais de frequência de Mel (MFCCs) são coeficientes que coletivamente constituem um MFC;  * label - o estilo musical da música.* **Objetivo**: treinar uma modelo e saiba a qual gênero sua música favorita pertence.  * A variável resposta será: label (nome do estilo musical).* **Técnica usada**: modelos ensembles: Bagging, Random Forest, AdaBoost, Gradiente Estocástico Boosting e Voting Ensemble.[base de dados](https://www.kaggle.com/insiyeah/musicfeatures)  **Carregando os dados**<jupyter_code>from google.colab import drive
drive.mount('/content/drive')
df = pd.read_csv('/content/drive/MyDrive/Colab Notebooks/Estagio_TAO_Python/Datasets/data_music.csv', sep = ",")

# tamanho da base de dados
print(df.shape)<jupyter_output>(1000, 30)<jupyter_text>Temos na base 30 variáveis, sendo 29 variáveis explciativas ($X$) e 1 variável resposta ($y$). Em cada linha temos dados de uma música.<jupyter_code># vizualizando as cinco primeiras linhas da base de dados
df.head(5)
df.label.unique()<jupyter_output><empty_output><jupyter_text>Nesta base de dados sobre música temos 10 estilos musicais, mostrados acima.  **Informações da base de dados** **Informações sobre os tipos das variáveis da base de dados**<jupyter_code>df.info()<jupyter_output><class 'pandas.core.frame.DataFrame'>
RangeIndex: 1000 entries, 0 to 999
Data columns (total 30 columns):
 #   Column              Non-Null Count  Dtype  
---  ------              --------------  -----  
 0   filename            1000 non-null   object 
 1   tempo               1000 non-null   float64
 2   beats               1000 non-null   int64  
 3   chroma_stft         1000 non-null   float64
 4   rmse                1000 non-null   float64
 5   spectral_centroid   1000 non-null   float64
 6   spectral_bandwidth  1000 non-null   float64
 7   rolloff             1000 non-null   float64
 8   zero_crossing_rate  1000 non-null   float64
 9   mfcc1               1000 non-null   float64
 10  mfcc2               1000 non-null   float64
 11  mfcc3               1000 non-null   float64
 12  mfcc4               1000 non-null   float64
 13  mfcc5               1000 non-null   float64
 14  mfcc6               1000 non-null   float64
 15  mfcc7               1000 non-null   float64
 16  mfcc8  [...]<jupyter_text>A base de dados tem 1000 linhas de dados, não havendo dados faltantes. A maiori dos dados é numérico (inteiro ou real), com exceção da label que é a variável resposta que contém o estilo musical da música e do filename, que tem o código da música. **Quantidade de dados por estilo musical**<jupyter_code>geral = pd.DataFrame([df['label'].value_counts(normalize = False), df['label'].value_counts(normalize = True)*100]).T
geral.columns = ['valor', 'proporção']
geral<jupyter_output><empty_output><jupyter_text>Verificamos que as classes referente ao estilo musical tem mesma proporção de dados.  **Análise descritiva dos dados** A seguir temos as estatísticas de cada variável da base de dados.<jupyter_code>df.describe().T<jupyter_output><empty_output><jupyter_text>**correlação entre as variáveis**<jupyter_code>corr = df.corr(method = 'spearman')
corr.style.background_gradient(cmap='coolwarm')<jupyter_output><empty_output><jupyter_text>* Com a matriz de correlação, podemos notar que há grande relação entre a vaariável tempo que se refere a velocidade da música e tempo que é o tempo total da música, o que instintivamente se espera porque o tempo total da música depende da velocidade.* Também verificamos correlação das variáveis "spectral_centroid", "spectral_bandwidth", "rolloff", "zero_crossing_rate", "mfcc1" com as variáveis "spectral_bandwidth", "rolloff", "zero_crossing_rate" entre si. O que referência a onda sonora e o espectro da onda, como as variáveis tem referência a aspectos semelhantes, faz sentido tem correlação entre estas variáveis.* Há outras correlações que são grande, mas nada que se deve ter um estudo separado. **Gráfico box plot para verificar existência de outliers**<jupyter_code>sns.boxplot(x = 'value', y = 'variable', data = df[['spectral_centroid', 'spectral_bandwidth',
                                                   'rolloff']].melt())
plt.show()
sns.boxplot(x = 'value', y = 'variable', data = df[['mfcc1']].melt())
plt.show()
sns.boxplot(x = 'value', y = 'variable', data = df[['tempo', 'mfcc2']].melt())
plt.show()
sns.boxplot(x = 'value', y = 'variable', data = df.drop(['filename', 'label', 'tempo', 'mfcc2',
                                                         'spectral_centroid', 'spectral_bandwidth',
                                                         'rolloff', 'mfcc1'], axis = 1).iloc[:, 0:28].melt())
plt.show()<jupyter_output><empty_output><jupyter_text>Pelos bloxplot acima verificamos que existe outliers na marioria das variáveis. Para remover os outliers utilizamos o código a seguir. Neste código removemos os valores abaixo de $Q1 - 1.5 IQR$ e acima de $Q3 + 1.5 IQR$, para cada uma das variáveis.<jupyter_code>for i in range(0, 26):
  data = df.drop(['filename', 'label'], axis = 1)
  name_column = data.columns[i]
  Q1 = data.describe().unstack()[name_column, '25%']
  Q3 = data.describe().unstack()[name_column, '75%']
  IQR = Q3 - Q1
  df_extra = np.array(data[name_column].values.tolist())
  df[name_column] = np.where(df_extra < Q1 - 1.5 * IQR, data.iloc[:, i].mean(), df_extra).tolist()
  df[name_column] = np.where(df_extra > Q3 + 1.5 * IQR, data.iloc[:, i].mean(), df_extra).tolist()
sns.boxplot(x = 'value', y = 'variable', data = df[['spectral_centroid', 'spectral_bandwidth',
                                                   'rolloff']].melt())
plt.show()
sns.boxplot(x = 'value', y = 'variable', data = df[['mfcc1']].melt())
plt.show()
sns.boxplot(x = 'value', y = 'variable', data = df[['tempo', 'mfcc2']].melt())
plt.show()
sns.boxplot(x = 'value', y = 'variable', data = df.drop(['filename', 'label', 'tempo', 'mfcc2',
                                                         'spectral_centroid', 'spectral_bandwidth',
                                                         'rolloff', 'mfcc1'], axis = 1).iloc[:, 0:28].melt())
plt.show()<jupyter_output><empty_output><jupyter_text>A maioria dos outliers foram removidos.  Normalizando as variáveis Neste passo separamos a variável explicativa ($X$) da variável resposta ($y$). Em seguinda normalizamos as variáveis, usando 'StandardScaler', para que fiquem na mesma escala.<jupyter_code>X = df.drop(['filename', 'label'], axis = 1)
y = df['label']
X.info()
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X = scaler.fit_transform(X)

X = pd.DataFrame(X, columns = df.drop(['filename', 'label'], axis = 1).columns)<jupyter_output><empty_output><jupyter_text>**Análise de Componentes Principais (PCA)** Usamos a análise de componentes principais para reduzir o tamanho da base de dados.<jupyter_code>from sklearn.decomposition import PCA
# escolhendo número de dimensões
pca = PCA()
pca.fit(X)
cumsum = np.cumsum(pca.explained_variance_ratio_)
d = np.argmax(cumsum >= 0.99999999) + 1
plt.plot(cumsum)
plt.ylabel('Variância explicada')
plt.xlabel('Dimensões')
plt.show()
from sklearn.decomposition import PCA
pca = PCA(n_components = d)
principalComponents = pca.fit_transform(X)
X = pd.DataFrame(data = principalComponents) #,  columns = ['principal component 1', 'principal component 2'])<jupyter_output><empty_output><jupyter_text>**Dados em treinamento e teste** Separamos dividimos os dados em dados de treinamento e dados de teste, sendo 30% para teste e 70% para treinamento.<jupyter_code># todas as colunas da base de dados
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.3, shuffle = 'False', random_state = 376)<jupyter_output><empty_output><jupyter_text>**Treinamento dos modelos Ensemble** * Agora com os dados organizados e arrumados aplicamos os modelos Ensemble.* Os modelos usados são os modelos ensemble. Os modelos ensemble são técnicas avançadas para resolver problemas conplexos, em que modelos independentes são conbinados para se conseguir um resultado melhor. A relação dos modelos usados é a seguinte:  * Bagging;  * Random Forest;  * AddaBoost;  * Gradiente Estocástico Boosting;  * Voting Ensemble.* Em cada aplicação de modelo, são apresentados os melhores modelos parâmetros usados em cada modelo ou o melhor modelo com seus parâmetros como no caso do modelo Voting Ensemble.  **Modelo Bagging**<jupyter_code>from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import BaggingClassifier
from sklearn import model_selection

kfold = model_selection.KFold(n_splits = 10, random_state = 376)
model_1 = BaggingClassifier(base_estimator = DecisionTreeClassifier(), n_estimators = 100, random_state = 376)

print(model_1.fit(X_train, y_train), '\n')

# predizendo a nota de novos alunos
y_pred = model_1.predict(X_test)

from sklearn.metrics import accuracy_score, confusion_matrix, classification_report

results_1 = accuracy_score(y_test, y_pred)
print('Acurácia modelo Bagging: {}.'.format(results_1))

print("Melhores parâmetros:")
print(model_1.base_estimator, '\n')

cm = confusion_matrix(y_test, y_pred)
sns.heatmap(cm, annot = True)
plt.show()

print(classification_report(y_test, y_pred))<jupyter_output>BaggingClassifier(base_estimator=DecisionTreeClassifier(ccp_alpha=0.0,
                                                        class_weight=None,
                                                        criterion='gini',
                                                        max_depth=None,
                                                        max_features=None,
                                                        max_leaf_nodes=None,
                                                        min_impurity_decrease=0.0,
                                                        min_impurity_split=None,
                                                        min_samples_leaf=1,
                                                        min_samples_split=2,
                                                        min_weight_fraction_leaf=0.0,
                                                        presort='deprecated',
                                                        random_state=None,
[...]<jupyter_text>**Random Forest Classification**<jupyter_code>from sklearn.ensemble import RandomForestClassifier

kfold = model_selection.KFold(n_splits = 10, random_state = 376)
model_rf = RandomForestClassifier(n_estimators = 100, max_features = 5)

print(model_rf.fit(X_train, y_train), '\n')

# predizendo a nota de novos alunos
y_pred = model_rf.predict(X_test)

from sklearn.metrics import accuracy_score, confusion_matrix, classification_report

results_rf = accuracy_score(y_test, y_pred)
print('Acurácia modelo Random Forest: {}.'.format(results_rf))

print("Melhores parâmetros:")
print(model_rf.base_estimator, '\n')

cm = confusion_matrix(y_test, y_pred)
sns.heatmap(cm, annot = True)
plt.show()

print(classification_report(y_test, y_pred))<jupyter_output>RandomForestClassifier(bootstrap=True, ccp_alpha=0.0, class_weight=None,
                       criterion='gini', max_depth=None, max_features=5,
                       max_leaf_nodes=None, max_samples=None,
                       min_impurity_decrease=0.0, min_impurity_split=None,
                       min_samples_leaf=1, min_samples_split=2,
                       min_weight_fraction_leaf=0.0, n_estimators=100,
                       n_jobs=None, oob_score=False, random_state=None,
                       verbose=0, warm_start=False) 

Acurácia modelo Random Forest: 0.62.
Melhores parâmetros:
DecisionTreeClassifier(ccp_alpha=0.0, class_weight=None, criterion='gini',
                       max_depth=None, max_features=None, max_leaf_nodes=None,
                       min_impurity_decrease=0.0, min_impurity_split=None,
                       min_samples_leaf=1, min_samples_split=2,
                       min_weight_fraction_leaf=0.0, presort='deprecated',
                       random_[...]<jupyter_text>**Modelo AdaBoost**<jupyter_code>from sklearn.ensemble import AdaBoostClassifier

kfold_ada = model_selection.KFold(n_splits = 10, random_state = 376)
model_ada = AdaBoostClassifier(n_estimators = 30, random_state = 376)

print(model_ada.fit(X_train, y_train), '\n')

# predizendo a nota de novos alunos
y_pred = model_ada.predict(X_test)
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report

results_ada = accuracy_score(y_test, y_pred)
print('Acurácia modelo AdaBoost: {}.'.format(results_ada))

print("Melhores parâmetros:")
print(model_ada.base_estimator, '\n')

cm = confusion_matrix(y_test, y_pred)
sns.heatmap(cm, annot = True)
plt.show()

print(classification_report(y_test, y_pred))<jupyter_output>AdaBoostClassifier(algorithm='SAMME.R', base_estimator=None, learning_rate=1.0,
                   n_estimators=30, random_state=376) 

Acurácia modelo AdaBoost: 0.15333333333333332.
Melhores parâmetros:
None<jupyter_text>**Modelo Gradiente Estocástico Boosting**<jupyter_code>from sklearn.ensemble import GradientBoostingClassifier

kfold_sgb = model_selection.KFold(n_splits = 10, random_state = 376)
model_sgb = GradientBoostingClassifier(n_estimators = 100, random_state = 376)

print(model_sgb.fit(X_train, y_train), '\n')

# predizendo a nota de novos alunos
y_pred = model_sgb.predict(X_test)

from sklearn.metrics import accuracy_score, confusion_matrix, classification_report

results_sgb = accuracy_score(y_test, y_pred)
print('Acurácia modelo Gradiente Estocástico Boosting: {}.'.format(results_sgb))

print("Melhores parâmetros:")
print(model_sgb.get_params, '\n')

cm = confusion_matrix(y_test, y_pred)
sns.heatmap(cm, annot = True)
plt.show()

print(classification_report(y_test, y_pred))<jupyter_output>GradientBoostingClassifier(ccp_alpha=0.0, criterion='friedman_mse', init=None,
                           learning_rate=0.1, loss='deviance', max_depth=3,
                           max_features=None, max_leaf_nodes=None,
                           min_impurity_decrease=0.0, min_impurity_split=None,
                           min_samples_leaf=1, min_samples_split=2,
                           min_weight_fraction_leaf=0.0, n_estimators=100,
                           n_iter_no_change=None, presort='deprecated',
                           random_state=376, subsample=1.0, tol=0.0001,
                           validation_fraction=0.1, verbose=0,
                           warm_start=False) 

Acurácia modelo Gradiente Estocástico Boosting: 0.6066666666666667.
Melhores parâmetros:
<bound method BaseEstimator.get_params of GradientBoostingClassifier(ccp_alpha=0.0, criterion='friedman_mse', init=None,
                           learning_rate=0.1, loss='deviance', max_depth=3,
                [...]<jupyter_text>**Modelo Voting Ensemble**<jupyter_code>from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.svm import SVC
from sklearn.ensemble import VotingClassifier

kfold_vc = model_selection.KFold(n_splits = 10, random_state = 376)
# Lines 2 to 8
estimators = []
mod_lr = LogisticRegression()
estimators.append(('logistic', mod_lr))
mod_dt = DecisionTreeClassifier()
estimators.append(('cart', mod_dt))
mod_sv = SVC()
estimators.append(('svm', mod_sv))
 
# Lines 9 to 11
ensemble = VotingClassifier(estimators)
results_vc = model_selection.cross_val_score(ensemble, X, y, cv = kfold_vc)
print(results_vc.mean())

from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.svm import SVC
from sklearn.ensemble import VotingClassifier

kfold_vc = model_selection.KFold(n_splits = 10, random_state = 376)
# Lines 2 to 8
estimators = []
mod_lr = LogisticRegression()
estimators.append(('logistic', mod_lr))
mod_dt = DecisionTreeClassifier()
estimators.append(('cart', mod_dt))
mod_sv = SVC()
estimators.append(('svm', mod_sv))

# Lines 9 to 11
ensemble = VotingClassifier(estimators)
print(ensemble.fit(X_train, y_train), '\n')

# predizendo a nota de novos alunos
y_pred = ensemble.predict(X_test)

from sklearn.metrics import accuracy_score, confusion_matrix, classification_report

results_vc = accuracy_score(y_test, y_pred)
print('Acurácia modelo Voting Ensemble: {}.'.format(results_vc))

print("Melhores parâmetros:")
print(ensemble.named_estimators_, '\n')

cm = confusion_matrix(y_test, y_pred)
sns.heatmap(cm, annot = True)
plt.show()

print(classification_report(y_test, y_pred))<jupyter_output>0.0
VotingClassifier(estimators=[('logistic',
                              LogisticRegression(C=1.0, class_weight=None,
                                                 dual=False, fit_intercept=True,
                                                 intercept_scaling=1,
                                                 l1_ratio=None, max_iter=100,
                                                 multi_class='auto',
                                                 n_jobs=None, penalty='l2',
                                                 random_state=None,
                                                 solver='lbfgs', tol=0.0001,
                                                 verbose=0, warm_start=False)),
                             ('cart',
                              DecisionTreeClassifier(ccp_alpha=0.0,
                                                     class_weight=None,
                                                     criterion...
                                    [...]<jupyter_text>**Resumo dos modelos** Por último apresentamos os resultados da acurácia dos modelos em forma de tabela e gráfico.<jupyter_code>import pandas as pd

results_ac = []
results_ac.append(round(results_1.mean(), 4))
results_ac.append(round(results_rf.mean(), 4))
results_ac.append(round(results_sgb.mean(), 4))
results_ac.append(round(results_ada.mean(), 4))
results_ac.append(round(results_vc.mean(), 4))
names = ['Bagging', 'Random Forest', 'Boosting Adaptável', 'AdaBoost', 'Voting Ensemble']
results_final = pd.DataFrame([names, results_ac]).T
results_final.columns = ['Modelo Ensemble', 'Acurácia']
results_final
results_final.sort_values(['Acurácia'], ascending = False)
plt.scatter(results_final['Acurácia'], results_final['Modelo Ensemble'])
for i in range(0, len(results_final['Acurácia'])):
  plt.annotate(results_final['Acurácia'][i], xy = (results_final['Acurácia'][i], 0.05 + i),
               xytext = (results_final['Acurácia'][i] - 0.14, -0.08 + i))
plt.title('Acurácia dos modelos Ensemble')
axes = plt.gca()
axes.set_xlim([0, 1])
# plt.set_ylim([ymin,ymax])
plt.show()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1010439235769155, 'fraction_numerical': 0.02132164664171755, 'mean_word_length': 3.2407600751722696, 'pattern_counts': {'":': 0, '<': 69, '<?xml version=': 0, '>': 69, 'https://': 1, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 3, 'word_list_counts': {'cursed_substrings.json': 57, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '18', 'dir': 'jupyter-structured-clean-dedup', 'id': '222604', 'license': 'MIT', 'n_tokens_mistral': 6913, 'n_tokens_neox': 6462, 'n_words': 1617, 'path': 'Case - Estilo Musical.ipynb', 'repo_name': 'fillipepierin/Portfolio_Data_Science', 'size': '20308'}