---
# System prepended metadata

title: '[INTRO2BIGDATA] LAB03 NOTES'

---

# LAB 03: MACHINE LEARNING ON SPARK 

---

## I. NỘI DUNG ĐỀ BÀI

### 1. Giới thiệu về Machine Learning trên Big Data với Apache Spark

Cùng với sự gia tăng (phát triển) về quy mô và độ phức tạp của các bộ datasets (dữ liệu), việc tận dụng các frameworks tính toán phân tán như Apache Spark trở nên cực kỳ cần thiết. Học máy (Machine Learning) hiện đại trên dữ liệu lớn dựa vào kiến trúc có khả năng mở rộng của Spark (Spark's scalable architecture) và các engine thực thi được tối ưu hoá (optimized execution engine) (Catalyst và Tungsten) để xử lý việc huấn luyện và dự báo mô hình quy mô lớn (large-scale model) một cách hiệu quả. Trong bài lab này, nhóm sẽ khám phá ba cách triển khai cụ thể như sau:
* **Structured API Implementation:** Sử dụng DataFrame dựa trên API cấp cao (high-level DataFrame-based API structure) (spark.ml) để xây dựng và đánh giá mô hình một cách nhanh chóng.
* **MLlib RDD-Based Implementation:** Tận dụng các chức năng tích hợp sẵn của MLlib trên dữ liệu RDD (spark.mllib) để thực hiện các tác vụ học máy (machine learning), từ đó hiểu sâu hơn về cách Spark xử lý RDD.
* **Low-level Operations Implementation:** Tự phân rã thủ công các thuật toán Machine Learning (ML algorithms) thành các phép toán RDD đơn giản, cơ bản (không sử dụng MLlib), qua đó nâng cao tư duy lập trình song song và hiểu thêm về tính toán phân tán.

#### 1.1. Yêu cầu (Requirements)

Sau khi hoàn thành bài lab thực hành này, nhóm sẽ có thể:
* Thiết kế và triển khai các pipeline học máy sử dụng API structured ở mức độ cấp cao (high-level API Structured)
* Làm việc quen tay với MLlib của Apache Spark trên dữ liệu RDD để sử dụng và tối ưu việc sử dụng các hàm machine learning (học máy) được tích hợp sẵn.
* Phân rã (Decompose) các thuật toán ML (ML algorithms) thành các phép biến đổi RDD cấp thấp (low-level RDD transformations) để hiểu sâu hơn về cách các thuật toán đó có thể được tối ưu và sử dụng song song hoá lẫn nhau.
* Đánh giá và so sánh hiệu suất (performance) và độ phức tạp (complexity) của từng cách tiếp cận triển khai.

#### 1.2. Machine Learning cho môi trường tính toán phân tán (Machine Learning Under Parallelized Settings)

Mặc dù Structured API (spark.ml) cung cấp một giao diện, thân thiện, ở mức độ cao cấp cho người dùng, bài lab này cũng yêu cầu chúng ta làm việc với:
* **MLlib RDD-Based Implementation:** Phương pháp này sử dụng các hàm tích hợp sẵn của MLlib trên dữ liệu RDD, mang lại cái nhìn sâu sắc hơn về các mô hình của học máy phân tán (distributed ML).
* **Low-Level Operations Implementation:** Nhóm sẽ tự thực hiện các thuật toán học máy sử dụng các phép biến đổi RDD cơ bản, giúp hiểu sâu cách phân rã các nhiệm vụ ML phức tạp thành các phép toán có khả năng mở rộng như map, reduce, filter, ... Sự tìm hiểu sâu này cũng củng cố tư duy xử lý dữ liệu lớn của nhóm.

### 2. Example of Linear Regression (Ví dụ về Hồi quy Tuyến tính)

Trong ví dụ này, nhóm sẽ xây dựng một mô hình hồi quy tuyến tính (linear regression) đơn giản để dự đoán giá nhà ở Boston bằng cách sử dụng 3 hướng tiếp cận khác nhau. Mỗi phương pháp sẽ minh hoạ cách tận dụng các API ngày càng phát triển của Spark cho các tác vụ học máy.

#### 2.1. Structured API Implementation Example (Ví dụ triển khai bằng Strutured API)

Bằng cách sử dụng API cấp cao dựa trên DataFrame (high-level DataFrame-based API) từ spark.ml, thực hiện theo các bước sau:

* **Data Preparation** (Chuẩn bị dữ liệu)

```python=
data = spark.read.csv("boston_house_price.csv", header = True, inferSchema = True)
```

* **Data Pre-processing** (Tiền xử lý dữ liệu)

```python=
from pyspark.ml.feature import VectorAssembler
# Use all columns except MEDV as feature
input_cols = [col for col in data.columns if col != "MEDV"]
# Assemble feature columns into a single vector 
assembler = VectorAssembler(inputCols=input_cols, outputCol="features")
assembled_data = assembler.transform(data).select("features", "MEDV")
```

* **Train-Test Splitting** (Tách dữ liệu train và dữ liệu test)

```python=
# Split the dataset into training and testing sets
train, test = assembled_data.randomSplit([0.8, 0.2], seed = 42)
```

* **Train the Linear Regression model using MLlib** (Huấn luyện mô hình Hồi quy Tuyến tính bằng cách sử dụng MLlib)

```python=
from pyspark.ml.regression import LinearRegression
# Initialize the Linear Regression estimator
lr = LinearRegression(featuresCol = "features", labelCol="MEDV")
model = lr.fit(train)
```

* **Evaluation the obtained model** (Đánh giá mô hình vừa thu được): Sử dụng đối tượng **`summary`**

```python=
summary = model.summary
print("Coefficients:", model.coefficients)
print("Intercept:", model.intercept)
print("RMSE:", summary.rootMeanSquaredError)
print("R^2:", summary.r2)
```

* **Kết quả mẫu dự kiến** (Sample expected output)

```tex=
y = Wx+b
Coefficients: [0.45, 1.23, -0.89, ...] # One coefficient per feature -> trọng số W (ma trận trọng số) (biến độc lập)
Intercept: 2.34 (hệ số chặn b)
RMSE: 4.56
R²: 0.78 (hệ số tương quan)
```
(Độ lỗi RootMSE = $\sqrt{\text{MSE}}$)

#### 2.2. MLlib RDD-Based Implementation Example

Cách tiếp cận này tận dụng các hàm hồi quy tuyến tính tích hợp sẵn của Spark MLlib trên dữ liệu RDD.

* **Load a file to a RDD data** (Tải một file vào dữ liệu RDD)
    * Đọc và load file CSV gốc dưới dạng text file.

```python=
lines = sc.textFile("boston_house_price.csv")
header = lines.first()
data = lines.filter(lambda line: line != header)
```

* **Parsing the data file** (Phân tách file dữ liệu): Phân tách mỗi dòng thành các phần bằng dấu phẩy và chuyển đổi các phần tử sang kiểu float.

```python=
parsed = data.map(lambda line: [float(x) for x in line.split(",")])
```

* **Data Pre-processing** (Tiền xử lý dữ liệu): Chuyển đổi dữ liệu đã phân tách thành dữ liệu RDD gồm các đối tượng `LabeledPoint` (`LabeledPoint(label, features)`), với các đặc trưng dưới dạng vector dày (dense vector).

```python=
from pyspark.mlib.regression import LabeledPoint
from pyspark.mllib.linalg import Vectors
rdd_data = parsed.map(lambda cols: LabeledPoint(cols[-1], Vectors.dense(cols[:-1])))
```

* **Training the Linear Regression model** (Huấn luyện mô hình Hồi quy Tuyến tính): huấn luyện mô hình hồi quy tuyến tính bằng cách sử dụng thuật toán **Stochastic Gradient Descent** (SGD).

```python=
from pyspark.mllib.regression import LinearRegressionWithSGD
Model_rdd = LinearRegressionWithSGD.train(rdd_data, iterations = 100, step = 0.0001)
```

* **Evaluate the obtained model** (Đánh giá mô hình vừa tìm được): bằng cách tính toán **Mean Squared Error**.

```python=
valuesAndPreds = rdd_data.map(lambda lp: (lp.label, model_rdd.predict(lp.features)))
mse = valuesAndPreds.map(lambda pl: (pl[0] - pl[1])**2).mean()
print("Mean Squared Error = ", mse)
```

* **Kết quả mẫu đầu ra dự kiến** (Sample expected output)

```python=
Mean Squared Error = 18.25
```

#### 2.3. Low-level Operations Implementation Example

Trong phương pháp thủ công này, nhóm sẽ triển khai hồi quy tuyến tính sử dụng các phép biển đổi RDD cơ bản mà không cần dùng hàm tích hợp của MLlib.

* **Read and prase the data into RDD** (Đọc và phân tích dữ liệu thành RDD)

```python=
# Load the CSV file as a text file and filter out the header
lines = sc.textFile("boston_house_price.csv")
header = lines.first()
data = lines.filter(lambda line: line != header)
# Parse each line: split by comma and convert each element to float.
# Assume that the last column is the label (MEDV) and all previous columns are features.
parsedData = data.map(lambda line: [float(x) for x in line.split(",")])
# Create an RDD where each record is a tuple: (features as list, label)
rdd_data = parsedData.map(lambda cols: (cols[:-1], cols[-1]))
```

* **Implement the Linear Regression model using low-level operations** (Triển khai mô hình Hồi quy Tuyến tính (Linear Regression) bằng cách sử dụng các phép toán ở mức độ cấp thấp)

```python=
# Initialize weights manually (number of features equals the length of the features list)
num_features = rdd_data.first()[0] # sample features list
initial_weights = [0.0] * len(num_features)
learning_rate = 0.0001
# Define a function to compute prediction as the dot product of weights and feature vector
def predict(features, weights):
    return sum(w * f for w, f in zip(weights, features))
```

* **Compute the prediction as well as gradient of the regressor for a single step** (Tính dự đoán và gradient của bộ hồi quy cho 1 bước duy nhất): Đối với mỗi điểm dữ liệu, tính `(prediction - label) * feature_vector`, sau đó tính tổng tất cả các điểm dữ liệu

```python=
gradients = rdd_data.map(lambda x: [(predict(x[0], initial_weights) - x[1]) * f for f in x[0]]).reduce(lambda a, b: [x + y for x, y in zip(a, b)])
```

* **Perform the gradient update for this step** (Cập nhật trọng số bằng một bước gradient descent): sử dụng công thức `new_weight = old_weight - learning_rate * gradient`

```python=
updated_weights = [w - learning_rate * grad for w, grad in zip(initial_weights, gradients)]
```

* **Check the weights after updated by the above gradient descent step** (Kiểm tra trọng số sau khi cập nhật ở từng bước)

```python=
print("Updated Weights:", updated_weights)
```

* **Kết quả mẫu đầu ra dự kiến** (Sample expected output): mỗi giá trị trọng số tương ứng với một đặc trưng

```python=
Updated Weights: [0.12, -0.03, 0.07, ...]
```

### 3. Đặt vấn đề (Problem Statements)

Trong bài lab thực hành này, nhóm sẽ giải quyết hai bài toán cơ bản của machine learning (học máy): **phân loại (classification)** và **hồi quy (regression)**. Những bài toán này sẽ là nền tảng của việc nghiên cứu và thực tiễn học máy (machine learning), và giải quyết chúng trên các nền tảng dữ liệu lớn như Spark thể hiện tính scalability and tính ứng dụng thực tế của việc học phân tán. Thông qua việc thực hiện các nhiệm vụ này, nhóm không chỉ học cách xây dựng mô hình sử dụng API ở mức high-level mà còn làm sâu sắc thêm hiểu biết về các mô hình tính toán phân tán cơ bản thông qua việc triển khai thực hành sử dụng các hàm dựa trên RDD của MLlib và các phép toán thủ công ở mức low-level.

Những ngôn ngữ lập trình cho phép là: **Python** và **Scala**. Tất nhiên, giống với những bài labs trước, bất kỳ teams nào có phiên bản triển khai thuật toán bằng Scala đều sẽ được thưởng điểm bonus cho các bài toán tương ứng. Vui lòng tham khảo tiêu chí chấm điểm ở phần cuối để biết thêm chi tiết.

Datasets:
* **Classification:** Credit Card Fraud Detection – Available at: [link here](https://www.kaggle.com/mlg-ulb/creditcardfraud)
* **Regression:** New York City Taxi Trip Duration – Available at: [link here](https://www.kaggle.com/c/nyc-taxi-trip-duration/data)

#### 3.1. Bài toán phân loại với Logistic Regression (Classification with Logistic Regression)

Bài toán **`Phân Loại` (Classification)** là một nhiệm vụ cốt lõi của tác vụ học máy, liên quan đến việc gán nhãn cho các mẫu. Hồi quy Logistic (Logistic Regression) là một thuật toán cơ bản được sử dụng cho các phân loại nhị phân. Trong bối cảnh của dữ liệu lớn, việc phát triển một bộ phân loại (classifier) có khả năng mở rộng (scalable) bằng cách sử dụng Spark thể hiện cách mà làm thế nào để dữ liệu lớn có thể được xử lý song song đồng thời đảm bảo việc đánh giá hiệu suất đáng tin cậy.

##### 3.1.1. Structured API Implementation (High-Level)

**Mục tiêu:** Sử dụng API Structured ở mức high-level của Spark (Spark's high-level Structured API) (spark.ml) để xây dựng một mô hình hồi quy logistic.
* Tiền xử lý dữ liệu một cách thích hợp, chính xác (e.g., xử lý giá trị bị thiếu hoặc chuẩn hoá các đặc trưng nếu cần).
* Sử dụng `VectorAssembler` (hoặc bộ chuyển đổi mức high-level tương đương) để kết hợp các đặc trưng dạng số (numeric) thành một cột vector đơn.
* Tối ưu và sử dụng bộ ước lượng (estimator) `LogisticRegression`, sau đó, kiểm tra các hệ số (coefficients), hệ số chặn (intercept) và các chỉ số đánh giá như accuracy, AUC, precision, và recall.
* Cân nhắc chia bộ dữ liệu thành thành tập train và tập test để đánh giá hiệu suất mô hình.

##### 3.1.2. MLlib RDD-Based Implementation

**Mục tiêu:** Tận dụng các hàm tích hợp sẵn của MLlib trên tập dữ liệu RDD để triển khai hồi quy logistic.
* Chuyển đổi bộ dữ liệu đã tiền xử lý thành RDD gồm các đối tượng `LabeledPoint`.
* Sử dụng các hàm hồi quy logistics của MLlib (ví dụ, `LogisticRegressionWithSGD` hay `LogisticRegressionWithLBFGS`) để huấn luyện mô hình.
* Thực nghiệm với các tham số (parameters) như số vòng lặp (number of iterations) và tốc độ học (step-size / learning rate) để cải thiện sự hội tụ.
* Sau quá trình huấn luyện, tính toán các chỉ số đánh giá (metrics) - hoặc bằng các công cụ được tích hợp sẵn hoặc tự so sánh dự đoán với nhãn thực tế một cách thủ công.
* Ghi lại bất kỳ quan sát nào về hiệu suất của phương pháp này so với hướng tiếp cận sử dụng Structured API.

##### 3.1.3. Low-Level Operations Implementation

**Mục tiêu:** Tự triển khai một cách thủ công hồi quy logistic bằng cách sử dụng các phép biển đổi RDD cơ bản mà không dựa vào các hàm tích hợp sẵn của MLlib.
* Phân tách dữ liệu và tạo một RDD mà mỗi bản ghi (records) chứa một vector đặc trưng (dưới dạng danh sách float) và nhãn (label).
* Viết các hàm riêng của bạn để tính toán tích vô hướng giữa vector trọng số và vector đặc trưng, sau đó áp dụng hàm sigmoid để tạo xác suất và suy ra gradient (đạo hàm) tại mỗi điểm dữ liệu.
* Triển khai từng bước cập nhật gradient descent đơn giản trong kịch bản nhiều vòng lặp để minh hoạ cơ chế cập nhật.
* So sánh các dự đoán tính toán bằng phương pháp low-level với các kết quả từ các cách triển khai bằng Structured API và MLlib.
* Giải thích các lựa chọn của nhóm (e.g., learning rate, iteration count) và thảo luận về bất kỳ thử thách nào gặp phải khi phân rã thuật toán.

#### 3.2. Bài toán hồi quy với Cây quyết định (Regression with Decision Tree)

Bài toán **`Hồi quy` (Regression)** liên quan đến việc dự đoán một biến phản hồi liên tục. Cây quyết định (decision tree) cung cấp một mô hình dễ giải thích có thể nắm bắt các quan hệ phi tuyến. Sử dụng cây quyết định trên dữ liệu lớn cho thấy cách Spark có thể phân vùng dữ liệu và xây dựng các mô hình song song có khả năng mở rộng một cách hiệu quả.

##### 3.2.1. Structured API Implementation (High-Level)

**Mục tiêu:** Sử dụng API Structured của Spark ở mức high-level (spark.ml) để xây dựng bộ điều chỉnh (regressor) cây quyết định.
* Tiền xử lý bộ dữ liệu bằng cách hợp nhất các đặc trưng dạng số thành một vector sử dụng các bộ chuyển đổi (transformers) ở mức high-level.
* Huấn luyện một mô hình `DecisionTreeRegressor`, điều chỉnh các tham số như độ sâu tối đa của cây, và độ tạo nhiễu (impurity (e.g., variance)) để kiểm soát độ phức tạp của mô hình.
* Trích xuất và phân tích cấu trúc cây và độ quan trọng của các đặc trưng để hiểu các quyết định của mô hình.
* Đánh giá mô hình bằng cách sử dụng các độ đô (metrics) như RMSE và $R^2$ trên bộ dữ liệu test.

##### 3.2.2. MLlib RDD-Based Implementation

**Mục tiêu:** Triển khai một mô hình cây quyết định hồi quy bằng cách sử dụng các hàm tích hợp sẵn của MLlib trên dữ liệu RDD.
* Chuyển đổi dữ liệu của nhóm thành RDD gồm các đối tượng `LabeledPoint`.
* Huấn luyện mô hình cây quyết định bằng cách sử dụng các hàm MLlib có sẵn cho bài toán hồi quy.
* Chú ý đến các tham số (parameters) xây dựng cây để xử lý quy mô của bộ dữ liệu.
* Tính toán các chỉ số độ đo hiệu suất (performance metrics) như RMSE và so sánh chúng vơí kết quả thu được từ API Structured.
* Đưa ra nhận xét (insights) về bất kỳ sự khác biệt nào quan sát được giữa hai hướng tiếp cận.

##### 3.2.3. Low-Level Operations Implementation

**Mục tiêu:** Mô phỏng thủ công logic cây quyết định bằng các phép toán RDD cơ bản mà không dựa vào các hàm estimator có sẵn của MLlib.
* Để đơn giản, hãy xem xét triển khai một cây quyết định truyền thống có độ sâu cố định, trong đó bạn có thể tìm hiểu các thuật toán xây dựng cây phổ biến.
* Cung cấp ví dụ dự đoán cho một vài trường hợp kiểm thử để minh họa cho triển khai low-level của nhóm.
* Thảo luận các thách thức khi mở rộng cách tiếp cận này cho các cây có độ sâu lớn hơn cũng như nhiều cây trong một tập hợp (a forest) -> random forest.

### 4. Hướng dẫn nộp bài (Submission Guideline)

Bài lab này yêu cầu nộp theo nhóm, trong đó công việc của các thành viên trong nhóm được tập hợp vào một thư mục duy nhất và chỉ một đại diện có thể nộp thư mục này lên Moodle. Thư mục nộp bài chứa một thư mục duy nhất có tên <RepresentativeID>, trong đó RepresentativeID là mã số sinh viên của thành viên đầu tiên (theo danh sách nhóm đã đăng ký). Cấu trúc bên trong như sau:
    
```tex=
<RepresentativeID>
├── docs
│   ├── Report.pdf       # Bao gồm phương pháp, giải thích chi tiết và ảnh chụp màn hình kết quả
│   ├── drive_link.txt   # Chứa đường dẫn Google Drive với kết quả dự đoán của tất cả các bài tập
│
├── src
│   ├── Classification
│   │   ├── Structured_API   # Thư mục mã cho Triển khai Structured API
│   │   ├── MLlib_RDD_Based  # Thư mục mã cho Triển khai MLlib RDD-Based
│   │   └── Low_Level        # Thư mục mã cho Triển khai Thao tác cấp thấp
│   ├── Regression
│   │   ├── Structured_API   # Thư mục mã cho Triển khai Structured API
│   │   ├── MLlib_RDD_Based  # Thư mục mã cho Triển khai MLlib RDD-Based
│   │   └── Low_Level        # Thư mục mã cho Triển khai Thao tác cấp thấp
│
└── README.md  # (Tùy chọn) Hướng dẫn chạy mã của bạn
```
    
File `drive_link.txt` chứa một liên kết đến thư mục Google Drive được tổ chức theo cấu trúc như mô tả bên trên. Tất nhiên, bất kỳ chỉnh sửa nào sau thời hạn đã quy định trên Moodle đều sẽ làm vô hiệu kết quả của nhóm. Cấu trúc bên trong thư mục Google Drive được tổ chức như sau:
    
```text=
<RepresentativeID>
├── <Classification/Regression>_Structured.csv
├── <Classification/Regression>_MLlib.csv
└── <Classification/Regression>_Low_level.csv
```
    
### 5. Tiêu chí chấm điểm
    
Tiêu chí chấm điểm cho cả hai bài toán trong phần Đề bài được tóm tắt trong bảng dưới đây, với mỗi bài toán chiếm 5.25 điểm:
    
| **Accomplished Requirements**                                          | **Points** |
| ---------------------------------------------------------------------- |:----------:|
| **High-level Structured API**                                          |  **1.25**  |
| Tải thành công bộ dữ liệu                                              |    0.25    |
| Tiền xử lý dữ liệu (bao gồm phân chia train-test)                      |    0.25    |
| Huấn luyện và đánh giá mô hình thành công                              |    0.25    |
| Báo cáo chi tiết                                                       |    0.25    |
| Triển khai bằng Scala                                                  |    0.25    |
| **MLlib RDD-Based Implementation**                                     |  **2.0**   |
| Tải thành công bộ dữ liệu                                              |    0.25    |
| Thành công phân tách bộ dữ liệu                                        |    0.25    |
| Tiền xử lý dữ liệu (bao gồm phân chia train - test)                    |    0.25    |
| Huấn luyện mô hình thành công                                          |    0.25    |
| Đánh giá mô hình thành công                                            |    0.25    |
| Báo cáo chi tiết                                                       |    0.25    |
| Hiệu suất mô hình của nhóm tương đương với hiệu suất mô hình của MLlib |    0.25    |
| Triển khai bằng Scala                                                  |    0.25    |
| **Low-Level Operations**                                               |  **2.0**   |
| Tải bộ dữ liệu thành công                                              |    0.25    |
| Thành công phân tách bộ dữ liệu                                        |    0.25    |
| Tiền xử lý dữ liệu (bao gồm phân chia train-test)                      |    0.25    |
| Thành công huấn luyện mô hình                                          |    0.25    |
| Thành công đánh giá mô hình                                            |    0.25    |
| Báo cáo chi tiết, bao gồm phân công nhiệm vụ của các thành viên        |    0.25    |
| Hiệu suất mô hình tương đương với hiệu suất mô hình của MLlib          |    0.25    |
| Triển khai bằng Scala                                                  |    0.25    |
| **Tổng số điểm cho mỗi bài toán**                                      |  **5.25**  |


### 6. Ghi chú (Notes)
    
Nhóm phải tuân thủ nghiêm ngặt cấu trúc thư mục ở trên và nén toàn bộ thư mục vào một file ZIP có tên <RepresentativeID>.zip, đây là file cuối cùng để nộp lên Moodle.
    
Xin lưu ý:
* Đảm bảo mã của bạn được chú thích rõ ràng.
* Bao gồm tất cả các file cần thiết, nhật ký và ảnh chụp màn hình để xác minh việc chạy thành công.
* Nếu mỗi nhiệm vụ được thực hiện trong các môi trường phức tạp hoặc ngôn ngữ lập trình khác nhau, hãy nhớ cung cấp hướng dẫn chạy cho từng nhiệm vụ nếu cần.
* Các thành viên trong nhóm chịu trách nhiệm đảm bảo tính chính trực của bài nộp; bất kỳ hành vi gian lận hoặc đạo văn nào bị phát hiện sẽ khiến cả nhóm bị điểm 0 cho tất cả các lab (tức là nếu một thành viên bị phát hiện gian lận trong một lab thì điểm của tất cả bốn lab của tất cả thành viên trong nhóm đó sẽ bị tính 0).
    
Các điểm lưu ý trong lab:
* Lab03 dời deadline về ngày chủ nhật 24.08.2025
* Sử dụng Spark + RDD (Low-Level) + MLlib (Medium-Level) + Structured API (High-Level)
* Không dùng Scala sẽ là 10 (tổng điểm là 10.5)
* Structured API -> Dùng DataFrame + MLlibs (Đánh giá trên MLlibs trên các tham số metrics nhất định -> dùng đồng nhất metrics) ... (Đánh giá so sánh ...)
* Bằng hoặc tốt hơn tất cả metrics của các level trước (data này hơi bias)
* Bắt đầu từ lab 02 sẽ dùng script đánh giá (code tương tự nhau -> 0đ) dựa theo code các nhóm trong lớp
* Bắt đầu từ lab 03 + 04 còn dùng thêm script đánh giá từ các bài của các nhóm lớp kỳ trước
* Script ko quan tâm đến tên biến mà quan tâm đến workflows -> nên hãy đừng paraphase variable.
* MLlib -> đọc file và xử lý file bằng RDD -> Các nhóm ko dùng Spark.read_csv() ở 2.2 và 2.3 (phải dùng RDD chứ ko dùng DataFrame)
* Script check cả logic chứ ko chỉ check tên biến.
* MLlib -> dùng các công cụ hỗ trợ của MLlib ...
* Low-level phải dùng RDD ko dùng Spark DataFrame
* 2.1 -> được dùng Spark DataFrame và MLlib
* 2.2 -> ko được Spark DataFrame -> dùng Spark RDD + MLlib
* 2.3 -> ko được dùng Spark DataFrame + MLlib -> chỉ dùng Spark RDD
* Dữ liệu Dataset đã ghi trong report -> dữ liệu hơi bias
* Rút kinh nghiệm dữ liệu nộp có thể output hơn 20MB trên Moodle + ko compile + biến thành java (chỉ dùng file code thuần)
* Dùng duy nhất trên một môi trường
* Report: nhớ trình bày công thức cho mỗi mô hình (training + inference + metrics) + trình bày cách đi từ công thức đó thành operations tương ứng + xây model cho low-level operations (chú ý: phần MLlib + Structured API ko bắt buộc trình bày công thức nhưng phần RDD low-levl phải trình bày công thức (công thức huấn luyện + inference + metrics) -> trình bày cách chuyển công thức thành low-level operations tương ứng)
* Ko trình bày code trong report mà chỉ trình bày workflows.
* Nếu như setup môi trường phức tạp thì phải hướng dẫn trong README.md
* Đọc và xử lý file RDD -> MLlib RDD-Based + Low-level Operations
* T6 tuần sau up xong Lab04 -> Deadline: 22.08.2025 -> 02.09.2025 (xàm lồn vãi cặc)

---

## II. QUẢN LÝ DỰ ÁN

### 1. Tài nguyên dự án

* Google Drive: [link here](https://drive.google.com/drive/folders/1qBFkBOqqKHCSFa9W3-reo8jUKvCCywy3?usp=sharing)
* drive_link.txt: [link here](https://drive.google.com/drive/folders/1hgkhH43W5Yspd2CVOq7tsZSf62cAsmvI?usp=sharing)
* Report: [link here](https://www.overleaf.com/2428873498qzmmsqpqrzvw#5a57ef)
* Github: [link here](https://github.com/PhuocPhat1005/LAB03-BIGDATA-ML-On-Spark.git)

### 2. Phân công dự án

|   MSSV   |    Họ và Tên    | Công việc được giao                                       | Mức độ hoàn thành |
|:--------:|:---------------:|:--------------------------------------------------------- |:-----------------:|
| 22127174 |  Ngô Văn Khải   | **[Regression]** Low-level Operations Implementation          |      $100\%$      |
| 22127208 | Nguyễn Anh Khôi | **[Classification]** MLlib RDD-Based Implementation           |      $100\%$      |
|          |                 | **[Classification]** Low-level Operations Implementation      |      $100\%$      |
| 22127260 |  Bùi Công Mậu   | **[Regression]** High-level Strutured API Implementation      |      $100\%$      |
|          |                 | **[Regression]** MLlib RDD-Based Implementation               |      $100\%$      |
| 22127322 |  Lê Phước Phát  | **[Classification]** High-level Structured API Implementation |      $100\%$      |


### 3. Quy trình dự án

#### 3.1. Classification

##### 3.1.1. Structured API Implementation (High-Level)
    
Điền nội dung ở đây ...
    
##### 3.1.2. MLlib RDD-Based Implementation
    
Điền nội dung ở đây ...

##### 3.1.3. Low-Level Operations Implementation
    
Điền nội dung ở đây ...

#### 3.2. Regression

##### 3.2.1. Structured API Implementation (High-Level)
    
Điền nội dung ở đây ...
    
##### 3.2.2. MLlib RDD-Based Implementation

Điền nội dung ở đây ...

##### 3.2.3. Low-Level Operations Implementation

Điền nội dung ở đây ...

## III. GIẢI ĐÁP THẮC MẮC

### Câu hỏi 01
    
:::info
Dạ Thầy @Huỳnh Lâm Hải Đăng cho em hỏi là chỗ tiêu chí em tô xanh, hình như là phải implement sao cho kết quả giống với High-level structured API phải không ạ

![image](https://hackmd.io/_uploads/r1Uy8U7Kxx.png)
:::
    
**Answer**
    
:::spoiler
Chào bạn, chỗ đó thầy có nói lúc meeting là kết quả của nhóm khi implement lại phải bằng hoặc cao hơn structured API trên tất cả metrics nhé
:::


### Câu hỏi 02
    
:::info
Dạ thầy cho em hỏi là implement lại nghĩa là mình code cho Structured API sao thì mình chuyển sang MLlib RDD-based implement tương tự, chỉ experiment parameters để  improve convergence thôi hay là mình được code thêm để cải thiện model cho MLlib RDD-based vậy thầy?
:::
    
**Answer**
    
:::spoiler
chào bạn, bạn có thể code thêm cải thiện model nếu làm chay không match được performance, đương nhiên là trên cùng flow preprocess nhé chứ structured bạn không preprocess mà vô rdd bạn preprocess thì hơn là đương nhiên đó
:::

### Câu hỏi 03

:::info
dạ thầy ơi cho em hỏi hồi lúc meeting cho bài lab 3 thì thầy có bảo là tất cả metrics của rdd và low level phải cao hơn của structured api thì có nhất thiết ko ạ hay chỉ cần ví dụ nhóm chọn 3 metrics thì 2 trong 3 cao hơn so với structured thôi thì có đc ko ạ  
:::
    
**Answer**
    
:::spoiler
chào bạn, do data hơi bias nên việc chỉnh hyperparameter để để RDD outperforms Structured trên 1 2 metrics là rất bình thường đó bạn. Thành ra là trên tất cả metrics mà bạn dùng nhé
:::
    
### Câu hỏi 04

:::info
Dạ Thầy @Huỳnh Lâm Hải Đăng ơi, mình được chạy cờ master local[*] khi chạy spark không ạ
:::
    
**Answer**

:::spoiler
miễn sao lúc các thầy chấm trên hadoop của các thầy thì code nhóm chạy worker là được nha em
:::

### Câu hỏi 05

:::info
Dạ Thầy @Huỳnh Lâm Hải Đăng ơi cho em hỏi ạ, 
Ở phần High Level API, trong bước preprocessing, em muốn làm thêm một vài bước A,B,C để xử lý dữ liệu riêng, điều này là để giảm accuracy xuống(do em thấy accuracy này quá cao và cải thiện nó sẽ hơi khó), và điều này cũng sẽ làm tăng precision lên chứ không làm giảm hết các metrics

Và trong MLlib RDD thì em cũng tiền xử lý y chang vậy, nhưng em xài thêm một số thứ khác bên ngoài như 1 model M nào đó(nhưng model chính để train vẫn là Logistic regression) để cải thiện số

thì thầy cho em hỏi là em có được quyền làm như 2 điều trên không ạ
    
Dạ theo như flow giữa em và cái nhận xét trên thì nó giống ạ. Nhưng mà do em thấy đề bài chỉ ghi là chỉ được xài "LogisticRegressionWithSGD or LogisticRegressionWithLBFGS", mà em muốn xài thêm 1 model khác để hỗ trợ nên em mới hỏi thêm ạ.

Ngoài ra thì, ở ý đầu tiên của em, em muốn là giảm accuracy xuống (nhưng precision sẽ tăng), thì em không biết là nó có vi phạm cái tiêu chí là "cải thiện model" không nên em mới hỏi ạ
:::

**Answer**

:::spoiler
nếu vẫn là logistics trong MLlib thì vẫn được nhé bạn còn preprocess thì miễn là cả 2 theo cùng flow là được rồi. Bản chất của 0.25 điểm này là mong muốn các bạn đi vào cái thư viện MLlib xem nó làm gì mà đạt kết quả tốt như vậy rồi reproduce thôi
:::
    
### Câu hỏi 06

:::info
Dạ, nếu em muốn sử dụng thêm model Linear Regression để tạo thêm 1 thứ j đó để hỗ trợ cải thiện metrics thì có được ko ạ Thầy
Linear Regression chỉ là ví dụ thôi ạ
:::
    
**Answer**

:::spoiler
Nếu bạn dùng linear reg để tạo thêm feature chẳng hạn thì xem như là feature engineering trong preprocessing nên bên structured API cũng phải làm tương tự vậy đó
:::

## IV. TÀI LIỆU THAM KHẢO

[1] Điền tài liệu ở đây ...
[2] Điền tài liệu ở đây ...
[3] Điền tài liệu ở đây ...