uczenie-maszynowe/lab/02_Wczytywanie_i_prezentowa...

797 KiB
Raw Blame History

Uczenie maszynowe — laboratoria

2. Wczytywanie i prezentowanie danych

2.1. Formaty CSV i TSV

Przechowywanie danych w plikach w formatach CSV i TSV

CSV (_Comma-Separated Values) i TSV (Tab-Separated Values) to proste formaty przechowywania danych tabelarycznych w postaci tekstowej.

Każdy rekord zapisywany jest w osobnym wierszu, a poszczególne pola oddzielone są przecinkami (CSV) lub znakami tabulacji (TSV).

Przykład

Następujące dane tabelaryczne:

imię nazwisko rok ur. adres
Jan Nowak 1999 Poznańska 3, Warszawa
Anna Kowalska 2001 Warszawska 9, Poznań
Ewa Kaczmarek 1990 Wrocławska 123, Gdańsk

możemy zapisać w formacie CSV jako:

imię,nazwisko,rok ur.,adres
Jan,Nowak,1999,"Poznańska 3, Warszawa"
Anna,Kowalska,2001,"Warszawska 9, Poznań"
Ewa,Kaczmarek,1990,"Wrocławska 123, Gdańsk"

lub w formacie TSV jako:

imię    nazwisko    rok ur. adres
Jan     Nowak       1999    Poznańska 3, Warszawa
Anna    Kowalska    2001    Warszawska 9, Poznań
Ewa     Kaczmarek   1990    Wrocławska 123, Gdańsk

W formacie TSV poszczególne pola oddzielone są znakami tabulacji, a nie spacjami.

Znak tabulacji to ten biały (tj. niedrukowalny) znak, który pojawia się po naciśnięciu klawisza Tab na klawiaturze.

Formaty CSV i TSV mają tę zaletę, że są proste, łatwe do przetorzenia przez komputer oraz czytelne dla człowieka.

Wczytywanie danych z plików CSV i TSV

Biblioteka csv

import csv

with open("data1.csv", encoding="utf-8") as data_file:
    reader = csv.reader(data_file)
    for row in reader:
        print(row)
['price', 'isNew', 'rooms', 'floor', 'location', 'sqrMetres']
['476118.0', 'False', '3', '1', 'Centrum', '78']
['459531.0', 'False', '3', '2', 'Sołacz', '62']
['411557.0', 'False', '3', '0', 'Sołacz', '15']
['496416.0', 'False', '4', '0', 'Sołacz', '14']
['406032.0', 'False', '3', '0', 'Sołacz', '15']
['450026.0', 'False', '3', '1', 'Naramowice', '80']
['571229.15', 'False', '2', '4', 'Wilda', '39']
['325000.0', 'False', '3', '1', 'Grunwald', '54']
['268229.0', 'False', '2', '1', 'Grunwald', '90']
import csv

with open("data1.csv", encoding="utf-8") as data_file:
    reader = csv.DictReader(data_file)
    for row in reader:
        print(dict(row))
{'price': '476118.0', 'isNew': 'False', 'rooms': '3', 'floor': '1', 'location': 'Centrum', 'sqrMetres': '78'}
{'price': '459531.0', 'isNew': 'False', 'rooms': '3', 'floor': '2', 'location': 'Sołacz', 'sqrMetres': '62'}
{'price': '411557.0', 'isNew': 'False', 'rooms': '3', 'floor': '0', 'location': 'Sołacz', 'sqrMetres': '15'}
{'price': '496416.0', 'isNew': 'False', 'rooms': '4', 'floor': '0', 'location': 'Sołacz', 'sqrMetres': '14'}
{'price': '406032.0', 'isNew': 'False', 'rooms': '3', 'floor': '0', 'location': 'Sołacz', 'sqrMetres': '15'}
{'price': '450026.0', 'isNew': 'False', 'rooms': '3', 'floor': '1', 'location': 'Naramowice', 'sqrMetres': '80'}
{'price': '571229.15', 'isNew': 'False', 'rooms': '2', 'floor': '4', 'location': 'Wilda', 'sqrMetres': '39'}
{'price': '325000.0', 'isNew': 'False', 'rooms': '3', 'floor': '1', 'location': 'Grunwald', 'sqrMetres': '54'}
{'price': '268229.0', 'isNew': 'False', 'rooms': '2', 'floor': '1', 'location': 'Grunwald', 'sqrMetres': '90'}
import csv

with open("data1.tsv", encoding="utf-8") as data_file:
    reader = csv.reader(data_file, delimiter="\t")
    for row in reader:
        print(row)
['price', 'isNew', 'rooms', 'floor', 'location', 'sqrMetres']
['476118.0', 'False', '3', '1', 'Centrum', '78']
['459531.0', 'False', '3', '2', 'Sołacz', '62']
['411557.0', 'False', '3', '0', 'Sołacz', '15']
['496416.0', 'False', '4', '0', 'Sołacz', '14']
['406032.0', 'False', '3', '0', 'Sołacz', '15']
['450026.0', 'False', '3', '1', 'Naramowice', '80']
['571229.15', 'False', '2', '4', 'Wilda', '39']
['325000.0', 'False', '3', '1', 'Grunwald', '54']
['268229.0', 'False', '2', '1', 'Grunwald', '90']
import csv

with open("data1.tsv", encoding="utf-8") as data_file:
    reader = csv.DictReader(data_file, delimiter="\t")
    for row in reader:
        print(dict(row))
{'price': '476118.0', 'isNew': 'False', 'rooms': '3', 'floor': '1', 'location': 'Centrum', 'sqrMetres': '78'}
{'price': '459531.0', 'isNew': 'False', 'rooms': '3', 'floor': '2', 'location': 'Sołacz', 'sqrMetres': '62'}
{'price': '411557.0', 'isNew': 'False', 'rooms': '3', 'floor': '0', 'location': 'Sołacz', 'sqrMetres': '15'}
{'price': '496416.0', 'isNew': 'False', 'rooms': '4', 'floor': '0', 'location': 'Sołacz', 'sqrMetres': '14'}
{'price': '406032.0', 'isNew': 'False', 'rooms': '3', 'floor': '0', 'location': 'Sołacz', 'sqrMetres': '15'}
{'price': '450026.0', 'isNew': 'False', 'rooms': '3', 'floor': '1', 'location': 'Naramowice', 'sqrMetres': '80'}
{'price': '571229.15', 'isNew': 'False', 'rooms': '2', 'floor': '4', 'location': 'Wilda', 'sqrMetres': '39'}
{'price': '325000.0', 'isNew': 'False', 'rooms': '3', 'floor': '1', 'location': 'Grunwald', 'sqrMetres': '54'}
{'price': '268229.0', 'isNew': 'False', 'rooms': '2', 'floor': '1', 'location': 'Grunwald', 'sqrMetres': '90'}

Biblioteka pandas

import pandas as pd

data = pd.read_csv("data1.csv")
print(data)
       price  isNew  rooms  floor    location  sqrMetres
0  476118.00  False      3      1     Centrum         78
1  459531.00  False      3      2      Sołacz         62
2  411557.00  False      3      0      Sołacz         15
3  496416.00  False      4      0      Sołacz         14
4  406032.00  False      3      0      Sołacz         15
5  450026.00  False      3      1  Naramowice         80
6  571229.15  False      2      4       Wilda         39
7  325000.00  False      3      1    Grunwald         54
8  268229.00  False      2      1    Grunwald         90
import pandas as pd

data = pd.read_csv("data1.tsv", sep="\t")
print(data)
       price  isNew  rooms  floor    location  sqrMetres
0  476118.00  False      3      1     Centrum         78
1  459531.00  False      3      2      Sołacz         62
2  411557.00  False      3      0      Sołacz         15
3  496416.00  False      4      0      Sołacz         14
4  406032.00  False      3      0      Sołacz         15
5  450026.00  False      3      1  Naramowice         80
6  571229.15  False      2      4       Wilda         39
7  325000.00  False      3      1    Grunwald         54
8  268229.00  False      2      1    Grunwald         90
print(data.to_numpy())  # dane z Pandas DataFrame można przekonwertować na tablicę NumPy
# data.values  # dla starszych wersji biblioteki Pandas
[[476118.0 False 3 1 'Centrum' 78]
 [459531.0 False 3 2 'Sołacz' 62]
 [411557.0 False 3 0 'Sołacz' 15]
 [496416.0 False 4 0 'Sołacz' 14]
 [406032.0 False 3 0 'Sołacz' 15]
 [450026.0 False 3 1 'Naramowice' 80]
 [571229.15 False 2 4 'Wilda' 39]
 [325000.0 False 3 1 'Grunwald' 54]
 [268229.0 False 2 1 'Grunwald' 90]]

2.2. Wykresy biblioteka matplotlib

Dokumentacja modułu pyplot biblioteki matplotlib: https://matplotlib.org/api/pyplot_api.html

%matplotlib inline  # Jupyterowa "magia", żeby wykresy wyświetlały się inline, a nie w osobnym oknie
import matplotlib.pyplot as plt

# Prosty wykres punktowy
# Litery 'ro' oznaczają, że dane zostaną przedstawione za pomocą czerwonych kółek:
#    'r' ('red')  czerwone
#    'o'  kółko
# Zobacz też: https://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.plot

plt.plot([1, 2, 3, 4], [1, 4, 9, 16], "ro")
plt.axis([0, 5, 0, 20])  # opcjonalnie ustawiamy zakres osi wykresu

plt.show()  # pokaż wykres
# Wykres danych wczytanych z pliku

import matplotlib.pyplot as plt
import pandas as pd

# Wczytanie danych
data = pd.read_csv("data1.tsv", sep="\t")
data_array = data.to_numpy()

# Wybór kolumn do przedstawienia na wykresie
x = data_array[:, 0]
y = data_array[:, 5]

plt.plot(x, y, "gx")  # "gx" - zielone (Green) krzyżyki (x)
plt.axis([0, 600000, 0, 100])  # opcjonalnie ustawiamy zakres osi wykresu

plt.show()  # pokaż wykres
import numpy as np
import matplotlib.pyplot as plt

# inicjalizacja
fig = plt.figure()
# dodanie "podwykresu" (zobacz: http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.subplot )
ax = fig.add_subplot(111)

ax.set_xlabel("x")  # opis osi x
ax.set_ylabel("y")  # opis osi y
ax.set_title("Wykres funkcji")  # tytuł wykresu

x = np.arange(0.0, 10.0, 0.01)  # x przebiega zakres od 0 do 10 co 0.01

# zdefiniowanie wartości y w zależności od x
y = np.sin(2 * np.pi * x)
# spróbuj też inne funkcje:
# y = 2 * x**2 + 5 * x - 10
# y = np.sqrt(x)

ax.plot(x, y, color="blue", lw=2)  # "lw" oznacza grubość linii (Line Width)

plt.show()  # pokaż wykres

Style wykresów

# Umieszczanie kilku układów współrzędnych i kilku wykresów na jednym rysunku

import numpy as np
import matplotlib.pyplot as plt

# inicjalizacja zestawu wykresów
fig = plt.figure(figsize=(10, 8))

# wygenerowanie danych
x = np.arange(0.0, 1.0, 0.025)
y1 = np.sin(2 * np.pi * x) + 5.0
y2 = np.sin(2 * np.pi * x) + 2.5
y3 = np.sin(2 * np.pi * x)

# pierwszy wykres
ax1 = fig.add_subplot(3, 1, 1)
ax1.set_ylabel("y")
ax1.set_title("pierwszy wykres")

ax1.plot(x, y1, color="red", lw=2)  # pierwsza krzywa - czerwona
ax1.plot(x, y2, color="green", lw=2)  # druga krzywa - zielona
ax1.plot(
    x, y3, color="#002d69", lw=2
)  # trzecia krzywa - kolor zdefiniowany szesnastkowo

# drugi wykres
ax2 = fig.add_subplot(3, 1, 2)
ax2.set_ylabel("y")
ax2.set_title("drugi wykres")

ax2.plot(x, y1, color="black", lw=2, linestyle="--")  # pierwsza krzywa - kreskowana
ax2.plot(x, y2, color="blue", lw=2, linestyle=":")  # druga krzywa - kropkowana
ax2.plot(
    x, y3, color="#ff0000", lw=2, linestyle="-."
)  # trzecia krzywa - kropkowano-kreskowana

# trzeci wykres
ax3 = fig.add_subplot(3, 1, 3)
ax3.set_ylabel("y")
ax3.set_title("trzeci wykres")

ax3.plot(x, y1, color="brown", marker="x")  # pierwsza krzywa - krzyżyki
ax3.plot(x, y2, color="purple", marker="o")  # druga krzywa - kółka
ax3.plot(x, y3, color="orange", marker="^")  # trzecia krzywa - trójkąty

# dostosowanie odstępów pomiędzy wykresami
plt.subplots_adjust(wspace=0.2, hspace=0.4)

plt.show()  # pokaż wykres

Wykresy trójwymiarowe  linie

import matplotlib as mpl
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection="3d")

theta = np.linspace(-4 * np.pi, 4 * np.pi, 50)
z = np.linspace(-2, 2, 50)
r = z**2 + 1
x = r * np.sin(theta)
y = r * np.cos(theta)

ax.plot(x, y, z, label="krzywa parametryczna")
ax.legend()  # pokaż legendę wykresu

plt.show()  # pokaż wykres

Wykresy trójwymiarowe powierzchnie

from mpl_toolkits.mplot3d import (
    Axes3D,
)  # niezbędne do rysowania powierzchni w 3 wymiarach
from matplotlib import cm
import matplotlib.pyplot as plt
import numpy as np

fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection="3d")

X = np.arange(-5, 5, 0.25)
Y = np.arange(-5, 5, 0.25)
X, Y = np.meshgrid(
    X, Y
)  # wygenerowanie tablicy danych wejściowych dla wykresu trójwymiarowego

# obliczenie wartości rzędnych
Z = np.sqrt(X**2 + Y**2)
# Spróbuj też innych funkcji
# Z = np.sin(np.sqrt(X**2 + Y**2))
# Z = np.cos(X + Y)
# Z = X**2 * Y

surf = ax.plot_surface(
    X, Y, Z, rstride=1, cstride=1, cmap=cm.jet, linewidth=0, antialiased=True
)

plt.show()

Wykresy kolumnowe

import numpy as np
import matplotlib.pyplot as plt

# data: scores in five groups for men and women
N = 5
menMeans = [18, 35, 30, 35, 27]
menStd = [2, 3, 4, 1, 2]
womenMeans = [25, 32, 34, 20, 25]
womenStd = [3, 5, 2, 3, 3]

# start creating figure
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111)

# necessary variables
LOCATIONS = np.arange(N)  # the x locations for the groups
WIDTH = 0.35  # the width of the bars

# the bars
rects_m = ax.bar(
    LOCATIONS,
    menMeans,
    WIDTH,
    color="blue",
    yerr=menStd,
    error_kw=dict(elinewidth=2, ecolor="red"),
)

rects_f = ax.bar(
    LOCATIONS + WIDTH,
    womenMeans,
    WIDTH,
    color="red",
    yerr=womenStd,
    error_kw=dict(elinewidth=2, ecolor="blue"),
)

# axes and labels
ax.set_xlim(-WIDTH, len(LOCATIONS))
ax.set_ylabel("Scores")
ax.set_title("Scores by group and gender")
xTickMarks = ["Group {}".format(i) for i in range(1, 6)]
ax.set_xticks(LOCATIONS + WIDTH)
xtickNames = ax.set_xticklabels(xTickMarks)
plt.setp(xtickNames, rotation=45, fontsize=10)

# add a legend
ax.legend((rects_m[0], rects_f[0]), ("Men", "Women"))

plt.show()

Wykresy punktowe

import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure(figsize=(15, 7))

# left panel
N = 1000
ax1 = fig.add_subplot(121)

x = np.random.randn(N)
y = np.random.randn(N)
ax1.scatter(x, y, color="blue", s=10, edgecolor="none")
# make axes square
ax1.set_aspect(1.0 / ax1.get_data_ratio())

# right panel
ax2 = fig.add_subplot(122)
props = dict(alpha=0.5, edgecolors="none")

M = 200
colors = ["blue", "green", "magenta", "cyan"]
handles = []

for color in colors:
    x = np.random.randn(M)
    y = np.random.randn(M)
    size = np.random.randint(25, 200)
    handles.append(ax2.scatter(x, y, c=color, s=size, **props))

# ax2.set_ylim([-5,10])
# ax2.set_xlim([-5,10])

ax2.legend(handles, colors)
ax2.grid(True)
ax2.set_aspect(1.0 / ax2.get_data_ratio())

plt.show()

Histogramy

import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111)

x = np.random.normal(0, 1, 1000)
num_bins = 50
ax.hist(x, num_bins, color="green", alpha=0.8)
plt.show()

2.3. Wizualizacja danych - biblioteka seaborn

Biblioteka seaborn (https://seaborn.pydata.org) to oparta o matplotlib biblioteka do wizualizacji danych.

Przykład 1

Wizualizacja zbioru danych _Iris poprzez rzutowanie go na różne osie:

import pandas as pd
import seaborn

data_iris = pd.read_csv("../wyk/iris.csv")

seaborn.pairplot(
    data_iris,
    vars=[c for c in data_iris.columns if c != "Gatunek"],
    hue="Gatunek",
    height=1.5,
    aspect=1.75,
)
<seaborn.axisgrid.PairGrid at 0x20279e6c0d0>

Przykład 2

Rozkład różnych typów zabudowy w zbiorze danych _Mieszkania4 pod względem roku budowy i powierzchni lokalu

import pandas as pd
import seaborn

data = pd.read_csv("../wyk/mieszkania4.tsv", sep="\t")

data = data[(data["Powierzchnia w m2"] < 10000) & (data["cena"] < 10000000)]

seaborn.relplot(data=data, x="Rok budowy", y="Powierzchnia w m2", hue="Typ zabudowy")
<seaborn.axisgrid.FacetGrid at 0x202002cc580>