Aviso: Eu estarei falando sobre como chegar no código python, caso queira ler o código em si, dirija-se a este repositório.
Conheça a Base para Classificação de Score de Crédito
A base de dados que vamos limpar vem do kaggle, a qual está no arquivo train.csv
, mas os passos que iremos falar também podem ser usados para test.csv
.
Há 28 colunas e 100 mil linhas neste banco de dados. Eu compilei uma descrição das variáveis na tabela a seguir.
Variável | Descrição |
---|---|
ID | Representa uma identificação única de uma entrada |
Customer_ID | Representa uma identificação única de uma pessoa |
Month | Representa o mês do ano |
Name | Representa o nome de uma pessoa |
Age | Representa a idade de uma pessoa |
SSN | Representa o número social de uma pessoa americana |
Occupation | Representa a profissão de uma pessoa |
Annual_Income | Representa o salário anual de uma pessoa |
Monthly_Inhand_Salary | Representa o salário mensal base de uma pessoa |
Num_Bank_Accounts | Representa quantas contas bancárias uma pessoa possui |
Num_Credit_Card | Representa o número de cartões de crédito que uma pessoa possui |
Interest_Rate | Representa a taxa de juros de um cartão de crédito |
Num_of_Loan | Representa quantos empréstimos uma pessoa fez com o banco |
Type_of_Loan | Representa os tipos de empréstimos feitos por uma pessoa |
Delay_from_due_date | Representa o numero médio de dias atrasados da data de pagamento |
Num_of_Delayed_Payment | Representa o numério médio de pagamentos atrasados feitos por uma pessoa |
Changed_Credit_Limit | Representa, em porcentagem, a mudança de limite do cartão de crédito |
Num_Credit_Inquiries | Representa o número de consultas de cartão de crédito |
Credit_Mix | Representa a classificação da mistura de créditos |
Outstanding_Debt | Representa a quantidade de saldo devedor a ser pago em dólares americanos |
Credit_Utilization_Ratio | Representa a proporção de utilização de cartões de crédito |
Credit_History_Age | Representa a idade do histórico de uso de crédito de uma pessoa |
Payment_of_Min_Amount | Representa se uma pessoa pagou apenas o mínimo |
Total_EMI_per_month | Representa os pagamentos das parcelas mensais de empréstimos em dólares americanos |
Amount_invested_monthly | Representa a quantidade de dinheiro investido pelo cliente em dólares americanos |
Payment_Behaviour | Representa o comportamento de pagamento do cliente em dólares americanos |
Monthly_Balance | Representa o extrato mensal do cliente em dólares americanos |
Credit_Score | Representa as faixas de score de crédito (Baixo, Médio, Bom) |
Mesmo tendo 100 mil linhas, dentro dessas linhas existem apenas 12.500 clientes diferentes, cada cliente aparece 8 vezes (de Janeiro a Agosto). Então basicamente nós podemos selecionar um cliente específico e olhar as informações dele e facilmente identificar dados incorretos e somos capazes de ajustá-los.
Lidando com Erros de Digitação e Outliers
Neste banco de dados há diversos erros de digitação ou simplesmente coisas que não fazem sentido. Você irá encontrar valores que são: _
, !@9#%8
, __10000__
, NM
ou _______
. Eu acredito que esses erros estão na base para representar o caos que você pode encontrar quando estiver lidando com dados reais e a maioria deles significam que esse valor é nulo.
Por um momento eu pensei que __10000__
poderia ser apenas um erro de digitação, mas não há nenhuma quantidade de dinheiro investida mensalmente que é superior a 200 dólares americanos.
|
|
Seguindo essa lógica, eu procurei por mais coisas que não faziam sentido no data frame e comecei a substituir esses valores pelos nan
s do numpy. Eu também procurei por outliers olhando a distribuição dos valores, se havia um valor que aparecia apenas uma vez e ele estava isolado, eu o substituia por um valor nulo. Eu não baseiei essa decisão apenas nisso, eu também procurei por clientes que tinham esse outlier e observei todos os dados desse cliente específico, e eu sempre encontrava coisas estranhas como:
Olhando para este cliente em específico é fácil ver que ele não ganhou todo esse dinheiro anualmente apenas um mês do ano.
Ao terminar essa busca por erros de digitação e outliers, não esqueça de passar o novo tipo de dados para suas variáveis. Algumas variáveis como age
começaram com caracteres string entre as idades e por isso ao ser feito a leitura dos dados o pandas os reconheceu como objeto e não como tipo int ou float.
Preenchendo Valores em Branco
Depois de lidar com todos os outliers e erros de digitação, nós terminamos com diversos valores nulos, como pode ser visto a baixo:
|
|
|
|
Ao invés de apagar todos os valores em branco eu primeiro tento preencher eles usando informação que já temos disponível. Lembra que eu mencionei que um cliente possui dados históricos de 8 meses atrás? Nós podemos apenas usar esses dados históricos para preencher os valores nulos usando uma medida resumo da nossa escolha filtrando para o cliente, isso será mais preciso do que apenas calcular a média do nosso banco de dados.
Eu decidir usar o valor médio para as seguintes colunas:
|
|
E o último valor não nulo para estas:
|
|
O motivo de não usar a média para todos os meus valores é porque eu não queria ter que lidar com uma pessoa tendo 20,5 anos de idade e Occupation
, Type_of_Loan
, e Credit_Mix
são dados discretos.
Engenharia das Features
Com os dados limpos, nós podemos seguir com a engenharia das features. Vamos começar com a variável Type_of_Loan
, que possui algumas ocorrências em que em uma única célula possui diversos tipos de empréstimos, como você pode ver:
|
|
Então eu vou salvar todos os tipos de empréstimos diferentes em um vetor, separando todos os empréstimos sempre que surgir uma ,
ou , and
.
|
|
Agora podemos criar variáveis dummies usando loan_types
, assim um cliente recebe o número 1 se ele tiver esse empréstimo ou 0 caso não tenha.
|
|
Agora eu continuo trabalhando nesse banco para o tornar pronto para o treinamento de um modelo de aprendizado de máquina. Para isso, eu preciso transformar todos os meus dados discretos em numéricos.
A variável Credit_History_Age
tem os valores como strings “22 Years and 5 Months” e esse padrão se repete, então podemos aproveitar isso e selecionar o ano multiplicado por 12 e somar o mês, resultando em um novo recurso com o crédito idade da história em meses. Quando acabarmos com isso ainda haverá valores nulos e, para preenchê-los, escolho interpolar os valores. Isso funciona muito bem quando o valor ausente é de fevereiro até julho porque interpola com a idade do histórico de crédito do cliente, mas torna-se uma suposição incorreta quando o valor ausente é em janeiro ou agosto.
Os nomes dos meses serão substituidos pelo seu representante numérico, logo janeiro será 1, fevereiro será 2, e assim por diante. credit_mix
e credit_score
possuem 3 categorias sequenciais, eu escolhi usar -1, 0, e 1, mas você também pode usar 1, 2, 3 e irá produzir o mesmo resultado.
Não se esqueça de checar o repositório no GitHub caso queira ver o código completo mencionado aqui e para baixar a base tratada.