Dane mozna pobrać po utworzeniu (darmowego) konta na portalu Kaggle.
Pobierz dane: interesują nas tylko pliki zbiorów train.csv i test.csv.
Zobaczmy jak wyglądają nasze dane:
import pandas as pdtrain = pd.read_csv('../data/train.csv')test = pd.read_csv('../data/test.csv')print("train ma {} wierszy i {} kolumn".format(*train.shape))print("test ma {} wierszy i {} kolumn".format(*test.shape))print(f"train to obiekt typu {type(train)}")
train ma 891 wierszy i 12 kolumn
test ma 418 wierszy i 11 kolumn
train to obiekt typu <class 'pandas.core.frame.DataFrame'>
Dla zbioru testowego mamy jedną kolumnę (Survived) mniej, dlaczego?
Ze względu, iz nie planujemy wrzucać wyników modeli na kaggle zbiór test nie jest nam potrzebny.
Informacje z metody info() przedstawiają tylko ogólne rzeczy, zobaczmy jak zbiór train wygląda w środku.
train.head()
PassengerId
Survived
Pclass
Name
Sex
Age
SibSp
Parch
Ticket
Fare
Cabin
Embarked
0
1
0
3
Braund, Mr. Owen Harris
male
22.0
1
0
A/5 21171
7.2500
NaN
S
1
2
1
1
Cumings, Mrs. John Bradley (Florence Briggs Th...
female
38.0
1
0
PC 17599
71.2833
C85
C
2
3
1
3
Heikkinen, Miss. Laina
female
26.0
0
0
STON/O2. 3101282
7.9250
NaN
S
3
4
1
1
Futrelle, Mrs. Jacques Heath (Lily May Peel)
female
35.0
1
0
113803
53.1000
C123
S
4
5
0
3
Allen, Mr. William Henry
male
35.0
0
0
373450
8.0500
NaN
S
Kazda kolumna reprezentuje jedną zmienną naszych danych. Identyfikatorem, bądź kluczem naszej tabeli jest PassengerId, która przyjmuje rózną wartość dla kazdego wiersza. Czy taka zmienna moze być dobra do modelowania? Zmienna Survived realizuje zmienną celu naszego zadania - pasazer przezyl (1) lub nie (0). Pclass to zmienna opisująca klasę pokładu zgodnie z biletem.
Czyszczenie danych
Nasze dane zawierają zarówno dane numeryczne jak i kategoryczne. Niektóre kategorie reprezentowane są przez wartości liczbowe, a niektóre przez tekst.
Na podstawie metody info() wiemy równiez, ze nie wszystkie kolumny mają zmienne wypełnione całkowicie.
Większość algorytmów ML nie radzi sobie z brakami danych. Istnieją trzy podstawowe opcje jak mozemy sobie z tym poradzić: 1. usunięcie wierszy w których pojawiają się jakieś braki danych. 2. usunięcie całej kolumny gdzie występują braki danych 3. Wypełnienie brakujących wartości (imputacja danych) zerem, wartością średnią, lub medianą.
# opcja 1 - tylko 2 pasazerow nie maja Embarked - nie znamy portu docelowego - mozemy usunac te wierszetrain = train.dropna(subset=['Embarked'])# opcja 2 - tutaj mamy tylko 204 wiersze z wartosciami w kolumnie Cabin - mozemy usunac te kolumnetrain = train.drop("Cabin", axis=1)# opcja 3 - znamy wiek 714 pasazerow. Dlatego opcja 2 nie jest dobra. Opcja 1 tez nie jest dobra bo usuniemy $22\%$ danych.mean = train['Age'].mean()train['Age'] = train['Age'].fillna(mean)train.info()
print('Zmienna PassengerId ma {} roznych wartosci'.format(train['PassengerId'].nunique()))print('Zmienna Name ma {} roznych wartosci'.format(train['Name'].nunique()))print('Zmienna Ticket ma {} roznych wartosci'.format(train['Ticket'].nunique()))
Zmienna PassengerId ma 889 roznych wartosci
Zmienna Name ma 889 roznych wartosci
Zmienna Ticket ma 680 roznych wartosci
from sklearn.preprocessing import LabelEncoderle = LabelEncoder()for col in ['Sex','Embarked']: le.fit(train[col]) train[col] = le.transform(train[col])train.head()
Survived
Pclass
Sex
Age
SibSp
Parch
Fare
Embarked
0
0
3
1
22.0
1
0
7.2500
2
1
1
1
0
38.0
1
0
71.2833
0
2
1
3
0
26.0
0
0
7.9250
2
3
1
1
0
35.0
1
0
53.1000
2
4
0
3
1
35.0
0
0
8.0500
2
Skalowanie danych
print('max wieku to {}'.format(train['Age'].max())) print('max zmiennej Fare to {}'.format(train['Fare'].max()))
/Users/air/Desktop/quarto_projects/intro_to_qml/venv/lib/python3.10/site-packages/sklearn/metrics/_classification.py:1471: UndefinedMetricWarning: Precision is ill-defined and being set to 0.0 due to no predicted samples. Use `zero_division` parameter to control this behavior.
_warn_prf(average, modifier, msg_start, len(result))
/Users/air/Desktop/quarto_projects/intro_to_qml/venv/lib/python3.10/site-packages/sklearn/metrics/_classification.py:1471: UndefinedMetricWarning: Precision is ill-defined and being set to 0.0 due to no predicted samples. Use `zero_division` parameter to control this behavior.
_warn_prf(average, modifier, msg_start, len(result))
Powyzsze kody realizują klasyfikatory, które nie zalezą od naszych danych pasazerów.
Preprocessing - przetworznie danych wejściowych do postaci przetwarzanej przez nasz obwód kwantowy. Wykorzystamy PQC. Ta część jest związana z klasycznym przetworzeniem danych i utworzeniem embeddingu.
PQC
Postprocessing - Nasz klasyfikator powinien zwracać wartość 0 lub 1. Tutaj powinien odbywać się proces przetłumaczenia wyniku realizowanego przez jakiś obwód kwanotwy na binarny wynik klasyfikacji. Tutaj równiez uzyjemy PQC do klasycznego przetworzenia.
Tylko druga część będzie w pełni realizowała obwód kwantowy. Łącząc wszystko razem otrzymujemy Wariacyjny hybrydowy klasyczno-kwantowy algorytm. Jest to jedno z najczęściej uzywanych podejść do modelowania danych klasycznych.
Dane kazdego pasazera składają się z 7 zmiennych. Ze względu, iz nie chcemy (na razie) zmieniać ostatniego kroku musimy znaleźć jakąś metodę pozwalającą przypisać 7 zmiennym prawdopodobieństwo przezycia i śmierci. W ostatnim kroku odczytujemy po pomiarze tylko te dwie wielkości.
Znalezienie prawdopodobieństwa dla 7 zmiennych nie jest prostym zadaniem (w końcu to robią nasze klasyczne modele ML). Jendak mozemy zacząć od bardzo statystycznego podejścia. Zakładamy, ze zmienne są od siebie niezalezne i kazda zmienna z jakąś wagą przyczynia się do wartości prawdopodobieństwa przezycia. \[
P(survival) = \sum (F \mu_F)
\]
from math import pi, sin, cos def get_state(theta):return [cos(theta/2), sin(theta/2)]def pre_process_weighted(passenger): mu = get_overall_probablity(passenger, correlations)# theta między 0 i pi 0 = |0> a pi = |1> quantum_state = get_state((1-mu)*pi)return quantum_state