1. Wprowadzenie
Biblioteka NumPy to podstawa w przypadku uczenia maszynowego z użyciem języka programowania Python. Pozwala ona przeprowadzać efektywne operacje na strukturach danych, które są najczęściej wykorzystywane w uczeniu maszynowym: wektor, macierz i tensor. Pokazane zostaną operacje NumPy najczęściej przeprowadzane podczas pracy wymagającej zastosowania uczenia maszynowego.
1.1. Tworzenie wektora
Użyj biblioteki NumPy do utworzenia tablicy jednowymiarowej.
# Wczytanie biblioteki.
import numpy as np
# Utworzenie wektora przedstawiającego wiersz.
vector_row = np.array([1, 2, 3])
# Utworzenie wektora przedstawiającego kolumnę.
vector_column = np.array([[1],
[2],
[3]])
Podstawową strukturą danych biblioteki NumPy jest tablica wielowymiarowa. Aby utworzyć wektor, należy po prostu zdefiniować tablicę jednowymiarową. Podobnie jak w przypadku wektora, także tablica może być przedstawiona poziomo (na przykład wiersz) lub pionowo (na przykład kolumna).
Linki:
1.2. Tworzenie macierzy
Użyj biblioteki NumPy do utworzenia tablicy dwuwymiarowej.
# Wczytanie biblioteki.
import numpy as np
# Utworzenie macierzy.
matrix = np.array([[1, 2],
[1, 2],
[1, 2]])
Do utworzenia macierzy można wykorzystać oferowaną przez bibliotekę NumPy tablicę dwuwymiarową. W przedstawionym rozwiązaniu macierz składa się z trzech wierszy i dwóch kolumn (są to kolumny jedynek i dwójek). Tak naprawdę biblioteka NumPy ma dedykowaną macierzy strukturę danych, która pokazana jest poniżej.
matrix_object = np.mat([[1, 2],
[1, 2],
[1, 2]])
Wynik:
matrix([[1, 2],
[1, 2],
[1, 2]])
Jednak z dwóch powodów nie zaleca się stosowania tej struktury danych. Po pierwsze, tablica jest faktycznie standardową strukturą danych w bibliotece NumPy. Po drugie, większość operacji przeprowadzanych za pomocą NumPy zwraca tablicę, a nie obiekt macierzy.
Linki:
1.3. Tworzenie macierzy rzadkiej
Jak w efektywny sposób przedstawić dane zawierające niewiele wartości niezerowych?
Utwórz macierz rzadką (ang. sparse matrix).
# Wczytanie bibliotek.
import numpy as np
from scipy import sparse
# Utworzenie macierzy.
matrix = np.array([[0, 0],
[0, 1],
[3, 0]])
# Utworzenie macierzy w formacie CSR.
matrix_sparse = sparse.csr_matrix(matrix)
Podczas stosowania uczenia maszynowego bardzo często zdarza się, że masz do dyspozycji ogromną ilość danych, przy czym większość elementów w zbiorze danych to zera. Na przykład macierz, w której kolumny przedstawiają filmy oferowane przez serwis Netflix, natomiast wiersze - użytkowników tego serwisu. Wartości w tej macierzy określają, ile razy użytkownik obejrzał dany film. Ta macierz będzie się składała z dziesiątek tysięcy kolumn i milionów wierszy. Skoro większość użytkowników obejrzało zaledwie niewielką liczbę filmów, dominującą wartością elementów macierzy będzie zero.
Macierz rzadka przechowuje jedynie elementy niezerowe. Zakłada się, że pozostałymi elementami są zera. Wymienione podejście pozwala na znaczne zmniejszenie obciążenia związanego z przetwarzaniem takiej macierzy. W omawianym rozwiązaniu utworzono tablicę NumPy wraz z dwoma zerami, a następnie skonwertowałnoją na postać macierzy rzadkiej. Po wyświetleniu macierzy rzadkiej można zobaczyć, że przechowuje ona jedynie wartości niezerowe.
# Wyświetlenie macierzy rzadkiej.
print(matrix_sparse)
(1, 1) 1
(2, 0) 3
Istnieje pewna liczba typów macierzy rzadkiej. W przypadku typu CSR (ang. compressed sparse row) (1, 1) i (2, 0) przedstawiają liczone od zera indeksy wartości niezerowych - odpowiednio 1 i 3. Na przykład element 1 znajduje się w drugim wierszu i drugiej kolumnie. Zalety macierzy rzadkiej ujawniają się w przypadku istnienia znacznie większej macierzy wraz z wieloma zerami, którą następnie można porównać z pokazaną wcześniej macierzą rzadką.
# Utworzenie większej macierzy.
matrix_large = np.array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[3, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
# Utworzenie macierzy w formacie CSR.
matrix_large_sparse = sparse.csr_matrix(matrix_large)
# Wyświetlenie początkowej macierzy rzadkiej.
print(matrix_sparse)
(1, 1) 1
(2, 0) 3
# Wyświetlenie macierzy rzadkiej utworzonej na podstawie większej macierzy.
print(matrix_large_sparse)
(1, 1) 1
(2, 0) 3
Jak można zobaczyć, pomimo dodania wielu elementów zerowych do większej macierzy utworzona na jej podstawie macierz rzadka jest dokładnie taka sama jak zdefiniowana na początku. Dlatego też dodanie elementów zerowych nie spowodowało zmiany wielkości macierzy rzadkiej. Jak wcześniej wspomniano, istnieje wiele różnych typów macierzy rzadkiej, między innymi CSC (ang. compressed sparse column), lista list, słownik kluczy itd. Warto w tym miejscu wspomnieć, że nie ma „najlepszego” typu macierzy rzadkiej. Istnieją między nimi znaczne różnice, które należy uwzględnić podczas wyboru konkretnego typu.
Linki:
- Artykuł ‘Sparse matrices’ w dokumentacji biblioteki SciPy
- Artykuł ‘101 Ways to Store a Sparse Matrix’
1.4. Pobieranie elementów
Jak pobrać co najmniej jeden element z wektora lub macierzy?
# Wczytanie biblioteki.
import numpy as np
# Utworzenie wiersza wektora.
vector = np.array([1, 2, 3, 4, 5, 6])
# Utworzenie macierzy.
matrix = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
# Pobranie trzeciego elementu wektora.
vector[2]
3
# Pobranie elementu znajdującego się w drugim wierszu i drugiej kolumnie.
matrix[1,1]
5
Tablice biblioteki NumPy mają indeksy liczone od zera. Dlatego też indeks pierwszego elementu to 0, a nie 1. Mając to na uwadze, można wykorzystać wiele oferowanych przez NumPy metod przeznaczonych do pobierania (na przykład za pomocą indeksu lub wycinka) elementów lub grup elementów w tablicy.
# Pobranie wszystkich elementów wektora.
vector[:]
array([1, 2, 3, 4, 5, 6])
# Pobranie wszystkich elementów wektora do trzeciego włącznie.
vector[:3]
array([1, 2, 3])
# Pobranie wszystkich elementów wektora od czwartego włącznie.
vector[3:]
array([4, 5, 6])
# Pobranie ostatniego elementu.
vector[-1]
6
# Pobranie pierwszych dwóch wierszy i wszystkich kolumn macierzy.
matrix[:2,:]
array([[1, 2, 3],
[4, 5, 6]])
# Pobranie wszystkich wierszy i drugiej kolumny.
matrix[:,1:2]
array([[2],
[5],
[8]])