Table of Contents
Laboratorium 3: Regresja liniowa
Zbiory danych
- xy-001 $f_{true}=2.37x+7$
- xy-002 $f_{true}=-1.5x^2+3x+4$
- xy-003 $f_{true}=-1.5x^2+3x+4$
- xy-004 $f_{true}=-10x^2+500x-25$
- xy-005 $f_{true}=(x+4)(x+1)(x-3)$
- xy-006 box
- xy-007 circle
- xy-008 fat-ellipse
- xy-009 ellipse
- xy-010 ellipse-outliers
1. Przetwarzamy zbiór xy-001
1.1. Ładowanie i przetwarzanie wstępne
1. Załaduj zbiór danych i wyświetl zawartość
2. Algorytm regresji działa na danych numerycznych. Kolumny X
i Y
są danymi numerycznymi, ale wejściem dla algorytmu jest wektor cech. Dlatego X musi być przekonwertowane do postaci wektora.
Uzyj klasy VectorAssembler, a w szczególności metod:
setInputCols()
- jedyną kolumną do przekonwertowania jestX
setOutputCol(“features”)
- po konwersji kolumna z wektorami danych ma się nazywaćfeatures
transform()
do przekonwertowania danych
Oczekiwany wynik:
+--------+---------+----------+ | X| Y| features| +--------+---------+----------+ |0.581807| 3.930072|[0.581807]| |0.969903| 6.831824|[0.969903]| | 1.03564| 6.630985| [1.03564]| |1.284787| 6.558356|[1.284787]| |1.949874|15.588728|[1.949874]| +--------+---------+----------+ only showing top 5 rows root |-- X: double (nullable = true) |-- Y: double (nullable = true) |-- features: vector (nullable = true)
1.2 Regresja
Typowy przebieg procesu uczenia to
- Definiowanie algorytmu i jego parametrów - klasa
LinearRgression
- Budowa modelu - klasa
LinearRegressionModel
- Ocena modelu (w tym przypadku tylko dla zbioru uczącego na podstawie danych zebranych w obiekcie klasy
LinearRegressionTrainingSummary
)
1. Dodaj poniższy kod
LinearRegression lr = new LinearRegression() .setMaxIter(10) .setRegParam(0.3) .setElasticNetParam(0.8) .setFeaturesCol("features") .setLabelCol("Y"); // Fit the model. LinearRegressionModel lrModel = lr.fit(df_trans);
2. Wydrukuj współczynniki regresji za pomocą metod + lrModel.coefficients()
oraz lrModel.intercept()
3. Wyświetl informacje o przebiegu uczenia i metryki
LinearRegressionTrainingSummary trainingSummary = lrModel.summary(); System.out.println("numIterations: " + trainingSummary.totalIterations()); System.out.println("objectiveHistory: " + Vectors.dense(trainingSummary.objectiveHistory())); trainingSummary.residuals().show(100); System.out.println("MSE: " + trainingSummary.meanSquaredError()); System.out.println("RMSE: " + trainingSummary.rootMeanSquaredError()); System.out.println("MAE: " + trainingSummary.meanAbsoluteError()); System.out.println("r2: " + trainingSummary.r2());
4. Jakie metryki są wyświetlane. Co to są residuals
5 Wyświetl historię uczenia trainingSummary.objectiveHistory()
za pomocą poniższej funkcji:
static void plotObjectiveHistory(List<Double> lossHistory){ var x = IntStream.range(0,lossHistory.size()).mapToDouble(d->d).boxed().toList(); Plot plt = Plot.create(); plt.plot().add(x, lossHistory).label("loss"); plt.xlabel("Iteration"); plt.ylabel("Loss"); plt.title("Loss history"); plt.legend(); try { plt.show(); } catch (IOException e) { throw new RuntimeException(e); } catch (PythonExecutionException e) { throw new RuntimeException(e); } }
1.3 Wykres funkcji i danych
Napisz funkcję służącą do rysowania wykresów:
- danych
- przebiegu funkcji regresji
- opcjonalnie: $f_{true}$ - prawdziwej funkcji z której został wygenerowany zbiór danych
/** * * @param x - współrzedne x danych * @param y - współrzedne y danych * @param lrModel - model regresji * @param title - tytuł do wyswietlenia (może być null) * @param f_true - funkcja f_true (może być null) */ static void plot(List<Double> x, List<Double> y, LinearRegressionModel lrModel, String title, Function<Double,Double> f_true){
1. Rysowanie danych x,y jest proste
Plot plt = Plot.create(); plt.plot().add(x, y,"o").label("data");
2. Oblicz zakresy zmienności x
– zmienne xmin
i xmax
i wygeneruj listę punktów
var xdelta = 0.05*(xmax-xmin); var fx = NumpyUtils.linspace(xmin-xdelta,xmax+xdelta,100);
3. Dla wszystkich wartości w fx
:
- przekształć je do postaci jednoelemntowego wektora typu
DenseVector
https://spark.apache.org/docs/latest/api/java/org/apache/spark/ml/linalg/DenseVector.html - wywołaj
lrModel.predict()
z wektorem jako argumentem - zgromadź wartości na liście
fy
- najkrócej - strumieniem i map
Wyświetl:
plt.plot().add(fx, fy).color("r").label("pred");
Jeżeli f_true!=null
oblicz jej wartość dla każdego elementu fx
: f_true.apply(_x)
i zgromadź wynik na liście. Następnie wyświetl:
plt.plot().add(fx, fy_true).color("g").linestyle("--").label("$f_{true}$");
1.4 Potencjalny wpływ parametrów algorytmu
Zaimplementowany w Apache Spark algorytm liniowej regresji może:
- Ustawić wagę składników regularyzacji w funkcji straty, lub je pominąć co odpowiada setRegParam(0.0)
- Mieszać składniki regularyzacji L1 i L2 ustwiajac proporcje za pomocą
setElasticNetParam(alpha)
. Cytując dokumentację: Param for the ElasticNet mixing parameter, in range [0, 1]. For alpha = 0, the penalty is an L2 penalty. For alpha = 1, it is an L1 penalty.
1. Ile iteracji zaobserwowano, jeżeli ustawiono setRegParam(0.0)
2. Przetestuj dla wartości parametru regularyzacji 10,20,50,100
- Jak wyglądają wykresy (zamieść rysunki)
- Jak zmieniają się miary, np. współczynnik determinacji r2
2. Przetwarzamy kolejne zbiory
Dla kolejnych zbiorów danych:
- Wyświetl wykresy
- Wyznacz metryki i zbierz ich wartości w tabelce
3. Porównanie xy-002 i xy-004
3.1 Wyniki regresji dla xy-002
Użyj następującego kodu w języku Python, aby wyświetlić informacje statystyczne dotyczące wyznaczonych współczynników. W tym przypadku stosowana jest metoda OLS (ang. ordinary least squares, czyli czysta regresja bez regularyzacji $𝑤=[X^TX]^{-1}X^Ty$ ). Metoda wymaga dodania kolumny z jedynkami na początku tablicy z danymi.
import numpy as np import statsmodels.api as sm x,y = np.loadtxt('xy-002.csv',delimiter=',',unpack=True,skiprows=1) X_plus_one = np.stack( (np.ones(x.size),x), axis=-1) X_plus_one ols = sm.OLS(y, X_plus_one) ols_result = ols.fit() print(ols_result.summary())
OLS Regression Results ============================================================================== Dep. Variable: y R-squared: 0.933 Model: OLS Adj. R-squared: 0.933 Method: Least Squares F-statistic: 1370. Date: Sat, 09 Mar 2024 Prob (F-statistic): 2.10e-59 Time: 18:20:11 Log-Likelihood: -711.10 No. Observations: 100 AIC: 1426. Df Residuals: 98 BIC: 1431. Df Model: 1 Covariance Type: nonrobust ============================================================================== coef std err t P>|t| [0.025 0.975] ------------------------------------------------------------------------------ const 652.8037 60.627 10.768 0.000 532.491 773.116 x1 -74.3271 2.008 -37.012 0.000 -78.312 -70.342 ============================================================================== Omnibus: 11.135 Durbin-Watson: 0.062 Prob(Omnibus): 0.004 Jarque-Bera (JB): 7.706 Skew: -0.547 Prob(JB): 0.0212 Kurtosis: 2.191 Cond. No. 61.2 ==============================================================================
- Jaką wartość ma współczynnik determinacji?
- Jaki jest błąd standardowy wyznaczonych współczynników?
- W jakim zakresie mieszczą się z 95% wiarygodnością?