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

 

4.5 Indexação avançada NumPy -- Visualizações e cópias de memória (L04: Computação científica em Python)



4.5 Indexação avançada NumPy -- Visualizações e cópias de memória (L04: Computação científica em Python)

Neste quinto vídeo, vamos nos aprofundar no tema da indexação mais uma vez. No entanto, ao contrário do vídeo inicial em que abordamos a indexação básica, agora exploraremos a indexação avançada. Este segmento apresentará conceitos como exibições de memória e criação de cópias de memória, que são práticas cruciais para evitar erros não intencionais, como sobrescrever valores de matriz por engano. Entender isso é vital, pois nos ajuda a evitar bugs e comportamentos inesperados no NumPy.

Agora, vamos começar. Na seção anterior, discutimos um aspecto dos arrays NumPy chamados "views". As exibições são criadas quando usamos indexação regular ou operações básicas de divisão. Essas visualizações atuam como dimensões implícitas, permitindo-nos realizar operações que não são viáveis dentro da estrita estrutura matemática da álgebra linear. No entanto, trabalhar com visualizações pode ser arriscado, pois podemos modificar acidentalmente o array original sem perceber.

Para ilustrar isso, vamos considerar um exemplo simples. Suponha que temos uma matriz bidimensional com duas linhas e três colunas. Por conveniência, atribuirei a primeira linha a uma variável separada chamada "first_row". Agora, aqui está o ponto crucial: atribuir a primeira linha a uma variável cria uma visão, não um novo objeto. Isso significa que essa variável apenas aponta para a localização do array original na memória. Conseqüentemente, se modificarmos os valores desta variável, modificaremos também os valores correspondentes no array original.

Para demonstrar isso, vamos incrementar cada elemento na variável "first_row" em 99. A execução desta operação não apenas alterará os valores na variável, mas também sobrescreverá os valores na primeira linha da matriz original. Esse comportamento serve como uma dica de que estamos trabalhando com uma visão em vez de um objeto independente. Não estar ciente disso pode ser perigoso, pois é fácil sobrescrever valores involuntariamente na matriz original ao trabalhar com uma exibição.

Por outro lado, as visualizações podem ser incrivelmente úteis para a eficiência da memória, pois nos permitem evitar cópias desnecessárias de arrays. No entanto, há situações em que podemos querer criar uma cópia de uma matriz explicitamente. Para isso, podemos utilizar a função "copy", que gera um novo array com os mesmos valores do original. No exemplo fornecido, crio uma cópia da segunda linha do array usando a função "copiar". Ao fazer isso, quaisquer modificações feitas na variável "first_row" não afetarão o array original.

É importante observar que, embora o fatiamento e a indexação baseada em número inteiro criem exibições de memória, há outro tipo de indexação chamado "indexação sofisticada" que produz cópias da matriz. A indexação sofisticada refere-se ao uso de vários índices inteiros para selecionar elementos específicos de uma matriz. Esse recurso é chamado de "extravagante" porque não é suportado em listas regulares do Python. No entanto, o NumPy nos permite realizar esse tipo de indexação, o que pode ser bastante poderoso.

Por exemplo, em uma lista regular do Python, não podemos recuperar simultaneamente o primeiro e o terceiro elementos. No entanto, no NumPy, podemos conseguir isso usando uma indexação sofisticada. Da mesma forma, podemos usar indexação sofisticada para selecionar colunas específicas de uma matriz bidimensional. Vale a pena notar que a indexação sofisticada sempre resulta em uma cópia da matriz, não em uma exibição.

A distinção entre visualizações e cópias está relacionada às considerações de eficiência no NumPy. O fatiamento nos permite armazenar em cache determinados valores na memória, otimizando o desempenho. No entanto, a implementação desse mecanismo de cache com indexação sofisticada não é direta, pois não podemos extrair um pedaço contíguo de memória. Em vez disso, selecionamos valores individuais, levando à criação de um novo array. Esse comportamento explica por que a indexação sofisticada produz cópias em vez de exibições.

Outro aspecto interessante da indexação sofisticada é que ela nos permite reorganizar a ordem das colunas em um array. Ao especificar os índices de coluna desejados usando indexação sofisticada, podemos embaralhar as colunas conforme necessário.

As máscaras booleanas no NumPy são uma maneira eficiente e poderosa de filtrar matrizes com base em certas condições. Uma máscara booleana é simplesmente uma matriz NumPy de valores booleanos (verdadeiro ou falso) que tem a mesma forma da matriz original. Aplicando a máscara booleana ao array original, podemos selecionar os elementos que satisfazem a condição dada e descartar o resto.

Para criar uma máscara booleana, primeiro definimos uma condição que retorna um valor booleano para cada elemento da matriz. Por exemplo, digamos que temos um array chamado arr:

import numpy as np
arr = np.array([1, 2, 3, 4, 5])
Podemos criar uma máscara booleana com base em uma condição, como selecionar apenas os elementos maiores que 3:
mask = arr > 3
A máscara booleana resultante, mask, será [False, False, False, True, True]. Cada elemento da máscara corresponde à mesma posição no array original, indicando se a condição é verdadeira ou falsa para aquele elemento.

Para aplicar a máscara booleana e recuperar os elementos que satisfazem a condição, podemos simplesmente usar a máscara como um índice para o array:

filtered_arr = arr[mask]
O arr_filtrado resultante será [4, 5], que contém apenas os elementos maiores que 3 do array original.

As máscaras booleanas podem ser combinadas usando operadores lógicos como & (e), | (ou) e ~ (não) para criar condições mais complexas. Por exemplo:

mask = (arr > 2) & (arr < 5)
filtered_arr = arr[mask]
Essa condição seleciona elementos maiores que 2 e menores que 5, resultando em um arr_filtrado [3, 4].

As máscaras booleanas são particularmente úteis ao trabalhar com grandes conjuntos de dados ou realizar filtragem e análise de dados. Eles permitem operações eficientes e concisas em arrays sem a necessidade de loops explícitos ou verificações de condição.

Além de filtrar matrizes, as máscaras booleanas também podem ser usadas para atribuição de elementos. Ao atribuir novos valores aos elementos selecionados por meio da máscara booleana, podemos modificar partes específicas do array com base em uma condição.

No geral, as máscaras booleanas fornecem uma maneira flexível e eficiente de manipular e filtrar matrizes NumPy com base em condições especificadas, tornando-as uma ferramenta valiosa no processamento e análise de dados.

4.5 NumPy Advanced Indexing -- Memory Views and Copies (L04: Scientific Computing in Python)
4.5 NumPy Advanced Indexing -- Memory Views and Copies (L04: Scientific Computing in Python)
  • 2020.09.20
  • www.youtube.com
We previously covered basic indexing. NumPy allows us to perform more advanced indexing beyond what regular Python lists are capable of. Jupyter notebook: ht...
 

4.6 Geradores de números aleatórios NumPy (L04: Computação científica em Python)



4.6 Geradores de números aleatórios NumPy (L04: Computação científica em Python)

Neste vídeo, forneceremos uma breve visão geral dos geradores de números aleatórios no NumPy. Embora não abordemos todos os diferentes métodos para gerar números aleatórios no NumPy, nosso foco será entender os geradores de números aleatórios e sua utilidade prática.

Vamos começar com um exemplo simples. Começaremos importando o NumPy, que é a biblioteca que usaremos para geração de números aleatórios. O NumPy possui um módulo aleatório que contém várias funções para desenhar números aleatórios. Embora a documentação à qual nos referiremos esteja um pouco desatualizada, ela fornece uma lista útil de diferentes funções e suas descrições.

Uma função comumente usada é random.rand, que gera amostras aleatórias de uma distribuição uniforme. Ao especificar a forma da matriz desejada (por exemplo, 2x3), esta função produzirá uma matriz bidimensional preenchida com números aleatórios de uma distribuição uniforme.

O NumPy também oferece outras funções, como random.random, que gera flutuações aleatórias no intervalo semi-aberto [0, 1). Você também pode extrair amostras aleatórias de diferentes distribuições, como a distribuição normal padrão, usando a função random.randn.

Às vezes, podemos querer garantir que nosso código produza os mesmos resultados aleatórios toda vez que for executado. Isso é útil para reprodutibilidade, especialmente ao compartilhar código ou comparar métodos diferentes. Para conseguir isso, podemos definir uma semente aleatória no início do nosso código ou notebook. A semente é um número arbitrário que garante que a mesma sequência de números aleatórios seja gerada a cada vez.

Ao definir uma semente aleatória, os números aleatórios gerados permanecerão constantes durante várias execuções do código. No entanto, é importante observar que, se extrairmos outra amostra aleatória, os resultados serão diferentes porque ainda é um processo aleatório.

Ter resultados consistentes pode ser particularmente útil em aplicativos de aprendizado de máquina, como mistura de dados ou implementações de teste. Por exemplo, ao dividir um conjunto de dados, definir uma semente aleatória garante que a divisão seja sempre a mesma. Isso permite uma comparação precisa e avaliação de diferentes métodos.

Para gerenciar a aleatoriedade de forma mais granular, podemos usar um objeto de estado aleatório no NumPy. O objeto de estado aleatório tem seu próprio gerador de números aleatórios, permitindo um controle refinado sobre onde a aleatoriedade é aplicada. Ao criar vários objetos de estado aleatório, podemos ter diferentes fontes de aleatoriedade em nosso código. Isso é especialmente benéfico quando queremos que certas partes do código produzam resultados consistentes, enquanto outras partes geram números aleatórios variados.

Embora a antiga classe random_state ainda seja amplamente usada, a comunidade NumPy agora recomenda o uso do novo gerador aleatório. Este novo gerador emprega um método diferente para gerar números aleatórios, mas para a maioria das aplicações simples, a escolha entre os dois não fará uma diferença perceptível. O que mais importa é definir uma semente aleatória para reprodutibilidade.

É importante lembrar que os geradores de números aleatórios no código não são realmente aleatórios, mas pseudo-aleatórios. Eles usam algoritmos para produzir sequências de números que imitam a aleatoriedade. Em nosso contexto, o foco está na consistência e reprodutibilidade, e não no algoritmo específico usado para geração de números aleatórios.

Concluindo, ao trabalhar com geradores de números aleatórios no NumPy, a escolha do próprio gerador não é crítica. O essencial é definir uma semente aleatória para garantir resultados consistentes e reprodutíveis. Isso se torna particularmente valioso ao compartilhar código, enviar atribuições ou comparar métodos diferentes.

4.6 NumPy Random Number Generators (L04: Scientific Computing in Python)
4.6 NumPy Random Number Generators (L04: Scientific Computing in Python)
  • 2020.09.21
  • www.youtube.com
Random number generators and seeds are at the core of reproducible research. In this video, I show you how to use random number generators in NumPy.Jupyter n...
 

4.7 Remodelando matrizes NumPy (L04: Computação científica em Python)



4.7 Remodelando matrizes NumPy (L04: Computação científica em Python)

Finalmente, estamos nos aproximando da conclusão da série NumPy. Com apenas três vídeos restantes, chegamos a um tópico importante: remodelar arrays NumPy. Remodelar matrizes é crucial quando precisamos transformar nossos dados na forma desejada, como converter uma matriz em um vetor ou vice-versa. Mencionei brevemente esse conceito na palestra introdutória, onde discuti o MNIST. Para ilustrar esse processo, vamos considerar um exemplo simplificado.

Imagine que temos um array com dimensões 28 por 28, representando uma imagem. Normalmente, cada elemento na matriz corresponderia a um valor de pixel. No entanto, para simplificar, vamos supor que cada elemento seja apenas um único dígito. Portanto, temos uma matriz de 28 por 28 representando uma imagem de dígito. No entanto, se quisermos usar essa matriz como um vetor de recursos para um classificador, precisamos remodelá-la em um único vetor longo com 784 elementos (28 * 28). Cada exemplo de treinamento será uma imagem e cada imagem terá 784 recursos.

Remodelar uma matriz pode ser feito usando a função reshape no NumPy. Por exemplo, podemos remodelar um vetor 1, 2, 3, 4, 5, 6 em uma matriz 2 por 3:

array([[1, 2, 3],
       [4, 5, 6]])
É importante observar que as dimensões especificadas durante a reformulação devem corresponder ao número total de elementos na matriz original. Se as dimensões estiverem incorretas, ocorrerá um erro. Por exemplo, tentar remodelar um vetor de 6 elementos em uma matriz 3 por 3 geraria um erro porque não há elementos suficientes.

Ao remodelar uma matriz, uma exibição de memória é criada em vez de uma nova matriz. Essa visualização de memória nos permite manipular a matriz remodelada sem duplicar os dados. Para verificar isso, podemos usar a função np.may_share_memory, embora nem sempre forneça um resultado 100% preciso.

O uso de -1 como uma dimensão na remodelagem é um recurso conveniente no NumPy. Ele atua como um espaço reservado, permitindo que o método determine a dimensão apropriada com base no número total de elementos. Por exemplo, se temos um vetor com seis elementos e o remodelamos usando -1, 2, o -1 será substituído por 3, pois só há uma maneira de dispor três linhas com duas colunas para obter seis elementos. Esse conceito de espaço reservado funciona com um número arbitrário de dimensões.

Além disso, podemos usar a função reshape para nivelar uma matriz. Ao especificar um único valor como a dimensão (por exemplo, reshape(6)), podemos transformar a matriz em um vetor unidimensional. Na prática, usar -1 é mais conveniente, pois elimina a necessidade de lembrar o tamanho. Por exemplo, reshape(-1) obtém o mesmo resultado que reshape(6) para uma matriz de seis elementos.

Existem várias maneiras de nivelar uma matriz no NumPy. A função reshape com -1 cria uma visualização de memória, enquanto a função flatten também nivela uma matriz, mas cria uma cópia. Outra função, ravel, também é usada para achatar arrays. Determinar as diferenças entre essas funções seria um bom teste de autoavaliação.

Finalmente, podemos concatenar arrays em NumPy, combinando-os ao longo de eixos especificados. Ao concatenar arrays ao longo do primeiro eixo, é semelhante a anexar elementos em listas do Python. Por exemplo, se tivermos dois arrays com um eixo, concatená-los ao longo desse eixo empilhará um abaixo do outro.

Remodelar matrizes NumPy é essencial para manipular dados na forma desejada. Compreender os vários métodos, espaços reservados e técnicas de concatenação nos permite trabalhar efetivamente com arrays e otimizar nosso código. No próximo vídeo, discutirei os operadores de comparação e as máscaras do NumPy, que são ferramentas poderosas quando combinadas com a remodelagem.

4.7 Reshaping NumPy Arrays (L04: Scientific Computing in Python)
4.7 Reshaping NumPy Arrays (L04: Scientific Computing in Python)
  • 2020.09.21
  • www.youtube.com
Sometimes, our arrays just don't have the right shape. In this video, I will show you how we can manipulate the axes of an array to get it into the required ...
 

4.8 Operadores e máscaras de comparação NumPy (L04: Computação científica em Python)



4.8 Operadores e máscaras de comparação NumPy (L04: Computação científica em Python)

No NumPy, os operadores de comparação e as máscaras de seleção oferecem muita flexibilidade e podem ser bastante agradáveis de se trabalhar. Em um vídeo anterior, apresentamos máscaras e operadores de comparação, mas agora vamos explorar alguns truques adicionais que você pode usar ao trabalhar com eles.

Vamos começar com um exemplo simples. Suponha que tenhamos uma matriz NumPy [1, 2, 3, 4] para simplificar. Podemos definir uma máscara para selecionar determinados valores do array. Essa máscara será um array booleano, ou seja, conterá valores True ou False. Podemos criar a máscara especificando uma condição, como selecionar valores maiores que dois. A matriz de máscara resultante terá o mesmo formato da matriz original, com valores True indicando as posições onde a condição é verdadeira e valores False indicando as posições onde a condição é falsa.

Em Python, existe uma relação prática entre valores booleanos e inteiros: True é equivalente a 1 e False é equivalente a 0. Essa relação nos permite realizar operações interessantes. Por exemplo, podemos usar a instrução if para verificar se uma condição é verdadeira simplesmente escrevendo if condition:. Também podemos usar o operador not para verificar se uma condição é falsa escrevendo if not condition:. Essas abordagens fornecem um código mais legível em comparação com a comparação explícita da condição com True ou False.

Outro recurso útil é a capacidade de contar o número de elementos em uma matriz que correspondem a uma determinada condição. Aplicando o operador de soma a uma máscara, podemos contar o número de valores True na máscara. Por exemplo, se tivermos uma máscara que seleciona valores maiores que dois, podemos contar o número desses valores chamando sum(mask). Da mesma forma, podemos contar o número de valores False subtraindo a soma do número total de elementos na matriz.

Para contar o número de valores negativos em uma matriz, podemos utilizar a função invert NumPy, que inverte os valores booleanos na máscara. Aplicando inverter a uma máscara e, em seguida, chamando sum, podemos contar o número de valores False (que agora representam os valores negativos).

Binarizar um array, ou seja, convertê-lo em uma representação binária, é outra operação comum. Podemos conseguir isso atribuindo um valor específico às posições em que uma condição é verdadeira e outro valor às posições em que a condição é falsa. No entanto, digitar toda a operação pode ser tedioso. Felizmente, o NumPy fornece a função where, que simplifica esse processo. A função where assume uma condição, e para as posições onde a condição é verdadeira, atribui o primeiro valor, e para as posições onde a condição é falsa, atribui o segundo valor. Usando where, podemos facilmente binarizar um array com apenas uma linha de código.

Além dos operadores de comparação, o NumPy oferece operadores lógicos como and, or, xor e not. Esses operadores podem ser combinados com máscaras para criar condições mais complexas. Por exemplo, podemos selecionar valores maiores que três ou menores que dois usando o operador ou. Ao combinar várias condições usando operadores lógicos, podemos criar máscaras de seleção intrincadas que atendam às nossas necessidades.

Essas máscaras booleanas, operadores lógicos e operadores de comparação no NumPy são incrivelmente úteis ao trabalhar com conjuntos de dados e implementar regras de árvore de decisão. Exploraremos mais esses conceitos nos próximos vídeos. No próximo vídeo, vamos nos aprofundar nos conceitos básicos de álgebra linear no NumPy. Fique atento!

4.8 NumPy Comparison Operators and Masks (L04: Scientific Computing in Python)
4.8 NumPy Comparison Operators and Masks (L04: Scientific Computing in Python)
  • 2020.09.22
  • www.youtube.com
Using comparison operators and selection masks goes hand in hand with fancy indexing in NumPy. This video explains how we can select relevant data convenient...
 

4.9 NumPy Linear Algebra Basics (L04: Scientific Computing in Python)



4.9 NumPy Linear Algebra Basics (L04: Scientific Computing in Python)

In this video, I would like to delve into some fundamental concepts of linear algebra, specifically in the context of NumPy. Although we won't extensively utilize linear algebra in this course, it is crucial to grasp basic operations like vector dot products and matrix multiplication. As I mentioned earlier, employing linear algebra notation enables us to write code that is more efficient and concise.

Let's begin by considering a one-dimensional array as a row vector. Alternatively, we can define it as a vector that consists of a single row with multiple elements. On the other hand, a column vector can be created by reshaping the row vector to have one column and multiple elements. Essentially, it represents the column vector representation. Notably, the use of square brackets is unnecessary in this context.

Instead of reshaping the vector explicitly, we can achieve the same result by adding a new axis using NumPy's newaxis function. By adding two new axes, we can even create a 3D tensor. Another approach is to use the None keyword, which serves the same purpose as newaxis. These three methods, namely reshaping, newaxis, and None, all achieve the goal of adding an additional axis when necessary.

Moving on, we encounter basic linear algebra notation for matrix multiplication. In linear algebra, matrix multiplication is equivalent to computing multiple dot products. For instance, if we have the vectors [1, 2, 3] and [1, 2, 3], their dot product results in 14. Similarly, the dot product of [4, 5, 6] and [1, 2, 3] yields 32. In NumPy, we can perform matrix multiplication using the matmul function. Alternatively, the @ operator can be used for convenience. However, it's important to note that in linear algebra, we cannot multiply matrices and vectors directly. Nevertheless, we can consider a column vector as a matrix, specifically a 3x1 matrix. This approach enables us to multiply a matrix with a vector, which is not possible in strict linear algebra. Thus, NumPy offers more flexibility compared to traditional linear algebra.

Moreover, NumPy provides the dot function for matrix multiplication, which is widely recommended due to its efficient implementation on most machines. This function allows us to write code more conveniently, especially when dealing with row vectors. It serves as a shortcut or operator overloading for matrix multiplication in NumPy. It's worth noting that the dot function can handle various combinations of matrices and vectors, performing either dot products or matrix multiplication based on the input shapes.

Regarding performance, both the matmul and dot functions have similar speed. The choice between them might depend on the specific machine. Nonetheless, the dot function is generally favored in practice. In addition, the transpose operation plays a role similar to the transpose operation in linear algebra, effectively flipping the matrix. Instead of using the transpose function explicitly, we can utilize the T attribute for brevity.

While NumPy includes a matrix type for two-dimensional arrays, it is not commonly used within the NumPy community. Regular multidimensional arrays serve the purpose in most cases. The matrix type is limited to two dimensions and introduces unnecessary complexity. It is advisable to avoid using it unless specifically required.

Lastly, we briefly touch upon SciPy, an impressive library that encompasses a wide range of additional functionality beyond NumPy. This library contains numerous specialized algorithms for scientific computing, such as linear algebra operations, Fourier transforms, interpolation techniques, optimization algorithms, statistical functions, and more. While it is based on NumPy, SciPy serves as an extension, providing specialized tools for various scientific computations. In this course, we will explore specific algorithms within SciPy as the need arises. You need not memorize all the details; I will introduce and explain relevant algorithms as we encounter them.

With this, we conclude our discussion on NumPy and SciPy for scientific computing in Python. In the next video, we will continue our scientific computing journey by exploring matplotlib, a powerful plotting library.

4.9 NumPy Linear Algebra Basics (L04: Scientific Computing in Python)
4.9 NumPy Linear Algebra Basics (L04: Scientific Computing in Python)
  • 2020.09.22
  • www.youtube.com
At its core, NumPy is an array library that implements tensors (including vectors and matrices) for linear algebra. After covering the basics of NumPy, this ...
 

4.10 Matplotlib (L04: Computação Científica em Python)



4.10 Matplotlib (L04: Computação Científica em Python)

Finalmente, chegamos ao final da palestra quatro, que foi bastante longa. No entanto, espero que os conceitos discutidos sobre o NumPy tenham sido valiosos para você. No futuro, usaremos o NumPy extensivamente em nossas tarefas de casa para implementar algoritmos de aprendizado de máquina. Portanto, é crucial que você se torne proficiente e familiarizado com o NumPy neste momento.

Passando para o último tópico da aula quatro, exploraremos o matplotlib, que é uma biblioteca de plotagem popular para Python. Embora existam várias bibliotecas de plotagem disponíveis hoje em dia, matplotlib continua sendo a mais usada. Pessoalmente, também é minha biblioteca de plotagem favorita e seu nome é inspirado no Metalab. A sintaxe do matplotlib é bastante semelhante ao MATLAB, que algumas pessoas apreciam, enquanto outras não. Eu, por exemplo, não gostava de usar o MATLAB durante meu tempo na pós-graduação, mas acho que o matplotlib é uma ótima ferramenta.

Mesmo que você não seja fã do MATLAB, acredito que o matplotlib é relativamente fácil de usar. Além disso, integra-se perfeitamente com o NumPy, o que é uma vantagem adicional. Então, vamos começar com o matplotlib. Devo mencionar que, pessoalmente, não memorizo todas as maneiras especiais de realizar tarefas no matplotlib porque é uma biblioteca de baixo nível. Isso significa que ele oferece um alto nível de opções de personalização, mas nem todas são intuitivas. Por isso, muitas vezes me pego procurando coisas. Quando preciso fazer algo específico, visito a galeria matplotlib, que mostra vários exemplos. Por exemplo, se eu quiser criar um gráfico de tronco, simplesmente procuro na galeria, encontro o exemplo e o adapto aos meus dados. Essa abordagem geralmente é suficiente para minhas necessidades. No entanto, se você preferir tutoriais mais detalhados, também pode explorar o site matplotlib.org, que oferece tutoriais explicativos sobre diferentes aspectos do matplotlib.

Para começar, ao trabalhar com matplotlib no Jupyter Lab ou Jupyter Notebooks, você pode usar a função inline para exibir plotagens no próprio notebook. Isso significa que as plotagens serão mostradas diretamente no notebook, evitando a necessidade de uma janela separada. Embora existam maneiras alternativas de conseguir isso, eu pessoalmente recomendo usar a abordagem inline, pois é mais confiável em diferentes computadores. Para ativar o modo inline, você pode usar o seguinte comando mágico: %matplotlib inline. Como alternativa, você pode adicionar um ponto e vírgula no final de suas instruções de plotagem, o que geralmente atinge o mesmo resultado. No entanto, é aconselhável usar plt.show() para exibir os gráficos, pois o truque do ponto-e-vírgula pode não funcionar bem em determinados computadores.

Agora vamos mergulhar na criação de alguns gráficos simples usando matplotlib. Por exemplo, podemos começar traçando uma curva senoidal. Para fazer isso, podemos usar a função np.linspace para gerar 100 valores variando de zero a dez e, em seguida, plotar esses valores em relação a np.sin, que é a função seno. A maneira mais simples de criar um gráfico é usando a função plt.plot, onde plt é a abreviação de matplotlib.pyplot. Podemos ajustar os intervalos do eixo do gráfico usando as funções plt.xlim e plt.ylim para definir os limites para o eixo x e o eixo y, respectivamente. Além disso, podemos adicionar rótulos aos eixos x e y usando as funções plt.xlabel e plt.ylabel. Por fim, para exibir o gráfico, podemos usar a função plt.show() ou adicionar um ponto e vírgula no final das instruções do gráfico para suprimir a saída indesejada.

Além de um único gráfico, também podemos criar vários gráficos dentro da mesma figura. Por exemplo, podemos plotar uma curva de seno e uma curva de cosseno em subtramas separadas. Para conseguir isso, podemos criar duas figuras usando a função plt.subplots e depois plotar as respectivas curvas seno e cosseno em cada subtrama. A função plt.subplots retorna um objeto figure e um array de objetos axes, que podemos usar para customizar cada subplot individualmente.

Aqui está um trecho de código de exemplo que demonstra a criação de várias subtramas:

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace( 0 , 10 , 100 )
y1 = np.sin(x)
y2 = np.cos(x)

fig, axs = plt.subplots( 2 , 1 )  # Create a figure with 2 subplots arranged vertically

# Plot the sine curve in the first subplot
axs[ 0 ].plot(x, y1)
axs[ 0 ].set_title( 'Sine Curve' )  # Set a title for the subplot
axs[ 0 ].set_xlabel( 'X' )
axs[ 0 ].set_ylabel( 'Y' )

# Plot the cosine curve in the second subplot
axs[ 1 ].plot(x, y2)
axs[ 1 ].set_title( 'Cosine Curve' )
axs[ 1 ].set_xlabel( 'X' )
axs[ 1 ].set_ylabel( 'Y' )

plt.tight_layout()  # Adjust the spacing between subplots for better readability
plt.show()  # Display the figure
Neste exemplo, usamos a função plt.subplots para criar uma figura com 2 subplots dispostos verticalmente (2, 1). A função retorna um objeto figura fig e uma matriz de objetos axes axs com dimensões correspondentes ao layout da subtrama especificada. Podemos acessar cada subplot indexando o array axs.

Dentro dos blocos de código específicos da subtrama, usamos a função plot para plotar as respectivas curvas e, em seguida, personalizamos o título de cada subtrama, o rótulo do eixo x e o rótulo do eixo y usando as funções set_title, set_xlabel e set_ylabel, respectivamente.

A função tight_layout é chamada para ajustar o espaçamento entre as subtramas, garantindo melhor legibilidade. Por fim, usamos plt.show() para exibir a figura contendo as subtramas.

Você pode tentar executar este código em seu ambiente Jupyter Notebook ou Jupyter Lab para ver a figura resultante com as curvas seno e cosseno exibidas em subtramas separadas.

Este é apenas um exemplo básico de criação de subplots, e há muito mais opções de personalização disponíveis no matplotlib para tornar seus gráficos mais informativos e visualmente atraentes. Você pode explorar a documentação e a galeria do matplotlib para obter mais exemplos e explicações detalhadas.

4.10 Matplotlib (L04: Scientific Computing in Python)
4.10 Matplotlib (L04: Scientific Computing in Python)
  • 2020.09.22
  • www.youtube.com
In this video, I am showing you how to use my favorite plotting library to plot data in Python.Jupyter notebook: https://github.com/rasbt/stat451-machine-lea...
 

5.1 Lendo um conjunto de dados de um arquivo de texto tabular (L05: Machine Learning com Scikit-Learn)



5.1 Lendo um conjunto de dados de um arquivo de texto tabular (L05: Machine Learning com Scikit-Learn)

Olá pessoal! Espero que todos tenham tido uma ótima semana e tenham a chance de trabalhar com todo o material do NumPy. Nesta semana, vamos nos concentrar em processamento de dados e aprendizado de máquina com scikit-learn, por isso é essencial ter um bom entendimento do NumPy. Acredito que é incrivelmente útil praticar a codificação e aplicar os conceitos que aprendemos em exemplos da vida real, e é por isso que faremos alguma codificação antecipadamente nesta palestra. Isso nos beneficiará mais tarde na aula, quando usarmos extensivamente essas ferramentas. Falando nisso, não há muito mais a acrescentar nesta palestra, exceto que carreguei a primeira grande tarefa de casa, que testará você nos conceitos que abordamos nas aulas anteriores, incluindo aprendizado supervisionado e exemplos de código usando NumPy. É uma ótima oportunidade para obter experiência prática com o algoritmo K-vizinho mais próximo e explorar o NumPy e o scikit-learn ainda mais.

Agora, enquanto você mergulha nos vídeos, faz o dever de casa e responde ao questionário de autoavaliação, quero lembrá-lo de se divertir e se divertir. O outono, minha estação favorita, acabou de começar aqui em Wisconsin, e adoro o clima mais frio e as lindas cores das folhas que mudam. A propósito, estou muito animado porque já fui a um canteiro de abóboras no fim de semana passado e ganhei algumas abóboras que mal posso esperar para esculpir para o Halloween. Então, vamos começar a palestra para que eu possa voltar às minhas aboborinhas e prepará-las para o Halloween.

Tudo bem, agora chegamos à parte três das aulas de fundamentos computacionais. Nesta palestra, abordaremos vários tópicos, começando com a leitura em um conjunto de dados de um arquivo de texto tabular, como um arquivo CSV, que é o formato de arquivo mais comum para tarefas tradicionais de aprendizado de máquina. Em seguida, discutiremos as técnicas básicas de manipulação de dados, incluindo a modelagem dos dados para algoritmos de aprendizado de máquina e procedimentos de treinamento.

Depois disso, vamos mergulhar no aprendizado de máquina com o scikit-learn. Mas antes disso, quero recapitular brevemente as classes Python e a programação orientada a objetos. Em exercícios anteriores, pedi que você se preparasse para o Python ou entendesse melhor seus conceitos. É importante ter uma boa compreensão da programação orientada a objetos porque o scikit-learn depende muito dela. Portanto, entender a programação orientada a objetos é necessário para entender como o scikit-learn funciona.

Continuando, discutiremos a preparação de dados de treinamento usando a API do transformador scikit-learn. Também abordaremos a definição de pipelines scikit-learn, que nos ajudam a encadear diferentes operações, como preparação de conjunto de dados, dimensionamento, normalização, redução de dimensionalidade e o próprio classificador. Ao usar pipelines, podemos criar fluxos de trabalho de treinamento eficientes que conectam vários aspectos do processo de aprendizado de máquina, tornando as coisas mais convenientes. Esse é um dos pontos fortes significativos do scikit-learn.

Para esta palestra, decidi usar slides novamente. Embora o Jupiter Lab seja uma ferramenta fantástica, acho mais fácil explicar certos conceitos anotando exemplos de código com uma caneta ou lápis. Portanto, nestes slides, capturei capturas de tela do Jupiter Lab e do Jupiter Notebook, que anotarei durante a palestra. No entanto, também carreguei todo o notebook de código no GitHub, onde você pode encontrar explicações adicionais. Considere este documento como curso opcional ou notas de aula para sua referência.

Vamos recapitular rapidamente onde estamos neste curso. Começamos com uma introdução ao aprendizado de máquina, cobrimos o básico e exploramos como o scikit-learn funciona. Em seguida, mergulhamos no Python, aprendendo sobre NumPy e computação científica. Agora, estamos entrando na fase de processamento de dados e aprendizado de máquina com o scikit-learn. Na próxima aula, retornaremos aos principais conceitos de aprendizado de máquina, como árvores de decisão, métodos de conjunto e avaliação de modelo. Embora esta seja a última parte das aulas de fundamentos computacionais, não significa que seja o fim do curso. Depois de concluir as palestras de fundamentos computacionais, passaremos para tópicos mais avançados em aprendizado de máquina, incluindo aprendizado profundo e redes neurais.

Agora, vamos mergulhar no primeiro tópico desta palestra: leitura em um conjunto de dados de um arquivo de texto tabular. Ao trabalhar com aprendizado de máquina, é comum ter dados armazenados em formatos tabulares, como arquivos CSV (Comma-Separated Values). Esses arquivos contêm linhas e colunas de dados, com cada linha representando uma amostra ou instância e cada coluna representando um recurso ou atributo.

Para ler um arquivo CSV em Python, podemos usar a biblioteca Pandas. O Pandas fornece poderosas ferramentas de análise e manipulação de dados, tornando-o uma escolha popular para trabalhar com dados tabulares em Python. Vejamos um exemplo:

import pandas as pd

# Read the CSV file into a DataFrame
data = pd.read_csv( 'data.csv' )

# Display the first few rows of the DataFrame
print(data.head())

Neste exemplo, primeiro importamos a biblioteca pandas e a apelidamos de pd por conveniência. Em seguida, usamos a função read_csv() para ler o arquivo CSV data.csv em um DataFrame, que é uma estrutura de dados tabular bidimensional fornecida pelo Pandas. O DataFrame é armazenado na variável data.

Depois de ler os dados, podemos usar a função head() para exibir as primeiras linhas do DataFrame. Isso nos permite inspecionar rapidamente os dados e verificar se eles foram lidos corretamente.

O Pandas fornece uma ampla variedade de funções e métodos para manipular e analisar dados. Podemos realizar várias operações, como filtrar linhas, selecionar colunas, agregar dados e muito mais. Se você é novo no Pandas, eu o encorajo a explorar sua documentação e experimentar diferentes operações por conta própria.

Agora que sabemos como ler dados, vamos passar para o próximo tópico: técnicas básicas de manipulação de dados. Ao trabalhar com dados para aprendizado de máquina, é essencial pré-processar e preparar os dados adequadamente. Isso inclui tarefas como lidar com valores ausentes, codificar variáveis categóricas, dimensionar recursos numéricos e dividir os dados em conjuntos de treinamento e teste.

Uma etapa de pré-processamento comum é lidar com valores ausentes. Os valores ausentes geralmente são representados como valores NaN (não é um número) ou NULL nos dados. Esses valores ausentes podem causar problemas ao treinar modelos de aprendizado de máquina, portanto, precisamos tratá-los adequadamente. Pandas fornece várias funções para lidar com valores ausentes, como isna() para verificar valores ausentes, fillna() para preencher valores ausentes com um valor especificado e dropna() para remover linhas ou colunas com valores ausentes.

A codificação de variáveis categóricas é outra etapa importante. Os modelos de aprendizado de máquina geralmente funcionam com dados numéricos, portanto, precisamos converter variáveis categóricas em uma representação numérica. Uma técnica de codificação comum é a codificação one-hot, em que criamos colunas binárias para cada categoria e indicamos a presença ou ausência de uma categoria com 1 ou 0, respectivamente.

import pandas as pd

# Create a DataFrame with categorical variables
data = pd.DataFrame({ 'color' : [ 'red' , 'blue' , 'green' , 'red' , 'green' ]})

# Perform one-hot encoding
encoded_data = pd.get_dummies(data)

# Display the encoded data
print(encoded_data)
Neste exemplo, criamos um DataFrame com uma coluna 'color' contendo variáveis categóricas. Em seguida, usamos a função get_dummies() do Pandas para executar a codificação one-hot. Os dados codificados resultantes contêm colunas binárias para cada categoria exclusiva na coluna 'cor' original.

O dimensionamento de recursos numéricos é outra etapa de pré-processamento comum. Muitos algoritmos de aprendizado de máquina são sensíveis à escala dos recursos. Se os recursos tiverem escalas diferentes, isso pode afetar o desempenho do modelo. Para resolver isso, podemos dimensionar os recursos para um intervalo padrão, como 0 a 1 ou -1 a 1. O Pandas fornece as classes MinMaxScaler e StandardScaler no módulo sklearn.preprocessing para executar o dimensionamento de recursos.

import pandas as pd
from sklearn.preprocessing import MinMaxScaler

# Create a DataFrame with numerical features
data = pd.DataFrame({ 'age' : [ 25 , 30 , 35 , 40 ], 'income' : [ 50000 , 60000 , 70000 , 80000 ]})

# Perform feature scaling using MinMaxScaler
scaler = MinMaxScaler()
scaled_data = scaler.fit_transform(data)

# Convert the scaled data back to a DataFrame
scaled_df = pd.DataFrame(scaled_data, columns=data.columns)

# Display the scaled data
print(scaled_df)
Neste exemplo, criamos um DataFrame com dois recursos numéricos: 'idade' e 'renda'. Em seguida, usamos a classe MinMaxScaler do módulo sklearn.preprocessing para executar o escalonamento de recursos. O método fit_transform() dimensiona os dados e os dados dimensionados resultantes são armazenados na variável scaled_data como uma matriz NumPy. Por fim, convertemos os dados dimensionados de volta em um DataFrame e os exibimos.

Por fim, dividir os dados em conjuntos de treinamento e teste é crucial para avaliar o desempenho dos modelos de aprendizado de máquina. Normalmente, dividimos os dados em dois conjuntos: um conjunto de treinamento usado para treinar o modelo e um conjunto de teste usado para avaliar seu desempenho. O Pandas fornece a função train_test_split() no módulo sklearn.model_selection para dividir os dados em conjuntos de treinamento e teste.

import pandas as pd
from sklearn.model_selection import train_test_split

# Read the CSV file into a DataFrame
data = pd.read_csv( 'data.csv' )

# Split the data into features and labels
X = data.drop( 'label' , axis= 1 )
y = data[ 'label' ]

# Split the data into training and testing sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size= 0.2 , random_state= 42 )
Neste exemplo, primeiro lemos o arquivo CSV 'data.csv' em um DataFrame. Em seguida, dividimos os dados em recursos X e rótulos y, onde X contém todas as colunas, exceto a coluna 'rótulo', e y contém apenas a coluna 'rótulo'.

Em seguida, usamos a função train_test_split() para dividir os dados em conjuntos de treinamento e teste. Passamos os recursos X e os rótulos y, especificamos o tamanho de teste desejado (por exemplo, 0,2 para um conjunto de teste de 20%) e definimos um estado aleatório para reprodutibilidade.

Depois de dividir os dados, podemos usar o conjunto de treinamento (X_train e y_train) para treinar nosso modelo de aprendizado de máquina e avaliar seu desempenho no conjunto de teste (X_test e y_test).

Estas são algumas técnicas básicas de manipulação de dados em aprendizado de máquina usando a biblioteca Pandas em Python. Lembre-se de que o pré-processamento e a preparação de dados são etapas essenciais no pipeline de aprendizado de máquina, e há muito mais técnicas e ferramentas disponíveis, dependendo dos requisitos específicos do seu projeto.

5.1 Reading a Dataset from a Tabular Text File (L05: Machine Learning with Scikit-Learn)
5.1 Reading a Dataset from a Tabular Text File (L05: Machine Learning with Scikit-Learn)
  • 2020.09.27
  • www.youtube.com
Machine learning begins with loading your data into a friendly array format. In this video, we will use pandas' read_csv function to get data into our active...
 

5.2 Manipulação básica de dados (L05: Machine Learning com Scikit-Learn)



5.2 Manipulação básica de dados (L05: Machine Learning com Scikit-Learn)

No vídeo anterior, discutimos como ler um arquivo de texto tabular como um conjunto de dados. Especificamente, focamos em trabalhar com um arquivo CSV e, mais especificamente, o conjunto de dados Iris. Importamos o conjunto de dados Iris de um arquivo CSV para um Pandas DataFrame.

Neste vídeo, vamos nos aprofundar na preparação dos dados no formato apropriado para aprendizado de máquina usando o scikit-learn. Exploraremos técnicas básicas de manipulação de dados usando Pandas e NumPy para transformar os dados em um formato adequado para aprendizado de máquina. Mas antes de prosseguirmos, vamos recapitular brevemente o conceito de funções do Python, pois será útil quando discutirmos a transformação de valores em um Pandas DataFrame.

Aqui temos uma função Python simples chamada "some_func". Ele pega um único argumento de entrada, "x", e o converte em uma string. Em seguida, ele concatena o valor convertido com a string fixa "hello world". Se fornecermos um número inteiro, como 123, como entrada, ele será convertido em uma string ("123") e concatenado com "hello world", resultando na string final. Esta é uma visão geral básica de como as funções do Python funcionam, com dois pontos indicando o corpo da função e uma declaração de retorno especificando a saída. Embora possa haver várias linhas de código dentro da função, a instrução return marca o fim.

Outro conceito que vale a pena mencionar são as funções lambda. As funções do Lambda são uma forma abreviada de definir pequenas funções sem nomeá-las explicitamente. Eles são comumente usados quando há necessidade de economizar linhas de código e escrever funções rapidamente. No contexto das transformações de dados nas colunas do Pandas, as funções lambda são frequentemente usadas. Embora as funções lambda ofereçam uma sintaxe mais concisa, elas executam essencialmente as mesmas operações que as funções regulares. Eles são especialmente úteis quando combinados com o método apply em uma coluna Pandas DataFrame.

Na aula anterior, lemos o conjunto de dados Iris em um Pandas DataFrame a partir do arquivo CSV. O conjunto de dados Iris consiste em 150 linhas, mas estamos exibindo apenas as primeiras cinco linhas para brevidade. O conjunto de dados inclui uma coluna de ID, que não é essencial, seguida pelas características representadas pela matriz de projeto X. Também temos os rótulos de classe, geralmente denotados como y. Tradicionalmente, o scikit-learn e outras bibliotecas não lidavam com variáveis de string como rótulos de classe, então era uma prática comum convertê-las em números inteiros. Por exemplo, "Iris setosa" seria convertido para o inteiro 0, "Iris versicolor" para 1 e "Iris virginica" para 2. Essa conversão foi necessária porque muitos algoritmos foram projetados para trabalhar com rótulos de classes inteiras em vez de rótulos de strings.

No entanto, o scikit-learn agora oferece suporte a rótulos de classe de string na maioria das funções, eliminando a necessidade de conversão explícita. Internamente, a conversão é feita automaticamente. No entanto, algumas ferramentas podem não lidar com dados de string corretamente, portanto, ainda é recomendável converter rótulos de classes em números inteiros. Ao fazer isso, você garante a compatibilidade com várias ferramentas e reduz a probabilidade de encontrar erros.

Para ilustrar o processo de conversão, usaremos a função lambda em conjunto com o método apply. Aplicando uma função lambda à coluna de espécies do DataFrame, podemos converter os rótulos de classe de string em rótulos inteiros. No entanto, vale a pena mencionar que usar um dicionário de mapeamento geralmente é uma abordagem melhor. Ele fornece melhor legibilidade e permite uma interpretação mais fácil das transformações de rótulos de classe. Além disso, se precisar recuperar os rótulos de classe originais mais tarde, você pode definir um dicionário reverso e usá-lo para mapear os rótulos inteiros de volta para suas representações de string originais.

Para demonstrar a conversão, recarregamos o conjunto de dados em seu estado original. Em seguida, em vez de aplicar, utilizamos a função map para converter os rótulos de string em números inteiros usando o dicionário de mapeamento. Também mostramos o uso do atributo values, que acessa o array NumPy subjacente. Trabalhando com matrizes NumPy.

Trabalhar com matrizes NumPy pode ser benéfico por vários motivos. As matrizes NumPy são mais eficientes em termos de memória em comparação com Pandas DataFrames, tornando-as ideais para grandes conjuntos de dados. Além disso, muitos algoritmos de aprendizado de máquina no scikit-learn esperam que os dados de entrada estejam na forma de matrizes NumPy.

Para converter nosso Pandas DataFrame em arrays NumPy, podemos simplesmente acessar o atributo values do DataFrame. Vejamos um exemplo:

import pandas as pd
import numpy as np

# Reload the Iris dataset
iris_df = pd.read_csv( 'iris.csv' )

# Convert the features (X) into a NumPy array
X = iris_df.drop([ 'species' ], axis= 1 ).values

# Convert the class labels (y) into a NumPy array
y = iris_df[ 'species' ].values
Neste exemplo, usamos o método drop do DataFrame para remover a coluna 'species' e obter os recursos como um DataFrame. Em seguida, acessando o atributo values, convertemos os recursos em um array NumPy e o atribuímos à variável X.

Da mesma forma, acessamos a coluna 'species' do DataFrame usando o operador de indexação [] e a convertemos em um array NumPy, atribuindo-o à variável y.

Agora, a variável X contém a matriz de recursos como uma matriz NumPy e a variável y contém os rótulos de classe como uma matriz NumPy. Podemos usar essas matrizes como entradas para vários algoritmos de aprendizado de máquina.

Digamos que queremos dividir nosso conjunto de dados em conjuntos de treinamento e teste para avaliação do modelo. O Scikit-learn fornece uma função utilitária chamada train_test_split que facilita essa tarefa. Aqui está um exemplo:

 from sklearn.model_selection import train_test_split

# Split the data into training and testing sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size= 0.2 , random_state= 42 )
Neste exemplo, importamos a função train_test_split do módulo sklearn.model_selection. Passamos as matrizes X e y como argumentos para a função, juntamente com o parâmetro test_size especificando a proporção do conjunto de dados a ser alocada para teste (neste caso, 20%). O parâmetro random_state garante a reprodutibilidade da divisão.

Depois de chamar train_test_split, obtemos quatro matrizes: X_train e y_train contêm os dados de treinamento, enquanto X_test e y_test contêm os dados de teste.

Agora você pode usar as matrizes X_train e y_train para treinar seu modelo de aprendizado de máquina e avaliar seu desempenho usando as matrizes X_test e y_test.

Em resumo, ao converter o Pandas DataFrame em matrizes NumPy, podemos aproveitar as vantagens do NumPy, como eficiência de memória e compatibilidade com algoritmos de aprendizado de máquina. Além disso, o scikit-learn fornece funções convenientes como train_test_split para dividir os dados em conjuntos de treinamento e teste.

5.2 Basic data handling (L05: Machine Learning with Scikit-Learn)
5.2 Basic data handling (L05: Machine Learning with Scikit-Learn)
  • 2020.09.27
  • www.youtube.com
Before we train a machine learning classifier, we have to make sure that the dataset looks right. This means, we want to make sure that the feature and label...
 

5.3 Programação Orientada a Objetos e Aulas de Python (L05: Machine Learning com Scikit-Learn)



5.3 Programação Orientada a Objetos e Aulas de Python (L05: Machine Learning com Scikit-Learn)

Antes de nos aprofundarmos no tópico de aprendizado de máquina com o scikit-learn na próxima aula, vamos discutir a programação orientada a objetos, especificamente classes Python. A compreensão das classes será altamente relevante, pois o scikit-learn depende fortemente de conceitos de programação orientada a objetos. No final deste vídeo, demonstrarei a implementação de K vizinhos mais próximos usando a API scikit-learn, que é a abordagem que o scikit-learn usa para implementar estimadores como classificadores.

Então, vamos começar discutindo classes Python. Para compreender melhor a API scikit-learn, é importante entender o básico das classes. Em termos simples, uma classe pode ser considerada como um projeto para a criação de objetos. Os objetos são instâncias de uma classe e podem ser visualizados como diferentes variações da mesma forma de cortador de biscoitos usada para fazer biscoitos. A própria classe atua como modelo de cortador de biscoitos, enquanto os cookies representam os objetos criados a partir da classe.

Em Python, definimos uma classe usando a palavra-chave class, seguida do nome da classe. Dentro da classe, definimos diferentes métodos de classe. Os métodos de classe são semelhantes às funções, mas possuem um primeiro argumento obrigatório chamado self, que se refere ao próprio objeto. Esse argumento self nos permite acessar os atributos e métodos do objeto. Em outras palavras, permite-nos interagir com os dados e o comportamento do objeto.

No contexto do exemplo do veículo, vamos considerar uma classe de veículo ingênua simples. Esta classe representa diferentes tipos de veículos, como carros, motocicletas ou caminhões. A classe tem vários métodos para definir seu comportamento. O primeiro método é o método __init__, também conhecido como construtor. Este método é executado automaticamente quando um novo objeto é criado a partir da classe. Ele aceita o argumento self e quaisquer argumentos adicionais necessários para inicializar o objeto.

No método __init__, definimos um atributo chamado horsepower, ao qual é atribuído o valor fornecido como um argumento. Este atributo representa a potência do veículo. Quando um novo objeto é criado, ele terá um atributo de potência que pode ser acessado para recuperar o valor de potência.

Além do método __init__, podemos definir outros métodos que modificam os atributos do objeto. Por exemplo, o método tune_motor dobra o atributo de potência do veículo, simulando um ajuste do motor. Ao chamar esse método no objeto veículo, seu atributo de potência será modificado de acordo.

Além disso, podemos definir métodos que retornam valores com base nos atributos do objeto. No exemplo, o método horsepower_to_torque calcula o valor do torque com base na potência do objeto e em um valor de RPM fornecido. Este método demonstra como os atributos do objeto podem ser utilizados para realizar cálculos e retornar resultados úteis.

Vale a pena notar que em Python existem convenções para indicar a visibilidade dos métodos. Métodos com um único prefixo de sublinhado, como _private_method, são considerados privados e não devem ser usados diretamente pelos usuários da classe. No entanto, os usuários ainda podem acessar e chamar esses métodos, embora isso seja geralmente desencorajado. Métodos com prefixo de sublinhado duplo, como __very_private_method, são ainda mais restritos e requerem uma sintaxe específica para acessá-los.

Além disso, o Python oferece suporte à herança de classes, permitindo criar classes filhas que herdam propriedades e métodos de uma classe pai. Esse conceito nos permite criar classes especializadas com atributos e comportamentos adicionais, aproveitando a funcionalidade existente definida na classe pai. Por exemplo, poderíamos criar uma classe Car especializada que herda da classe Vehicle e adiciona um atributo number_of_wheels especificamente para carros.

Para ilustrar os conceitos discutidos, é fornecido um exemplo de classificador de K vizinhos mais próximos. Essa implementação segue as convenções da API do scikit-learn e demonstra o uso de uma classe de estimador no scikit-learn. Aqui está uma implementação simplificada:

 class KNNClassifier:

    def __init__( self , k):
         self .k = k
         self .X_train = None
         self .y_train = None
    
    def fit( self , X_train, y_train):
         self .X_train = X_train
         self .y_train = y_train
    
    def predict( self , X_test):
        predictions = []
         for x in X_test:
            distances = []
             for i, x_train in enumerate( self .X_train):
                distance = self ._calculate_distance(x, x_train)
                distances.append((distance, self .y_train[i]))
            distances.sort()
            k_nearest = distances[: self .k]
            prediction = self ._majority_vote(k_nearest)
            predictions.append(prediction)
         return predictions
    
    def _calculate_distance( self , x1, x2):
         # Calculate the distance between two data points
         # (e.g., Euclidean distance)
        pass
    
    def _majority_vote( self , neighbors):
         # Determine the majority class among the nearest neighbors
        pass

Neste exemplo, KNNClassifier é uma classe que representa um classificador de K vizinhos mais próximos. O construtor recebe um parâmetro k, que especifica o número de vizinhos mais próximos a serem considerados.

O método fit é usado para treinar o classificador. Leva dois argumentos: X_train (os dados de treinamento) e y_train (os rótulos correspondentes). O método simplesmente armazena os dados de treinamento e rótulos nos atributos do objeto para uso posterior.

O método predict é usado para fazer previsões sobre novos dados. Ele usa X_test (os dados de teste) como um argumento e retorna os rótulos previstos para os dados de teste. Para cada ponto de dados em X_test, o método calcula as distâncias para todos os pontos de dados no conjunto de treinamento usando o método _calculate_distance. Em seguida, ele seleciona os k vizinhos mais próximos e determina a classe majoritária usando o método _majority_vote. O rótulo previsto é anexado à lista de previsões.

O método _calculate_distance é um método privado (indicado pelo sublinhado à esquerda) que calcula a distância entre dois pontos de dados. Esta poderia ser a distância euclidiana ou qualquer outra métrica de distância adequada para o problema.

O método _majority_vote é outro método privado que determina a classe majoritária entre um conjunto de vizinhos. Isso pode ser feito contando as ocorrências de cada rótulo de classe e selecionando o rótulo com a contagem mais alta.

Este exemplo demonstra a estrutura básica de uma classe de estimador no scikit-learn. Obviamente, o scikit-learn fornece uma implementação mais sofisticada e otimizada de K vizinhos mais próximos na classe KNeighborsClassifier, mas esta versão simplificada ilustra os princípios subjacentes.

5.3 Object Oriented Programming & Python Classes (L05: Machine Learning with Scikit-Learn)
5.3 Object Oriented Programming & Python Classes (L05: Machine Learning with Scikit-Learn)
  • 2020.09.27
  • www.youtube.com
In my opinion, the scikit-learn machine learning library is one of the best-designed Python libraries out there. It heavily relies on object oriented program...
 

5.4 Introdução ao Scikit-learn (L05: Machine Learning com Scikit-Learn)



5.4 Introdução ao Scikit-learn (L05: Machine Learning com Scikit-Learn)

Neste vídeo relativamente curto, o objetivo é apresentar o aprendizado de máquina com o scikit-learn. Scikit-learn é uma biblioteca de aprendizado de máquina amplamente usada em Python que fornece um conjunto abrangente de ferramentas e algoritmos para várias tarefas de aprendizado de máquina. Embora você já tenha visto o scikit-learn antes no contexto das palestras do k-vizinho mais próximo (KNN), este vídeo tem como objetivo dar um passo atrás e apresentar a biblioteca adequadamente.

Após este pequeno vídeo, haverá um vídeo mais longo que se aprofunda na preparação do conjunto de dados de treinamento usando o scikit-learn. Isso abrangerá técnicas e ferramentas que tornam a preparação de dados mais conveniente e eficiente em comparação com as abordagens tradicionais.

No vídeo a seguir, exploraremos alguns dos conceitos interessantes do scikit-learn, como combinar técnicas de pré-processamento, ajuste de classificador de aprendizado de máquina e treinamento, usando pipelines do scikit-learn. Isso permite um fluxo de trabalho mais simplificado e eficiente.

Agora, vamos discutir o aprendizado de máquina com o scikit-learn com mais detalhes. O Scikit-learn é amplamente considerado a principal biblioteca de aprendizado de máquina para Python devido à sua reputação estabelecida, grande base de usuários e natureza amigável. É uma biblioteca bem projetada que oferece uma API consistente e intuitiva. O Scikit-learn também é mantido ativamente e atualizado regularmente, com vários colaboradores, tornando-o uma escolha robusta e confiável para tarefas de aprendizado de máquina.

É importante observar que o scikit-learn é focado principalmente em técnicas tradicionais de aprendizado de máquina e não se destina ao aprendizado profundo. O aprendizado profundo é um campo separado com suas próprias bibliotecas especializadas. Para aprendizado profundo, outras bibliotecas como TensorFlow ou PyTorch são normalmente usadas. No entanto, para tarefas tradicionais de aprendizado de máquina, o scikit-learn costuma ser a biblioteca preferida.

O Scikit-learn já existe há algum tempo, com seu lançamento inicial datado de 2007. Apesar de sua idade, continua sendo uma biblioteca popular e mantida ativamente. Começou como um projeto Google Summer of Code de David Cournapeau e ganhou contribuições de muitos outros desenvolvedores ao longo do tempo. Com mais de 1.875 colaboradores no GitHub e quase 150.000 usuários, é evidente que o scikit-learn é uma biblioteca altamente conceituada com suporte substancial da comunidade.

Você pode encontrar o site oficial do scikit-learn, que inclui documentação, tutoriais e outros recursos úteis. Se você utiliza o scikit-learn em seus projetos de pesquisa, é uma boa prática citar a biblioteca como referência, reconhecendo o esforço investido em seu desenvolvimento.

Para entender a API Estimator do scikit-learn, vamos nos aprofundar em seus principais componentes. A Estimator API é usada para tarefas de aprendizado supervisionado e inclui regressores para análise de regressão e classificadores para tarefas de classificação. Ao usar o scikit-learn, você normalmente inicializa um estimador com hiperparâmetros específicos, que são definidos no construtor da classe.

O processo de ajuste é crucial para um estimador. Após a inicialização, é necessário chamar o método fit, fornecendo os dados de treinamento (características) e seus rótulos correspondentes. O método de ajuste treina o estimador nos dados fornecidos, permitindo que ele faça previsões posteriormente. Durante o processo de ajuste, determinados atributos são atribuídos ao estimador, indicados por um sublinhado à direita, indicando que foram criados durante o ajuste do modelo.

Depois que o modelo é ajustado, você pode usar o método de previsão para fazer previsões sobre novos dados. O método de previsão usa os dados de teste (com os mesmos recursos dos dados de treinamento) como entrada e retorna os rótulos previstos.

Além disso, o scikit-learn fornece um método de pontuação que calcula o desempenho do modelo. Para classificadores, geralmente representa a precisão, enquanto para regressores, normalmente calcula o coeficiente de determinação (pontuação R^2). Este método serve como uma maneira conveniente de avaliar o desempenho do modelo.

Além desses componentes principais, o scikit-learn também oferece uma ampla variedade de técnicas e utilitários de pré-processamento para aprimorar seu fluxo de trabalho de aprendizado de máquina.

Um aspecto importante do aprendizado de máquina é o pré-processamento de dados, que envolve a transformação de dados brutos em um formato adequado para treinar um modelo. O Scikit-learn fornece vários módulos de pré-processamento que podem lidar com tarefas como dimensionamento de recursos, manipulação de valores ausentes, codificação de variáveis categóricas e muito mais.

Por exemplo, a classe StandardScaler pode ser usada para padronizar recursos subtraindo a média e dimensionando para a variação da unidade. Isso é importante ao trabalhar com recursos que possuem escalas diferentes, pois ajuda os algoritmos a convergir mais rapidamente e a produzir resultados mais precisos.

Outra técnica de pré-processamento útil é lidar com valores omissos. A classe SimpleImputer fornece estratégias para substituir valores ausentes por alternativas adequadas, como usar a média, a mediana ou os valores mais frequentes dos recursos correspondentes.

Ao lidar com variáveis categóricas, o scikit-learn oferece as classes OneHotEncoder e LabelEncoder. O LabelEncoder converte rótulos categóricos em valores numéricos, enquanto o OneHotEncoder transforma recursos categóricos em uma representação vetorial binária, permitindo que os algoritmos trabalhem com dados categóricos de forma eficaz.

Para otimizar seu fluxo de trabalho de aprendizado de máquina, o scikit-learn fornece uma ferramenta poderosa chamada pipelines. Um pipeline combina várias etapas de pré-processamento e um modelo de aprendizado de máquina em um único objeto, facilitando o gerenciamento e a aplicação consistente de todo o fluxo de trabalho.

Os pipelines garantem que as mesmas etapas de pré-processamento sejam aplicadas de forma consistente aos conjuntos de dados de treinamento e teste, evitando vazamento de dados e possíveis erros. Eles também simplificam o processo de implantação, pois você pode salvar todo o objeto de pipeline e reutilizá-lo em novos dados sem se preocupar com etapas de pré-processamento individuais.

Usando a funcionalidade de pipeline do scikit-learn, você pode encadear várias técnicas de pré-processamento, como dimensionamento, imputação de valores ausentes e codificação de variáveis categóricas, com o modelo de aprendizado de máquina desejado. Isso resulta em um fluxo de trabalho mais simplificado e eficiente, permitindo que você se concentre nos aspectos principais do seu projeto de aprendizado de máquina.

O Scikit-learn oferece suporte a uma ampla variedade de algoritmos de aprendizado de máquina, incluindo regressão linear, regressão logística, máquinas de vetor de suporte, árvores de decisão, florestas aleatórias, aumento de gradiente e muito mais. Cada algoritmo é implementado como uma classe de estimador com métodos consistentes, como ajuste, previsão e pontuação.

Para selecionar o algoritmo apropriado para sua tarefa, o scikit-learn fornece várias ferramentas para seleção e avaliação de modelo. Isso inclui técnicas para validação cruzada, ajuste de hiperparâmetros e métricas de avaliação de modelo. A validação cruzada ajuda a avaliar o desempenho de seu modelo, dividindo os dados em várias divisões de teste de treinamento, treinando e avaliando o modelo em diferentes subconjuntos de dados.

O ajuste de hiperparâmetro envolve encontrar os valores ideais para os hiperparâmetros de um modelo, que são parâmetros que não são aprendidos com os dados, mas são definidos antes do treinamento. O Scikit-learn fornece métodos como pesquisa de grade e pesquisa aleatória para automatizar o processo de pesquisa dos melhores valores de hiperparâmetros.

As métricas de avaliação do modelo, como exatidão, precisão, recuperação, pontuação F1 e área sob a curva ROC, são cruciais para avaliar o desempenho do seu modelo em diferentes tarefas. O Scikit-learn oferece uma ampla variedade de métricas que podem ser facilmente calculadas e comparadas.

Scikit-learn é uma poderosa e popular biblioteca de aprendizado de máquina em Python que fornece uma ampla variedade de ferramentas e algoritmos para várias tarefas de aprendizado de máquina. Sua API amigável, extensa documentação e comunidade ativa o tornam uma excelente escolha para iniciantes e profissionais experientes. Se você precisa pré-processar seus dados, criar pipelines, selecionar modelos ou avaliar o desempenho, o scikit-learn tem as ferramentas necessárias para realizar o trabalho com eficiência e eficácia.

5.4 Intro to Scikit-learn (L05: Machine Learning with Scikit-Learn)
5.4 Intro to Scikit-learn (L05: Machine Learning with Scikit-Learn)
  • 2020.09.30
  • www.youtube.com
Finally! It's about time to introduce my favorite machine learning library! Jupyter Notebook: https://github.com/rasbt/stat451-machine-learning-fs20/blob/ma...