Lộ trình
Là các nhà khoa học dữ liệu, thường thì chúng ta không tham gia vào khâu triển khai và vận hành—chúng ta xây dựng mô hình thống kê, còn kỹ sư lo phần còn lại.
Tuy nhiên, điều đó đang dần thay đổi!
Với nhu cầu ngày càng tăng về các nhà khoa học dữ liệu có thể nối liền khoảng cách giữa tạo mô hình và đưa vào sản xuất, việc làm quen với các công cụ tự động hóa và CI/CD (Tích hợp Liên tục/Triển khai Liên tục) có thể mang lại lợi thế chiến lược.
Trong hướng dẫn này, chúng ta sẽ tìm hiểu về hai công cụ tự động hóa phổ biến: Make (tự động hóa cục bộ) và GitHub Actions (tự động hóa trên đám mây). Trọng tâm chính là đưa các công cụ này vào dự án dữ liệu của chúng ta.

GitHub Action và Make. Ảnh: Abid Ali Awan.
Nếu bạn muốn tìm hiểu thêm về tự động hóa trong bối cảnh khoa học dữ liệu, hãy xem khóa học Fully Automated MLOps.
Giới thiệu về MakeFile
Makefile là bản thiết kế (blueprint) để xây dựng và quản lý dự án phần mềm. Đây là một tệp chứa hướng dẫn tự động hóa tác vụ, tinh gọn quy trình build phức tạp và đảm bảo tính nhất quán.
Để thực thi các lệnh trong Makefile, chúng ta dùng công cụ dòng lệnh make. Công cụ này có thể chạy như một chương trình Python bằng cách cung cấp đối số hoặc chỉ chạy trực tiếp.
Thành phần cốt lõi
Một Makefile thường gồm danh sách target, dependency, action và biến:
- Target: Kết quả mong muốn, như "build", "test" hoặc "clean". Hãy coi chúng là các mục tiêu bạn muốn đạt được qua Makefile.
- Dependencies: Các tệp cần thiết để build target. Nghĩ về chúng như nguyên liệu cho mỗi công thức (target).
- Actions: Hướng dẫn hoặc script chỉ cho hệ thống cách build target. Có thể bao gồm các lệnh như
python test.py. - Variables: Makefile cung cấp các biến toàn cục, hoạt động như đối số truyền cho action. Với ví dụ action ở trên, ta có thể có
python test.py $variable_1 $variable_2.
Tóm lại, mẫu MakeFile có thể trông như sau:
Variable = some_value
Target: Dependencies
Actions (commands to build the target) $Variable
Sử dụng các ví dụ ở trên, MakeFile có thể như sau:
# Define variables
variable_1 = 5
variable_2 = 10
# Target to run a test with variables
test: test_data.txt # Dependency on test data file
python test.py $variable_1 $variable_2
Cài đặt công cụ Make CLI
Chúng ta có thể cài đặt công cụ Make CLI trên mọi hệ điều hành.
Linux
Với Linux, chạy lệnh sau trong terminal:
$ sudo apt install make
MacOS
Với macOS, có thể dùng homebrew để cài make:
$ brew install make
Windows
Windows hơi khác. Công cụ Make có thể dùng theo nhiều cách. Các lựa chọn phổ biến nhất là WSL (Ubuntu Linxus), w64devkit và GnuWin32.
Hãy tải và cài đặt GnuWin32 từ trang SourceForge.
Để dùng như công cụ dòng lệnh trong terminal, chúng ta cần thêm vị trí thư mục vào biến môi trường Windows. Các bước thực hiện:
- Tìm "environment variables" trong menu Start—thao tác này sẽ đưa chúng ta đến cửa sổ System Properties.
- Trong cửa sổ System Properties, nhấp nút Environment Variables.
- Trong phần biến hệ thống, tìm biến "Path" và chỉnh sửa—thao tác này sẽ mở cửa sổ khác nơi chúng ta có thể thêm đường dẫn mới tới thư mục Make.

Để kiểm tra Make đã cài thành công, gõ make -h trong PowerShell.

Sử dụng MakeFile cho dự án khoa học dữ liệu
Phần này, chúng ta sẽ học cách sử dụng Makefile và công cụ Make CLI trong một dự án khoa học dữ liệu.
Chúng ta sẽ dùng bộ dữ liệu World Happiness Report 2023 để thực hiện xử lý dữ liệu, phân tích, và lưu tóm tắt dữ liệu cùng trực quan hóa.
Thiết lập
Bắt đầu bằng cách vào thư mục dự án và tạo một thư mục có tên Makefile-Action. Sau đó tạo tệp data_processing.py trong thư mục đó và mở trình soạn thảo VSCode.
$ cd GitHub
$ mkdir Makefile-Action
$ cd .\Makefile-Action\
$ code data_processing.py
Xử lý dữ liệu
Chúng ta bắt đầu xử lý dữ liệu bằng Python. Trong khối mã dưới đây, ta thực hiện các bước sau (lưu ý: đây là mã ví dụ—trong thực tế, có thể cần nhiều bước hơn):
- Tải bộ dữ liệu thô từ đường dẫn do người dùng cung cấp.
- Đổi tên tất cả cột để dễ đọc hơn.
- Điền giá trị khuyết.
- Lưu bộ dữ liệu đã làm sạch.
Tệp: data_processing.py
import sys
import pandas as pd
# Check if the data location argument is provided
if len(sys.argv) != 2:
print("Usage: python data_processing.py <data_location>")
sys.exit(1)
# Load the raw dataset (step 1)
df = pd.read_csv(sys.argv[1])
# Rename columns to more descriptive names (step 2)
df.columns = [
"Country",
"Happiness Score",
"Happiness Score Error",
"Upper Whisker",
"Lower Whisker",
"GDP per Capita",
"Social Support",
"Healthy Life Expectancy",
"Freedom to Make Life Choices",
"Generosity",
"Perceptions of Corruption",
"Dystopia Happiness Score",
"GDP per Capita",
"Social Support",
"Healthy Life Expectancy",
"Freedom to Make Life Choices",
"Generosity",
"Perceptions of Corruption",
"Dystopia Residual",
]
# Handle missing values by replacing them with the mean (step 3)
df.fillna(df.mean(numeric_only=True), inplace=True)
# Check for missing values after cleaning
print("Missing values after cleaning:")
print(df.isnull().sum())
print(df.head())
# Save the cleaned and normalized dataset to a new CSV file (step 4)
df.to_csv("processed_data\WHR2023_cleaned.csv", index=False)
Phân tích dữ liệu
Tiếp tục phân tích dữ liệu và lưu toàn bộ mã vào tệp data_analysis.py. Có thể tạo tệp này bằng lệnh terminal sau:
$ code data_analysis.py
Chúng ta cũng có thể dùng lệnh echo để tạo tệp Python và mở nó trong một trình soạn thảo khác.
$ echo "" > data_analysis.py
Trong khối mã dưới đây, chúng ta:
- Tải bộ dữ liệu đã làm sạch bằng đầu vào do người dùng cung cấp.
- Tạo tóm tắt dữ liệu, thông tin dữ liệu và 5 dòng đầu của DataFrame và lưu vào tệp TXT.
- Vẽ trực quan hóa cho:
- Phân phối điểm hạnh phúc
- Top 20 quốc gia theo điểm hạnh phúc
- Điểm hạnh phúc so với GDP bình quân đầu người
- Điểm hạnh phúc so với hỗ trợ xã hội
- Bản đồ nhiệt tương quan
- Lưu tất cả trực quan hóa vào thư mục “figures”.
Tệp: data_analysis.py
import io
import sys
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
# Check if the data location argument is provided
if len(sys.argv) != 2:
print("Usage: python data_analysis.py <data_location>")
sys.exit(1)
# Load the clean dataset (step 1)
df = pd.read_csv(sys.argv[1])
# Data summary (step 2)
print("Data Summary:")
summary = df.describe()
data_head = df.head()
print(summary)
print(data_head)
# Collecting data information
buffer = io.StringIO()
df.info(buf=buffer)
info = buffer.getvalue()
## Write metrics to file
with open("processed_data/summary.txt", "w") as outfile:
f"\n## Data Summary\n\n{summary}\n\n## Data Info\n\n{info}\n\n## Dataframe\n\n{data_head}"
print("Data summary saved in processed_data folder!")
# Distribution of Happiness Score (step 3)
plt.figure(figsize=(10, 6))
sns.displot(df["Happiness Score"])
plt.title("Distribution of Happiness Score")
plt.xlabel("Happiness Score")
plt.ylabel("Frequency")
plt.savefig("figures/happiness_score_distribution.png")
# Top 20 countries by Happiness Score
top_20_countries = df.nlargest(20, "Happiness Score")
plt.figure(figsize=(10, 6))
sns.barplot(x="Country", y="Happiness Score", data=top_20_countries)
plt.title("Top 20 Countries by Happiness Score")
plt.xlabel("Country")
plt.ylabel("Happiness Score")
plt.xticks(rotation=90)
plt.savefig("figures/top_20_countries_by_happiness_score.png")
# Scatter plot of Happiness Score vs GDP per Capita
plt.figure(figsize=(10, 6))
sns.scatterplot(x="GDP per Capita", y="Happiness Score", data=df)
plt.title("Happiness Score vs GDP per Capita")
plt.xlabel("GDP per Capita")
plt.ylabel("Happiness Score")
plt.savefig("figures/happiness_score_vs_gdp_per_capita.png")
# Visualize the relationship between Happiness Score and Social Support
plt.figure(figsize=(10, 6))
plt.scatter(x="Social Support", y="Happiness Score", data=df)
plt.xlabel("Social Support")
plt.ylabel("Happiness Score")
plt.title("Relationship between Social Support and Happiness Score")
plt.savefig("figures/social_support_happiness_relationship.png")
# Heatmap of correlations between variables
corr_matrix = df.drop("Country", axis=1).corr()
plt.figure(figsize=(12, 10))
sns.heatmap(corr_matrix, annot=True, cmap="coolwarm", square=True)
plt.title("Correlation Heatmap")
plt.savefig("figures/correlation_heatmap.png")
print("Visualizations saved to figures folder!")
Tạo Makefile
Trước khi tạo Makefile, chúng ta cần thiết lập tệp requirements.txt để cài tất cả gói Python cần thiết trên máy mới. Tệp requirements.txt sẽ như sau:
pandas
numpy
seaborn
matplotlib
black
Makefile của chúng ta gồm biến, phụ thuộc, target và action—chúng ta sẽ tìm hiểu mọi khối xây dựng. Tạo tệp tên Makefile và bắt đầu thêm action cho các target:
- install: Nâng cấp phiên bản pip và cài mọi gói Python cần thiết bằng tệp requirements.txt.
- format: Định dạng tất cả tệp Python bằng công cụ Black.
- process: Chạy tệp Python `data_processing.py` với đường dẫn dữ liệu thô dưới dạng biến và phụ thuộc.
- analyze: Chạy tệp Python `data_analysis.py` với đường dẫn dữ liệu đã xử lý dưới dạng biến và phụ thuộc.
- clean: Xóa tất cả tệp và hình ảnh được tạo trong quá trình chạy các tệp Python.
- all: Chạy tất cả target hợp lệ theo trình tự.
Tệp: Makefile
RAW_DATA_PATH = "raw_data/WHR2023.csv"
PROCESSED_DATA = "processed_data/WHR2023_cleaned.csv"
install:
pip install --upgrade pip &&\
pip install -r requirements.txt
format:
black *.py --line-length 88
process: ./raw_data/WHR2023.csv
python data_processing.py $(RAW_DATA_PATH)
analyze: ./processed_data/WHR2023_cleaned.csv
python data_analysis.py $(PROCESSED_DATA)
clean:
rm -f processed_data/* **/*.png
all: install format process analyze
Để thực thi target, chúng ta sẽ dùng công cụ make và cung cấp tên target trong terminal.
$ make format
Script Black đã chạy thành công.

Hãy thử chạy script Python để xử lý dữ liệu.
Lưu ý rằng nó kiểm tra phụ thuộc của target trước khi chạy target process. Trong trường hợp này, nó kiểm tra xem tệp dữ liệu thô có tồn tại không. Nếu không, lệnh sẽ không khởi chạy.
$ make process
Như bạn thấy, rất đơn giản.

Bạn thậm chí có thể ghi đè biến hiện có bằng cách cung cấp đối số bổ sung cho lệnh make.
Trong trường hợp này, chúng ta đã thay đổi đường dẫn dữ liệu thô.
$ make process RAW_DATA_PATH="WHR2022.csv"
Script Python đã chạy với đối số đầu vào khác.

Để tự động hóa toàn bộ quy trình, chúng ta sẽ dùng all làm target, target này sẽ lần lượt chạy learn, install, format, process và analyze.
$ make all
make đã cài các gói Python, định dạng mã, xử lý dữ liệu và lưu tóm tắt cùng các trực quan hóa.


Thư mục dự án của bạn sẽ trông như thế này sau khi chạy lệnh make all:

Giới thiệu về GitHub Actions
Trong khi Make vượt trội trong tự động hóa cục bộ trong môi trường phát triển, GitHub Actions cung cấp một lựa chọn thay thế trên đám mây.
GitHub Actions thường được dùng cho CI/CD, cho phép nhà phát triển biên dịch, build, kiểm thử và triển khai ứng dụng lên production trực tiếp từ GitHub.
Ví dụ, chúng ta có thể tạo một workflow tùy chỉnh được kích hoạt dựa trên các sự kiện cụ thể như push hoặc pull request. Workflow đó sẽ chạy shell script và Python script, hoặc thậm chí dùng các action dựng sẵn. Workflow tùy chỉnh là một tệp YML và thường khá dễ hiểu để bắt đầu viết các lần chạy và action tùy chỉnh.
Thành phần cốt lõi
Hãy khám phá các thành phần cốt lõi của GitHub Actions:
- Workflows được định nghĩa bằng tệp YML, chỉ định các bước cần thực thi và điều kiện thực thi.
- Events là các hoạt động cụ thể kích hoạt việc chạy workflow như push, pull_request, schedule, v.v.
- Runners là các máy chạy workflow khi được kích hoạt. GitHub cung cấp runner miễn phí, được lưu trữ sẵn cho Linux, Windows và macOS.
- Jobs là tập hợp bước được thực thi trên cùng một runner. Mặc định, các job chạy song song nhưng có thể cấu hình chạy tuần tự.
- Steps là các tác vụ chạy lệnh hoặc action tương tự action trong Makefile.
- Actions là ứng dụng tùy chỉnh cho nền tảng GitHub Actions để thực hiện tác vụ phức tạp nhưng lặp lại thường xuyên. Có rất nhiều action để lựa chọn, phần lớn được cộng đồng nguồn mở hỗ trợ.
Bắt đầu với GitHub Actions
Phần này, chúng ta sẽ học cách dùng GitHub Actions và thử tái tạo các lệnh đã dùng trong Makefile trước đó.
Để chuyển mã lên GitHub, chúng ta phải chuyển đổi thư mục dự án thành kho Git bằng cách:
$ git init
Sau đó, tạo một repository mới trên GitHub và sao chép URL.

Trong terminal, nhập các lệnh dưới đây để:
- Thêm liên kết repository từ xa.
- Kéo tệp từ repository từ xa.
- Thêm và commit tất cả tệp với thông điệp commit.
- Đẩy tệp từ
mastercục bộ lên nhánhmaintừ xa.
$ git remote add github https://github.com/kingabzpro/Makefile-Actions.git
$ git pull github main
$ git add .
$ git commit -m "adding all the files"
$ git push github master:main
Lưu ý thêm, nếu bạn cần ôn nhanh về GitHub hoặc Git, hãy xem hướng dẫn thân thiện cho người mới bắt đầu về GitHub và Git. Khóa này sẽ giúp bạn quản lý phiên bản dự án khoa học dữ liệu và chia sẻ với nhóm bằng công cụ Git CLI.
Tiếp tục bài học—chúng ta thấy rằng mọi tệp đã được chuyển thành công lên repository từ xa.

Tiếp theo, chúng ta sẽ tạo một workflow GitHub Action. Trước tiên, vào thẻ Actions trên repository kingabzpro/Makefile-Actions. Sau đó, nhấp dòng chữ xanh “set up a workflow yourself.”

Chúng ta sẽ được chuyển đến tệp YML, nơi viết toàn bộ mã để thiết lập môi trường và thực thi lệnh. Chúng ta sẽ:
- Đặt tên cho workflow.
- Thiết lập sự kiện kích hoạt để thực thi workflow khi mã được push lên nhánh
mainhoặc có pull request lên nhánhmain. - Thiết lập một job với máy Ubuntu Linux mới nhất.
- Sử dụng action checkout v3 trong phần step. Nó giúp workflow truy cập repository.
- Cài đặt các gói Python cần thiết, định dạng mã và chạy cả hai script Python với biến.
name: Data Processing and Analysis
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install Packages
run: |
pip install --upgrade pip
pip install -r requirements.txt
- name: Format
run: black *.py --line-length 88
- name: Data Processing
env:
RAW_DATA_DIR: "./raw_data/WHR2023.csv"
run: python data_processing.py $RAW_DATA_DIR
- name: Data Analysis
env:
CLEAN_DATA_DIR: "./processed_data/WHR2023_cleaned.csv"
run: python data_analysis.py $CLEAN_DATA_DIR
Sau khi commit tệp workflow kèm thông điệp, workflow sẽ tự động bắt đầu chạy.

Sẽ mất ít nhất 20 giây để hoàn tất tất cả bước.
Để xem log, trước tiên nhấp vào lượt chạy workflow, sau đó nút Build, rồi nhấp vào từng job để truy cập log.

Nếu bạn thấy thú vị, bạn sẽ thích Hướng dẫn CI/CD cho Machine Learning dành cho người mới bắt đầu, bao quát những điều cơ bản để xây dựng và tự động hóa quy trình machine learning.
Kết hợp GitHub Actions với MakeFile
Để đơn giản hóa và tiêu chuẩn hóa workflow của GitHub Action, các nhà phát triển dùng lệnh Make trong tệp workflow. Phần này, chúng ta sẽ học cách đơn giản hóa mã workflow bằng lệnh Make và học sử dụng action continuous machine learning (CML).
Trước khi bắt đầu, chúng ta cần pull tệp workflow từ repository từ xa.
$ git pull
Sử dụng CML
Continuous Machine Learning (CML) là thư viện nguồn mở của iterative.ai cho phép chúng ta triển khai tích hợp liên tục trong dự án khoa học dữ liệu.
Trong dự án này, chúng ta sẽ dùng GitHub Action iterative/setup-cml sử dụng các hàm CML trong workflow để tạo báo cáo phân tích bằng hình ảnh và thống kê dữ liệu.
Báo cáo sẽ được tạo và đính kèm vào commit trên GitHub để nhóm xem xét và phê duyệt trước khi merge.
Chúng ta sẽ chỉnh Makefile và thêm target “summary”. Lưu ý rằng:
- Target là một script nhiều dòng chuyển dữ liệu văn bản từ summary.txt sang report.md.
- Sau đó, lần lượt thêm tiêu đề cho từng hình và mã Markdown để hiển thị hình trong tệp report.md.
- Cuối cùng, chúng ta dùng công cụ
cmlđể tạo báo cáo phân tích dữ liệu và hiển thị dưới phần bình luận của commit.
Hãy tưởng tượng thêm nhiều dòng như vậy vào tệp workflow của GitHub—sẽ khó đọc và chỉnh sửa. Thay vào đó, chúng ta sẽ dùng make summary.
Tệp: Makefile
summary: ./processed_data/summary.txt
echo "# Data Summary" > report.md
cat ./processed_data/summary.txt >> report.md
echo '\n# Data Analysis' >> report.md
echo '\n## Correlation Heatmap' >> report.md
echo '' >> report.md
echo '\n## Happiness Score Distribution' >> report.md
echo '' >> report.md
echo '\n## Happiness Score vs GDP per Capita' >> report.md
echo '' >> report.md
echo '\n## Social Support vs Happiness Relationship' >> report.md
echo '' >> report.md
echo '\n## Top 20 Countries by Happiness Score' >> report.md
echo '' >> report.md
cml comment create report.md

Chỉnh sửa tệp GiHub Action
Giờ chúng ta sẽ chỉnh tệp main.yml, nằm trong thư mục .github/workflows.
Chúng ta thay tất cả lệnh và script Python bằng lệnh make và cấp quyền cho CML Action tạo báo cáo dữ liệu trong bình luận commit. Ngoài ra, đừng quên thêm Action iterative/setup-cml@v3 vào lượt chạy.
name: Data Processing and Analysis
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
permissions: write-all
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: iterative/setup-cml@v3
- name: Install Packages
run: make install
- name: Format
run: make format
- name: Data Processing
env:
RAW_DATA_DIR: "./raw_data/WHR2023.csv"
run: make process RAW_DATA_PATH=$RAW_DATA_DIR
- name: Data Analysis
env:
CLEAN_DATA_DIR: "./processed_data/WHR2023_cleaned.csv"
run: make analyze PROCESSED_DATA=$CLEAN_DATA_DIR
- name: Data Summary
env:
REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: make summary
Chạy workflow
Để thực thi workflow, chúng ta chỉ cần commit mọi thay đổi và đồng bộ với nhánh main từ xa.
$ git commit -am "makefile and github action combo"
$ git push github master:main

Mất 32 giây để chạy workflow—báo cáo của chúng ta đã sẵn sàng để xem xét. Để làm điều đó, vào phần tóm tắt build, cuộn xuống nhấp vào thẻ Data Summary, rồi nhấp vào đường dẫn bình luận (đường dẫn bạn thấy ở dòng 20 trong hình dưới):

Như bạn thấy, tóm tắt dữ liệu và các trực quan hóa đã được đính kèm vào commit.

Dự án có sẵn tại kingabzpro/Makefile-Actions, bạn có thể dùng làm tài liệu tham khảo khi gặp vướng mắc. Repository là công khai, hãy fork và tự mình trải nghiệm!
Bạn muốn lấy chứng chỉ GitHub? Xem hướng dẫn toàn diện của chúng tôi về các chứng chỉ GitHub!
Kết luận
Trong hướng dẫn này, chúng ta tập trung vào Makefile và GitHub Actions để tự động hóa việc tạo báo cáo phân tích dữ liệu.
Chúng ta cũng học cách xây dựng và chạy workflow, cũng như dùng công cụ Make trong workflow của GitHub để tối ưu và đơn giản hóa quy trình tự động hóa. Thay vì viết nhiều dòng mã, chúng ta có thể dùng make summary để tạo báo cáo phân tích dữ liệu sẽ được đính kèm vào commit.
Nếu bạn muốn làm chủ CI/CD cho khoa học dữ liệu, hãy thử khóa học CI/CD for Machine Learning. Khóa học bao quát các nền tảng CI/CD, GitHub Actions, quản lý phiên bản dữ liệu và tự động hóa tối ưu siêu tham số cùng đánh giá mô hình.
Là một nhà khoa học dữ liệu được chứng nhận, tôi đam mê tận dụng công nghệ tiên tiến để tạo ra các ứng dụng học máy đổi mới. Với nền tảng vững chắc về nhận dạng giọng nói, phân tích và báo cáo dữ liệu, MLOps, AI hội thoại và NLP, tôi đã rèn giũa kỹ năng phát triển các hệ thống thông minh có thể tạo ra tác động thực sự. Bên cạnh chuyên môn kỹ thuật, tôi cũng là một người truyền đạt tốt, có khả năng chắt lọc các khái niệm phức tạp thành ngôn ngữ rõ ràng, súc tích. Nhờ đó, tôi trở thành một blogger được nhiều người quan tâm trong lĩnh vực khoa học dữ liệu, chia sẻ góc nhìn và kinh nghiệm với cộng đồng các chuyên gia dữ liệu ngày càng lớn. Hiện tại, tôi tập trung vào sáng tạo và biên tập nội dung, làm việc với các mô hình ngôn ngữ lớn để phát triển nội dung mạnh mẽ và hấp dẫn, giúp doanh nghiệp và cá nhân tận dụng tối đa dữ liệu của mình.
