5.1. Kodowanie nominalnych cech kategoryzujących

# Wczytanie bibliotek.
import numpy as np
from sklearn.preprocessing import LabelBinarizer, MultiLabelBinarizer

# Utworzenie cechy.
feature = np.array([["Teksas"],
                    ["Kalifornia"],
                    ["Teksas"],
                    ["Delaware"],
                    ["Teksas"]])

# Utworzenie kodera „gorącojedynkowego”.
one_hot = LabelBinarizer()

# Zakodowanie cechy za pomocą przygotowanego kodera.
one_hot.fit_transform(feature)

array([[0, 0, 1],
       [1, 0, 0],
       [0, 0, 1],
       [0, 1, 0],
       [0, 0, 1]])





# Wyświetlenie klas cechy.
one_hot.classes_
array(['Kalifornia', 'Delaware', 'Teksas'],
      dtype='<U10')





# Odwrócenie wyniku użycia kodowania „gorącojedynkowego”.
one_hot.inverse_transform(one_hot.transform(feature))

array(['Teksas', 'Kalifornia', 'Teksas', 'Delaware', 'Teksas'],
      dtype='<U10')





# Wczytanie biblioteki.
import pandas as pd

# Utworzenie przykładowych zmiennych na podstawie cechy.
pd.get_dummies(feature[:,0])





# Utworzenie funkcji składającej się z wielu klas.
multiclass_feature = [("Teksas", "Floryda"),
                      ("Kalifornia", "Alabama"),
                      ("Teksas", "Floryda"),
                      ("Delaware", "Floryda"),
                      ("Teksas", "Alabama")]

# Utworzenie kodera „gorącojedynkowego” dla wielu klas.
one_hot_multiclass = MultiLabelBinarizer()

# Zakodowanie cechy za pomocą przygotowanego kodera.
one_hot_multiclass.fit_transform(multiclass_feature)

array([[0, 0, 0, 1, 1],
       [1, 1, 0, 0, 0],
       [0, 0, 0, 1, 1],
       [0, 0, 1, 1, 0],
       [1, 0, 0, 0, 1]])





# Wyświetlenie klas.
one_hot_multiclass.classes_

array(['Alabama', 'Kalifornia', 'Delaware', 'Floryda', 'Teksas'], dtype=object)





5.2. Kodowanie porządkowych cech kategoryzujących

# Wczytanie biblioteki.
import pandas as pd

# Utworzenie cech.
dataframe = pd.DataFrame({"Score": ["niski", "niski", "średni", "średni", "wysoki"]})

# Utworzenie mapowania.
scale_mapper = {"niski": 1,
                "średni": 2,
                "wysoki": 3}

# Zastąpienie wartości cechy skalą.
dataframe["Score"].replace(scale_mapper)

0    1
1    1
2    2
3    2
4    3
Name: Score, dtype: int64





dataframe = pd.DataFrame({"Score": ["niski",
                                    "niski",
                                    "średni",
                                    "średni",
                                    "wysoki",
                                    "nieco więcej niż średni"]})

scale_mapper = {"niski": 1,
                "średni": 2,
                "nieco więcej niż średni": 3,
                "wysoki": 4}

dataframe["Score"].replace(scale_mapper)

0    1
1    1
2    2
3    2
4    4
5    3
Name: Score, dtype: int64





scale_mapper = {"niski": 1,
                "średni": 2,
                "nieco więcej niż średni": 2.1,
                "wysoki": 3}

dataframe["Score"].replace(scale_mapper)

0    1.0
1    1.0
2    2.0
3    2.0
4    3.0
5    2.1
Name: Score, dtype: float64





5.3. Kodowanie słowników cech

# Wczytanie biblioteki.
from sklearn.feature_extraction import DictVectorizer

# Utworzenie słownika.
data_dict = [{"czerwony": 2, "niebieski": 4},
             {"czerwony": 4, "niebieski": 3},
             {"czerwony": 1, "żółty": 2},
             {"czerwony": 2, "żółty": 2}]

# Utworzenie słownika, czyli egzemplarza typu DictVectorizer.
dictvectorizer = DictVectorizer(sparse=False)

# Konwersja słownika na macierz cech.
features = dictvectorizer.fit_transform(data_dict)

# Wyświetlenie macierzy cech.
features

array([[ 4.,  2.,  0.],
       [ 3.,  4.,  0.],
       [ 0.,  1.,  2.],
       [ 0.,  2.,  2.]])





# Pobranie nazw cech.
feature_names = dictvectorizer.get_feature_names()

# Wyświetlenie nazw cech.
feature_names

['niebieski', 'czerwony', 'żółty']





# Wczytanie biblioteki.
import pandas as pd

# Utworzenie obiektów DataFrame na podstawie cech.
pd.DataFrame(features, columns=feature_names)





# Utworzenie liczby wystąpień słów dla czterech dokumentów słowników.
doc_1_word_count = {"czerwony": 2, "niebieski": 4}
doc_2_word_count = {"czerwony": 4, "niebieski": 3}
doc_3_word_count = {"czerwony": 1, "żółty": 2}
doc_4_word_count = {"czerwony": 2, "żółty": 2}

# Utworzenie listy.
doc_word_counts = [doc_1_word_count,
                   doc_2_word_count,
                   doc_3_word_count,
                   doc_4_word_count]

# Konwersja listy słowników liczby wystąpień słów na macierz cech.
dictvectorizer.fit_transform(doc_word_counts)

array([[ 4.,  2.,  0.],
       [ 3.,  4.,  0.],
       [ 0.,  1.,  2.],
       [ 0.,  2.,  2.]])





5.4. Wstawianie brakujących wartości klas

# Wczytanie bibliotek.
import numpy as np
from sklearn.neighbors import KNeighborsClassifier

# Utworzenie macierzy cech wraz z cechą kategoryzującą.
X = np.array([[0, 2.10, 1.45],
              [1, 1.18, 1.33],
              [0, 1.22, 1.27],
              [1, -0.21, -1.19]])

# Utworzenie macierzy cechy wraz z brakującymi wartościami cechy kategoryzującej.
X_with_nan = np.array([[np.nan, 0.87, 1.31],
                       [np.nan, -0.67, -0.22]])

# Wytrenowanie algorytmu KNN.
clf = KNeighborsClassifier(3, weights='distance')
trained_model = clf.fit(X[:,1:], X[:,0])

# Prognozowanie brakujących wartości klas.
imputed_values = trained_model.predict(X_with_nan[:,1:])

# Połączenie kolumny prognozowanej klasy wraz z pozostałymi cechami.
X_with_imputed = np.hstack((imputed_values.reshape(-1,1), X_with_nan[:,1:]))

# Połączenie dwóch macierzy cech.
np.vstack((X_with_imputed, X))

array([[ 0.  ,  0.87,  1.31],
       [ 1.  , -0.67, -0.22],
       [ 0.  ,  2.1 ,  1.45],
       [ 1.  ,  1.18,  1.33],
       [ 0.  ,  1.22,  1.27],
       [ 1.  , -0.21, -1.19]])





from sklearn.impute import SimpleImputer

# Połączenie dwóch macierzy cech.
X_complete = np.vstack((X_with_nan, X))

imputer = SimpleImputer(strategy='most_frequent')

imputer.fit_transform(X_complete)

array([[ 0.  ,  0.87,  1.31],
       [ 0.  , -0.67, -0.22],
       [ 0.  ,  2.1 ,  1.45],
       [ 1.  ,  1.18,  1.33],
       [ 0.  ,  1.22,  1.27],
       [ 1.  , -0.21, -1.19]])





5.5. Obsługa niezrównoważonych klas

# Wczytanie bibliotek.
import numpy as np
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_iris

# Wczytanie danych Iris.
iris = load_iris()

# Utworzenie macierzy cech.
features = iris.data

# Utworzenie wektora docelowego.
target = iris.target

# Usunięcie pierwszych 40 obserwacji.
features = features[40:,:]
target = target[40:]

# Utworzenie binarnego wektora docelowego, wskazującego, czy mamy do czynienia z klasą 0.
target = np.where((target == 0), 0, 1)

# Wyświetlenie niezrównoważonego wektora docelowego.
target

array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1])





# Zdefiniowanie wagi.
weights = {0: .9, 1: 0.1}

# Utworzenie klasyfikatora losowego lasu wraz ze zdefiniowaną wagą.
RandomForestClassifier(class_weight=weights)

RandomForestClassifier(class_weight={0: 0.9, 1: 0.1})





# Trenowanie modelu losowego lasu wraz ze zrównoważoną wagą klas.
RandomForestClassifier(class_weight="balanced")

RandomForestClassifier(class_weight='balanced')





# Indeksy poszczególnych klas obserwacji.
i_class0 = np.where(target == 0)[0]
i_class1 = np.where(target == 1)[0]

# Liczba obserwacji w poszczególnych klasach.
n_class0 = len(i_class0)
n_class1 = len(i_class1)

# Dla każdej obserwacji klasy 0 należy losowo wybrać
# obserwację z klasy 1 bez zwracania.
i_class1_downsampled = np.random.choice(i_class1, size=n_class0, replace=False)

# Połączenie wektora docelowego klasy 0
# ze zmniejszonym wektorem docelowym klasy 1.
np.hstack((target[i_class0], target[i_class1_downsampled]))

array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1])

# Połączenie macierzy cech klasy 0
# ze zmniejszoną macierzą cech klasy 1.
np.vstack((features[i_class0,:], features[i_class1_downsampled,:]))[0:5]

array([[ 5. ,  3.5,  1.3,  0.3],
       [ 4.5,  2.3,  1.3,  0.3],
       [ 4.4,  3.2,  1.3,  0.2],
       [ 5. ,  3.5,  1.6,  0.6],
       [ 5.1,  3.8,  1.9,  0.4]])





# Dla każdej obserwacji klasy 1 losowo pobieramy obserwację klasy 0 wraz ze zwracaniem.
i_class0_upsampled = np.random.choice(i_class0, size=n_class1, replace=True)

# Połączenie poddanego upsamplingowi wektora docelowego klasy 0 z wektorem docelowym klasy 1.
np.concatenate((target[i_class0_upsampled], target[i_class1]))

array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1])

# Połączenie poddanej upsamplingowi macierzy cech klasy 0 z macierzą cech klasy 1.
np.vstack((features[i_class0_upsampled,:], features[i_class1,:]))[0:5]

array([[ 5. ,  3.5,  1.6,  0.6],
       [ 5. ,  3.5,  1.6,  0.6],
       [ 5. ,  3.3,  1.4,  0.2],
       [ 4.5,  2.3,  1.3,  0.3],
       [ 4.8,  3. ,  1.4,  0.3]])
