John Paul Mueller

Algorithms For Dummies


Скачать книгу

      Note that the output contains the number of rows found in matrix a and the number of columns found in matrix b. So how does this all work? To obtain the value found in the output array at index [0,0] of 22, you sum the values of a[0,0] * b[0,0] (which is 1), a[0,1] * b[1,0] (which is 6), and a[0,2] * b[2,0] (which is 15) to obtain the value of 22. The other entries work precisely the same way.

      

To perform an element-by-element multiplication using two matrix objects, you must use the numpy multiply() function.

      Defining advanced matrix operations

      This book takes you through all sorts of interesting matrix operations, but you use some of them commonly, which is why they appear in this chapter. When working with arrays, you sometimes get data in a shape that doesn't work with the algorithm. Fortunately, numpy comes with a special reshape() function that lets you put the data into any shape needed. In fact, you can use it to reshape a vector into a matrix, as shown in the following code:

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

      When you run this code, you see these outputs (spaces added for clarity):

       [1 2 3 4 5 6 7 8] [[1 2 3 4] [5 6 7 8]] [[[1 2] [3 4]] [[5 6] [7 8]]]

      

The starting shape of changeIt is a vector, but using the reshape() function turns it into a matrix. In addition, you can shape the matrix into any number of dimensions that work with the data. However, you must provide a shape that fits with the required number of elements. For example, calling changeIt.reshape(2,3,2) will fail because there aren't enough elements to provide a matrix of that size.

      You may encounter two important matrix operations in some algorithm formulations. They are the transposition and inverse of a matrix. Transposition occurs when a matrix of shape n x m is transformed into a matrix m x n by exchanging the rows with the columns. Most texts indicate this operation by using the superscript T, as in AT. You see this operation used most often for multiplication in order to obtain the right dimensions. When working with numpy, you use the transpose function to perform the required work. For example, when starting with a matrix that has two rows and four columns, you can transpose it to contain four rows with two columns each, as shown in this example:

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

      The outputs look like this:

       [[1 2 3 4] [5 6 7 8]] [[1 5] [2 6] [3 7] [4 8]]

      You apply matrix inversion to matrixes of shape m x m, which are square matrixes that have the same number of rows and columns. This operation is quite important because it allows the immediate resolution of equations involving matrix multiplication, such as y = bX, where you know vector y and matrix X, and you have to discover the values in the vector b. Because most scalar numbers (exceptions include zero) have a number whose multiplication results in a value of 1, the idea is to find a matrix inverse whose multiplication will result in a special matrix called the identity matrix. To see an identity matrix in numpy, use the identity function, like this:

       print(np.identity(4))

      which produces an output of:

       [[1. 0. 0. 0.] [0. 1. 0. 0.] [0. 0. 1. 0.] [0. 0. 0. 1.]]

      Note that an identity matrix contains all ones on the diagonal. Finding the inverse of a scalar is quite easy (the scalar number n has an inverse of n–1 that is 1/n). It's a different story for a matrix. Matrix inversion involves quite a large number of computations. The inverse of a matrix A is indicated as A–1. When working with numpy, you use the linalg.inv() function to create an inverse. The following example shows how to create an inverse, use it to obtain a dot product, and then compare that dot product to the identity matrix by using the allclose() function.

       a = np.array([[1,2], [3,4]])b = np.linalg.inv(a) print(np.allclose(np.dot(a,b), np.identity(2)))

      

The output of True tells you b is the inverse of a. Sometimes, finding the inverse of a matrix is impossible. When a matrix cannot be inverted, it is referred to as a singular matrix or a degenerate matrix. Singular matrixes aren't the norm; they’re quite rare.

      Distinguishing permutations

      When you receive raw data, it appears in a specific order. The order can represent just about anything, such as the log of a data input device that monitors something like a production line. Perhaps the data is a series of numbers representing the number of products made at any particular moment in time. The reason that you receive the data in a particular order is important, but that order might not lend itself to obtaining the output you need from an algorithm. Creating a data permutation, a reordering of the data so that it presents a different view, might help to achieve a desired result.

      You can view permutations in a number of ways. One method of viewing a permutation is as a random presentation of the sequence order. In this case, you can use the numpy random.permutation() function, as shown here:

       a = np.array([1,2,3])print(np.random.permutation(a))

      What you see is a randomized version of the original data, such as [2 1 3]. Each time you run this code, you receive a different random ordering of the data sequence, which comes in handy with algorithms that require you to randomize the dataset to obtain the desired results. For example, sampling is an essential part of data analytics, and the technique shown is an efficient way to perform this task.

      Another way to view the issue is the need to obtain all the permutations for a dataset so that you can try each one in turn. To perform this task, you need to import the itertools package. The following code shows a technique you can use to obtain a list of all the permutations of a particular vector:

       from itertools import permutations a = np.array([1,2,3]) for p in permutations(a): print(p)

      The output you see looks like this:

       (1, 2, 3)(1, 3, 2)(2, 1, 3)(2, 3, 1)(3, 1, 2)(3, 2, 1)

      If you want to use the list comprehension (https://www.w3schools.com/python/python_lists_comprehension.asp) approach, which is a shorter method of performing repetitive tasks, you can use [print(p) for p in permutations(a)] instead. You can read more about itertools at https://docs.python.org/3/library/itertools.html.