From 4d8b438723a35592b2acb263154e4eaa38c880d5 Mon Sep 17 00:00:00 2001 From: andrzej Date: Mon, 11 May 2020 13:09:57 +0200 Subject: [PATCH] Praca nad raportem --- Andrzej_Preibisz.md | 49 ++++++++++++++++++----- package_location_classifier/classifier.py | 8 ++-- 2 files changed, 43 insertions(+), 14 deletions(-) diff --git a/Andrzej_Preibisz.md b/Andrzej_Preibisz.md index 9e018ed..8bd0692 100644 --- a/Andrzej_Preibisz.md +++ b/Andrzej_Preibisz.md @@ -29,19 +29,48 @@ W świecie projektu różny rodzaj towarów ma różne "progi", od których moż na przykład kładąc paczkę z lakierem/benzyną na regale lepiej mieć trochę większą pewność, że towar nie nagrzeje się nadmiernie, aniżeli kładąc książkę - że nie zniszczeje od wilgoci. W związku z tym zamiast prostej odpowiedzi Tak/Nie na pytanie czy dany obiekt można położyć na danym regale potrzebna była przewidywana wartość prawdopodobieństwa że w danym miejscu -zachowa się on w dobrym stanie. Wszystkie te progi wynoszą odpowiednio: -`` -PACKAGE_PLACE_TRESHOLD = { - "normal": 0.8, - "freezed": 0.85, - "fragile": 0.85, - "flammable": 0.9, - "keep_dry": 0.8 -} +zachowa się on w dobrym stanie. Wszystkie te progi wynoszą odpowiednio: \ `` + PACKAGE_PLACE_TRESHOLD = { + "normal": 0.8, + "freezed": 0.85, + "fragile": 0.85, + "flammable": 0.9, + "keep_dry": 0.8 + } +``\ Zdecydowałem się więc na wybór drzewa regresyjnego. Biblioteką której użyłem w celu implementacji drzewa jest scikit-learn. Najważniejszym problemem oprócz dokładności oszacowań dokonanych przy pomocy drzewa było uniknięcie overfittingu(przepasowania), czyli sytuacji, w której drzewo perfekcyjnie dopasuje się do danych ze zbioru uczącego, jednak z danymi spoza tego zbioru poradzi sobie już dużo gorzej. Oprócz błędnej oceny danych innych niż ze zbioru uczącego sygnałem wskazującym na overfitting drzewa -jest zbyt duża jego głębokość drzewa (odległość od korzenia do najdalszego liścia), oraz liście zawierające tylko 1 rekord. \ No newline at end of file +jest zbyt duża jego głębokość drzewa (odległość od korzenia do najdalszego liścia), oraz liście zawierające tylko 1 rekord. +W celu uniknięcia overfittingu zdecydowałem się na ograniczenie maksymalnej głębokości drzewa, oraz na ustawienie minimalnej +ilości rekordów w liściu. Drzewo wraz z odpowiednimi ograniczeniami zdefiniowane jest w następujący sposób \ +``clf = DecisionTreeRegressor(ccp_alpha=0.02, min_samples_leaf=5, max_depth=5)``\ +gdzie argumenty min_samples_leaf, oraz max_depth oznaczają odpowiednio minimalną ilość rekordów(przykładów ze zbioru uczącego) w liściu, oraz maksymalną głębokość drzewa. +Kryterium według którego mierzona jest "jakość" rozgałęzienia jest tzw. MSE(Mean Squared Error), czyli kwadrat odchylenia standardowego wartości przewidywanej wobec faktycznej. +Dobierając te parametry wyszedłem z założenia że jeżeli 5 rekordów będzie w jednym liściu, to znaczy że najprawdopodbniej zachodzi +już w ich przypadku pewna prawidłowość, i mają one jakieś wspólne cechy, które determinują taką, a nie inną wartość przewidywaną, +w odróżnieniu od sytuacji gdy liść zawierałby tylko 1-2 rekordy, co wskazywałoby na bardzo specyficzne parametry takiego/ich rekordu/ów, +i prawdopodobnie oznaczało overfitting drzewa. W przypadku głębokości chodziło o uniknięcie nadmiernego rozrostu drzewa. +Zastosowany zbiór uczący obejmuje 373 rekordy zapisane w formacie .csv, w którym poszczególne kolumny oznaczają odpowiednio: +produkt, kategorię produktu, temperature na regale, wilgotność powietrza na danym regale, szansę że przedmiot po dłuższym czasie przechowywania będzie w dobrym stanie, oraz informację czy można bezpiecznie go tu położyć. +Przykładowy rekord: ``frozen food,freezed,21, 0.5, 0.01, 0 `` . Zbiór testowy z kolei zawiera 26 rekordów w tym samym formacie. +Przygotowanie zbioru uczącego i testowego dla drzewa: \ + `` + products = pd.read_csv("package_location_classifier/trainset/trainset.csv", header=0, sep=",", names=cols_names) + testset = pd.read_csv("package_location_classifier/testset/testset.csv", header=None, sep=",", names=cols_names) + products = products.round({"chance_of_survive": 1}) + testset = testset.round({"chance_of_survive": 1}) + products.chance_of_survive *= 10 + testset.chance_of_survive *= 10 + test_X = pd.get_dummies(testset[feature_cols]) + test_y = testset.chance_of_survive + products = products.sample(frac=1) + X_train = pd.get_dummies(products[feature_cols]) + y_train = products.chance_of_survive + `` +Drzewo wygenerowane dla tego zbioru uczącego: \ +[Przykładowe drzewo](Drzewo.png) + diff --git a/package_location_classifier/classifier.py b/package_location_classifier/classifier.py index 5f8e13c..525c2d5 100644 --- a/package_location_classifier/classifier.py +++ b/package_location_classifier/classifier.py @@ -49,10 +49,10 @@ class PackageLocationClassifier(): evaluation = pd.DataFrame({'category': testset.category, 'temperature': testset.temperature , 'humid': testset.humidity ,'Actual': test_y, 'Predicted': y_pred}) evaluation['Prediction_diff'] = abs(evaluation['Actual'] - evaluation['Predicted']) print("Prediction differs from actual value by average {}".format(round(evaluation['Prediction_diff'].mean(), 2))) - # export_graphviz(clf, out_file=data, filled=True, rounded=True, special_characters=True, feature_names=dummies_names) - # graph = pydotplus.graph_from_dot_data(data.getvalue()) - # graph.write_png('Drzewo.png') - # Image(graph.create_png()) + export_graphviz(clf, out_file=data, filled=True, rounded=True, special_characters=True, feature_names=dummies_names) + graph = pydotplus.graph_from_dot_data(data.getvalue()) + graph.write_png('Drzewo.png') + Image(graph.create_png()) def check_if_can_place(self, package, tile): category = package.category