{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# 1. Classificador ZeroR\n\nEste notebook foi criado com o objetivo de mostrar o resultado obtido por um classificador que sempre classifica com a classe zero. Um motivo para fazer isso é que as classes são desbalanceadas, como será mostrado.\nAdicionalmente será mostrado que, para a métrica desta competição, os valores das probabilidades não são o mais importante, e sim a ordem das probabilidades para cada exemplo.\nFoi escolhida a competição [Santander Customer Transaction Prediction](https://www.kaggle.com/c/santander-customer-transaction-prediction/overview). Essa é uma competição encerrada em Abril de 2019 que ofereceu US$ 65.000 do 1° ao 5° lugares. Nessa competição, o objetivo é prever quais clientes irão realizar uma transação específica no futuro, independente do valor.","metadata":{}},{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport seaborn as sns # gráficos\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"execution":{"iopub.status.busy":"2022-07-17T22:15:02.874204Z","iopub.execute_input":"2022-07-17T22:15:02.874477Z","iopub.status.idle":"2022-07-17T22:15:02.893530Z","shell.execute_reply.started":"2022-07-17T22:15:02.874449Z","shell.execute_reply":"2022-07-17T22:15:02.892501Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df= pd.read_csv(\"../input/santander-customer-transaction-prediction/train.csv\")\ntest_df = pd.read_csv('../input/santander-customer-transaction-prediction/test.csv')\nsample_submission = pd.read_csv('../input/santander-customer-transaction-prediction/sample_submission.csv')\n#sample_submission.head()","metadata":{"execution":{"iopub.status.busy":"2022-07-17T22:15:06.931891Z","iopub.execute_input":"2022-07-17T22:15:06.932695Z","iopub.status.idle":"2022-07-17T22:15:24.899411Z","shell.execute_reply.started":"2022-07-17T22:15:06.932639Z","shell.execute_reply":"2022-07-17T22:15:24.898447Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Uma análise superficial de dados permite observar que existem muito mais transações com probabilidade 0 (não realizadas) do que transações com probabilidade 1 (realizadas).","metadata":{}},{"cell_type":"code","source":"train_df.target.value_counts()","metadata":{"execution":{"iopub.status.busy":"2022-07-17T22:16:11.765164Z","iopub.execute_input":"2022-07-17T22:16:11.765488Z","iopub.status.idle":"2022-07-17T22:16:11.774859Z","shell.execute_reply.started":"2022-07-17T22:16:11.765452Z","shell.execute_reply":"2022-07-17T22:16:11.774107Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sns.countplot(x = train_df.target.values)","metadata":{"execution":{"iopub.status.busy":"2022-07-17T22:15:40.113426Z","iopub.execute_input":"2022-07-17T22:15:40.114157Z","iopub.status.idle":"2022-07-17T22:15:40.348601Z","shell.execute_reply.started":"2022-07-17T22:15:40.114113Z","shell.execute_reply":"2022-07-17T22:15:40.347691Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"A partir dessas observações, é possível concluir que um classificador do tipo ZeroR terá um desempenho melhor se sempre \"chutar\" a probabilidade 0 (transação não realizada).\n\nConvenientemente já é fornecida uma tabela no arquivo \"sample_submission.csv\" importada para o dataframe \"sample_submission\".","metadata":{}},{"cell_type":"code","source":"sample_submission.target.value_counts()","metadata":{"execution":{"iopub.status.busy":"2022-07-17T22:30:27.796471Z","iopub.execute_input":"2022-07-17T22:30:27.796808Z","iopub.status.idle":"2022-07-17T22:30:27.805750Z","shell.execute_reply.started":"2022-07-17T22:30:27.796774Z","shell.execute_reply":"2022-07-17T22:30:27.805101Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sns.countplot(x = sample_submission.target.values)","metadata":{"execution":{"iopub.status.busy":"2022-07-17T22:30:56.306779Z","iopub.execute_input":"2022-07-17T22:30:56.307667Z","iopub.status.idle":"2022-07-17T22:30:56.512426Z","shell.execute_reply.started":"2022-07-17T22:30:56.307619Z","shell.execute_reply":"2022-07-17T22:30:56.511298Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"O código a seguir, realiza a submissão com todos os \"chutes\" em 0.","metadata":{}},{"cell_type":"code","source":"y_envio = sample_submission\ny_envio.to_csv(\"submission.csv\", index=False)","metadata":{"execution":{"iopub.status.busy":"2022-05-28T02:21:43.014385Z","iopub.execute_input":"2022-05-28T02:21:43.015059Z","iopub.status.idle":"2022-05-28T02:21:43.845098Z","shell.execute_reply.started":"2022-05-28T02:21:43.015003Z","shell.execute_reply":"2022-05-28T02:21:43.844271Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 2. Sobre a métrica da competição\n\nConforme regramento, os resultados submetidos à competição serão avaliados pela área sob a [curva ROC](https://en.wikipedia.org/wiki/Receiver_operating_characteristic), nesse caso é possível observar (vide pontuação do presente notebook) que é obtido um resultado ruim porém previsível (0,5) para um classificador aleatório.\n\nA seguir, seguem os resultados de pequenos testes do funcionamento da métrica roc_auc_score do sklearn.\n\nO primeiro teste mostra um classificador acertando \"na mosca\".\n","metadata":{}},{"cell_type":"code","source":"from sklearn.metrics import roc_auc_score\n\ny_true = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]\ny_score = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]\nscore = roc_auc_score(y_true, y_score)\nprint(\"Perfeito: \",score)","metadata":{"execution":{"iopub.status.busy":"2022-07-18T12:33:01.920425Z","iopub.execute_input":"2022-07-18T12:33:01.921069Z","iopub.status.idle":"2022-07-18T12:33:03.059869Z","shell.execute_reply.started":"2022-07-18T12:33:01.920962Z","shell.execute_reply":"2022-07-18T12:33:03.058808Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"A seguir, é mostrada a métrica para um classificador que errou todas as previsões.","metadata":{}},{"cell_type":"code","source":"y_score = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]\nscore = roc_auc_score(y_true, y_score)\nprint(\"Errado perfeito: \",score)","metadata":{"execution":{"iopub.status.busy":"2022-07-18T12:33:35.612856Z","iopub.execute_input":"2022-07-18T12:33:35.613325Z","iopub.status.idle":"2022-07-18T12:33:35.622107Z","shell.execute_reply.started":"2022-07-18T12:33:35.613291Z","shell.execute_reply":"2022-07-18T12:33:35.621239Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Esse resultado mostra uma área sob a curva ROC de 0, que é o pior resultado possível.\nA seguir é calculada a métrica para um classificador que \"chuta\" sempre zero.","metadata":{}},{"cell_type":"code","source":"y_score = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]\nscore = roc_auc_score(y_true, y_score)\nprint(\"Zeros: \",score)","metadata":{"execution":{"iopub.status.busy":"2022-07-18T12:34:04.941818Z","iopub.execute_input":"2022-07-18T12:34:04.942137Z","iopub.status.idle":"2022-07-18T12:34:04.951223Z","shell.execute_reply.started":"2022-07-18T12:34:04.942103Z","shell.execute_reply":"2022-07-18T12:34:04.950332Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Curiosamente, esse classificador obtém o mesmo resultado da submissão deste notebook.\nSerá realizado novamente o mesmo teste \"chutando\" sempre um.","metadata":{}},{"cell_type":"code","source":"y_score = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]\nscore = roc_auc_score(y_true, y_score)\nprint(\"Uns: \",score)","metadata":{"execution":{"iopub.status.busy":"2022-07-18T12:34:35.904113Z","iopub.execute_input":"2022-07-18T12:34:35.905102Z","iopub.status.idle":"2022-07-18T12:34:35.913735Z","shell.execute_reply.started":"2022-07-18T12:34:35.905044Z","shell.execute_reply":"2022-07-18T12:34:35.912923Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Novamente foi obtido o mesmo resultado.\nA seguir, será realizado o cálculo da métrica para um classificador que resulta apenas em probabilidades baixas para a classe 1, porém com probabilidades ligeiramente maiores para os exemplos que realmente são da classe 1.","metadata":{}},{"cell_type":"code","source":"y_score = [0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,\n           0.2,0.2,0.2,0.2,0.2,0.2,0.2,0.2,0.2,0.2,0.2,0.2,0.2,0.2,0.2]\nscore = roc_auc_score(y_true, y_score)\nprint(\"Baixo: \",score)","metadata":{"execution":{"iopub.status.busy":"2022-07-18T12:36:01.292554Z","iopub.execute_input":"2022-07-18T12:36:01.292899Z","iopub.status.idle":"2022-07-18T12:36:01.302988Z","shell.execute_reply.started":"2022-07-18T12:36:01.292844Z","shell.execute_reply":"2022-07-18T12:36:01.302057Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Curiosamente o resultado foi o mesmo do classificador que acertou \"na mosca\". Apesar de as probabilidades serem baixas, o que intuitivamente sugere que os resultados  serão da classe 0, é como se o limiar entre as previsões da classe 0 e da classe 1 fosse perfeitamente escolhido em um valor entre 0,1 e 0,2.\n\nSerá realizado outro teste, porém com as probabilidades próximas a 1","metadata":{}},{"cell_type":"code","source":"y_score = [0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.8,\n           0.9,0.9,0.9,0.9,0.9,0.9,0.9,0.9,0.9,0.9,0.9,0.9,0.9,0.9,0.9]\nscore = roc_auc_score(y_true, y_score)\nprint(\"Alto: \",score)","metadata":{"execution":{"iopub.status.busy":"2022-07-18T12:37:53.998035Z","iopub.execute_input":"2022-07-18T12:37:53.998450Z","iopub.status.idle":"2022-07-18T12:37:54.007525Z","shell.execute_reply.started":"2022-07-18T12:37:53.998419Z","shell.execute_reply":"2022-07-18T12:37:54.006617Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"O resultado foi o mesmo. É como se o limiar entre as previsões da classe 0 e da classe 1 fosse perfeitamente escolhido em um valor entre 0,8 e 0,9.\nEsse mesmo comportamento pode ser observado para um conjunto de valores que estão fora da faixa intuitiva de probabilidade entre 0 e 1.","metadata":{}},{"cell_type":"code","source":"y_score = [-20,-20,-20,-20,-20,-20,-20,-10,-10,-10,-10,-10,-10,-10,-10,\n           100,100,100,100,100,100,100,200,200,200,200,200,200,200,200]\nscore = roc_auc_score(y_true, y_score)\nprint(\"Maluco: \",score)","metadata":{"execution":{"iopub.status.busy":"2022-07-18T12:39:53.329624Z","iopub.execute_input":"2022-07-18T12:39:53.329955Z","iopub.status.idle":"2022-07-18T12:39:53.341188Z","shell.execute_reply.started":"2022-07-18T12:39:53.329920Z","shell.execute_reply":"2022-07-18T12:39:53.340456Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Esse comportamento sugere que, mais importante que prever a classe mais provável para cada exemplo, é prever a sequencia correta de probabilidades.","metadata":{}}]}