Aprendizado de máquina e redes neurais - página 67

 

2.4 Big O de K vizinhos mais próximos (L02: Métodos do vizinho mais próximo)



2.4 Big O de K vizinhos mais próximos (L02: Métodos do vizinho mais próximo)

Agora, vamos nos aprofundar no tópico da complexidade do tempo de execução, focando especificamente na notação Big O e na complexidade do tempo de execução do algoritmo k-vizinhos mais próximos (KNN).

A notação Big O é um conceito usado na ciência da computação para analisar a eficiência de algoritmos. Refere-se principalmente à complexidade do tempo de execução, que determina como a velocidade de execução de um algoritmo se comporta à medida que o tamanho da entrada aumenta. Além disso, a notação Big O também pode ser usada para analisar a eficiência de memória de um algoritmo, indicando a quantidade de memória necessária para sua execução.

No caso do KNN, a etapa de treinamento envolve salvar o conjunto de dados de treinamento, o que pode consumir muita memória. Armazenar um grande conjunto de dados de treinamento pode exigir uma quantidade significativa de RAM ou espaço de armazenamento no disco rígido. Embora o espaço de armazenamento tenha ficado mais barato com o tempo, ele ainda pode apresentar limitações ao lidar com conjuntos de dados massivos, como milhões de imagens.

No entanto, vamos mudar nosso foco para a complexidade do tempo de execução do KNN durante a etapa de previsão. Antes de prosseguirmos, vamos introduzir brevemente a notação Big O. É uma notação usada para descrever a eficiência de algoritmos, geralmente denotada por funções. Essas funções representam a complexidade do tempo de execução dos algoritmos, com exemplos comuns incluindo O(1) (constante), O(log n) (logarítmico) e assim por diante. Essas funções indicam como o tempo de execução de um algoritmo é dimensionado com o tamanho de entrada (n).

Para entender melhor a complexidade do tempo de execução, podemos organizar as funções em ordem crescente de eficiência, de O(1) à complexidade exponencial. Nesse contexto, uma função constante é ideal, pois não é afetada pelo tamanho da entrada, garantindo uma velocidade de execução consistente. As funções logarítmicas e lineares também são eficientes, embora não sejam tão ideais quanto as funções constantes. No entanto, à medida que a complexidade aumenta para quadrática, cúbica e exponencial, a eficiência do algoritmo se deteriora significativamente. A complexidade exponencial é particularmente prejudicial e deve ser evitada, especialmente ao lidar com grandes conjuntos de dados em aprendizado de máquina.

Para visualizar a complexidade do tempo de execução em termos de n (tamanho da entrada), um gráfico pode ser criado, onde o eixo x representa n e o eixo y representa a complexidade do algoritmo. À medida que n aumenta, certas funções exibem um desempenho cada vez mais fraco. É essencial evitar algoritmos de alta complexidade, como quadráticos, cúbicos ou exponenciais, pois podem levar a tempos de execução excessivamente longos.

Agora, vamos explorar como derivamos a notação Big O para uma determinada função. Por exemplo, considere uma função quadrática f(x) = ax^2 + bx + c. Ao derivar a notação Big O, focamos no termo dominante que cresce mais rápido. Neste caso, o termo dominante é x^2. Portanto, a notação Big O para esta função seria O(x^2), indicando complexidade quadrática.

Vamos considerar outra função para ilustrar melhor esse processo. Suponha que temos uma função f(x) = ax(log x). Novamente, identificamos o termo dominante, que é x(log x). Aqui, desconsideramos o fator constante a e focamos no termo x(log x). Conseqüentemente, a notação Big O para esta função seria O(x log x), indicando complexidade log-linear.

Vale a pena mencionar que a base do logaritmo (por exemplo, log base 2 ou logaritmo natural) não afeta a notação Big O. Bases diferentes introduzem apenas um fator de escala, que pode ser ignorado ao determinar a complexidade do tempo de execução. Portanto, para simplificar, costumamos considerar o logaritmo natural (log) sem especificar a base.

Para solidificar ainda mais sua compreensão, vamos examinar uma função Python para multiplicação de matrizes, demonstrando a aplicação da notação Big O a algoritmos computacionais. A função realiza a multiplicação de matrizes entre duas matrizes, A e B. Embora a implementação seja intencionalmente ineficiente para fins de ilustração, ela nos permite analisar sua complexidade de tempo de execução.

A função começa com a inicialização de uma matriz vazia C de tamanho nxn, onde n é a dimensão das matrizes de entrada. Em seguida, itera por cada linha i da matriz A e cada coluna j da matriz B. Dentro dos loops aninhados, calcula o produto escalar da linha i na matriz A e coluna j na matriz B, armazenando o resultado na célula correspondente de matriz C.

Aqui está o código Python para a função de multiplicação de matrizes:

def matrix_multiplication(A, B):
    n = len(A)  # Assuming square matrices of size n x n
    C = [[ 0 ] * n for _ in range(n)]  # Initialize matrix C
    
     for i in range(n):
         for j in range(n):
             for k in range(n):
                C[i][j] += A[i][k] * B[k][j]  # Calculate dot product and update C[i][j]
    
    return C
Para analisar a complexidade do tempo de execução dessa função, vamos dividi-la. O loop externo itera n vezes, representando as linhas da matriz A. O segundo loop também itera n vezes, representando as colunas da matriz B. Dentro desses loops, há um loop aninhado que também itera n vezes, representando o cálculo do produto escalar. Assim, a complexidade geral é O(n^3), indicando complexidade cúbica.

É importante observar que a complexidade cúbica não é ideal, especialmente para grandes valores de n. À medida que o tamanho da entrada aumenta, o tempo de execução dessa função aumenta significativamente. Conseqüentemente, para matrizes maiores, um algoritmo mais eficiente deve ser usado para realizar a multiplicação de matrizes, como o algoritmo de Strassen ou outras abordagens otimizadas que alcançam melhores complexidades de tempo de execução, como O(n^2.81).

Em resumo, entender a complexidade do tempo de execução dos algoritmos, denotada pela notação Big O, é crucial para avaliar sua eficiência e escalabilidade. Ele nos permite estimar o desempenho de um algoritmo à medida que o tamanho da entrada aumenta, permitindo escolher os algoritmos mais adequados para diferentes cenários e evitar ineficientes para grandes conjuntos de dados.

2.4 Big O of K-nearest neighbors (L02: Nearest Neighbor Methods)
2.4 Big O of K-nearest neighbors (L02: Nearest Neighbor Methods)
  • 2020.09.08
  • www.youtube.com
In this video, we are looking at the Big-O runtime complexity of a naive implementation of k-nearest neighbors-------This video is part of my Introduction of...
 

2.5 Melhorando os k vizinhos mais próximos (L02: Métodos do vizinho mais próximo)



2.5 Melhorando os k vizinhos mais próximos (L02: Métodos do vizinho mais próximo)

Neste vídeo, vamos nos aprofundar no tópico de melhoria do algoritmo K-vizinhos mais próximos por meio de algumas modificações e consideração de hiperparâmetros. No vídeo anterior, discutimos o uso de uma fila de prioridade como uma estrutura de dados para aumentar a eficiência de encontrar os vizinhos mais próximos. Essa fila de prioridade ajuda a evitar a busca em todo o conjunto de treinamento para cada novo vizinho.

Agora, vamos explorar outra abordagem para melhorar o desempenho computacional do algoritmo K-vizinhos mais próximos, utilizando estruturas de dados de particionamento de espaço. Uma dessas estruturas de dados é o heap, que serve como uma estrutura de particionamento de espaço para agilizar o processo de pesquisa nos exemplos de treinamento. Ao dividir o conjunto de dados em subconjuntos dentro da estrutura de dados, podemos minimizar a necessidade de cálculos de distância para cada ponto de dados de treinamento.

Um método de particionamento de espaço é chamado de bucketing. Isso envolve dividir o conjunto de dados em subconjuntos ou blocos com base em critérios específicos, como blocos de tamanho igual ou limites definidos por medições de recursos. Ao fazer isso, podemos evitar pesquisar todo o conjunto de treinamento e focar apenas em pontos relevantes dentro de um intervalo específico ao procurar vizinhos de um ponto de consulta. Essa otimização aumenta significativamente a eficiência do processo de pesquisa.

Outra técnica de particionamento de espaço é a árvore KD, que constrói hipercubos para dividir o conjunto de dados. Este método difere do bucketing, mas compartilha o objetivo de melhorar a eficiência da busca reduzindo o número de cálculos de distância. As árvores KD são particularmente adequadas para conjuntos de dados com um grande número de recursos.

Da mesma forma, o algoritmo da árvore de bolas cria hiperesferas como partições de espaço. A escolha entre árvores KD e árvores de bola depende das características do conjunto de dados. Para conjuntos de dados com alta dimensionalidade, o algoritmo de árvore de esferas é frequentemente preferido. Vale ressaltar que a biblioteca de aprendizado de máquina scikit-learn, uma ferramenta amplamente utilizada, oferece diferentes opções para o algoritmo do classificador K-vizinho mais próximo, selecionando automaticamente o algoritmo de particionamento de espaço mais eficiente com base no conjunto de dados. No entanto, você pode substituir manualmente essa configuração, se desejar.

Além disso, podemos melhorar o desempenho dos K-vizinhos mais próximos empregando técnicas de redução de dimensionalidade. A redução de dimensionalidade vem em dois tipos: extração de recursos e seleção de recursos. A extração de recursos envolve transformar ou combinar recursos existentes para criar uma representação de dimensão inferior dos dados. Por outro lado, a seleção de recursos envolve selecionar um subconjunto dos recursos disponíveis sem criar novos. Ao reduzir o número de recursos, podemos reduzir o custo computacional dos cálculos de distância e potencialmente melhorar a eficiência do algoritmo. Além disso, conjuntos de dados de alta dimensão geralmente sofrem da maldição da dimensionalidade, o que pode levar a um desempenho de generalização ruim devido ao overfitting. Assim, a redução de dimensionalidade também pode ajudar a aliviar esse problema.

Para otimizar o desempenho computacional dos K vizinhos mais próximos, podemos explorar técnicas de edição ou remoção. A poda envolve a remoção de pontos de dados desnecessários do conjunto de treinamento sem afetar o limite de decisão. Ao eliminar pontos redundantes, podemos reduzir o número de comparações e cálculos de distância, tornando o algoritmo mais eficiente. Da mesma forma, a criação de protótipos envolve a substituição de uma região densa de pontos de dados de treinamento por um único ponto representativo. Essa estratégia reduz os requisitos de espaço de armazenamento enquanto preserva a precisão preditiva do algoritmo.

Além disso, o ajuste de hiperparâmetros desempenha um papel crucial na melhoria do desempenho preditivo do algoritmo K-vizinhos mais próximos. Os hiperparâmetros são configurações ajustáveis que afetam o comportamento do algoritmo, mas não são aprendidas com os dados de treinamento. Eles incluem o valor de K (o número de vizinhos a serem considerados), a escala de recurso, a medida de distância usada e o esquema de ponderação para cálculo de distância. A escolha de valores apropriados para esses hiperparâmetros pode afetar significativamente o desempenho do algoritmo. No entanto, é essencial ser cauteloso e evitar o ajuste excessivo do modelo aos dados de treinamento.

Aproveitando estruturas de dados de particionamento de espaço, empregando técnicas de redução de dimensionalidade, aplicando métodos de edição e poda e hiperparâmetros de ajuste fino, podemos aprimorar o desempenho computacional e preditivo do algoritmo K-vizinhos mais próximos.

2.5 Improving k-nearest neighbors (L02: Nearest Neighbor Methods)
2.5 Improving k-nearest neighbors (L02: Nearest Neighbor Methods)
  • 2020.09.08
  • www.youtube.com
This video summarizes some of the common tricks for making k-nearest neighbors more efficient in terms of computational performance and predictive performanc...
 

2.6 K vizinhos mais próximos em Python (L02: métodos de vizinho mais próximo)



2.6 K vizinhos mais próximos em Python (L02: métodos de vizinho mais próximo)

Após uma discussão abrangente sobre K vizinhos mais próximos, o texto apresenta um exemplo Python que mostra a implementação de K vizinhos mais próximos usando a popular biblioteca scikit-learn. O autor reconhece que nem todos os aspectos podem ser imediatamente claros e garante aos leitores que as palestras futuras se aprofundarão em Python, NumPy e scikit-learn. No entanto, o exemplo fornecido serve como um teaser para oferecer uma perspectiva de cima para baixo sobre como essas ferramentas funcionam.

Para dar suporte ao exemplo de implementação, o autor refere-se a um site onde os leitores podem encontrar exemplos de código. Além disso, o autor explica o processo de download de um repositório do GitHub usando o arquivo zip ou clonando-o. Enfatizando a importância do GitHub como uma ferramenta do mundo real, o autor sugere que ter um perfil do GitHub e compartilhar projetos pode ser vantajoso para mostrar o trabalho de alguém a potenciais empregadores.

O texto fornece instruções detalhadas sobre como clonar um repositório usando o link do GitHub e o comando "git clone". Embora reconheça que o processo pode variar um pouco para usuários do Windows, o autor recomenda buscar tutoriais ou assistência do TA (assistente de ensino). Depois que o repositório é clonado com sucesso, o autor instrui os leitores a navegar até a pasta e explica que as atualizações podem ser obtidas usando o comando "git pull".

Passando para os exemplos de código, o autor demonstra a abertura de um Jupyter Notebook, especificamente o Jupyter Lab, e a execução de comandos passo a passo. Para evitar sobrecarregar os leitores, o autor enfatiza a importância de limpar as saídas após cada execução. Além disso, o autor menciona a utilidade da extensão de marca d'água nos Jupyter Notebooks, que exibe as versões dos pacotes de software utilizados. Essas informações auxiliam na solução de problemas e garantem a replicabilidade dos resultados. Pacotes essenciais como Pandas, NumPy, Matplotlib e scikit-learn são instalados para facilitar a implementação.

Em seguida, o autor carrega o conjunto de dados Iris de um arquivo CSV e mostra o uso de comandos como "cabeça" e "cauda" para visualizar o conjunto de dados. Os dados são carregados em um Pandas DataFrame usando a função "read_csv". Embora observe que o aprendizado de máquina normalmente emprega matrizes NumPy, o autor destaca que o scikit-learn também oferece suporte a DataFrames. Para ilustrar isso, o autor fornece um exemplo de extração de colunas específicas do DataFrame para criar uma matriz NumPy. A forma da matriz, indicando o número de exemplos e recursos de treinamento, é exibida usando o comando "forma".

O texto descreve uma série de etapas que constituem um fluxo de trabalho de aprendizado de máquina usando Python e a biblioteca scikit-learn. Aqui está um resumo detalhado dessas etapas:

  1. Embaralhando índices e rótulos: o autor inicia o fluxo de trabalho discutindo o processo de embaralhar índices e rótulos em um conjunto de dados. O objetivo do embaralhamento é randomizar a ordem dos pontos de dados, garantindo que cada rótulo corresponda à linha correta na matriz de recursos.

  2. Divisão do conjunto de dados: O conjunto de dados é dividido em um conjunto de treinamento e um conjunto de teste. O autor seleciona manualmente os primeiros 105 exemplos para o conjunto de treinamento e reserva os 45 exemplos restantes para o conjunto de teste. Essa divisão é crucial para avaliar o desempenho do modelo de aprendizado de máquina.

  3. Introdução ao scikit-learn e ao conjunto de dados Iris: o autor apresenta a biblioteca scikit-learn, especificamente a implementação do conjunto de dados Iris e a função "train_test_split". O conjunto de dados Iris é um conjunto de dados popular amplamente usado para tarefas de classificação. A função "train_test_split" embaralha automaticamente o conjunto de dados e o divide nas proporções especificadas para treinamento e teste.

  4. Visualização usando uma matriz de gráfico de dispersão: O autor fornece uma função conveniente chamada "matriz de gráfico de dispersão" para visualizar o conjunto de dados. Esta função utiliza a biblioteca matplotlib para criar uma matriz de gráfico de dispersão com histogramas exibidos na diagonal. A matriz do gráfico de dispersão representa visualmente as relações entre diferentes recursos no conjunto de dados.

  5. Demonstração da matriz do gráfico de dispersão: O autor demonstra o uso da matriz do gráfico de dispersão plotando o conjunto de dados Iris. Diferentes cores são atribuídas para representar diferentes classes de flores. Notavelmente, o autor destaca que características específicas, como comprimento e largura da pétala, são particularmente úteis para distinguir entre diferentes classes de flores.

  6. Introdução ao classificador de k-vizinhos mais próximos (k-NN): O autor passa a explicar o classificador de k-vizinhos mais próximos (k-NN), que é um algoritmo direto que classifica pontos de dados com base em sua proximidade com pontos de dados vizinhos. Para instanciar o classificador k-NN, o autor cria um objeto com três vizinhos.

  7. Ajustando o classificador k-NN: O classificador k-NN é ajustado ao conjunto de treinamento usando o método "fit". Esta etapa treina o modelo usando os dados de treinamento fornecidos.

  8. Previsão no conjunto de teste: o autor emprega o classificador k-NN ajustado para fazer previsões no conjunto de teste usando o método "prever". As previsões são armazenadas em uma variável chamada "pred".

  9. Avaliação de Desempenho: Para avaliar o desempenho do modelo, o autor compara os rótulos previstos (armazenados em "pred") com os rótulos verdadeiros do conjunto de teste (armazenados em "y_test"). Ao calcular o número de previsões corretas, a precisão do modelo no conjunto de teste pode ser determinada.

  10. Conclusão e exploração adicional: A palestra termina incentivando os leitores a explorar a documentação do scikit-learn para obter informações adicionais sobre o algoritmo k-vizinhos mais próximos e suas várias opções. Além disso, o autor questiona os leitores sobre a métrica de distância padrão usada pelo classificador k-NN e sugere um exercício para investigar e discutir esse aspecto.

A palestra fornece uma explicação abrangente de vários tópicos, incluindo o conceito de K-vizinhos mais próximos, um exemplo de implementação usando a biblioteca scikit-learn, diretrizes para download e clonagem de repositórios do GitHub, uma introdução ao Jupyter Notebook e Jupyter Lab, carregando um conjunto de dados em um Pandas DataFrame e demonstrando a extração de colunas e a conversão para matrizes NumPy.

2.6 K-nearest neighbors in Python (L02: Nearest Neighbor Methods)
2.6 K-nearest neighbors in Python (L02: Nearest Neighbor Methods)
  • 2020.09.10
  • www.youtube.com
In this video, we are talking about using k-nearest neighbors in Python using scikit-learn. Jupyter Notebook: https://github.com/rasbt/stat451-machine-learni...
 

3.1 (Opcional) Visão geral do Python



3.1 (Opcional) Visão geral do Python

Espero que todos estejam tendo uma ótima semana até agora e aproveitando as palestras. Hoje, quero discutir alguns tópicos importantes abordados nas palestras recentes.

Primeiramente, tivemos uma palestra sobre a melhoria de Canaan, seguida de uma palestra sobre a implementação de kin em Python usando o aprendizado psíquico. Com base em seus comentários da introdução ao questionário Conheça você, descobri que a maioria de vocês tem experiência em programação ou já fez um curso de programação antes. Esta é uma ótima notícia porque será muito benéfica para você neste curso. No entanto, notei que apenas cerca de metade de vocês tem experiência sólida com Python. Portanto, antes de mergulharmos na computação científica com Python e explorarmos o aprendizado psíquico com mais detalhes, pensei que seria útil fornecer alguma ajuda na configuração do Python para aqueles que são novos nele. Isso garantirá que a próxima palestra seja mais tranquila para todos.

Em uma nota mais leve, eu realmente gostei de ler sobre seus hobbies favoritos. Parece que muitos de vocês compartilham meu amor por atividades ao ar livre, como esqui cross country, corrida e caminhadas. Passar um tempo na natureza é realmente revigorante, embora eu entenda que dias chuvosos e invernos longos podem limitar essas oportunidades. Alguns de vocês também mencionaram seu interesse por videogames, com um aluno mencionando a série Zelda. Devo admitir que também sou um grande fã da série e gosto de jogá-la durante os dias de Natal com neve ou depois de um dia agitado para relaxar.

Seguindo em frente, como prometido, a palestra de hoje será opcional. Se você já tem uma forte experiência em Python e o configurou em seu computador, pode pular os três vídeos a seguir. No entanto, se você é novo no Python ou precisa de ajuda para configurá-lo, recomendo assisti-los. Esses vídeos fornecerão motivação e conselhos práticos com base em minha própria experiência com Python. É importante observar que você não precisa ser um programador especialista para usar o Python neste curso. Vamos nos concentrar nos fundamentos necessários para o aprendizado de máquina e você aprenderá mais à medida que progredirmos.

Na próxima semana, teremos nossa primeira tarefa de casa real, onde você implementará um algoritmo K-vizinho mais próximo. Esta tarefa exigirá que você escreva seu próprio código, além de usar o aprendizado psíquico. Portanto, seria benéfico para você configurar o Python esta semana em preparação para o dever de casa. Não se preocupe; a tarefa foi projetada para ajudá-lo a entender melhor o algoritmo KNN e não será muito difícil, pois é a primeira lição de casa. Depois de concluir esta tarefa, nos aprofundaremos nos aspectos conceituais do aprendizado de máquina.

Antes de prosseguirmos, vamos ter uma rápida visão geral do progresso do curso. Na primeira semana, cobrimos a introdução ao aprendizado de máquina e K-vizinhos mais próximos. Atualmente, estamos na segunda semana, focando em fundamentos computacionais. Esses fundamentos são cruciais, pois os usaremos posteriormente para implementar vários conceitos de aprendizado de máquina. Portanto, é essencial nos familiarizarmos com o Python e seu uso desde o início. Nesta palestra, discutiremos principalmente o Python e como configurá-lo. Observe que demonstrarei o processo de configuração no meu Mac, mas nosso TA pode ajudar com qualquer dúvida relacionada ao Windows.

Python é uma linguagem de programação interpretada e dinâmica, o que a torna mais interativa e fácil de usar em comparação com linguagens de tipagem estática como C ou C++. Embora o Python possa ser mais lento do que essas linguagens, não é uma preocupação significativa para nossos propósitos. Muitas bibliotecas de computação científica, que exploraremos na próxima aula, são escritas em C ou Fortran e oferecem tempos de execução rápidos. Python é uma linguagem de programação multifuncional amplamente usada em vários aplicativos, incluindo estruturas da Web como Django e serviços populares como Instagram e Dropbox.

Agora, vamos comparar Python com uma linguagem de tipagem estática como C escrevendo um programa simples. Em C, precisamos declarar variáveis e especificar explicitamente seus tipos de dados, como inteiros, flutuantes ou caracteres. Aqui está um exemplo de um programa simples em C:

#include <stdio.h>

int main() {
     int age = 25 ;
     float height = 1.75 ;
     char initial = 'J' ;

    printf( "My age is %d\n" , age);
    printf( "My height is %.2f meters\n" , height);
    printf( "My initial is %c\n" , initial);

     return 0 ;
}
Neste programa em C, declaramos as variáveis idade, altura e inicial com seus respectivos tipos de dados. Em seguida, atribuímos valores a essas variáveis e as imprimimos usando printf().

Agora, vamos comparar o mesmo programa em Python:

age = 25
height = 1.75
initial = 'J'

print( "My age is" , age)
print( "My height is" , height, "meters" )
print( "My initial is" , initial)
Em Python, você não precisa declarar explicitamente os tipos de variáveis. Você pode atribuir valores diretamente às variáveis e o Python inferirá automaticamente os tipos de dados. A função print() é usada para exibir a saída.

A simplicidade e a legibilidade do Python o tornam uma excelente escolha tanto para iniciantes quanto para programadores experientes. Possui um vasto ecossistema de bibliotecas e estruturas que o tornam adequado para computação científica, análise de dados, aprendizado de máquina e muito mais.

Agora, vamos configurar o Python em seu computador. Existem diferentes maneiras de instalar o Python, mas eu recomendo usar a distribuição Anaconda, que vem pré-empacotada com muitas bibliotecas úteis para computação científica. Aqui estão os passos para instalar o Anaconda:

  1. Visite o site da Anaconda ( https://www.anaconda.com/products/individual ) e baixe o instalador apropriado para o seu sistema operacional (Windows, macOS ou Linux).

  2. Execute o instalador e siga as instruções na tela. Você pode escolher as opções de instalação padrão, a menos que tenha preferências específicas.

  3. Após a conclusão da instalação, você deve ter o Anaconda Navigator e o Anaconda Prompt (ou Anaconda PowerShell Prompt) instalados em seu computador. Essas são ferramentas convenientes para gerenciar ambientes e pacotes Python.

  4. Abra o Anaconda Navigator e clique na guia "Ambientes". Aqui, você pode criar um novo ambiente para este curso. Clique no botão "Criar", forneça um nome para o ambiente (por exemplo, "aprendizado de máquina") e escolha a versão do Python (de preferência Python 3.x). Clique em "Criar" para criar o ambiente.

  5. Uma vez criado o ambiente, clique na aba "Home" no Anaconda Navigator. Você deve ver uma lista de aplicativos e ambientes disponíveis. Selecione seu ambiente recém-criado no menu suspenso na parte superior da janela.

  6. Na guia "Página inicial", clique no botão "Instalar" na seção Jupyter Notebook. Isso instalará o Jupyter Notebook, que usaremos para programação interativa e execução de código Python.

  7. Após a instalação, clique no botão "Launch" ao lado do Jupyter Notebook. Isso abrirá uma nova guia em seu navegador da Web, executando o Jupyter Notebook.

Parabéns! Você instalou com sucesso o Python e o Jupyter Notebook usando a distribuição Anaconda. Agora você está pronto para começar a codificar em Python para este curso. Na próxima palestra, mergulharemos mais fundo na computação científica com Python e exploraremos a popular biblioteca chamada scikit-learn.

Se você encontrar algum problema durante o processo de instalação ou tiver alguma dúvida, não hesite em perguntar no fórum de discussão ou entrar em contato com o TA para obter ajuda.

Observe que essas instruções são específicas para o Anaconda, mas se você preferir usar uma distribuição Python diferente, como Miniconda ou a distribuição Python padrão, ainda poderá acompanhar o curso.

3.1 (Optional) Python overview
3.1 (Optional) Python overview
  • 2020.09.16
  • www.youtube.com
In this optional videos, I mainly talk about the use of Python in this course. I will also show a quick demo using C (a statically typed language) vs Python....
 

3.2 (Opcional) Configuração do Python


3.2 (Opcional) Configuração do Python

No segundo vídeo do curso, abordaremos o processo de configuração e como instalar o Python. No vídeo anterior, abordamos os fundamentos das linguagens de programação interpretadas e dinâmicas, destacando o Python como uma linguagem interpretada dinâmica.

Antes de prosseguirmos com a instalação, é importante assistir ao vídeo e evitar instalar qualquer coisa em seu computador enquanto assiste. Essa medida de precaução garante que você tenha um entendimento completo das diferentes opções de instalação antes de tomar uma decisão. Instalar software sem conhecimento adequado pode levar a arrependimentos mais tarde.

Para começar, é recomendável verificar se você já possui uma versão atualizada do Python instalada em seu computador. No Mac ou Linux, você pode usar o comando "which Python" para determinar o local e a versão da instalação. Da mesma forma, no Windows, você pode usar o comando "where" para encontrar o local de instalação.

Muitos Macs tradicionalmente vêm com uma versão desatualizada do Python, especificamente o Python 2. É altamente recomendável atualizar o Python, pois o Python 2 não é mais suportado pela comunidade Python. O ideal é instalar o Python 3.8 ou 3.7, pois a versão 3.9 mais recente ainda está em desenvolvimento.

O método oficial de instalação do Python é visitando python.org e baixando o instalador. No entanto, uma abordagem alternativa frequentemente preferida é o uso do Anaconda ou, mais especificamente, do Miniconda. Miniconda é uma versão leve do Anaconda que não inclui bibliotecas desnecessárias, economizando espaço de armazenamento em seu computador. Enquanto o Anaconda vem com bibliotecas pré-instaladas, o Miniconda permite um processo de instalação mais personalizado.

Pessoalmente, o instrutor recomenda o uso do Miniconda devido à sua conveniência e à experiência positiva que muitos membros da comunidade de computação científica Python tiveram com ele. O Miniconda oferece um gerenciador de pacotes abrangente que garante que todas as versões de pacote necessárias sejam instaladas e gerencie as dependências do pacote. Esse recurso facilita a manutenção de um ambiente de desenvolvimento estável e compatível.

Para instalar o Miniconda, você pode visitar o site de documentação, docs.conda.io, e navegar até a versão mais recente em inglês da página de instalação do Miniconda. A partir daí, você pode escolher o instalador apropriado para o seu sistema operacional. Para usuários de Mac, o instalador bash é comumente usado. Após baixar o instalador, execute o script, aceite o contrato de licença e escolha o local de instalação.

Depois que o Miniconda estiver instalado, você pode verificar sua versão padrão do Python abrindo um shell do Python, que agora deve exibir a versão atualizada. O Miniconda também fornece ferramentas para gerenciar diferentes ambientes, permitindo criar ambientes isolados para diferentes projetos. Embora não sejam necessários para este curso, esses ambientes podem ser úteis se você trabalhar em vários projetos simultaneamente.

Para instalar pacotes, como o pacote "numpy" necessário para a próxima aula, você pode usar o gerenciador de pacotes "pip" ou o instalador Conda. Como você está usando o Miniconda, é recomendável usar o instalador Conda sempre que possível, pois garante melhor compatibilidade e gerenciamento de versões. No entanto, se um pacote não estiver disponível no Conda, você pode recorrer ao uso de "pip".

Caso precise instalar pacotes não disponíveis no Conda, como o pacote "mlxtend", você pode explorar o Conda Forge. O Conda Forge é um repositório voltado para a comunidade que hospeda bibliotecas suportadas pela comunidade Conda mais ampla. Ao pesquisar o pacote desejado no Conda Forge, você pode encontrar instruções de instalação específicas para esse pacote.

Lembre-se de que você também pode atualizar pacotes usando o gerenciador de pacotes Conda, usando comandos como "conda update" seguido do nome do pacote ou com "pip" usando "pip install --upgrade" seguido do nome do pacote.

Seguindo essas diretrizes de instalação e gerenciamento de pacotes, você pode garantir uma configuração suave e eficiente do Python para este curso.

Para instalar pacotes do canal Conda Forge, você pode usar o seguinte comando:

conda install -c conda-forge <nome do pacote>

Por exemplo, para instalar o pacote MLX Extent do Conda Forge, você usaria:

conda install -c conda-forge mlx_ext

Este comando irá procurar o pacote no canal Conda Forge e instalá-lo em seu ambiente.

Se o pacote que você precisa não estiver disponível no Conda Forge ou em qualquer outro canal Conda, você também pode usar o gerenciador de pacotes pip para instalá-lo. Pip é o gerenciador de pacotes padrão para Python e permite que você instale pacotes do Python Package Index (PyPI).

Para instalar um pacote usando pip, você pode usar o seguinte comando:

pip install <nome do pacote>

Por exemplo, para instalar um pacote chamado "example-package" usando pip, você usaria:

pip instalar pacote de exemplo

Certifique-se de substituir <package-name> pelo nome real do pacote que deseja instalar.

Lembre-se de que, ao usar o Conda e o pip, geralmente é recomendável usar o Conda como o gerenciador de pacotes principal para manter a compatibilidade do pacote e gerenciar as dependências. No entanto, se um pacote não estiver disponível no Conda, usar o pip é uma alternativa adequada.

Isso conclui as instruções de configuração para instalar o Python e gerenciar pacotes usando Conda e pip. Lembre-se de assistir ao tutorial em vídeo antes de instalar qualquer coisa em seu computador e siga as etapas recomendadas para garantir um processo de instalação tranquilo.

3.2 (Optional) Python setup
3.2 (Optional) Python setup
  • 2020.09.16
  • www.youtube.com
In this optional video, I am demonstrating how to install Python using Miniconda on macOS. Also, I provide some brief demo of the conda package manager.-----...
 

3.3 (Opcional) Executando o código Python


3.3 (Opcional) Executando o código Python

No terceiro e último vídeo da aula três, demonstrarei diferentes métodos para executar o código Python. Este vídeo se concentrará nos notebooks Júpiter, um formato de arquivo e programa que permite codificação conveniente, escrita de texto, renderização de equações e plotagem em um único documento, que será usado para a próxima tarefa de casa.

Antes de mergulhar nos notebooks do Júpiter, primeiro mostrarei a maneira mais fácil de executar o código Python, que é usando o interpretador Python ou o que algumas pessoas chamam de REPL (Read-Eval-Print Loop). O interpretador permite a execução interativa do código Python, o que significa que o código é avaliado imediatamente. Para usar o interpretador, você pode abrir seu terminal e digitar "python". A partir daí, você pode inserir expressões Python e ver os resultados imediatamente. Por exemplo, digitar "print(1 + 2)" exibirá o resultado "3". Você também pode usar o interpretador para tarefas mais complexas, como repetir valores e imprimi-los.

Embora o interpretador possa ser útil para cálculos ou cálculos rápidos, não é recomendado para escrever códigos mais complicados. Pode ser fácil perder o controle dos cálculos e tornar-se complicado rolar para trás e localizar comandos executados anteriormente. Portanto, para códigos mais complexos, é preferível usar um script Python ou um notebook Jupiter.

Em seguida, apresento um interpretador Python interativo alternativo chamado IPython. O IPython oferece recursos e funcionalidades adicionais em comparação com o interpretador regular, incluindo coloração de sintaxe, função de histórico para fácil modificação de código e comandos mágicos. Comandos mágicos são comandos especiais que começam com um sinal de porcentagem (%) e fornecem funcionalidades úteis. Um exemplo é o comando mágico "timeit", que permite comparar diferentes implementações de código. Eu demonstro isso implementando duas funções para inverter strings e comparando sua eficiência usando o comando "timeit".

Depois de mostrar os benefícios do IPython, explico que os notebooks Jupiter foram originalmente chamados de notebooks IPython porque foram construídos sobre o IPython. Mesmo agora, os notebooks Jupiter dependem do IPython, fornecendo os mesmos benefícios e recursos adicionais. Para instalar o IPython, eu uso o Conda e mostro o site do IPython para mais documentação.

Prosseguindo, discuto o segundo método de execução do código Python, que é o uso de scripts Python. Esse método envolve a criação de um arquivo com extensão .py, a gravação do código no arquivo e sua execução na linha de comando. Forneço um exemplo de script Python que usa um loop para imprimir números de 0 a 4.

Por fim, menciono a importância de aderir às diretrizes de estilo de codificação, como PEP 8, para escrever um código limpo e legível. Mostro como o uso de um linter, como o Flake8, em um ambiente de desenvolvimento integrado como o Visual Studio Code pode ajudar a identificar e corrigir problemas de estilo, melhorando a qualidade geral do código.

O vídeo abordou diferentes maneiras de executar o código Python, incluindo o uso do interpretador, a criação de scripts Python e o aproveitamento dos benefícios dos notebooks IPython e Jupiter. Cada método tem suas próprias vantagens e é adequado para diferentes propósitos.

3.3 (Optional) Running Python code
3.3 (Optional) Running Python code
  • 2020.09.16
  • www.youtube.com
In this third and last video of the optional lecture 3, I am demonstrating the different ways for running Python code: the REPL, IPython, .py scripts, and Vi...
 

4.1 Introdução ao NumPy (L04: Computação científica em Python)



4.1 Introdução ao NumPy (L04: Computação científica em Python)

Neste tutorial, abordaremos o básico do NumPy, incluindo a criação de arrays, acesso a elementos, execução de operações de array e muito mais. Vamos começar!

Para começar, precisamos importar a biblioteca NumPy. Convencionalmente, é importado sob o pseudônimo np. Execute o seguinte código para importar o NumPy:

import numpy as np
Agora que importamos o NumPy, vamos criar nosso primeiro array. Arrays NumPy são criados usando a função np.array(), que usa uma lista Python como entrada. Execute o seguinte código para criar uma matriz:

arr = np.array([1, 2, 3, 4, 5])
print(arr)
Você deve ver a seguinte saída:

[1 2 3 4 5]
Parabéns! Você criou sua primeira matriz NumPy. Agora vamos explorar algumas operações básicas que podemos realizar em arrays.

Acessando elementos da matriz

Para acessar elementos em uma matriz NumPy, podemos usar indexação e divisão, semelhantes às listas do Python. A indexação começa em 0.

Execute o seguinte código para acessar elementos na matriz:

 print (arr[ 0 ])   # Access the first element
print (arr[ 2 ])   # Access the third element
print (arr[- 1 ])   # Access the last element
A saída será:

1
3
5
Também podemos usar fatias para acessar uma variedade de elementos em uma matriz. A sintaxe para divisão é start:stop:step, onde start é o índice inicial, stop é o índice de parada (exclusivo) e step é o tamanho do passo.

Execute o seguinte código para dividir a matriz:

 print (arr[ 1 : 4 ])   # Access elements from index 1 to 3
print (arr[:: 2 ])   # Access every other element

A saída será:

[2 3 4]
[1 3 5]
Operações de Matriz

As matrizes NumPy suportam várias operações matemáticas, como adição, subtração, multiplicação e divisão. Essas operações são aplicadas elemento a elemento aos arrays.

Execute o seguinte código para realizar operações de array:

arr1 = np. array ([ 1 , 2 , 3 ])
arr2 = np. array ([ 4 , 5 , 6 ])

# Addition
print (arr1 + arr2)

# Subtraction
print (arr1 - arr2)

# Multiplication
print (arr1 * arr2)

# Division
print (arr1 / arr2)
A saída será:

 [5 7 9]
[-3 -3 -3]
[4 10 18]
[0.25 0.4  0.5]
O NumPy também fornece várias funções matemáticas que podem ser aplicadas a arrays. Por exemplo, a função np.sin() pode ser usada para calcular o seno de uma matriz.

Execute o seguinte código para aplicar uma função matemática a uma matriz:

arr = np. array ([ 0 , np.pi/ 2 , np.pi])

# Calculate sine
print (np.sin(arr))
A saída será:

[0.0000000e+00 1.0000000e+00 1.2246468e-16]

Forma de Array e Remodelagem

A forma de uma matriz NumPy representa suas dimensões, como o número de linhas e colunas. Podemos usar o atributo shape para verificar a forma de um array.

Execute o seguinte código para verificar a forma de uma matriz:

arr = np.array([[1, 2, 3], [4, 5, 6]])
print(arr.shape)
A saída será:

(2, 3)
Também podemos alterar a forma de um array usando a função reshape(). Esta função nos permite redimensionar um array sem alterar seus dados.

Execute o seguinte código para remodelar uma matriz:

arr = np.array([1, 2, 3, 4, 5, 6])
reshaped_arr = arr.reshape((2, 3))
print(reshaped_arr)
A saída será:

[[1 2 3]
 [4 5 6]]
Estas são apenas algumas das operações básicas que você pode realizar com o NumPy. A biblioteca fornece uma ampla gama de funções e recursos para trabalhar com matrizes de forma eficiente. Encorajo você a explorar a documentação do NumPy para saber mais sobre seus recursos.
4.1 Intro to NumPy (L04: Scientific Computing in Python)
4.1 Intro to NumPy (L04: Scientific Computing in Python)
  • 2020.09.20
  • www.youtube.com
This first video in the "L04: Intro to Scientific Computing in Python" introduces NumPy on a basic level before diving into more details in the following vid...
 

4.2 Construção e indexação de matriz NumPy (L04: Computação científica em Python)



4.2 Construção e indexação de matriz NumPy (L04: Computação científica em Python)

No segundo vídeo, gostaria de discutir a construção e indexação de matrizes não Python. Rotinas de construção de array são blocos de construção úteis ou funções para criar arrays. Eles são úteis quando você precisa de uma matriz de espaço reservado que pode ser preenchida posteriormente com valores específicos. Deixe-me demonstrar o que quero dizer.

Para criar um array preenchido com o número um, podemos usar a função uns. Por exemplo, ones((3, 3)) gerará uma matriz 3x3 com todos os elementos definidos como um. Você também pode especificar dimensões diferentes, como uns((3, 4)), que criará uma matriz 3x4 preenchida com uns. A função one aceita vários argumentos, incluindo o parâmetro dtype, que determina o tipo de dados do array (o padrão é float64 para máquinas de 64 bits). Você pode defini-lo como int64 para criar uma matriz de números inteiros. Além disso, você pode especificar o parâmetro order, que controla como a matriz é disposta na memória. O padrão é C, representando o estilo de linha principal, mas você pode escolher F para layout de estilo Fortran. No entanto, para esta aula, você não precisa se preocupar com esses detalhes, pois eles são mais relevantes para combinar NumPy com código C ou Fortran.

Da mesma forma, a função zeros pode ser usada para criar uma matriz preenchida com zeros. Você pode usá-lo da mesma forma que os outros. Lembre-se, se quiser saber mais sobre essas funções, você pode usar a função de ajuda ou usar um ponto de interrogação (?) no Jupyter Lab ou IPython.

Existe também a função empty, que cria um array vazio sem inicializar seus valores. Na maioria dos casos, você não precisará se preocupar com os detalhes dessa função, pois ela simplesmente cria uma matriz com valores arbitrários. A função identidade cria uma matriz identidade, onde os elementos diagonais são uns e o resto são zeros. Ele pode ser usado para criar uma matriz diagonal com valores específicos.

Passando para a indexação, a indexação básica em arrays NumPy é semelhante à indexação em listas Python. Você pode acessar elementos usando colchetes. Por exemplo, array[0] retorna o primeiro elemento, array[1] retorna o segundo elemento e assim por diante. O fatiamento também é possível, assim como nas listas do Python. Por exemplo, array[1:4] retornará uma fatia do array do índice 1 ao 3 (excluindo o índice 4).

Ao lidar com arrays bidimensionais, você pode usar uma notação de vírgula para indexar as duas dimensões. O primeiro índice especifica a linha, enquanto o segundo índice especifica a coluna. Por exemplo, array[0, 0] retorna o elemento na primeira linha e primeira coluna, array[1, 2] retorna o elemento na segunda linha e terceira coluna e assim por diante.

A indexação negativa pode ser usada para acessar elementos do final de uma matriz. Por exemplo, array[-1, -1] retornará o último elemento do array. Da mesma forma, array[-1, -2] retornará o penúltimo elemento. Isso pode ser útil ao trabalhar com arrays grandes, já que você não precisa controlar o tamanho do array.

Para recuperar uma linha ou coluna inteira, você pode omitir um dos índices. Por exemplo, array[0, :] retorna a primeira linha inteira e array[:, 1] retorna a segunda coluna inteira. Isso equivale a especificar o intervalo de índices (por exemplo, array[0, 0:3] para a primeira linha). O fatiamento funciona em ambas as dimensões, permitindo que você selecione partes específicas da matriz. Por exemplo, array[1:3, 2:4] retorna um subarray que consiste nas linhas 1 e 2 (excluindo a linha 3) e nas colunas 2 e 3 (excluindo a coluna 4).

A indexação booleana é outro recurso poderoso do NumPy. Você pode usar uma matriz booleana para indexar uma matriz, selecionando apenas os elementos que correspondem aos valores True na matriz booleana. Por exemplo, suponha que temos um array chamado array com a forma (3, 3):

array( [[1, 2, 3] ,
       [4, 5, 6] ,
       [7, 8, 9] ])

Podemos criar um array booleano com base em uma condição, como array > 5, que retornará o seguinte array booleano:

array([[ False , False , False ],
       [ False , False , True ],
       [ True , True , True ]])
Usando este array booleano como índice para o array original, podemos selecionar apenas os elementos que correspondem aos valores True, resultando em:

array([6, 7, 8, 9])
A indexação booleana permite a seleção flexível e eficiente de elementos com base em condições específicas.

Além da indexação básica, o NumPy fornece técnicas avançadas de indexação, como indexação de array inteiro e uso de arrays como índices. Essas técnicas permitem operações de indexação mais complexas e não contíguas em arrays. No entanto, eles são tópicos mais avançados e podem não ser necessários para a manipulação básica de matrizes.

4.2 NumPy Array Construction and Indexing (L04: Scientific Computing in Python)
4.2 NumPy Array Construction and Indexing (L04: Scientific Computing in Python)
  • 2020.09.20
  • www.youtube.com
This video explains how we can construct arrays in NumPy and how we access individual elements via indexing operations.Link to the Jupyter notebook: https://...
 

4.3 NumPy Array Math e Funções Universais (L04: Computação Científica em Python)



4.3 NumPy Array Math e Funções Universais (L04: Computação Científica em Python)

Depois de investir um tempo considerável na criação de uma corrida e na indexação de valores individuais em um array, vamos passar para um tópico mais intrigante: array não remunerado, matemática e funções universais.

As funções universais, muitas vezes abreviadas como Ufunk ou Frank, são um conceito poderoso na programação. Uma função universal (Ufunk) é uma forma abreviada de uma função universal, que permite um trabalho mais eficiente e conveniente com arrays Numpy. Ele introduz um conceito chamado vetorização.

A vetorização envolve a execução de uma operação matemática ou aritmética em uma sequência de objetos, como uma matriz. Ao invés de executar a operação individualmente em cada elemento do array, a vetorização nos permite realizar a operação em paralelo, aproveitando a falta de dependências entre os elementos.

Por exemplo, vamos considerar a tarefa de adicionar um número a cada elemento em um array. Com um loop for do Python, iteramos sobre cada elemento e chamamos uma função de adição. Porém, com a vetorização, podemos realizar a adição em todo o array simultaneamente, sem a necessidade de um loop. Isso melhora significativamente a eficiência.

No Numpy, a vetorização é obtida usando funções universais (Ufunk). Existem mais de 60 Ufunk implementados no Numpy, cada um servindo a um propósito específico. Recomenda-se consultar a documentação oficial para obter uma lista completa dos Ufunk disponíveis.

Para ilustrar o conceito, vamos nos concentrar na adição elementar, uma operação comum. Suponha que tenhamos um array bidimensional implementado como uma lista de listas em Python. Se quisermos adicionar 1 a cada elemento, normalmente usaríamos loops aninhados ou compreensões de lista. No entanto, essas abordagens podem ser ineficientes, especialmente para matrizes grandes.

No Numpy, podemos usar o Ufunk "np.add" para adicionar o número 1 a todo o array de maneira vetorizada. Isso elimina a necessidade de loops explícitos e melhora significativamente o desempenho.

Vale a pena mencionar que o Numpy aproveita a sobrecarga do operador, o que permite o uso intuitivo do Ufunk. Por exemplo, usar o operador "+" entre uma matriz e um número invoca automaticamente o Ufunk "np.add".

Outro Ufunk útil é "np.square", que eleva ao quadrado cada elemento em uma matriz. As funções Ufunk podem ser unárias (operando em um único valor) ou binárias (recebendo dois argumentos). A documentação oficial do Numpy fornece mais detalhes sobre o Ufunk disponível.

Passando para um caso mais interessante, vamos explorar o uso do Ufunk em conjunto com o método "reduce". A operação "reduzir" aplica uma operação ao longo de um eixo especificado, reduzindo vários valores em um único valor. Por exemplo, podemos calcular as somas das colunas usando "np.add" com o método "reduce".

Neste cenário, rolamos o eixo especificado (eixo 0 neste caso) e combinamos os elementos usando a operação especificada. A operação de "redução" é comumente associada a conceitos como "redução de mapa" e Hadoop, em que as computações são distribuídas por vários nós e, em seguida, combinadas para produzir o resultado final.

Embora isso possa parecer esmagador, entender esses conceitos permite uma programação mais eficiente e eficaz com o Numpy. Aproveitando o Ufunk e a vetorização, podemos executar operações complexas em arrays com facilidade e otimizar nosso código para melhorar o desempenho.

Lembre-se de consultar a documentação oficial do Numpy para obter uma lista abrangente de Ufunk disponíveis, bem como exemplos e diretrizes de uso. Explorar as possibilidades do Ufunk irá expandir seu kit de ferramentas e ajudá-lo a lidar com várias tarefas computacionais em projetos futuros.

Então, no NumPy, temos uma função chamada reduce, que nos permite realizar operações de redução ao longo de um eixo especificado de um array. A operação de redução combina vários valores em um único valor. Por padrão, a redução é aplicada ao longo do primeiro eixo (eixo 0) da matriz.

Vamos dar um exemplo para entender melhor esse conceito. Considere a seguinte matriz:

array( [[1, 2, 3] ,
       [4, 5, 6] ,
       [7, 8, 9] ])
Se quisermos calcular as somas das colunas, podemos usar a função de redução. Esta operação rolará sobre o primeiro eixo (eixo 0) e combinará os valores em cada coluna. Assim, o resultado será um array unidimensional contendo as somas de cada coluna.

Para conseguir isso, podemos usar a função np.add, que executa a adição elemento a elemento. Passamos np.add como o argumento da função para reduzir, indicando que queremos adicionar os valores ao longo do eixo especificado.

Veja como o código se parece:

import numpy as np

array = np. array ([[ 1 , 2 , 3 ],
                  [ 4 , 5 , 6 ],
                  [ 7 , 8 , 9 ]])

column_sums = np.reduce(np.add, array )
print (column_sums)
A saída será:

[12 15 18]
Neste exemplo, a função de redução itera sobre as colunas da matriz e adiciona os valores. Ele combina a primeira coluna (1 + 4 + 7), a segunda coluna (2 + 5 + 8) e a terceira coluna (3 + 6 + 9) em uma única matriz que representa as somas das colunas.

Essa abordagem é mais eficiente do que iterar manualmente nas colunas e adicionar os valores um por um. A operação vetorizada fornecida pelo NumPy nos permite realizar a computação em paralelo, aproveitando os algoritmos subjacentes otimizados.

Tenha em mente que a redução pode ser usada com várias outras funções além de np.add, dependendo da operação que você deseja realizar. O conceito de redução é poderoso e pode ser aplicado a muitos cenários diferentes.

4.3 NumPy Array Math and Universal Functions (L04: Scientific Computing in Python)
4.3 NumPy Array Math and Universal Functions (L04: Scientific Computing in Python)
  • 2020.09.20
  • www.youtube.com
This video discusses one of the core aspects of NumPy: it's functions that allow us to work with NumPy arrays efficiently.Jupyter notebook: https://github.co...
 

4.4 Transmissão NumPy (L04: Computação Científica em Python)



4.4 Transmissão NumPy (L04: Computação Científica em Python)

O NumPy oferece um recurso fascinante conhecido como "broadcasting", que introduz dimensões implícitas e nos permite realizar operações que normalmente seriam impossíveis dentro dos limites da álgebra linear estrita. Esse conceito de transmissão permite mais flexibilidade e conveniência ao trabalhar com arrays.

Aproveitando a transmissão, o NumPy pode alinhar automaticamente matrizes com formas diferentes, essencialmente expandindo-as para corresponder e executar operações elementares. Essa criação de dimensão implícita nos permite executar operações perfeitamente em arrays de tamanhos variados, resultando em código conciso e eficiente.

No contexto da álgebra linear, onde regras matemáticas regem as operações, a transmissão fornece uma ferramenta poderosa para simplificar cálculos complexos. Ele nos permite realizar cálculos em arrays com formas díspares, eliminando a necessidade de redimensionar manualmente ou percorrer os elementos.

Graças à transmissão, podemos aplicar operações sem esforço em arrays com dimensões implícitas, alcançando resultados que, de outra forma, exigiriam extensa manipulação manual. Essa capacidade expande o escopo do que podemos realizar com o NumPy, tornando-o uma biblioteca versátil e indispensável para computação científica e análise de dados.

4.4 NumPy Broadcasting (L04: Scientific Computing in Python)
4.4 NumPy Broadcasting (L04: Scientific Computing in Python)
  • 2020.09.20
  • www.youtube.com
One of the cool things about NumPy is that it allows us to "broadcast." Here, that means that it is creating implicit dimensions that allow us to do things t...