Entradas, Saídas e Análise de Dados Pedro Barahona DI/FCT/UNL Introdução aos Computadores e à Programação 2º Semestre 2006/2007 20 Abril 2007 Entradas, Saídas e Análise de Dados 1 Regressão Linear : Um Exemplo Exemplo • Um dado produto é fabricado numa linha de produção por lotes. Os lotes são encomendados pelos clientes e têm um número variável de exemplares do produto, de acordo com a ordem do cliente. • A empresa produtora está interessada em desenvolver um modelo de produção, de forma a poder prever – Qual o tempo que demora cada lote a ser produzido – Quais os lotes que são produzidos em mais ou menos tempo que o esperado, de forma a poderem ser analisados os factores que facilitam ou dificultam o fabrico. • Para fazer esse estudo a empresa detem um histórico da produção de vários lotes no passado. 20 Abril 2007 Entradas, Saídas e Análise de Dados 2 Regressão Linear : Um Exemplo • O modelo desenvolvido tem em conta que – Antes de se começar a produzir o produto é necessário gastar um dado tempo (t0: tempo de setup) para preparar um conjunto de recursos (por exemplo, máquinas e instalações). – Uma vez estabelecida essa preparação o número de peças produzidas é basicamente proporcional ao tempo, demorando um tempo t1 a fabricar cada peça. • Assim parece apropriado um modelo do tipo, em que o tempo T que necessário para se produzirem P peças é dado por T = t1 P + • t0 O problema consiste pois em determinar os valores de t0 e t1 a partir dos dados históricos. 20 Abril 2007 Entradas, Saídas e Análise de Dados 3 Análise de Dados – Regressão Linear Exemplo • Este problema é apenas um exemplo de aplicação da técnica de análise de dados, denominada, regressão linear, que na sua forma geral se pode descrever por • Regressão Linear: Dado um conjunto de dados, xi e yi verificar se eles estão numa relação linear Y = m X +b • O problema tem dois subproblemas: – Determinar os valores de m e b mais apropriados aos valores dos vários pares de valores xi – yi. – Avaliar se é razoável assumir a relação linear acima, ou seja, se os pares de valores <xi, yi> a “suportam” (ou ainda, se existe uma boa correlação linear entre X e Y). 20 Abril 2007 Entradas, Saídas e Análise de Dados 4 Regressão Linear : Um Exemplo • Podemos ilustrar esta técnica com dois exemplos gráficos. Os valores de • m (inclinação da recta); e de • b (intersecção da recta com o eixo Y) são idênticos nos dois casos y y x X e Y têm uma correlação linear forte 20 Abril 2007 x X e Y têm uma correlação linear fraca Entradas, Saídas e Análise de Dados 5 Determinação dos Parâmetros m e b • O tratamento matemático para a determinação dos valores de m e b é relativamente simples. • Basicamente pretende determinar-se os valores de m e b que minimizem o erro entre os resultados esperados e os resultados experimentais. • Para cada ponto xi-yi o erro “experimental” é dado por ei = yi – (m xi + b) • O erro E que se pretende minimizar é o erro quadrático médio, E n 2 e i i 1 • Assim sendo o problema reduz-se a determinar os valores de m e b que minimizam o erro E. 20 Abril 2007 Entradas, Saídas e Análise de Dados 6 Determinação dos Parâmetros m e b • O mínimo de uma função em relação a uma variável ocorre quando a derivada dessa função em ordem a essa variável é nula. • Assim sendo, há que obter os zeros das derivadas (parciais) de E em relação às incógnitas m e b. – Nota 1: Assume-se uma função contínua e continuamente derivável, caso contrário o mínimo pode não ocorrer no zero da derivada. – Nota 2: A função E tem duas variáveis, m e b. A análise em Rn justifica que o mínimo deve corresponder ao zero das duas derivadas. – Nota 3: Como o mínimo de se a função F = E2 = ei2 • E coincide com o mínimo de E, pode minimizar- Assim o problema reduz-se a determinar os valores de m e b que minimizam o erro, isto é, que garantem 20 Abril 2007 F 0 b bem como F 0 m Entradas, Saídas e Análise de Dados 7 Determinação dos Parâmetros m e b • Ora F 0 b ( yi m xi b) 2 b 2( yi m xi b) 0 ( y m x b) 0 ( y m x ) nb 0 donde • Por outro lado 20 Abril 2007 F 0 m 0 i i i i b ( yi mxi ) / n ( yi m xi b) 2 0 m 2 xi ( yi m xi b) 0 ( xi yi m xi bxi ) 0 2 Entradas, Saídas e Análise de Dados 8 Determinação dos Parâmetros m e b b ( yi mxi ) / n • Usando agora o valor de b anteriormente encontrado na fórmula anterior, obtemos F 0 m ( xi yi m xi bxi ) 0 ( xi yi m xi xi ( yi m xi ) / n) 0 (nxi yi m nxi xi ( yi m xi )) 0 (nx y m nx ) x ( y m x ) 0 n x y m n x x y m x x m( n x ( x ) ) n x y x y donde 20 Abril 2007 2 2 2 2 i i i i i i 2 i i i i i 0 2 2 i m i i i i i i i n xi yi xi yi n xi ( xi ) 2 2 Entradas, Saídas e Análise de Dados 9 Parâmetros m e b em OCTAVE • Assim, dados vectores X e Y, com n valores de xi e yi os valores de m e de b podem ser obtidos através das fórmulas b ( yi mxi ) / n m n xi yi xi yi n xi ( xi ) 2 2 • Em Octave, estas expressões podem ser calculadas facilmente. Começamos por definir os vários somatórios envolvidos Sx = sum(X); Sy = sum(Y); Sxx = sum(X.*X); Syy = sum(Y.*Y); Sxy = sum(X.*Y); que são usados nas definições de b e de m m = (n * Sxy – Sx*Sy) / (n*Sxx – Sx^2) b = 20 Abril 2007 (Sy – m * Sx) / n Entradas, Saídas e Análise de Dados 10 Correlação entre X e Y • Para medir a qualidade da relação linear entre X e Y pode usar-se o coeficiente de correlação r, definido como r n x i n xi yi xi yi 2 ( xi ) 2 n yi ( yi ) 2 2 • Este coeficiente (cuja derivação exige um maior conhecimento de estatística) varia entre 1 (correlação perfeita) e 0 (correlação nula). • O seu valor em OCTAVE pode ser obtido naturalmente através das definições anteriores r = (n*Sxy – Sx*Sy) / sqrt((n*Sxx – Sx^2)(n*Syy – Sy^2)) onde Sx = sum(X); Sy = sum(Y); Sxx = sum(X.*X); Syy = sum(Y.*Y); Sxy = sum(X.*Y); 20 Abril 2007 Entradas, Saídas e Análise de Dados 11 Armazenamento de Dados • Quando a quantidade de dados é grande, não é razoável ou mesmo possível introduzi-los “manualmente” num programa. • Tipicamente esses dados são armazenados em ficheiros que têm de ser lidos pelos programas que os tratam (podendo esses ficheiros estar organizados em bases de dados mais ou menos complexas) • As funções básicas de manutenção de ficheiros (criação, alteração e destruição, localização, acesso ao seu conteúdo, etc.) são definidas no sistema de ficheiros (file system) , componente do sistema operativo (Operating System - Windows, Linux, MacOS, ...). • Todas as linguagens de programação têm acesso a essas funções básicas (primitivas), implementadas através de chamadas ao sistema, mas que são disponibilizadas ao nível da linguagem através de instruções próprias. 20 Abril 2007 Entradas, Saídas e Análise de Dados 12 Armazenamento de Dados • Existe uma grande variedade de formas nessas instruções mas algumas características são razoavelmente gerais: • Antes de se escrever ou ler num ficheiro, este tem de ser aberto num modo apropriado (leitura, escrita, leitura/escrita,...). • Na abertura de um ficheiro, este é associado a um “canal” com um identificador (tipicamente um número) único. Todos os acessos ao ficheiro referem esse valor e não o nome com que o ficheiro é conhecido no sistema de ficheiros. • Os acessos de leitura e escrita de dados dos ficheiros dependem da forma como os dados são codificados. Estes podem ser armazenados como texto ou numa forma codificada que optimiza o espaço. • Após todos os acessos pretendidos terem sido executados, um ficheiro devem ser fechado. • Como estas operações podem ser muito variadas, vamos centrar-nos nos acessos a ficheiros texto em OCTAVE. 20 Abril 2007 Entradas, Saídas e Análise de Dados 13 Entrada de Dados • Após a abertura de um ficheiro texto, ele pode ser lido de duas formas básicas: – Leitura caracter a caracter, sendo tarefa do programador interpretar as sequências de caracteres como números, palavras, etc... – Leitura de acordo com determinados padrões (templates) em que existem primitivas da linguagem que interpretam directamente os caracteres para o tipo de dados pretendido. • Por exemplo, assumamos um ficheiro com a sequência “ 23 45.2 ”. Neste caso podemos – ler os 11 caracteres e tendo em atenção os espaços interpretar esses caracteres como dois números (um inteiro e outro decimal). – Indicar como padrão de leitura um inteiro seguido de um decimal que são retornados em variáveis indicadas. 20 Abril 2007 Entradas, Saídas e Análise de Dados 14 Saída de Dados • O armazenamento de dados num ficheiro segue passos semelhantes. A abertura de um ficheiro em modo escrita, cria um ficheiro, que pode ser escrito de duas formas básicas: – Escrita caracter a caracter, sendo tarefa do programador criar as sequências adequadas de caracteres para representar números, palavras, etc... – Escrita de acordo com determinados padrões (templates) disponibilizados por primitivas da linguagem. • Por exemplo, para se escreverem os dados 23 e 45.2 ( “ 23 45.2 ”) num ficheiro, pode-se – escrever os 11 caracteres sequencialmente, isto é, ‘ ’,‘ ’,‘2’,’3’,‘ ’,‘ ’,‘4’,‘5’,‘.’,’2’,‘ ’ – indicar como padrão de escrita um inteiro (com 4 dígitos, seguido de um espaço, seguido de um decimal com 5 casas, incluindo uma casa decimal, seguido de um espaço. 20 Abril 2007 Entradas, Saídas e Análise de Dados 15 Entrada / Saída de Dados • Assumamos pois um ficheiro em duas colunas, em que data_in.txt 188 40 145 ... 61 139 – A primeira coluna representa o número de peças de cada lote (Pi) – A segunda coluna, o número de necessárias para produzir esse lote (Ti) horas Objectivos: • Estabelecer uma relação linear T = t1 P + t0 ; e – Escrever um ficheiro em 3 colunas em que: • As duas primeiras colunas são como antes • A 3ª coluna, representa a diferença entre o tempo estimado e o tempo gasto efectivamente 20 Abril 2007 606.39 161.35 396.18 196.93 357.33 data_out.txt 188 40 145 ... 61 139 Entradas, Saídas e Análise de Dados 606.39 161.35 396.18 19.51 19.55 -61.39 196.93 357.33 -8.03 -82.19 16 Leitura de Ficheiros • O programa abaixo permite ler um ficheiro com duas colunas de dados, para dois vectores X e Y. • A instrução fopen abre o ficheiro com o nome “linear.txt”, em modo de leitura (“r” read), e atribui-lhe um ´número de canal ‘fid’, usado posteriormente. • A instrução fclose fecha o canal com número ‘fid. [fid,msg] = fopen("linear.txt", "r"); i = 0; X = zeros(0,1); Y = zeros(0,1); [xi,yi,count] = fscanf(fid,"%i%f",”C”); while !feof(fid) i = i + 1; X(i) = xi; Y(i) = yi; [xi,yi,count] = fscanf(fid,"%i%f",”C”); endwhile; n=i; fclose(fid); 20 Abril 2007 data_in.txt 188 40 145 ... 61 139 Entradas, Saídas e Análise de Dados 606.39 161.35 396.18 196.93 357.33 17 Leitura de Ficheiros • A instrução [xi,yi,count] = fscanf(fid,"%i%f",”C”) permite ler dados – do canal de entrada (1º argumento - fid) – de acordo com um padrão (template - ,"%i%f") – como na linguagem C (3º argumento – “C”) – os dados efectivamente lidos são colocados nas variáveis xi e yi – o seu número é colocado na variável count. • Neste caso, são lidos 2 números do canal de entrada. O primeiro é um inteiro ("%i") e o segundo é decimal ("%f"). data_in.txt [xi,yi,count] = fscanf(fid,"%i%f",”C”); xi = 188 yi = 606.39 count = 2 20 Abril 2007 Entradas, Saídas e Análise de Dados 188 40 145 ... 61 139 606.39 161.35 396.18 196.93 357.33 18 Leitura de Ficheiros • Quando não há mais dados para ler, a instrução [xi,yi,count] = fscanf(fid,"%i%f",”C”) retorna xi e yi vazios (xi = yi = []) e count = 0. • Normalmente existe uma função “end of file” para indicar se a última leitura já foi feita após o fim do ficheiro. Em Octave essa função é expressa por feof(fid). [xi,yi,count] = fscanf(fid,"%i%f",”C”), F = feof(fid). count = 2, xi = 88, yi = 248.63, F = 0 [xi,yi,count] = fscanf(fid,"%i%f",2) F = feof(fid). count = 0, xi = [], yi = [], F = 1 20 Abril 2007 data_in.txt 188 40 145 ... 61 139 Entradas, Saídas e Análise de Dados 606.39 161.35 396.18 196.93 357.33 19 Leitura de Ficheiros • Notas: 1. A chamada de fscanf é feita antes do ciclo. 2. A condição de entrada no ciclo é !feof 3. A variável n guarda o número de pontos X e Y lidos. [fid,msg] = fopen("linear.txt", "r"); i = 0; X = zeros(0,1); Y = zeros(0,1); [xi,yi,count] = fscanf(fid,"%i%f",”C”); while !feof(fid) i = i + 1; X(i) = xi; Y(i) = yi; [xi,yi,count] = fscanf(fid,"%i%f",”C”); endwhile; n=i; fclose(fid); 20 Abril 2007 data_in.txt 188 40 145 ... 61 139 Entradas, Saídas e Análise de Dados 606.39 161.35 396.18 196.93 357.33 20 Tratamento dos Dados • Uma vez obtidos os vectores X e Y com n pontos, os parâmetros m, b e r da regressão linear podem ser recalculados. • Os erros (entre os valores observados e os valores esperados), são guardados no vector E. sx = sum(X); sy = sum(Y); sxy = sum(X.*Y); syy = sum(Y.*Y); sxx = sum(X.*X); m = (n*sxy-sx*sy)/(n*sxx-sx^2); b = (sy-m*sx)/n; r = (n*sxy-sx*sy)/sqrt((n*sxx-sx^2)*(n*syy-sy^2)); E = zeros(1,n); for i = 1:n E(i) = Y(i) - (m * X(i) + b); endfor; 20 Abril 2007 Entradas, Saídas e Análise de Dados 21 Visualização dos Dados • Ax e Ay , e portanto As, definem os limites dos eixos dos X e Y (na realidade P – nº de peças e T – tempo de fabrico). • Os vários plots destinam-se ao eixo X, os valores X e Y (na forma de pontos – formato “@)”, a recta de regressão (Y2 tem os dois pontos limites) e finalmente os erros (na forma de linhas de impulso – formato “^”). Ax = [0, max(X)]; Ay = [min(E),max(Y)]; As = [Ax,Ay]; Y2 = [m*min(Ax)+b, m*max(Ax)+b]; clg; hold on; axis(As); plot(Ax,[0,0],'6'); plot(X,Y,'@33'); plot(Ax,Y2,'2'); plot(X,E,'^1'); 20 Abril 2007 Entradas, Saídas e Análise de Dados 22 Escrita de Ficheiros • As instruções fopen e fclose são semelhantes, mas com modo de escrita (“w” - write). • A instrução fprintf escreve no canal de saída com identificador fid os 3 valores indicados com formatos – Inteiro com 5 dígitos (1º dado – X(i)) – Decimal, com 7 casas, das quais duas decimais (2º/3º dado – Y(i) e E(i)) – Separados por espaços (no template) e com mudança de linha (“\n”) [fid,msg] = fopen("linear_out.txt", "w"); for i = 1:n fprintf(fid,"%5i %7.2f %7.2f\n", X(i),Y(i),E(i)); endfor; fclose(fid); data_out.txt 188 40 145 ... 61 139 20 Abril 2007 606.39 161.35 396.18 19.51 19.55 -61.39 196.93 357.33 -8.03 -82.19 Entradas, Saídas e Análise de Dados 23 Ficheiros Texto em EXCEL • Os ficheiros de entrada e saída, do tipo texto (extensão “.txt”) podem ser, repectivamente produzidos e lidos em EXCEL, desde que se utilizem as opções apropriadas no EXCEL quanto ao formato dos ficheiros. data_in.xls A 1 2 3 29 30 188 40 145 61 139 B 606.39 161.35 396.18 196.93 357.33 data_in.txt C 188 40 145 ... 61 139 606.39 161.35 396.18 196.93 357.33 • Tudo o que é necessário fazer é – guardar o ficheiro em formato: Text (tab delimited) (*.txt) – Ler o ficheiro em formato : Text files (*.prn; *.txt; *.csv) e usar as opções • Delimited - Characters such as commas or tabs separate each field. • Delimiters - Tabs 20 Abril 2007 Entradas, Saídas e Análise de Dados 24 Ficheiros CSV em EXCEL • Outra opção para os ficheiros de entrada e saída consiste em separar os dados por vírgulas (“Comma separated values”) em vez de tabs, trabalhando-se com ficheiros do formato csv (extensão “.csv”) • Nota: Neste caso há que garantir que o separador decimal é o ponto. data_in.xls A 1 2 3 188 40 145 29 30 61 139 B 606.39 161.35 396.18 196.93 357.33 data_in.csv C 188,606.39, 40,161.35, 145,396.18, ... 158,421.84 61,196.93 • Tudo o que é necessário fazer é – guardar o ficheiro em formato: CSV (Comma delimited) (*.csv) – Ler o ficheiro em formato : Text files (*.prn; *.txt; *.csv) 20 Abril 2007 Entradas, Saídas e Análise de Dados 25 Ficheiros CSV em EXCEL • Trabalhando-se com formatos de números decimal em que o sepradaor decimal é uma vírgula, tem de usar-se como separador um outro caracter (por exemplo o ponto-evírgula) e trabalhar-se com ficheiros do formato txt (extensão “.txt”) data_in.xls A 1 2 3 188 40 145 29 30 61 139 B 606.39 161.35 396.18 196.93 357.33 data_in.txt C 188;606,39; 40;161,35; 145;396,18; ... 158;421,84; 61;196,93; • Tudo o que é necessário fazer é – guardar o ficheiro em formato: Text (tab delimited) (*.txt) – Ler o ficheiro em formato : Text files (*.prn; *.txt; *.csv) e usar as opções • Delimited - Characters such as commas or tabs separate each field. • DElimiters - Semicolon 20 Abril 2007 Entradas, Saídas e Análise de Dados 26 Escrita de Ficheiros CSV • As instruções fopen e fclose são semelhantes, mas com modo de escrita (“w” - write). • A instrução fprintf escreve no canal de saída com identificador fid os 3 valores indicados, sem comprimento definido dos campos, mas simplesmente separados por vírgulas. [fid,msg] = fopen("linear_out.csv", "w"); for i = 1:n fprintf(fid,"%i,%f,%f,\n", X(i),Y(i),E(i)); endfor; fclose(fid); data_out.csv 188,606.390000,19.512270, 40,161.350000,19.547397, 145,396.180000,-61.385362, ... 61,196.930000,-8.025154, 139,357.330000,-82.191776, 20 Abril 2007 Entradas, Saídas e Análise de Dados 27