<jupyter_start><jupyter_text>Análise preliminar do conjunto de dadosEsse **Jupyter Notebook** tem como objetivo fazer uma análise preliminar do conjunto de dados. Nenhum Pré-Processamento, modelagem ou predição será feita agora. Apenas observações para trabalhos futuros.  01 -  Baixando & Importando as bibliotecas necessárias Inicialmente vamos baixar as bibliotecas necessárias para nossa análise (Eu já tenho todas baixadas no meu ambiente virtual, mas você pode remover o comentário e baixar para sua máquina local ou Ambiente Virtual).<jupyter_code>#!pip install --upgrade -r ../requirements.txt --user<jupyter_output><empty_output><jupyter_text>Agora vamos importar as bibliotecas:<jupyter_code>import matplotlib.pyplot as plt
import scipy.stats as stats
import seaborn as sns
import pandas as pd
import py7zr<jupyter_output><empty_output><jupyter_text>02 - OverviewVamos iniciar com uma **Visão Geral (Overview)** do conjunto de dados:<jupyter_code># For Linux users.
with py7zr.SevenZipFile("../datasets/Train_rev1.7z", mode='r') as archive:
  archive.extractall(path="/tmp")
# For Windows users.
with py7zr.SevenZipFile("../datasets/Train_rev1.7z", mode='r') as archive:
  archive.extractall(path="C:\Windows\Temp")<jupyter_output><empty_output><jupyter_text>**NOTE:**  Como é conjunto de dados é muito grande resolvi baixar a versão mais comprimida **.7z**. Optei também por descomprimir o conjunto de dados em um local temporário (diretório **/temp** no meu caso que estou utilizando Linux).<jupyter_code># For Linux users.
df = pd.read_csv("/tmp/Train_rev1.csv")
# For Windows users.
df = pd.read_csv("C:\Windows\Temp\Train_rev1.csv")
df.head()
df.info()<jupyter_output><class 'pandas.core.frame.DataFrame'>
RangeIndex: 244768 entries, 0 to 244767
Data columns (total 12 columns):
 #   Column              Non-Null Count   Dtype 
---  ------              --------------   ----- 
 0   Id                  244768 non-null  int64 
 1   Title               244767 non-null  object
 2   FullDescription     244768 non-null  object
 3   LocationRaw         244768 non-null  object
 4   LocationNormalized  244768 non-null  object
 5   ContractType        65442 non-null   object
 6   ContractTime        180863 non-null  object
 7   Company             212338 non-null  object
 8   Category            244768 non-null  object
 9   SalaryRaw           244768 non-null  object
 10  SalaryNormalized    244768 non-null  int64 
 11  SourceName          244767 non-null  object
dtypes: int64(2), object(10)
memory usage: 22.4+ MB<jupyter_text>Vejam que nós temos um grande número de dados: - 244.768 amostras; - 12 colunas (atributos/campos/features).  03 - Tipos de dadosNa análise acima já deu para ver os tipos de dados de cada coluna, mas vamos ver outra abordagem que foca apenas nas colunas e seus, respectivos, tipos:<jupyter_code>df.dtypes<jupyter_output><empty_output><jupyter_text>Olhando para as colunas acima da para ver que a maioria dos dados *não são* numéricos. Apenas: - **Id** - Que não é relevante (apenas para identificar cada amostra) quando se trata de aplicação estatística e criação de modelos. - **SalaryNormalized** - Que é a nossa variável *target*.**NOTE:**  Uma observação aqui é que a maioria dos dados mesmo sendo do tipo *object* são textos (informações) sobre as vagas de emprego. Futuramente nós vamos ter que fazer um Pré-Processamento desses textos (informações) para tirar insights dos mesmos.  04 - Dados missingNessa parte da nossa análise vamos verificar dados ausentes em cada variável (feature): - Por quantidade numérica; - E por, porcentagem (%).  04.1 - Dados Missing por quantidade numéricaVamos começar visualizando a quantidade numérica de dados faltantes por coluna:<jupyter_code>data_missing = df.isnull().sum()
data_missing<jupyter_output><empty_output><jupyter_text>04.2 - Dados Missing por porcentagem Agora, vamos analisar quanto porcento (%) representam esses dados faltantes:<jupyter_code>percentMissing = (data_missing / len(df.index)) * 100
percentMissing<jupyter_output><empty_output><jupyter_text>Vejam que as colunas **ContractType**, **ContractTime** e **Company** estão com mais de 10% dos dados faltando (missing).**NOTE:**  Outra observação é a coluna **ContractType** tem 73% dos dados faltando, o que chega a ser crítico.> **Isso, por que se você tem uma variável (atributo/feature) com mais de 60% dos dados faltando (missing) talvez essa variável na criação do modelo seja quase nula.**  05 - Análise Estatística> Por fim, vamos fazer uma breve **Análise Estatística** no conjunto de dados.  05.1 - Overview EstatísticoVamos começar com um Overview básico das estatísticas de nossas variáveis (features) numéricas:<jupyter_code>print(df.describe())<jupyter_output>Id  SalaryNormalized
count  2.447680e+05     244768.000000
mean   6.970142e+07      34122.577576
std    3.129813e+06      17640.543124
min    1.261263e+07       5000.000000
25%    6.869550e+07      21500.000000
50%    6.993700e+07      30000.000000
75%    7.162606e+07      42500.000000
max    7.270524e+07     200000.000000<jupyter_text>**NOTE:**  Bem, como vocês podem ver a única variável (feature) que faz sentido alguma **Análise Estatística** é a **"SalaryNormalized" (que representa os salários normalizados anualmente pelo a Adzuna)**.**Mesmo sendo uma única variável (feature) nós podemos tirar alguns insights da mesma:** - O **menor** salário de todos (anualmente) foi de **5.000**; - O **maior** salário de todos (anualmente) foi de **200.000**; - A **média (mean)** de todos os salários (anualmente) foi de **34.122**; - A **mediana (median/2° Quartil = 50% dos dados)** de todos os salários (anualmente) foi de **30.000**:   - Vejam que a nossa mediana não está tão distante da nossa média. - O **Desvio Padrão (Standard Deviation/ que representa quão longe nós estamos da média)** é **17.640**.**NOTE:**  Claro que essa é apenas uma **Análise Preliminar** e talvez nós vamos precisar melhorar essa variável (feature) futuramente, mesmo sabendo que essa variável é o resultado de um Pré-Processamento feito pelo **Adzuna**.  05.2 - Verificando a moda (mode) da variável (feature) "SalaryNormalized"Agora vamos utilizar a função **mode()** do próprio *Pandas* para verificar qual o salário mais frequente entre todos os salários.<jupyter_code>df.SalaryNormalized.mode()<jupyter_output><empty_output><jupyter_text>**NOTE:**  Agora, vamos utilizar a classe **Counter** para contar os 10 primeiros valores mais frequentes entre os salários.<jupyter_code>from collections import Counter
c = Counter(df.SalaryNormalized)
c.most_common(10)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.09287551051278173, 'fraction_numerical': 0.05445469671759189, 'mean_word_length': 4.349514563106796, 'pattern_counts': {'":': 0, '<': 40, '<?xml version=': 0, '>': 42, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '10', 'dir': 'jupyter-structured-clean-dedup', 'id': '183521', 'license': 'MIT', 'n_tokens_mistral': 2492, 'n_tokens_neox': 2209, 'n_words': 746, 'path': 'notebooks/preliminary-analysis.ipynb', 'repo_name': 'drigols/job-salary-prediction', 'size': '6611'}