Arquivo de etiquetas: algoritmo

Classificação de títulos de bolsa com Clustering

O seguinte trabalho pretende fazer a Classificação de títulos de bolsa nacionais e internacionais com base no algoritmo K-Means, um problema de classificação não supervisionada (clustering) que agrupa objetos em “k” número de grupos baseados nas suas características.

O intuito deste trabalho é encontrar as melhores ações de bolsa a nível “mundial”, através dos seus indicadores de Retorno e Volatilidade anuais, com  base no histórico dos últimos dois anos. Termino com uma seleção de títulos “apetecíveis” especificando os seus valores atuais em bolsa.

O trabalho passa por diferentes métodos de Data Science e é todo realizado em Python:

  • obtenção de dados da web através de Web Scrapping,
  • tratamento dos mesmos em Pandas,
  • aplicação do modelo de classificação K-means, começando por procurar o melhor do número de clusters (“k”),
  • remoção de outliers,
  • seleção das melhores ações com retorno anual igual ou acima de 10% e volatilidade abaixo de 40% (escolha pessoal!),
  • obtenção dos preços atuais dos títulos da alínea anterior,
  • amostragem final das “melhores” ações em diferentes colorações consoante o seu preço

Elbow curve – escolha do número de clusters para o algoritmo k-means (k=3):Picture5

Classificação de títulos implementando 3 Clusters face ao Retorno e Volatilidade anuais:
Picture1

Remoção de outliers:
Picture2

Títulos com Rentabilidade acima de 10% ao ano e Volatilidade inferior a 40%:Picture3

Seleção de títulos com preços abaixo de 50€:Picture4

O script Python (jupyter) está disponível no GitHub, sendo esta a conclusão final:

  • valor até 5€: o título EGL.LS é o que mostra maior retorno com uma taxa de volatilidade abaixo dos 35%. Logo de seguida o BCP.LS
  • inferior a 10€: o título BBVA.MC tem um retorno acima de 30% e volatilidade abaixo dos 30%
  • inferior a 20€ ou 50€: se optarmos por um título mais estável, abaixo dos 20% de volatilidade, temos a SEM.LS (inf20) e o DTE.DE (inf50)

Acesso ao trabalho completo no GitHub


Introducing the k-means algorithm
The term k-means was first used by MacQueen in 1967, although the idea dates back to Steinhaus in 1957. K-means is an unsupervised classification (clustering) algorithm that groups objects into k groups based on their characteristics.

Clustering is done by minimizing the sum of distances between each object and the centroid of its group or cluster. Quadratic distance is often used. The algorithm consists of three steps:

Initialization: once the number of groups, k, has been chosen, k centroids are established in the data space, for example, choosing them randomly.
Assign objects to centroids: each data object is assigned to its nearest centroid.
Centroid update: the position of the centroid of each group is updated, taking as the new centroid the position of the average of the objects belonging to said group.
Steps 2 and 3 are repeated until the centroids do not move, or move below a threshold distance at each step.

Função SQL para Validar NIF

Olá,
esta semana necessitei de criar um script para validação do NIF, número de identificação fiscal, mais conhecido por número de contribuinte.

O código foi implementado em numa linguagem diferente mas achei interessante recriar o mesmo em TSQL.

Explicações mais profundas sobre esta matéria podem consultar por ex. aqui:
https://pt.m.wikipedia.org/wiki/N%C3%BAmero_de_identifica%C3%A7%C3%A3o_fiscal

Vou apenas resumir o algoritmo a implementar:

O NIF é constituído por nove dígitos, sendo os oito primeiros sequenciais e o último um dígito de controlo. Adicionalmente, o primeiro dígito do NIF não pode ser zero nem quatro.

Para ser calculado o digito de controlo:

Multiplicar 1º digito por 9, o 2.º dígito por 8, o 3.º dígito por 7, o 4.º dígito por 6, o 5.º dígito por 5, o 6.º dígito por 4, o 7.º dígito por 3 e o 8.º dígito por 2.

Seguidamente somar os resultados.

Calcular o resto da divisão do número por 11: se o resto for 0 (zero) ou 1 (um) o dígito de controlo será 0 (zero); se for outro qualquer algarismo X o dígito de controlo será o resultado da subtracção 11 – X.

Por fim, basta ver a igualdade do dígito de controlo com o último dígito do NIF. No caso de ser igual o NIF está correcto; no caso de ser diferente o NIF não é válido.

O código TSQL foi colocado como uma função. Esta é chamada com um NIF e o retorno será o próprio NIF se estiver válido ou vazio caso não o seja.
Denominei a função como [dbo].[up_check_nif] e codifica-se da seguinte forma:

/*
Função valida NIF,
2021 JG
*/

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

if OBJECT_ID('[dbo].[up_check_nif]') IS NOT NULL       drop function dbo.up_check_nif
GO

CREATE function [dbo].up_check_nif (@nif_input varchar(9))
RETURNS varchar(9)
AS
BEGIN

declare @j int = 9
declare @i int = 1
declare @total int = 0
declare @digit_control int 
declare @result varchar(9)
-- nif_pri_digito   = '1,2,3,5,6,7,8,9'

IF  LEN(@nif_input) = 9 AND @nif_input NOT LIKE '%[^0-9]%' AND LEFT(@nif_input,1) not in (0,4)      
BEGIN   

    -- SUM( primeiros 8 digitos * [9,8,7,6,5,4,3,2])
    WHILE @i < LEN(@nif_input)  
    BEGIN
         SET @total = @total + SUBSTRING(@nif_input,@i,1) * @j               
         SET @j = @j-1 
         SET @i = @i+1
    END             

    IF (@total % 11) = 0 OR (@total % 11) = 1 
         SET @digit_control = 0          
    ELSE            
         SET @digit_control = 11 - (@total % 11) 

    IF @digit_control = RIGHT(@nif_input,1)                                 
         SET @result = @nif_input   /* nif válido */        
    ELSE                    
         SET @result = ''          /* nif inválido */  
END
ELSE

        SET @result = ''           /* nif inválido */  

RETURN @result  

END

A função poderá ser chamada da seguinte forma:

select dbo.up_check_nif(‘123456789’) AS NIF_Validado

Espero que vos seja útil,

JG