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
Last revision Both sides next revision
ed:lab_08 [2024/04/09 14:37]
pszwed [3.1 Przeanalizujemy informacje zebrane w training summary]
ed:lab_08 [2024/04/24 23:19]
pszwed [3. LogisticRegressionScores - ocena wyników]
Line 1: Line 1:
-====== Regresja logistyczna ======+====== Laboratorium 8 - regresja logistyczna ======
  
 Celem jest budowa modelu regresji logistycznej pozwalającej przewidywać, czy dany student zdał egzamin z języka C++ w pierwszym terminie. Celem jest budowa modelu regresji logistycznej pozwalającej przewidywać, czy dany student zdał egzamin z języka C++ w pierwszym terminie.
Line 14: Line 14:
  
 === Zbiory danych === === Zbiory danych ===
-  * {{ :ed:egzamin-cpp.csv |egzamin-cpp.csv}} - zanonimizowane wyniki zaliczeń/egzaminu z C i C++ w 2016 roku +  * {{ :ed:egzamin-cpp.csv |egzamin-cpp.csv}} - poddane anonimizacji wyniki zaliczeń/egzaminu z C i C++ w 2016 roku 
   * {{ :ed:grid.csv |grid.csv}} - kombinacje ocen    * {{ :ed:grid.csv |grid.csv}} - kombinacje ocen 
  
Line 88: Line 88:
 </code> </code>
  
-**2.** Regresja logistyczna wymaga, aby atrybutów wejściowe były typu numerycznego. Jets też metodą klasyfikacji binarnej (etykiety powinny mieć wartości 0 i 1)+**2.** Regresja logistyczna wymaga, aby atrybutów wejściowe były typu numerycznego. Jest też metodą klasyfikacji binarnej (etykiety powinny mieć wartości 0 i 1)
   * przekonwertuj datę  za pomocą funkcji ''unix_timestamp'' - nadaj nowej kolumnie nazwę ''timestamp''   * przekonwertuj datę  za pomocą funkcji ''unix_timestamp'' - nadaj nowej kolumnie nazwę ''timestamp''
   * Dodaj kolumnę ''Wynik'' będącą wynikiem testu, czy ''Egzamin>=3.0'' - użyj funkcji SQL IF()   * Dodaj kolumnę ''Wynik'' będącą wynikiem testu, czy ''Egzamin>=3.0'' - użyj funkcji SQL IF()
Line 110: Line 110:
 </code> </code>
  
-===== 2. Analiza działania algorytmu  =====+===== 2. LogisticRegressionAnalysis - analiza działania algorytmu  =====
  
 ==== 2.1 Budowa modelu i interpretacja współczynników ==== ==== 2.1 Budowa modelu i interpretacja współczynników ====
Line 139: Line 139:
 **3.** Zinterpretuj współczynniki równania regresji (napisz kod lub zamieść wykonane obliczenia). Pamiętaj, że timestamp jest wyrażony w sekundach. **3.** Zinterpretuj współczynniki równania regresji (napisz kod lub zamieść wykonane obliczenia). Pamiętaj, że timestamp jest wyrażony w sekundach.
  
-Poniższe wyniki były wygenerowane za pomocą kodu. W praktyce wynik nie zależy od daty...+Poniższe wyniki były wygenerowane programowo. W praktyce wynik nie zależy od daty...
 <code> <code>
 Wzrost OcenaC o 1 zwiększa logit o 0.719097, a szanse zdania razy 2.052578 czyli o 105.257821% Wzrost OcenaC o 1 zwiększa logit o 0.719097, a szanse zdania razy 2.052578 czyli o 105.257821%
Line 240: Line 240:
 Instrukcja ''df_predictions = df_predictions.repartition(1);'' jest opcjonalna. Jaka będzie postać wyjścia, kiedy zmienimy argument ''repartition'' - np. ustawimy 5. Instrukcja ''df_predictions = df_predictions.repartition(1);'' jest opcjonalna. Jaka będzie postać wyjścia, kiedy zmienimy argument ''repartition'' - np. ustawimy 5.
  
-===== 3. Ocena wyników =====+===== 3. LogisticRegressionScores - ocena wyników =====
  
-Napisz funkcję tarinAndTest, która:+Napisz funkcję trainAndTest, która:
  
   * dokona podziału na zbiór treningowy i testowy   * dokona podziału na zbiór treningowy i testowy
Line 249: Line 249:
  
 <code java> <code java>
-    static void trainAndTest(Dataset<Row> df){+    static LogisticRegressionModel trainAndTest(Dataset<Row> df){
         int splitSeed = 123;         int splitSeed = 123;
         Dataset<Row>[] splits = df.randomSplit(new double[]{0.7, 0.3},splitSeed);         Dataset<Row>[] splits = df.randomSplit(new double[]{0.7, 0.3},splitSeed);
Line 263: Line 263:
  
         LogisticRegressionModel lrModel = lr.fit(df_train);         LogisticRegressionModel lrModel = lr.fit(df_train);
 +        ... 
 +        return lrModel; 
 +    }
 </code> </code>
  
Line 341: Line 343:
 ==== 3.2 Dobór progu prawdopodobieństwa ==== ==== 3.2 Dobór progu prawdopodobieństwa ====
  
 +Krzywą ROC można wykorzystać do doboru progu prawdopodobieństwa. Patrz [[https://home.agh.edu.pl/~pszwed/wiki/lib/exe/fetch.php?media=med:med-w04.pdf|Wykład 4 slajd 27]]
  
 +**1.** Dobierzemy próg według miary //F-measure//. To będzie gdzieś tu:
 <code java> <code java>
 +Dataset<Row> df_fmeasures = trainingSummary.fMeasureByThreshold();
 +df_fmeasures.offset(35).show();
 </code> </code>
  
 +<code>
 ++-------------------+------------------+
 +|          threshold|         F-Measure|
 ++-------------------+------------------+
 +| 0.4627032508959811|0.8869565217391304|
 +| 0.4382847817892507|0.8793103448275861|
 +| 0.4034706528697256| 0.888888888888889|
 +| 0.3858997834933381|0.8813559322033898|
 +| 0.3461380134069699| 0.859504132231405|
 +| 0.3143853597224281|0.8524590163934427|
 +|0.19135299955580787|0.8455284552845529|
 +| 0.1472470120383692|0.8387096774193548|
 +|0.13010893832947723|             0.832|
 ++-------------------+------------------+
 +</code>
  
 +**2.** Wyznacz programowo najlepszy próg. 
 +  * Wpierw wyznacz maksymalną wartość F-measure (przykład kodu poniżej)
 +  * A następnie odpowiadającą jej wartość progu (używając ''where ... equalTo ... select...'')
 +  * W powyższej tabelce możesz sprawdzić, czy znalezione zostały właściwe wartości (oczywiście one zależą od sposobu podziału na zbiór treningowy i testowy, a więc ziarna ''seed''  
 +
 +<code java>
 +double maxFMeasure = df_fmeasures.select(functions.max("F-Measure")).head().getDouble(0);
 +</code>
 +
 +**3.** Ustaw próg klasyfikatora
 +
 +<code java>
 +lrModel.setThreshold(bestThreshold);
 +</code>
 +
 +==== 3.3 Ewaluacja na zbiorze testowym ====
 +
 +**1.** Wywołaj funkcję predykcji i skonfiguruj ewaluator
 +
 +<code java>
 +        Dataset<Row> predictions = lrModel.transform(df_test);
 +
 +        MulticlassClassificationEvaluator eval = new MulticlassClassificationEvaluator()
 +                .setLabelCol("Wynik")
 +                .setPredictionCol("prediction");
 +</code>
 +
 +**2.** Wyznacz:
 +  * accuracy
 +  * weightedPrecision
 +  * weightedRecall
 +  * f1   
 +
 +Oczekiwane są wartości rzędu 0.82-0.83
 +
 +Nazwy dostępnych metryk:
 +<code>
 +(f1|accuracy|weightedPrecision|weightedRecall|weightedTruePositiveRate| weightedFalsePositiveRate|weightedFMeasure|truePositiveRateByLabel| falsePositiveRateByLabel|precisionByLabel|recallByLabel|fMeasureByLabel| logLoss|hammingLoss)'
 +</code>
 +
 +
 +===== 4. LogisticRegressionGrid - tworzenie tabeli ocen =====
 +
 +Celem jest utworzenie tabeli ocen postaci, jak poniżej
 +
 +<code>
 ++--------------+------+----------+--------+--------+
 +|  ImieNazwisko|OcenaC|     DataC|OcenaCpp|   Wynik|
 ++--------------+------+----------+--------+--------+
 +|'Xxxxx Yyyyyy'  3.0|2016-01-17|     2.0|Nie zdał|
 +|'Xxxxx Yyyyyy'  3.0|2016-01-17|     3.0|Nie zdał|
 +|'Xxxxx Yyyyyy'  3.0|2016-01-17|     3.5|    Zdał|
 +|'Xxxxx Yyyyyy'  3.0|2016-01-17|     4.0|    Zdał|
 +|'Xxxxx Yyyyyy'  3.0|2016-01-17|     4.5|    Zdał|
 +|'Xxxxx Yyyyyy'  3.0|2016-01-17|     5.0|    Zdał|
 +|'Xxxxx Yyyyyy'  3.5|2016-01-17|     2.0|Nie zdał|
 +|'Xxxxx Yyyyyy'  3.5|2016-01-17|     3.0|Nie zdał|
 +|'Xxxxx Yyyyyy'  3.5|2016-01-17|     3.5|    Zdał|
 +|'Xxxxx Yyyyyy'  3.5|2016-01-17|     4.0|    Zdał|
 +
 +...
 +</code>
 +
 +**Uwaga:** wynik może się nieco różnić w zależności od konfiguracji, np. progu prawdopodobieństwa 
 +
 +**1.** Wytrenuje klasyfikator na zbiorze ''egzamin-cpp.csv''. Wykorzystuj kod z poprzedniej części, ustaw próg prawdopodobieństwa.
 +
 +**2.** Napisz funkcje
 +
 +<code java>
 +void addClassificationToGrid(SparkSession spark, LogisticRegressionModel lrModel)
 +</code>
  
 +która:
 +  * Wczyta zbiór danych ''grid.csv''
 +  * Przetworzy daty, tak aby stały się wartościami numerycznymi
 +  * Skonfiguruje VectorAssembler
 +  * Wywoła funkcję predykcji zmiennej ''lrMpdel''
 +  * Usunie nadmiarowe kolumny
 +  * Za pomocą funkcji ''IF()'' SQL lub zarejestrowanej funkcji użytkownika UDF dokona konwersji etykiet //0->Nie zdał// oraz //1->Zdał//
 +  * Wyświetli wynik
 +  * Zapisze w pliku ''grid-with-classification.csv'' 
ed/lab_08.txt · Last modified: 2024/04/24 23:20 by pszwed
CC Attribution-Share Alike 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0