Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
ed:lab_04 [2024/03/10 17:59]
pszwed [Funkcja do rysowania wykresów]
ed:lab_04 [2024/03/21 02:25]
pszwed [Funkcja do rysowania wykresów]
Line 12: Line 12:
 ===== 1. Cechy wielomianowe 2 stopnia =====  ===== 1. Cechy wielomianowe 2 stopnia ===== 
 **Umieść kod w klasie  ''LinearRegressionPolynomialFeaturesOrderTwo''** **Umieść kod w klasie  ''LinearRegressionPolynomialFeaturesOrderTwo''**
 +
 +**Ponieważ przetwarzane są kolejne zbiory, najwygodniej będzie umieścić kod w funkcji postaci\\
 +''static void processDataset(SparkSession spark,String filename,Function<Double,Double> f_true)''**
 +
  
 **1.** Dodaj do zbioru danych kolumnę ''X2'' zawierającą po prostu wynik wyrażenia "X*X" **1.** Dodaj do zbioru danych kolumnę ''X2'' zawierającą po prostu wynik wyrażenia "X*X"
Line 42: Line 46:
 **4.** Wyświetl wyniki. Przy wyświetlaniu aproksymowanej funkcji wywoływana jest funkcja ''lrModel.predict()''. Jako argument musisz dostarczyć wektor zawierający zarówno wartość wejściową, jak i jej kwadrat. Możesz to zrealizować dodają parametr order do funkcji plot (przyda się przy regresji 3-stopnia) lub po prostu dodając element. **4.** Wyświetl wyniki. Przy wyświetlaniu aproksymowanej funkcji wywoływana jest funkcja ''lrModel.predict()''. Jako argument musisz dostarczyć wektor zawierający zarówno wartość wejściową, jak i jej kwadrat. Możesz to zrealizować dodają parametr order do funkcji plot (przyda się przy regresji 3-stopnia) lub po prostu dodając element.
  
-**5.** Przetwórz wszystkie pliki i wyświetl ich wykresy+**5.** Przetwórz wszystkie pliki i wyświetl ich wykresy oraz w każdym przypadku podaj równanie regresji
  
 Niewątpliwie ciekawym wykresem jest dopasowanie wielomianu 2-stopnia do danych wygenerowanych z wielomianu 3 stopnia  Niewątpliwie ciekawym wykresem jest dopasowanie wielomianu 2-stopnia do danych wygenerowanych z wielomianu 3 stopnia 
Line 96: Line 100:
 **Kod umieść w klasie ''LinearRegressionPolynomialFeaturesPipeline''** **Kod umieść w klasie ''LinearRegressionPolynomialFeaturesPipeline''**
  
-Dodawanie manualne cech jako kolumn zbioru danych jest zbyt żmudne - zachodzi konieczność nazywania tych kolumn, później modyfikacji kodu w kilku miejscach. Raczej buduje się ciąg przetwarzania: ''Pipeline'', którego elementami są wstępne przetwarzanie danych i budowa modelu estymatora. Rozszerzenie cech o cechy wielomianowe jest dokonywane za pomocą odpowiedniej funkcji transformującej dane tablicowe :  ''PolynomialExpansion''.+**Ponieważ przetwarzane są kolejne zbiory, najwygodniej będzie umieścić kod w funkcji postaci\\ 
 +''static void processDataset(SparkSession spark,String filename,int degree,Function<Double,Double> f_true)''** 
 + 
 + 
 +Dodawanie manualne cech jako kolumn zbioru danych jest zbyt żmudne - zachodzi konieczność nazywania tych kolumn, później modyfikacji kodu w kilku miejscach. Raczej buduje się ciąg przetwarzania: ''Pipeline'', którego elementami są wstępne przetwarzanie danych i budowa modelu estymatora.  
 + 
 +Rozszerzenie cech o cechy wielomianowe jest dokonywane za pomocą odpowiedniej funkcji transformującej dane tablicowe :  ''PolynomialExpansion''.
  
 ==== Budowa ciągu przetwarzania  ==== ==== Budowa ciągu przetwarzania  ====
Line 165: Line 175:
 </code> </code>
  
-Aby przetworzyć je za pomocą ''pipeline'' musimy zamienić je na Dataset<Row> zawierający kolumnę o nazwie ''X'' z odpowiednimi wartościami.+Aby przetworzyć je za pomocą ''pipeline'' musimy zamienić je na obiekt typu Dataset<Row> zawierający kolumnę o nazwie ''X'' z odpowiednimi wartościami.
  
 **2.** Zamiana wartości double na ''Row'' **2.** Zamiana wartości double na ''Row''
  
-Przeiteruj przez elementy fx i dla każdego z nich utwórz obiekt ''Row'', np. wołając ''Row r = RowFactory.create(d);'' lub odpowiednią funkcje strumienia. Zbierz wynik w ''List<Row> rows''+Przeiteruj przez elementy fx i dla każdego z nich utwórz obiekt ''Row'', np. wołając ''Row r = RowFactory.create(d);'' lub umieść takie odwzorowanie w odpowiedniej funkcji strumienia. Zbierz wynik w ''List<Row> rows''
  
 **3.** Zdefiniuj schemat i utwórz zbiór danych: **3.** Zdefiniuj schemat i utwórz zbiór danych:
Line 227: Line 237:
  
 **4.** Należy oczywiście wyświetlić zawartość kolumny prediction **4.** Należy oczywiście wyświetlić zawartość kolumny prediction
 +
 +===== 4. Podział na zbiór uczący i testowy =====
 +
 +
 +==== Rozwiązanie 1 ====
 + 
 +**1.** Po załadowaniu zbioru do podziel go korzystając z funkcji ''limit'' i ''offset'':
 +
 +<code java>
 +        long rowsCount = df.count();
 +        int trainCount = (int)(rowsCount*.7);
 +        var df_train = df.select("*").limit(trainCount);
 +        var df_test = df.select("*").offset(trainCount);
 +        System.out.println(df_train.count());
 +        System.out.println(df_test.count());
 +
 +</code>
 +
 +**2.** Zamień wywołania w kodzie tak, aby przetwarzany i wyświetlany był zbiór df_train
 +
 +**3.** Dodaj wyświeltanie df_test:
 +
 +<code java>
 +        x = df_test.select("X").as(Encoders.DOUBLE()).collectAsList();
 +        y = df_test.select("Y").as(Encoders.DOUBLE()).collectAsList();
 +        plot(x,y,model,spark,String.format("Linear regression: %s (test data)",filename),f_true);
 +</code>
 +
 +
 +**4.** Dodaj kod odpowiedzialny za obliczanie  metryk na zbiorze testowym
 +
 +  * wpierw przetrannsformuj go
 +  * następnie oblicz metryki korzystając z kolumn ''Y'' i ''prediction''
 +
 +<code java>
 +        var df_test_prediction = model.transform(df_test);
 +        RegressionEvaluator evaluator = new RegressionEvaluator()
 +                .setLabelCol("Y")
 +                .setPredictionCol("prediction")
 +                .setMetricName("rmse"); // or any other evaluation metric
 +        double rmse = evaluator.evaluate(df_test_prediction);
 +        evaluator.setMetricName("r2");
 +        double r2 = evaluator.evaluate(df_test_prediction);
 +</code>
 +
 +**5.** Wydrukuj wartości metryk i obejrzyj wykresy
 +
 +Podziały przetestuj na plikach 
 +  * ''xy-003.csv'' dla cech wielomianowych 3 stopnia.
 +  * ''xy-005.csv'' dla cech wielomianowych 2 stopnia
 +
 +Zapisz rysunki i metryki.
 +
 +==== Rozwiązanie 2 ====
 +
 +Zamień sposób podziału na losowy (np. zakomentuj poprzedni kod lub utwórz kopię klasy).
 +
 +<code java>
 +var dfs = df.randomSplit(new double[]{0.7,0.3});
 +var df_train = dfs[0];
 +var df_test = dfs[1];
 +</code>
 +
 +**1.** Przetestuj takie same konfiguracje zbiorów danych i stopni wielomianu
 +
 +Podział jest losowy. Może się zdarzyć, że w danym losowaniu osiągniemy nie najlepszy podział
 +Można oczywiście ustawić seed i otrzymać powtarzalne wyniki (np. seed =3 wydaje się całkiem dobry).
 +
 +**2.** Wróć do poprzedniego rozwiązania
 +Stały podział może być całkiem dobry, jeżeli wcześniej dane zostały losowo pomieszane. Jest to częste podejście przy publikacji zbiorów testowych.
 +
 +Dodaj przed podziałem następujący kod i porównaj wyniki:
 +
 +<code java>
 +df = df.orderBy(org.apache.spark.sql.functions.rand(3));
 +</code>
 +
 +**3.** Zbierz w tabelce metryki dla wszystkich sposobów ustalania podziału 
 +
 +
 + 
  
ed/lab_04.txt · Last modified: 2024/03/21 02:25 by pszwed
CC Attribution-Share Alike 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0