K-Means là một trong những thuật toán phổ biến và được sử dụng rất nhiều trong kỹ thuật gom cụm. Ý tưởng chính của thuật toán này là tìm cách phân nhóm các đối tượng đã cho vào K cụm sao cho tổng khoảng cách giữa các đối tượng đến tâm nhóm là nhỏ nhất. Thường K là số cụm được xác định trước và thường lấy ý kiến của chuyên gia, K phải nguyên dương. Khoảng cách giữa các đối tượng thường được sử dụng là khoảng cách Euclid.
Trong toán học, khoảng cách Euclid (tiếng Anh: Euclidean distance) giữa hai điểm trong không gian Euclid là độ dài của đoạn thẳng nối hai điểm đó. Có thể tính nó từ tọa độ Descartes của hai điểm bằng cách sử dụng định lý Pythagoras, do đó còn có tên gọi khác là khoảng cách Pythagoras (tiếng Anh: Pythagorean distance).
Src: Wikipedia
Đầu vào:
•Tập các đối tượng X = {xi| i = 1, 2, …, N},
•Số cụm: K
Đầu ra:
•Các cụm Ci ( i = 1 ÷ K) tách rời và hàm tiêu chuẩn E đạt giá trị tối thiểu.
Trong đó cj là trọng tâm của cụm Cj
Chu trình hoạt động thuật toán:
Thuật toán hoạt động trên 1 tập vectơ d chiều, tập dữ liệu X gồm N phần tử:
X = {xi | i = 1, 2, …, N}
K-Mean lặp lại nhiều lần quá trình:
Gán dữ liệu.
Cập nhật lại vị trí trọng tâm.
Quá trình lặp dừng lại khi trọng tâm hội tụ và mỗi đối tượng là 1 bộ phận của 1 cụm.
Các bước thực hiện thuật toán:
Dựa vào chu trình và lưu đồ thuật toán, ta có thể diễn giải các bước thực hiện như sau:
•Bước 1 – Khởi tạo
Chọn K trọng tâm {ci} ngẫu nhiên hoặc theo tiêu chuẩn (i = 1÷K).
•Bước 2 – Tính toán khoảng cách
•Bước 3 – Cập nhật lại trọng tâm, ta thường tính giá trị trung bình
•Bước 4 – Điều kiện dừng
Ví dụ gom cụm bằng K-Means với bảng dữ liệu sau (k=2) và giả sử r3, r5 là center mặc định:
…
Value 1
Value 2
Value 3
Value 4
Value 5
Value 6
Value 7
Value 8
Value 9
Value 10
Value 11
r1
1
1
0.5
0.5
0
0
0
0.5
0.25
0
0
r2
1
1
0.5
0.5
0
0
0
0.5
0.25
0
0
r3
0.5
0.5
1
1
0
0
0
0.33
0.33
0
0
r4
0.5
0.5
1
1
0
0
0
0.33
0.33
0
0
r5
0
0
0
0
1
1
1
0
0
0
0
r6
0
0
0
0
1
1
1
0
0
0
0
r7
0
0
0
0
1
1
1
0
0
0
0
r8
0.5
0.5
0.33
0.33
0
0
0
1
0.25
0.17
0.17
r9
0.25
0.25
0.33
0.33
0
0
0
0.25
1
0.75
0.75
r10
0
0
0
0
0
0
0
0.17
0.75
1
1
r11
0
0
0
0
0
0
0
0.17
0.75
1
1
Sau đây là chi tiết các bước thực hiện giải thuật K-Means để gom cụm. Dùng Euclid để tính các khoảng cách:
Bước 1: Khởi tạo Giả sử chọn ngẫu nhiên 2 Trọng tâm ban đầu: r3; r5
* Gọi V1 là véc tơ trọng tâm của C1: Ta tính được V1(0.5,0.5,1,1,0,0,0,0.33,0.33,0,0) * Gọi V2 là véc tơ trọng tâm của C2: Ta tính được V2(0,0,0,0,1,1,1,0,0,0,0)
Bước 2: Tính khoảng cách từ các đỉnh tới các Vector trọng tâm:
– d([r1],V1)=1.02 < d([r1],V2)=2.41. Vậy ta gom [r1] vào cụm C1.
Lý giải:
Ta tính được d([r1],V1)=1.02 từ công thức sau:
Tương tự ta cũng tính được d([r1],V2)=2.41 từ công thức sau:
Tương tự ta tính được khoảng cách tới trọng tâm cho các đỉnh còn lại (Các bạn cần viết lại công thức chi tiết như minh họa ở trên):
– d([r2],V1)=1.02 < d([r2],V2)=2.41. Vậy ta gom [r2] vào cụm C1. – d([r4],V1)=0 < d([r4],V2)=2.39.Vậy ta gom [r4] vào cụm C1. – d([r6],V1)=2.39 > d([r6],V2)=0. Vậy ta gom [r6] vào cụm C2. – d([r7],V1)=2.39 > d([r7],V2)=0. Vậy ta gom [r7] vào cụm C2. – d([r8],V1)=1.18 < d([r8],V2)=2.2. Vậy ta gom [r8] vào cụm C1. – d([r9],V1)=1.61 < d([r9],V2)=2.35. Vậy ta gom [r9] vào cụm C1 – d([r10],V1)=2.17 < d([r10],V2)=2.36. Vậy ta gom [r10] vào cụm C1 – d([r11],V1)=2.17 < d([r11],V2)=2.36. Vậy ta gom [r11] gom vào cụm C1
*Vậy ta có phân bố cụm lần 1:
U=1
r1
r2
r3
r4
r5
r6
r7
r8
r9
r10
r11
C1
1
1
1
1
0
0
0
1
1
1
1
C2
0
0
0
0
1
1
1
0
0
0
0
Bước 3: Cập nhật lại vector trọng tâm * Gọi V1 là véc tơ trọng tâm mới của C1: Ta tính được V1(0.47,0.47,0.46,0.46,0,0,0,0.41,0.49,0.36,0.36)
Lý giải trọng tâm mới được tính như sau:
Tương tự cho các thuộc tính và Vector còn lại. * Gọi V2 là véc tơ trọng tâm mới của C2: Ta tính được V2(0,0,0,0,1,1,1,0,0,0,0)
Bước 4:Kiểm tra điều kiện dừng Ta so sánh Vector trọng tâm mới được tạo ở bước 3 so với Vector trọng tâm cũ: Tập Vector Trọng tâm cũ: V1(0.5,0.5,1,1,0,0,0,0.33,0.33,0,0)
V2(0,0,0,0,1,1,1,0,0,0,0) Tập Vector Trọng tâm Mới: V1(0.47,0.47,0.46,0.46,0,0,0,0.41,0.49,0.36,0.36)
V2(0,0,0,0,1,1,1,0,0,0,0) Ta kiểm tra thấy trọng tâm bị thay đổi nên lặp lại bước 2.
Bước 2: Tính khoảng cách từ các đỉnh tới các Vector trọng tâm: – d([r1],V1)=0.95 < d([r1],V2)=2.41. Vậy ta gom [r1] vào cụm C1. – d([r2],V1)=0.95 < d([r2],V2)=2.41. Vậy ta gom [r2] vào cụm C1. – d([r3],V1)=0.94 < d([r3],V2)=2.39. Vậy ta gom [r3] vào cụm C1. – d([r4],V1)=0.94 < d([r4],V2)=2.39. Vậy ta gom [r4] vào cụm C1. – d([r5],V1)=2.13 > d([r5],V2)=0 . Vậy ta gom [r5] vào cụm C2. – d([r6],V1)=2.13 > d([r6],V2)=0. Vậy ta gom [r6] vào cụm C2. – d([r7],V1)=2.13 > d([r7],V2)=0. Vậy ta gom [r7] vào cụm C2. – d([r8],V1)=0.72 < d([r8],V2)=2.2. Vậy ta gom [r8] vào cụm C1. – d([r9],V1)=0.84 < d([r9],V2)=2.35. Vậy ta gom [r9] vào cụm C1. – d([r10],V1)=1.34 < d([r10],V2)=2.36. Vậy ta gom [r10] vào cụm C1. – d([r11],V1)=1.34 < d([r11],V2)=2.36. Vậy ta gom [r11] vào cụm C1. *Vậy ta có phân bố cụm lần 2:
U=2
r1
r2
r3
r4
r5
r6
r7
r8
r9
r10
r11
C1
1
1
1
1
0
0
0
1
1
1
1
C2
0
0
0
0
1
1
1
0
0
0
0
Bước 3: Cập nhật lại vector trọng tâm
* Gọi V1 là véc tơ trọng tâm mới của C1:
Ta tính được V1(0.47,0.47,0.46,0.46,0,0,0,0.41,0.49,0.36,0.36)
* Gọi V2 là véc tơ trọng tâm mới của C2:
Ta tính được V2(0,0,0,0,1,1,1,0,0,0,0)
Bước 4: Kiểm tra điều kiện dừng Ta so sánh Vector trọng tâm mới được tạo ở bước 3 so với Vector trọng tâm cũ:
Vậy ta thấy U2 và U1 Không có sự thay đổi. Giải thuật K-Means kết thúc.
Cuối cùng ta được 2 cụm như sau:
Cụm 1 {r1;r2;r3;r4;r8;r9;r10;r11}
Cụm 2 {r5;r6;r7}
Bài tập tương tự: Cho bảng ma trận dữ liệu dưới đây, hãy giải thích từng bước quá trình K-Means hoạt động, với số cụm là 3, center vector khởi tạo ban đầu là Daisy, Vitor, Real
Customer
Attribute 1
Attribute 2
John
1
1
Peter
11
12
Daisy
2
3
Case
1
2
Ronie
2
6
Vitor
9
8
Rehm
0
1
Tom
11
10
Bob
0
2
Lie
10
11
Tide
10
12
Real
7
4
Jassor
5
6
Bài học sau Tui hướng dẫn cách sử dụng K-Means để gom cụm khách hàng theo thu nhập, độ tuổi và ngân sách chi tiêu. Chúng ta dùng phương pháp Elbow để tìm ra K Cụm tối ưu nhất để gom, trực quan hóa các cụm bằng 2D và 3D. Đồng thời phân loại chi tiết Khách hàng theo từng cụm để dễ dàng đưa ra các chính sách chăm sóc và tiếp thị phù hợp.
Bài học này Tui hướng dẫn các bạn xây dựng mô hình máy học sử dụng hồi quy tuyến tính đa biến để thống kê và dự báo chi tiêu của khách hàng, sử dụng cơ sở dữ liệu “lecturer_retails” có Số lượng dữ liệu gồm 99457 dòng, dữ liệu tải ở đây: https://tranduythanh.com/datasets/PurchaseDataset.rar
Chương trình được tách ra làm 2 nhóm chức năng chính:
Chức năng thống kê:
(1.1) Thống kê tỉ lệ mua hàng theo giới tính
(1.2) Thống kê số lượng mua hàng theo độ tuổi
(1.3) Thống kê số lượng mua hàng theo danh mục sản phẩm
(1.4) Thống kê trị giá hàng hóa bán được theo danh mục
(1.5) Thống kê lượng hàn bán ra theo độ tuổi và danh mục
(1.6) Thống kê số lượng giao dịch theo phương thức thanh toán
(1.7) Thống kê tỉ lệ bán hàng theo Trung tâm thương mại (Shopping Mall)
(1.8) Thống kê trị giá hàng hóa bán được theo danh mục và giới tính
(1.9) Thống kê tần suất mua hàng theo độ tuổi và giới tính
(1.10) Thống kê biến động doanh thu theo tháng
(1.11) Thống kê biến động doanh thu theo tháng và theo năm
Chức năng huấn luyện mô hình máy học:
Dự báo biến động giá theo giới tính và độ tuổi
Dự báo biến động giá theo giới tính, độ tuổi và phương thức thanh toán
Giao diện phần mềm cho Thống kê tương tự như dưới đây:
Giao diện phần mềm cho Máy học tương tự như dưới đây:
Dữ liệu “lecturer_retails“, được lưu trong MySQL Server có cấu trúc như mô tả chi tiết dưới đây:
Cấu trúc bảng purchasehistory như sau:
invoice_no
customer_id
gender
age
category
quantity
price
payment_method
invoice_date
shopping_mall
Số lượng dữ liệu gồm 99457 dòng. Dataset các bạn tải ở link sau, và cần import vào MySQL Server của bạn trước:
Các bạn giải nén ra, trong MySQL Workbench tạo Schema tên “lecturer_retails“, sau đó import dataset vào Schema này. Cách import dataset các bạn xem lại bài học 47 cách import và export dataset
Tạo dự án “MLBAProject” có cấu trúc như dưới đây:
Vì bài này dài, và nó tổng hợp nhiều kiến thức nên Tui giải thích tổng quan như này:
(1) Thư mục “Assets” là thư mục tạo ra để lưu trữ các mô hình máy học được train thành công, dĩ nhiên người sử dụng có thể lưu ở bất cứ nơi nào, nhưng đề xuất lưu vào đây để dễ quản lý
(2) Thư mục “Connectors” là thư mục lưu thư viện kết nối và tương tác cơ sở dữ liệu MySQL Server
(3) Thư mục “Images” là thư mục lưu trữ các hình ảnh để sử dụng cho phần mềm
(4) Thư mục “Models” là thư mục chưa các lớp thư viện liên quan tới thống kê và máy học
(5) Thư mục “Tests” Là thư mục chứa các tập tin mã lệnh để thử nghiệm các hàm thống kê và máy học trước khi sử dụng thực tế. Thư mục này bạn có thể bỏ qua
(6) Thư mục “UI” là thư mục chứa các file thiết kế giao diện và generate python code cho giao diện, cũng như đồ thị
(7) Thư mục “Utils” là thư mục chưa thư viện xử lý tập tin, dùng để lưu mô hình máy học và tải mô hình máy học
(8) Cuối cùng là tập tin “App.py” để thực thi chương trình.
Vì không có nhiều thời gian, Tui không giải thích hết được các hàm trong các mã lệnh dưới đây, tuy nhiên Tui có đặt tên hàm và tên biến có ý nghĩa, nên các bạn đọc vào có thể hiểu ngay chức năng của nó. Đồng thời các thông số kết nối cơ sở dữ liệu các bạn cần đổi lại cho đúng với trên máy tính của mình.
Bước 1: Tạo và viết mã lệnh cho “Connector.py” trong thư mục “Connectors“
Thư viện trên dùng để kết nối, đóng kết nối, truy vấn dữ liệu và danh sách các bảng trong cơ sở dữ liệu.
Bước 2: Trong thư mục “Models“, lần lượt tạo các tập tin mã lệnh Python sau:
Bước 2.1: Tạo lớp “MetricsResult.py” để lưu kết quả đánh giá mô hình, lớp này lưu các thông số: MAE, MSE, RMSE, R2_SCORE
class MetricsResult:
def __init__(self,mae,mse,rmse,r2_score):
self.MAE=mae
self.MSE=mse
self.RMSE=rmse
self.R2_SCORE=r2_score
def __str__(self):
result="MAE=%s"%self.MAE+"\n"+"MSE=%s"%self.MSE+"\n"+"RMSE=%s"%self.RMSE+"\n"+"R2_SCORE=%s"%self.R2_SCORE+"\n"
return result
Bước 2.2: Tạo lớp “TrainedModel.py” để lưu trữ mô hình máy học được trained (model) các dữ liệu của biến độc lập và biến phụ thuộc, cũng như tên các biến này. Mục đích để lưu và nạp lại mô hình theo chủ ý của ta.
Bước 2.4: Tạo lớp “PurchaseMLModel.py” lớp này cung cấp tiền xử lý và chuyển đổi dữ liệu (transformation) để phục vụ các mô hình máy học
# Features encoding
from sklearn.preprocessing import LabelEncoder
import seaborn as sns
from matplotlib import pyplot as plt
from Models.PurchaseStatistic import PurchaseStatistic
class PurchaseMLModel(PurchaseStatistic):
def __init__(self,connector=None):
super().__init__(connector)
self.le = LabelEncoder()
def processTransformByColumns(self,df,columns):
for col in columns:
x=df[col]
df[col] = self.le.fit_transform(x)
def processTransform(self):
categorical_feature = ['gender', 'category', 'payment_method', 'shopping_mall']
numerical_feature = ['age', 'quantity', 'month', 'year']
dropping = ['customer_id', 'invoice_no', 'day', 'invoice_date']
result = ['price']
self.dfTransform=self.df.copy(deep=True)
self.dfTransform[["day", "month", "year"]] = self.dfTransform["invoice_date"].str.split("/", expand=True)
self.dfTransform.drop(dropping, axis=1, inplace=True)
for col in categorical_feature:
x=self.dfTransform[col]
self.dfTransform[col] = self.le.fit_transform(x)
return self.dfTransform
def buildCorrelationMatrix(self,df):
plt.figure(figsize=(8, 6))
df_corr = df.corr(numeric_only=True) # Generate correlation matrix
ax = sns.heatmap(df_corr, annot=True)
plt.show()
Bước 2.5: Tạo lớp “PurchaseLinearRegression.py” lớp này cung cấp chức năng train mô hình máy học với hồi quy đa biến:
import pandas as pd
from matplotlib import pyplot as plt
from sklearn.model_selection import train_test_split
#data modelling
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_absolute_error, mean_squared_error,r2_score
from sklearn.preprocessing import StandardScaler, LabelEncoder
from Models.MetricsResult import MetricsResult
from Models.PurchaseMLModel import PurchaseMLModel
from Models.TrainedModel import TrainedModel
from Utils.FileUtil import FileUtil
class PurchaseLinearRegression(PurchaseMLModel):
def __init__(self,connector=None):
super().__init__(connector)
self.le = LabelEncoder()
self.sc_std = StandardScaler()
def processTrain(self,columns_input,column_target,test_size,random_state):
self.execPurchaseHistory()
self.processTransform()
print(self.dfTransform.columns)
print(self.dfTransform.iloc[0])
y = self.dfTransform[column_target]
X = self.dfTransform[columns_input]
print("X=",X)
print("y=", y)
self.X_train, self.X_test, self.y_train, self.y_test = train_test_split(X, y, test_size=test_size, random_state=random_state)
self.trainedmodel=TrainedModel()
self.trainedmodel.X_train=self.X_train
self.trainedmodel.X_test=self.X_test
self.trainedmodel.y_train=self.y_train
self.trainedmodel.y_test=self.y_test
self.trainedmodel.columns_input=columns_input
self.trainedmodel.column_target=column_target
#self.sc_std = StandardScaler()
self.X_train = self.sc_std.fit_transform(self.X_train)
self.X_test = self.sc_std.transform(self.X_test)
self.lr = LinearRegression()
self.model = self.lr.fit(self.X_train, self.y_train)
self.trainedmodel.model=self.model
def visualizeActualAndPredictResult(self):
plt.figure(figsize=(8, 6))
plt.scatter(self.lr.predict(self.X_train), self.y_train)
plt.xlabel('Predicted value of Y')
plt.ylabel('Real value of Y')
plt.show()
def evaluate(self):
pred = self.model.predict(self.X_test)
mae=mean_absolute_error(self.y_test, pred)
mse = mean_squared_error(self.y_test, pred, squared=True)
rmse = mean_squared_error(self.y_test, pred, squared=False)
r2score=r2_score(self.y_test, pred)
return MetricsResult(mae,mse,rmse,r2score)
def predictPriceFromGenderAndAge(self,gender,age):
data_gender = {'gender': ["Male", "Female"]}
df_gender = pd.DataFrame(data=data_gender)
df_gender_transform = self.le.fit_transform(df_gender)
col_gender = 0
if gender == 'Male':
col_gender = 0
else:
col_gender = 1
data = [[df_gender_transform[col_gender], age]]
input_transform = self.sc_std.transform(data)
pred = self.predict(input_transform)
return pred
def predictPriceFromGenderAndAgeAndPayment(self,gender,age,payment_method):
data_gender= {'gender': ["Male", "Female"]}
df_gender=pd.DataFrame(data=data_gender)
df_gender_transform=self.le.fit_transform(df_gender)
data_payment_method={"payment_method":["Credit Card","Debit Card","Cash"]}
df_payment_method=pd.DataFrame(data=data_payment_method)
df_payment_method_transform=self.le.fit_transform(df_payment_method)
col_gender=0
if gender == 'Male':
col_gender=0
else:
col_gender = 1
col_payment=0
if payment_method=="Credit Card":
col_payment=0
elif payment_method=="Debit Card":
col_payment=1
else:
col_payment = 2
data = [[df_gender_transform[col_gender], age,df_payment_method_transform[col_payment]]]
input_transform = self.sc_std.transform(data)
pred = self.predict(input_transform)
return pred
def predict(self,columns_input):
pred = self.model.predict(columns_input)
return pred
def saveModel(self,fileName):
ret=FileUtil.saveModel(self.trainedmodel,fileName)
return ret
def loadModel(self,fileName):
self.trainedmodel=FileUtil.loadModel(fileName)
self.sc_std.fit_transform(self.trainedmodel.X_train)
self.model=self.trainedmodel.model
return self.model
Bước 3: Tạo các lớp test các thư viện ở bước 2 trong thư mục “Tests“
Bước 3.1: Tạo “AppStatistic.py” để test các hàm thống kê. Ta có thể chạy tập tin này độc lập để test:
from Connectors.Connector import Connector
from Models.PurchaseStatistic import PurchaseStatistic
connector=Connector(server="localhost",port=3306,database="lecturer_retails",username="root",password="@Obama123")
connector.connect()
pm=PurchaseStatistic()
pm.connector=connector
pm.execPurchaseHistory()
dfGender=pm.processGenderDistribution()
print(dfGender)
pm.visualizePieChart(dfGender,"gender","count","Gender Distribution")
dfAge=pm.processAgeDistribution(30,50)
print(dfAge)
pm.visualizePlotChart(dfAge,"age","count","Age Distribution 30~50")
dfCategory=pm.processCategoryDistribution()
print(dfCategory)
pm.visualizePieChart(dfCategory,"category","count","Categories Distribution",legend=False)
dfCateSpending=pm.processCategorySpending()
print(dfCateSpending)
pm.visualizeBarChart(dfCateSpending,"category","price","Distribution category and Spending")
dfGenderCategory=pm.processGenderAndCategoryCounter()
print(dfGenderCategory)
pm.visualizeCountPlot(pm.df,"category","count","gender","Distribution gender and category")
dfPayment=pm.processPaymentMethod()
print(dfPayment)
pm.visualizePieChart(dfPayment,"payment_method","count","Payment Distribution",legend=False)
dfShoppingMall=pm.processShoppingMall()
print(dfShoppingMall)
pm.visualizePieChart(dfShoppingMall,"shopping_mall","count","Shopping Mall Distribution",legend=False)
dfGenderCateSpending=pm.processGenderCategorySpending()
print(dfGenderCateSpending)
pm.visualizeBarPlot(dfGenderCateSpending,"category","price","gender","Male and Female category Total Price Spend")
dfAgeGender=pm.processAgeOrderFrequence()
print(dfAgeGender)
pm.visualizeScatterPlot(dfAgeGender,"age","count","Age VS Order Frequence")
dfMonthlySalesAmount=pm.processMonthlySalesAmount()
print(dfMonthlySalesAmount)
pm.visualizeLinePlotChart(dfMonthlySalesAmount,"month","sales_amount","Monthly Variation in Sales Amount")
dfMonthlyAndYearSalesAmount=pm.processMonthlyAndYearSalesAmount()
print(dfMonthlyAndYearSalesAmount)
pm.visualizeLinePlotChart(dfMonthlyAndYearSalesAmount,"month","sales_amount","Monthly Variation in Sales Amount Over Years",hue="year")
Bước 3.2: Tạo “AppModel.py” để test tiền xử lý và transformation. Ta có thể chạy tập tin này độc lập để test:
from Connectors.Connector import Connector
from Models.PurchaseMLModel import PurchaseMLModel
connector=Connector(server="localhost",port=3306,database="lecturer_retails",username="root",password="@Obama123")
connector.connect()
pm=PurchaseMLModel(connector)
pm.execPurchaseHistory()
dfTransform=pm.processTransform()
print(dfTransform.head())
pm.buildCorrelationMatrix(dfTransform)
Bước 3.3: Tạo “AppLinearRegression.py” để test train mô hình máy học, cũng như prediction. Ta có thể chạy tập tin này độc lập để test:
from Connectors.Connector import Connector
from Models.PurchaseLinearRegression import PurchaseLinearRegression
connector=Connector(server="localhost",port=3306,database="lecturer_retails",username="root",password="@Obama123")
connector.connect()
pm=PurchaseLinearRegression(connector=connector)
pm.processTrain(["gender","age"],"price",0.2,0)
#pm.processTrain(["gender","age","payment_method"],"price")
#pm.visualizeActualAndPredictResult()
eresult=pm.evaluate()
print(eresult)
gender="Male"
age=61
pred=pm.predictPriceFromGenderAndAge(gender,age)
print("Gender=%s and Age=%s=>Price=%s"%(gender,age,pred))
gender="Female"
age=61
pred=pm.predictPriceFromGenderAndAge(gender,age)
print("Gender=%s and Age=%s=>Price=%s"%(gender,age,pred))
print("------------------"*10)
pm=PurchaseLinearRegression()
pm.connector=connector
pm.processTrain(["gender","age","payment_method"],"price",0.2,0)
eresult=pm.evaluate()
print(eresult)
gender="Male"
age=61
payment="Credit Card"
pred=pm.predictPriceFromGenderAndAgeAndPayment(gender,age,payment)
print("Gender=%s and Age=%s and payment=%s=>Price=%s"%(gender,age,payment,pred))
gender="Male"
age=61
payment="Debit Card"
pred=pm.predictPriceFromGenderAndAgeAndPayment(gender,age,payment)
print("Gender=%s and Age=%s and payment=%s=>Price=%s"%(gender,age,payment,pred))
gender="Male"
age=61
payment="Cash"
pred=pm.predictPriceFromGenderAndAgeAndPayment(gender,age,payment)
print("Gender=%s and Age=%s and payment=%s=>Price=%s"%(gender,age,payment,pred))
ret=pm.saveModel("../Assets/LR_mymodel.zip")
print("ret save model=%s"%ret)
Bước 3.4: Tạo “TestLoadModel.py” để nạp mô hình từ ổ cứng , cũng như prediction. Ta có thể chạy tập tin này độc lập để test:
from Models.PurchaseLinearRegression import PurchaseLinearRegression
pm=PurchaseLinearRegression()
pm.loadModel("../Assets/TrainedModel_GenderAgePayment.zip")
gender="Female"
age=61
payment="Cash"
pred=pm.predictPriceFromGenderAndAgeAndPayment(gender,age,payment)
print("Gender=%s and Age=%s and payment=%s=>Price=%s"%(gender,age,payment,pred))
#Gender=Female and Age=61 and payment=Cash=>Price=[692.98688316]
Bước 4: Tạo lớp tập tin “FileUtils.py” trong thư mục Utils để lưu mô hình máy học và nạp mô hình máy học:
Bước 5.5: Tạo Python code kế “DatabaseConnectEx.py” thừa Ui_MainWindow của mã lệnh Generate Python code giao diện “DatabaseConnect.py” để xử lý sự kiện tương tác người dùng:
import traceback
from PyQt6.QtCore import Qt
from PyQt6.QtWidgets import QMessageBox
from Connectors.Connector import Connector
from UI.DatabaseConnect import Ui_MainWindow
class DatabaseConnectEx(Ui_MainWindow):
def setupUi(self, MainWindow):
super().setupUi(MainWindow)
self.MainWindow=MainWindow
self.pushButtonConnect.clicked.connect(self.connectDatabase)
def connectDatabase(self):
try:
self.connector=Connector()
self.connector.server=self.lineEditServer.text()
self.connector.port=(int)(self.lineEditPort.text())
self.connector.database=self.lineEditDatabase.text()
self.connector.username=self.lineEditUser.text()
self.connector.password=self.lineEditPassword.text()
self.connector.connect()
self.msg=QMessageBox()
self.msg.setText("Connect database successful!")
self.msg.setWindowTitle("Info")
#self.msg.show()
self.MainWindow.close()
if self.parent!=None:
self.parent.checkEnableWidget(True)
except:
traceback.print_exc()
self.msg = QMessageBox()
self.msg.setText("Connect database failed")
self.msg.setWindowTitle("Info")
self.msg.show()
def show(self):
self.MainWindow.setWindowModality(Qt.WindowModality.ApplicationModal)
self.MainWindow.show()
Bước 5.6: Tạo giao diện chính của dự án để thực hiện chức năng thống kê và máy học “MainWindow.ui“:
Thiết kế giao diện và đặt tên các Widget như trên.
Bước 5.7: Generate Python code cho “MainWindow.ui“, ta có dữ liệu mã lệnh “MainWindow.py“:
Bước 5.8: Tạo Python code kế “MainWindowEx.py” thừa Ui_MainWindow của mã lệnh Generate Python code giao diện “MainWindow.py” để xử lý sự kiện tương tác người dùng:
from PyQt6.QtWidgets import QApplication, QMainWindow
from UI.MainWindowEx import MainWindowEx
qApp=QApplication([])
qmainWindow=QMainWindow()
window=MainWindowEx()
window.setupUi(qmainWindow)
window.show()
qApp.exec()
Chạy App.py ta có kết quả:
Vào menu System chọn Connect Database:
Nhập thông số kết nối:
Bấm “Connect” để kết nối, nếu kết nối thành công ta có giao diện như dưới đây:
Các bạn thử 11 chức năng thông kế sẽ có các kết quả như mong muốn
(1.1) Thống kê tỉ lệ mua hàng theo giới tính
(1.2) Thống kê số lượng mua hàng theo độ tuổi
(1.3) Thống kê số lượng mua hàng theo danh mục sản phẩm
(1.4) Thống kê trị giá hàng hóa bán được theo danh mục
(1.5) Thống kê lượng hàn bán ra theo độ tuổi và danh mục
(1.6) Thống kê số lượng giao dịch theo phương thức thanh toán
(1.7) Thống kê tỉ lệ bán hàng theo Trung tâm thương mại (Shopping Mall)
(1.8) Thống kê trị giá hàng hóa bán được theo danh mục và giới tính
(1.9) Thống kê tần suất mua hàng theo độ tuổi và giới tính
(1.10) Thống kê biến động doanh thu theo tháng
(1.11) Thống kê biến động doanh thu theo tháng và theo năm
Về thử nghiệm chức năng máy học:
Như vậy tới đây Tui đã trình bày hoàn chỉnh dự án MLBAProject. dự án phục vụ thống kê và train mô hình máy học, dự án kết nối cơ sở dữ liệu, tổng hợp nhiều kiến thức.
Các bạn nhớ thực hành nhiều lần để hiểu rõ hơn về dự án.
Source code dự án đầy đủ các bạn tham khảo tại đây:
Bài 53 và bài 54 các bạn đã hiểu rõ và thực hành thuần thục mô hình hồi quy đơn biến. Trong bài học này Tui trình bày về hồi quy đa biến – Multiple Linear Regression. Hầu hết các dự báo với bài toán hồi quy thường rơi vào mô hình đa biến. Ví dụ bài 54 ta tính giá nhà dựa trên mô hình đơn biến, nhưng trong thực tế giá nhà nó lệ thuộc vào nhiều yếu tố như Số phòng, số tầng, mặt tiền… Đó chính là dấu hiệu của đa biến.
Hay dự báo giá sản phẩm lệ thuộc vào màu sắc, chất lượng… đây cũng là dấu hiệu của đa biến.
Multiple Linear Regression: Mô hình hồi quy tuyến tính đa biến có nhiều hơn một biến độc lập, biểu diễn mối quan hệ tuyến tính giữa các biến độc lập và biến phụ thuộc.
Về cơ bản không có sự khác biệt giữa hồi quy tuyến tính ‘giản đơn’ và ‘đa biến’. Cả hai đều làm việc tuân theo nguyên tắc OLS –Ordinary Least Square và thuật toán để có được đường hồi quy tối ưu nhất cũng tương tự. Trong trường hợp sau, phương trình hồi quy sẽ có một hình dạng như sau:
Công thức chung:
Y=B0+B1*X1+B2*X2+B3*X3…..+Bn*Xn
Bi: Các hệ số khác nhau
Xi: Các biến độc lập khác nhau
Bài học này chúng ta dùng Microsoft Excel để lập trình các dữ kiện phục cho cho mô hình hồi quy đa biến.
Giả sử ta có tập dữ liệu như dưới đây:
Color
Quality
Price
7
5
65
3
7
38
5
8
51
8
1
38
9
3
55
5
4
43
4
0
25
2
6
33
8
7
71
6
4
51
9
2
49
Quan sát tập dữ liệu trên gồm có 3 biến Color, Quality, Price.
Biến độc lập: Color, Quality
Biến phụ thuộc: Price
Dùng hồi quy tuyến tính để tính Price predicted, thực hiện các công thức trong Microsoft Excel.
Ta Cần tính được 4 đại lượng dưới đây:
(X’X)
(X’X)_inv
(X’Y)
B_hat
Sau đó lắp ráp công thức:
Y=B0+B1*X1+B2*X2+B3*X3…..+Bn*Xn
Ta bắt đầu thực hiện:
Bước 1: Chèn cột x0 có giá trị như hình dưới đây (mặc định là 1)
Bạn quan sát, dữ liệu gốc gồm có 3 cột trong Excel: Color, Quality, Price
Sau đó ta chèn x0 là cột đầu tiền trong ma trận dữ liệu mới
Bước 2: Tính (X’X)
Nhập công thức, lựa chọn các cột như hình và nhấn Enter
Lưu ý tích ma trận (X’X) sử dụng công thức MMULT trả về tích ma trận của 2 mảng, và TRANSPOSE chuyển vị ma trận.
Sau khi nhập công thức và nhấn Enter, ta có kết quả:
Ta thấy Excel ra giá trị #VALUE!, lưu ý đây không phải lỗi.
Ta bôi đen 3 Cell của (X’Y) và thực hiện theo đúng thứ tự 3 bước sau:
(01) Giá trị sẽ xuất hiện
(02) Bôi đen cột K, bôi đủ 3 cell cho (X’Y)
(03) Di chuyển trỏ chuột tới ô địa chỉ của Excel: Nhấn CTRL+SHIFT+ENTER
Sau khi nhấn CTRL+SHIFT+ENTER, ta có kết quả:
Bước 5:Tính B_hat
Nhập công thức, lựa chọn các cột như hình và nhấn Enter
Lưu ý B_hat tính tích 2 ma trận (X’X)_inv và (X’Y), ta dùng công thức MMULT như trên, cùng với kéo các ma trận đúng địa chỉ ô Cell.
Sau khi nhận công thức hoàn tất, nhấn phím Enter, ta có kết quả:
Ta tiếp tục thực hiện đúng thứ tự các bước sau:
(01) Giá trị sẽ xuất hiện
(02) Bôi đen cột N, bôi đủ 3 cell cho B_hat
(03) Di chuyển trỏ chuột tới ô địa chỉ của Excel: Nhấn CTRL+SHIFT+ENTER
Sau khi nhấn CTRL+SHIFT+ENTER, ta có kết quả:
Bước 6:Lắp ráp công thức để tính:
Y=B0+B1*X1+B2*X2+B3*X3…..+Bn*Xn
Bổ sung thêm cột Predicted Price cho file excel, và lắp ráp công thức như dưới đây:
Bạn quan sát kỹ cách ráp công thức B_hat để nhân vào các biến độc lập cho cột Predicted Price.
N9 là B0
N10 là B1
N11 là B2
predicted price=N9+N10*F2+N11*G2
Các dấu $ là địa chỉ tuyệt đối vì B0, B1, B2 là cố định.
Sau khi nhấn Enter, bạn kéo công thức xuống hết các dòng dữ liệu để xem Predicted Price:
Bước 7:Kiểm tra sai số khi Prediction, sử dụng Square Error, MSE, RMSE:
Cột Squared Error Tui mới bổ sung ở trên, đơn giản chỉ là lấy giá trị thực – giá trị prediction. Nó phục vụ để tính MSE và RMSE
MSE tính theo công thức: Trung bình cộng của Squared Error
RMSE tính theo công thức: Là căn bậc 2 của MSE
Như vậy tới đây Tui đã hoàn tất việc hướng dẫn phương trình hồi quy tuyến tính với mô hình Đa Biến. các công thức thực hiện trên Microsoft Excel
các bạn cần làm lại nhiều lần để hiểu rõ lý thuyết vì sao sử dụng các ma trận, các thao tác trên ma trận ở trên để có thể vận dụng thực hiện hồi quy đa biến vào dự báo giá nhà.
Bạn có thể tải file Excel chi tiết Tui thực hiện ở đây, trong Excel có link và youtube hướng dẫn tham khảo:
Trong bài 53 Tui đã trình bày chi tiết công thức hồi quy đơn biến, cũng như giải thích cách tính chi tiết các thông số của công thức, thực hiện trên Excel và lập trình bằng Python, trực quan hóa kết quả thực hiện hồi quy đơn biến.
Để củng cố thêm kiến thức cũng như kỹ năng lập trình và ứng dụng hồi quy đơn biến, trong bài này Tui tiếp tục cung cấp một ví dụ minh họa về dự báo giá nhà áp dụng hồi quy đơn biến. Đặc biệt Tui minh họa thêm cách huấn luyện mô hình hồi quy đơn biến bằng Sklearn-Python. Như vậy trong ví dụ thứ 2 này chúng ta sẽ thực hành bằng 3 cách để dự báo giá nhà:
Tập dữ liệu gồm có 2 biến x, y. Biến độc lập là x (diện tích nhà), biến phụ thuộc là y (Giá nhà – tỉ VNĐ)
Dùng hồi quy tuyến tính để tính y predicted giá nhà
Cách 1:Tính toán hồi quy đơn biên trong Microsoft Excel
Như đã đề cập về cách tính toán các thông số cho phương trình hồi quy:
Y = Β0 + Β1*X
Tính độ lệch chuẩn của biến độc lập x: Sử dụng Công thức STDEV
Tính độ lệch chuẩn của biến phụ thuộc y: Sử dụng Công thức STDEV
Tính trung bình của các biến độc lập x: Sử dụng Công thức AVERAGE
Tính trung bình của các biến phụ thuộc y: Sử dụng công thức AVERAGE
Tính độ tương quan giữa x và y: Sử dụng Công thức CORREL
Tính B1: Sử dụng Công thức
Độ Tương quan *( Độ lệch chuẩn của y / Độ lệch chuẩn của x)
7. Tính B0: Sử dụng công thức
Trung bình (Y) – B1 * Trung bình (X)
Ta bắt đầu lắp ráp công thức trong Excel để tính 7 dữ kiện cho công thức hồi quy đơn biến như dưới đây:
Hình trên là công thức để tính 7 dữ kiện liên quan tới hồi quy đơn biến. Ta quan sát kết quả đạt được:
Sau khi có 7 dữ kiện, ta bổ sung cột y_predicted để lắp ráp vào công thức:
Y = Β0 + Β1*X
Ta xem công thức Tui thực hiện cho phương trình:
Bạn chú ý các ô Cell tính toán công thức nó lệ thuộc vào dữ liệu bạn nhập, nếu nhập theo đúng cấu trúc mà Tui chụp hình ở trên thì các địa chỉ cell không cần đổi, còn nếu bạn nhập khác với cấu trúc file Excel mà Tui cung cấp thì cần tham chiếu địa chỉ ô cell cho đúng.
Ta xem kết quả thực hiện y-predicted:
Ta quan sát thấy kết quả dự báo rất sát với kết quả thực tế, ta xem thêm trực quan hóa đồ thị:
Các bạn có thể tải file Excel cùng với các công thức mà Tui đã thực hiện ở đây:
Cách 2: Lập trình Python để tính toán các dữ kiện nhằm thực hiện công thức hồi quy đơn biến
Ta thực hiện mã lệnh Python để tính toán dựa trên toán học ra các kết quả b1, b0 như dưới đây:
import matplotlib.pyplot as plt
import numpy as np
# area
x = np.array([[73.5,75.,76.5,79.,81.5,82.5,84.,85.,86.5,87.5,89.,90.,91.5]]).T
# price
y = np.array([[1.49,1.50,1.51,1.54,1.58,1.59,1.60,1.62,1.63,1.64,1.66,1.67,1.68]]).T
def calculateb1b0(x,y):
# tính trung bình
xbar = np.mean(x)
ybar = np.mean(y)
x2bar = np.mean(x ** 2)
xybar = np.mean(x * y)
# tính b0, b1
b1 = (xbar * ybar - xybar) / (xbar ** 2 - (x2bar))
b0 = ybar - b1 * xbar
return b1,b0
#calulate b1, b0
b1,b0=calculateb1b0(x,y)
print("b1=",b1)
print("b0=",b0)
y_predicted=b0+b1*x
print(y_predicted)
Thực hiện lệnh trên ta có kết quả:
Ta quan sát kết quả, rất giống với cách thực hiện trong Excel.
Tiếp tục viết mã lệnh để trực quan hóa kết quả, so sánh giá trị thực và giá trị predicted:
# Visualize data
def showGraph(x, y,y_predicted, title="", xlabel="", ylabel=""):
plt.figure(figsize=(14, 8))
plt.plot(x, y, 'r-o', label="price")
plt.plot(x, y_predicted, 'b-*', label="predicted value")
x_min = np.min(x)
x_max = np.max(x)
y_min = np.min(y)
y_max = np.max(y)
# mean y
ybar = np.mean(y)
plt.axhline(ybar, linestyle='--', linewidth=4, label="mean")
plt.axis([x_min*0.95, x_max*1.05, y_min*0.95, y_max*1.05])
plt.xlabel(xlabel, fontsize=16)
plt.ylabel(ylabel, fontsize=16)
plt.text(x_min, ybar*1.01, "mean", fontsize=16)
plt.legend(fontsize=15)
plt.title(title, fontsize=20)
plt.show()
showGraph(x, y,y_predicted,
title='Giá nhà theo diện tích',
xlabel='Diện tích (m2)',
ylabel='Giá nhà (tỷ VND)')
Thực thi lệnh trên ta có kết quả:
Nhìn vào kết quả trực quan hóa, ta thấy mô hình hồi quy đơn biến cho ra kết quả prediction khá tương đồng với giá trị thực, tức là mô hình chất lượng. Tuy nhiên đây chỉ là đơn biến, giá nhà nó không chỉ lệ thuộc vào diện tích mà nó còn lệ thuộc vào rất nhiều yếu tố khác như: số phòng, số tầng, mặt tiền, các tiện ích xung quanh….
Các bạn có thể tải Source code Python tính toán hồi quy đơn biến ở đây:
Cách 3: Huấn luyện mô hình máy học cho mô hình hồi quy tuyến tính đơn biến
Cách này chúng ta dùng linear_model trong thư viện sklearn để huấn luyện mô hình hồi quy. Chúng ta sẽ so sánh cách lập trình Python theo công thức toán học và theo thư viện sklearn.
import matplotlib.pyplot as plt
import numpy as np
from sklearn import linear_model
# area
x = np.array([[73.5,75.,76.5,79.,81.5,82.5,84.,85.,86.5,87.5,89.,90.,91.5]]).T
# price
y = np.array([[1.49,1.50,1.51,1.54,1.58,1.59,1.60,1.62,1.63,1.64,1.66,1.67,1.68]]).T
# input matrix X
X = np.concatenate([x], axis = 1)
def calculateb1b0(x,y):
# tính trung bình
xbar = np.mean(x)
ybar = np.mean(y)
x2bar = np.mean(x ** 2)
xybar = np.mean(x * y)
# tính b0, b1
b1 = (xbar * ybar - xybar) / (xbar ** 2 - (x2bar))
b0 = ybar - b1 * xbar
return b1,b0
#calulate b1, b0
b1,b0=calculateb1b0(x,y)
print("Lập trình Python theo công thức toán học:")
print("b1=",b1)
print("b0=",b0)
y_predicted=b0+b1*x
print(y_predicted)
# fit the model by Linear Regression
# fit_intercept = False for calculating the bias
regr = linear_model.LinearRegression(fit_intercept=True)
regr.fit(X, y)
print("Lập trình Python theo mô hình huấn luyện máy học LinearRegression:")
# Compare two results
print('Coefficient : ', regr.coef_)
print('Interception : ', regr.intercept_)
# Dự báo giá nhà ngay trên tập huấn luyện
ypred = regr.predict(X)
print(ypred)
Thực hiện lệnh trên ta có kết quả so sánh của 2 cách:
Quan sát các giá trị:
Theo công thức lập trình dựa trên tính toán toán học: b1, b0, y_predicted
Theo huấn luận mô hình máy học: Coefficient, Interception và ypred
Các giá trị này là tương đương nhau.
Như vậy rõ ràng, khi dùng thư viện huấn luyện mô hình máy học sẽ nhanh gọn lẹ hơn, vì ta chỉ cần học cách sử dụng thư viện (với 2 dòng lệnh là tính ra được b1(Coefficient), b0(Interception)).
Tiếp theo ta bổ sung mã lệnh để trực quan hóa kết quả:
Dưới đây là mã lệnh đầy đủ của huấn luyện mô hình máy học:
import matplotlib.pyplot as plt
import numpy as np
from sklearn import linear_model
# area
x = np.array([[73.5,75.,76.5,79.,81.5,82.5,84.,85.,86.5,87.5,89.,90.,91.5]]).T
# price
y = np.array([[1.49,1.50,1.51,1.54,1.58,1.59,1.60,1.62,1.63,1.64,1.66,1.67,1.68]]).T
# input matrix X
X = np.concatenate([x], axis = 1)
def calculateb1b0(x,y):
# tính trung bình
xbar = np.mean(x)
ybar = np.mean(y)
x2bar = np.mean(x ** 2)
xybar = np.mean(x * y)
# tính b0, b1
b1 = (xbar * ybar - xybar) / (xbar ** 2 - (x2bar))
b0 = ybar - b1 * xbar
return b1,b0
#calulate b1, b0
b1,b0=calculateb1b0(x,y)
print("Lập trình Python theo công thức toán học:")
print("b1=",b1)
print("b0=",b0)
y_predicted=b0+b1*x
print(y_predicted)
# fit the model by Linear Regression
# fit_intercept = False for calculating the bias
regr = linear_model.LinearRegression(fit_intercept=True)
regr.fit(X, y)
print("Lập trình Python theo mô hình huấn luyện máy học LinearRegression:")
# Compare two results
print('Coefficient : ', regr.coef_)
print('Interception : ', regr.intercept_)
# Dự báo giá nhà ngay trên tập huấn luyện
ypred = regr.predict(X)
print(ypred)
# Visualize data
def showGraph(x, y_act, y_pred, title="", xlabel="", ylabel=""):
plt.figure(figsize=(14, 8))
plt.plot(x, y_act, 'r-o', label="price actual")
plt.plot(x, y_pred, '--', label="price predict")
x_min = np.min(x)
x_max = np.max(x)
y_min = np.min(y_act)
y_max = np.max(y_act)
# mean price
ybar = np.mean(y_act)
plt.axhline(ybar, linestyle='--', linewidth=4, label="mean actual")
plt.axis([x_min*0.95, x_max*1.05, y_min*0.95, y_max*1.05])
plt.xlabel(xlabel, fontsize=16)
plt.ylabel(ylabel, fontsize=16)
plt.text(x_min, ybar*1.01, "mean actual", fontsize=16)
plt.legend(fontsize=15)
plt.title(title, fontsize=20)
plt.show()
showGraph(x, y,ypred,
title='Dự báo Giá nhà theo diện tích',
xlabel='Diện tích (m2)',
ylabel='Giá nhà (tỷ VND)')
Như vậy tới đây Tui đã hướng dẫn đầy đủ ví dụ thứ 2, với 3 cách: Vừa thực hiện trong Excel, vừa lập trình Python theo công thức toán học để tính ra b0, b1 và predicted. Và cuối cùng là huấn luyện mô hình máy học theo thư viện sklearn. Cả 3 cách này đều cho kết quả như nhau, do đó nền tảng toán học rất quan trọng, nếu hiểu toán học để áp dụng thì việc sử dụng thư viện sẽ thuận tiện hơn vì ta đã hiểu được bản chất.
Source code của huấn luyện mô hình các bạn tải ở đây:
Phương trình hồi qui tuyến tính có rất nhiều ứng dụng trong thực tiễn và là một trong những lớp mô hình đặc biệt quan trọng trong machine learning.
Ứng dụng vào việc dự báo về nhu cầu thị trường của một doanh nghiệp để chuẩn bị kế hoạch sản suất kinh doanh. Trong tài chính chúng ta có thể dự báo giá chứng khoán và các chỉ số tài chính dựa trên hồi qui tuyến tính. Hay ta có thể ứng dụng dự báo chỉ số lạm phát, tốc độ tăng trưởng GDP của quốc gia…
Hầu hết các bài toán dự báo liên quan tới biến mục tiêu liên tục thì đều có thể sử dụng hồi qui tuyến tính để dự báo.
Bài học hồi quy tuyến tính đơn biến – Simple Linear Regression sẽ được Tui viết thành 2 bài Blog với 2 ví dụ khác nhau. Các bài học đều thử nghiệm trên Excel và trong Python để các bạn dễ dàng hiểu lý thuyết cũng như ứng dụng trong thực tế.
Sau khi trình bày lý thuyết xong, Tui sẽ hướng dẫn các bạn cách tính Hồi quy đơn biến bằng các công thức trong Microsoft Excel và sau đó là lập trình bằng Python:
Ta có thể triển khai hồi quy tuyến tính(Linear Regression) bằng:
R linear regression.
MATLAB linear regression
Sklearn linear regression
Linear regression Python
Linear regression C#
Linear regression Java
Excel linear regression
Tự thực hiện theo các công thức toán học
Simple Linear Regression: Mô hình hồi quy tuyến tính đơn biến chỉ có một biến độc lập (input feature) mô tả mối quan hệ tuyến tính giữa biến phụ thuộc (output target) và biến độc lập. Công thức tổng quát:
Y = Β0 + Β1*X
Ý nghĩa của các biến và hằng số:
Y = Biến phụ thuộc
X = Biến độc lập
Β0 = Hằng số
Β1 = Hệ số mối quan hệ giữa X và Y
Một số đặc tính của hồi quy tuyến tính:
Đường hồi quy luôn luôn đi qua trung bình của biến độc lập x cũng như trung bình của biến phụ thuộc y
Đường hồi quy tối thiểu hóa tổng của “Diện tích các sai số“. Nên đôi khi được gọi là “Ordinary Least Square (OLS)“
Β1 giải thích sự thay đổi trong Y với sự thay đổi X bằng một đơn vị. Nói cách khác, nếu chúng ta tăng giá trị của X bởi một đơn vị thì nó sẽ là sự thay đổi giá trị của Y
Để tính được giá trị của phương trình hồi quy đơn biến ta cần tính được các dữ kiện sau:
Độ lệch chuẩn của biến độc lập x
Độ lệch chuẩn của biến phụ thuộc y
Trung bình của các biến độc lập x
Trung bình của các biến phụ thuộc y
Độ tương quan giữa biến độc lập x và biến phục thuộc y
Y = Β0 + Β1*X
Tính B1
Cuối cùng là tính B0
Bây giờ chúng ta bắt đầu thực hiện hồi quy đơn biến trong Microsoft Excel, giả sử chúng ta có tập dữ liệu trong Excel như dưới đây:
x
y
1
2
2
4
3
3
4
6
5
9
6
12
7
13
8
15
9
18
10
20
Tập dữ liệu gồm có 2 biến x và y. Trong đó biến độc lập là x, biến phụ thuộc là y Dùng hồi quy tuyến tính để tính y predicted
Để cho nhanh và dễ hiểu, chúng ta thực hiện trong Excel trước, sau đó chúng ta sẽ lập trình bằng Python
Như đã đề cập về cách tính toán các thông số cho phương trình hồi quy:
Y = Β0 + Β1*X
Tính độ lệch chuẩn của biến độc lập x: Sử dụng Công thức STDEV
Tính độ lệch chuẩn của biến phụ thuộc y: Sử dụng Công thức STDEV
Tính trung bình của các biến độc lập x: Sử dụng Công thức AVERAGE
Tính trung bình của các biến phụ thuộc y: Sử dụng công thức AVERAGE
Tính độ tương quan giữa x và y: Sử dụng Công thức CORREL
Tính B1: Sử dụng Công thức
Độ Tương quan *( Độ lệch chuẩn của y / Độ lệch chuẩn của x)
7. Tính B0: Sử dụng công thức
Trung bình (Y) – B1 * Trung bình (X)
Ta bắt đầu lắp ráp công thức trong Excel để tính 7 dữ kiện cho công thức hồi quy đơn biến như dưới đây:
Các bạn quan sát Tui nhập các công thức tính toán các thông số, các bạn nhập chính xác như trên. Lưu ý các địa chỉ ô Excel tính toán nó lệ thuộc vào dữ liệu bạn nhập trong Excel, nếu nhập như bài học Tui đã soạn thì không cần đổi địa chỉ ô Excel.
Kết quả thực hiện sẽ hiển thị ra như dưới đây:
Sau khi có các kết quả rồi, ta bổ sung thêm một cột Y-Predicted để lắp ráp tính toán công thức:
Y = Β0 + Β1*X
Kết quả thực hiện phương trình hồi quy đa biến sẽ hiển thị như dưới đây:
Dựa vào cột y và y-predicted mà ta so sánh được kết quả giữa giá trị thực và giá trị dự báo:
Đường màu xanh là giá trị thực (y), đường màu cam là giá trị dự báo (y-predicted). Ta thấy kết quả dự báo khá sát với thực tế.
Bây giờ ta thử lập trình hồi quy đơn biến với Python:
import matplotlib.pyplot as plt
import numpy as np
x = np.array([[1,2,3,4,5,6,7,8,9,10]]).T
y = np.array([[2,4,3,6,9,12,13,15,18,20]]).T
def calculateb1b0(x,y):
# tính trung bình
xbar = np.mean(x)
ybar = np.mean(y)
x2bar = np.mean(x ** 2)
xybar = np.mean(x * y)
# tính b0, b1
b1 = (xbar * ybar - xybar) / (xbar ** 2 - (x2bar))
b0 = ybar - b1 * xbar
return b1,b0
#calulate b1, b0
b1,b0=calculateb1b0(x,y)
print("b1=",b1)
print("b0=",b0)
y_predicted=b0+b1*x
print(y_predicted)
Thực thi mã lệnh Python ở trên ta tính được b1 và b0 giống như Excel mà ta đã tính ở bên trên:
Tính được b1 và b0 coi như đã hoàn thành được phương trình hồi quy đơn biến. Vì có b1 và b0 ta tính được:
y_predicted=b0+b1*x
So sánh kết quả y_predicted cũng giống như Excel đã tính.
Ta tiếp tục bổ sung mã lệnh để trực quan hóa dữ liệu:
# Visualize data
def showGraph(x, y,y_predicted, title="", xlabel="", ylabel=""):
plt.figure(figsize=(14, 8))
plt.plot(x, y, 'r-o', label="value sample")
plt.plot(x, y_predicted, 'b-*', label="predicted value")
x_min = np.min(x)
x_max = np.max(x)
y_min = np.min(y)
y_max = np.max(y)
# mean y
ybar = np.mean(y)
plt.axhline(ybar, linestyle='--', linewidth=4, label="mean")
plt.axis([x_min*0.95, x_max*1.05, y_min*0.95, y_max*1.05])
plt.xlabel(xlabel, fontsize=16)
plt.ylabel(ylabel, fontsize=16)
plt.text(x_min, ybar*1.01, "mean", fontsize=16)
plt.legend(fontsize=15)
plt.title(title, fontsize=20)
plt.show()
showGraph(x, y,y_predicted,
title='Giá trị Y theo X',
xlabel='Giá trị X',
ylabel='Giá trị Y')
Chạy mã lệnh trên ta có kết quả:
Như vậy cách tính hồi quy đơn biến trong Excel và trong Python là giống nhau.
Sourecode đầy đủ của hồi quy đơn biến đối với bài học này:
import matplotlib.pyplot as plt
import numpy as np
x = np.array([[1,2,3,4,5,6,7,8,9,10]]).T
y = np.array([[2,4,3,6,9,12,13,15,18,20]]).T
def calculateb1b0(x,y):
# tính trung bình
xbar = np.mean(x)
ybar = np.mean(y)
x2bar = np.mean(x ** 2)
xybar = np.mean(x * y)
# tính b0, b1
b1 = (xbar * ybar - xybar) / (xbar ** 2 - (x2bar))
b0 = ybar - b1 * xbar
return b1,b0
#calulate b1, b0
b1,b0=calculateb1b0(x,y)
print("b1=",b1)
print("b0=",b0)
y_predicted=b0+b1*x
print(y_predicted)
# Visualize data
def showGraph(x, y,y_predicted, title="", xlabel="", ylabel=""):
plt.figure(figsize=(14, 8))
plt.plot(x, y, 'r-o', label="value sample")
plt.plot(x, y_predicted, 'b-*', label="predicted value")
x_min = np.min(x)
x_max = np.max(x)
y_min = np.min(y)
y_max = np.max(y)
# mean y
ybar = np.mean(y)
plt.axhline(ybar, linestyle='--', linewidth=4, label="mean")
plt.axis([x_min*0.95, x_max*1.05, y_min*0.95, y_max*1.05])
plt.xlabel(xlabel, fontsize=16)
plt.ylabel(ylabel, fontsize=16)
plt.text(x_min, ybar*1.01, "mean", fontsize=16)
plt.legend(fontsize=15)
plt.title(title, fontsize=20)
plt.show()
showGraph(x, y,y_predicted,
title='Giá trị Y theo X',
xlabel='Giá trị X',
ylabel='Giá trị Y')
Như vậy tới đây Tui đã hướng dẫn xong lý thuyết về hồi quy đơn biến, giải thích chi tiết các thông số trong công thức hồi quy đơn biến, cũng như các dữ kiện cần phải tính toán, và minh họa được cách tính hồi quy đơn biến trong Excel và bằng Python code.
Các bạn lưu ý thực hiện bài này nhiều lần, bài học sau Tui tiếp tục trình bày thêm một ví dụ về hồi quy đơn biến để dự báo giá nhà, cũng thực hiện trong Excel và trong Python code.
Bài học này Tui sẽ trình bày cách tái sử dụng mô hình máy học đã được train trong bài 44 để sử dụng trong phiên bản Website này.
Rõ ràng việc train mô hình máy học nó tốn thời gian và cần nhiều tài nguyên, như vậy sau khi train xong thì ta chỉ tái sử dụng thôi, chứ không phải mỗi lần chạy phần mềm lên là train lại mô hình nó sẽ không tối ưu hệ thống.
Thông qua bài này, các bạn sẽ biết cách tái sử dụng mô hình máy học ở các nền tảng khác nhau. Ví dụ bài 44, Tui đã hướng dẫn cách train mô hình máy học trên giao diện Windows viết bằng Python Tkinter, tạo ra được mô hình máy học lưu lại với file zip định dạng pickle. Bài này thì sẽ dùng Web python Flask Microservice để triệu gọi mô hình máy học được train để để sử dụng (tức không phải thực hiện các bước chọn dataset, train mô hình).
Thông qua ví dụ này, bạn có thể viết các module để đính kèm vào hệ thống thương mại điện tử có sẵn để tích hợp mô hình máy học vào chạy trên nền web. Đưới đây là màn hình Website chúng ta sẽ thiết kế và sử dụng mô hình máy học:
Và bắt buộc phải có kiến thức cơ bản về Website, HTML, Javascript, các bạn có thể học tại đây nếu chưa có kiến thức về nó:
Bây giờ ta bắt đầu thực hiện dự án:
Bạn cần phải tạo dự án có cấu trúc các tập tin và thư mục chính xác ở trên để nó khớp với các mã lệnh. Tui giải thích sơ lược như sau:
Thư mục “web” chứa các static files được lưu trong thư mục css và images. Đồng thời chứa thư mục “templates” để lưu trữ html
Thư mục “css” là định dạng Cascading Style Sheets (CSS) để định dạng website cho nó đẹp theo ý mình. Các định dạng được lưu trong file “maincss.css”
Thư mục “images” sẽ lưu các hình ảnh tĩnh để sử dụng cho thiết kế website trong các trang .html
Thư mục “templates” là thư mục chứa các mã lệnh html để thiết kế website cũng như tương tác lệnh với Python Flask, Ajax…
File “housingmodel_2024-07-15_13-30-34.zip” là file mô hình máy học được tạo ra từ bài 44. Bạn có thể lấy bất kỳ file mô hình máy học được train.
File “FileUtil.py” là file mã lệnh để nạp mô hình máy học vào bộ nhớ sau đó nó được đưa vào để sử dụng trên nền Web
File chính “app.py” là file mã lệnh Python dạng Flask MicrosoService để gọi các lệnh render website, nạp mô hình máy học, và triệu gọi mô hình máy học cũng như xuất kết quả prediction cho người sử dụng trên nền website.
Bây giờ ta đi vào chi tiết của từng mã lệnh:
File “FileUtil.py” mã lệnh này quen thuộc dùng để lưu mô hình xuống ổ cứng với định dạng pickle và tải mô hình máy học lên bộ nhớ, ta đã sử dụng ở các bài học trước:
Chỗ này ta cần khai báo chính xác như cấu trúc thư mục mà ta tạo trong Pycharm. Điều đó có nghĩa là gì? tức là nếu trong Pycharm ta tạo cấu trúc như thế nào thì khai báo ở đây y chang như mong muốn là được (tức là không cần phải giống như Tui tạo). Như cố gắng tạo cấu trúc như Tui hướng dẫn để tránh sai sót trong quá trình lập trình.
Vì ta đã khai báo template_folder trong đối tượng khởi tạo Flask rồi, nên khi gọi lệnh render_template(“index.html”) chương trình sẽ tự hiểu và tự động tạo giao diện website với index.html
Để kích hoạt website khi chạy, thì ta có lệnh:
if __name__ == "__main__":
app.run(host="localhost", port=9500, debug=True)
Ở trên ta chạy port 9500, bạn có thể đổi qua Port khác. Và tui để debug để tìm lỗi nếu có. Vì đang chạy local nên host là localhost
Cuối cùng đó là API doprediction để nhận kết quả từ Client (là các ô nhập liệu từ website) sau đó tải mô hình máy học để tiến hành prediction, sau khi prediction xong thì trả kết quả lại cho Client:
Như vậy Tui đã trình bày xong cách thiết kế giao diện Website, tích hợp mô hình máy học để dự báo giá nhà. Các bạn đã biết cách tái sử dụng mô hình máy học trong dự án, có kiến thức về HTML, CSS, Javascript và Python Flask Microservice.
Bài học sau Tui sẽ hướng dẫn các bài liên quan tới hệ quản trị cơ sở dữ liệu MySQL để quản trị dữ liệu, và phục vụ cho xử lý mô hình máy học, viết các dự án liên quan tới thống kê và máy học.
Trong bài 43, Chúng ta đã build ứng dụng máy học dự báo giá nhà chạy trên môi trường console, nó khó cho người sử dụng.
Bài này tui sẽ trình bày minh họa phần mềm mẫu sử dụng mô hình máy học để dự báo giá nhà bằng các tương tác trên giao diện Tkinter và vẫn sử dụng local dataset CSV ở bài học 43. Bài học sau Tui sẽ trình bày phần mềm tương tác giao diện bằng Web Python Flask Microservice để dự báo giá nhà.
Chúng ta xem kết quả phần mềm có giao diện tương tác như dưới đây sau khi thực hiện bài học này nhé:
Phần mềm gồm có các chức năng sau:
Chọn và tải Dataset để sử dụng
Hiển thị xem Dataset chi tiết
Lựa chọn tỉ lệ train và train mô hình máy học
Đánh giá chất lượng mô hình máy học để quyết định có chọn mô hình này hay không
Lưu mô hình máy học để tái sử dụng
Chọn và nạp mô hình máy học đã train để sử dụng
Sử dụng mô hình máy học đã train để dự báo giá trị căn nhà
Bây giờ ta đi vào chi tiết từng bước lập trình:
Bước 1: Tạo cấu trúc dự án “HousePricePrediction” trong Pycharm như hình dưới đây:
Mô tả sơ lược trước ý nghĩa của từng tập tin, thư mục để các bạn nắm tổng quan:
Thư mục “dataset” là thư mục chứa các dataset cùng cấu trúc để sử dụng trong dự án, trường hợp này Tui để sẵn dataset “USA_Housing.csv”, bạn có thể tải nó ở đây https://tranduythanh.com/datasets/USA_Housing.csv
Thư mục “model” dùng để lưu các mô hình máy học đã được train, và nó được tái sử dụng để prediction giá nhà trên phần mềm tùy vào lựa chọn của khách hàng
File “FileUtil.py” là file mã lệnh để lưu mô hình máy học dạng pickle
File “DataSetViewer.py” là file mã lệnh để hiển thị chi tiết dataset lên giao diện
File “HousePricePrediction.py” là là file mã lệnh chính để thiết kế giao diện và các tác vụ liên quan tới phần mềm
savemode(model, filename) : hàm này để lưu mô hình máy học được trained dạng pickle, thường có đuôi là .zip. Và ta mặc định sẽ lập trình để nó lưu vào thư mục model mà ta đã tạo trong dự án:
loadmodel(filename) hàm này tải lại mô hình máy học được lưu, filename là đường dẫn của mô hình máy học.
Tiếp theo là tới file mã lệnh “DataSetViewer.py“, file mã lệnh này để hiển thị chi tiết dữ liệu dạng lưới có dòng cột để quan sát
from tkinter import *
from tkinter import ttk
import pandas as pd
class DataSetViewer:
def __int__(self):
pass
def create_ui(self):
self.root = Tk()
self.root.title("Dataset viewer - House Pricing Prediction")
self.root.geometry("800x600")
main_panel = PanedWindow(self.root)
main_panel["bg"] = "yellow"
main_panel.pack(fill=BOTH, expand=True)
# define columns
columns = ('Avg. Area Income', 'Avg. Area House Age', 'Avg. Area Number of Rooms',
'Avg. Area Number of Bedrooms', 'Area Population','Price')
self.tree = ttk.Treeview(main_panel, columns=columns, show="headings")
# define headings
self.tree.heading("Avg. Area Income", text="Avg. Area Income")
self.tree.heading("Avg. Area House Age", text="Avg. Area House Age")
self.tree.heading("Avg. Area Number of Rooms", text="Avg. Area Number of Rooms")
self.tree.heading("Avg. Area Number of Bedrooms", text="Avg. Area Number of Bedrooms")
self.tree.heading("Area Population", text="Area Population")
self.tree.heading("Price", text="Price")
#self.tree.grid(row=0, column=0, sticky="nsew")
self.tree.pack(side=LEFT,fill=BOTH, expand=True)
scrollbar = ttk.Scrollbar(main_panel, orient=VERTICAL, command=self.tree.yview)
self.tree.configure(yscroll=scrollbar.set)
#scrollbar.grid(row=0, column=1, sticky="ns")
scrollbar.pack(side=RIGHT,fill=BOTH,expand=True)
def show_ui(self):
self.root.mainloop()
def show_data_listview(self,fileName):
df = pd.read_csv(fileName)
for i in range(0,len(df)):
values = [df.iloc[i][0], df.iloc[i][1], df.iloc[i][2], df.iloc[i][3], df.iloc[i][4], df.iloc[i][5]]
print(values)
self.tree.insert('', END, values=values)
Giao diện của DatasetViewer khi thực hiện nó sẽ như dưới đây:
Tiếp theo mã lệnh “HousePricePrediction.py” ta thực hiện như sau (khá phức tạp) và Tui đang để các lệnh xử lý máy học trong giao diện luôn chứ không tách riêng từng lớp hướng đối tượng, ta xem giao diện dưới đây mà ta cần phải làm:
Như vậy để có giao diện tương tác như trên thì chúng ta phải làm các công việc sau:
Bước 1: Thiết kế giao diện người dùng
Bước 2: Chức năng “1.PickDataset” để chọn dataset từ máy tính
Bước 3: Chức năng “2.View Dataset” để hiển thị chi tiết Dataset lên giao diện mà ta đã chọn
Bước 4: Chức năng train model “3.Train Model”
Bước 5: Chức năng đánh giá chất lượng mô hình “4.Evaluate Model”
Bước 6: Chức năng lưu mô hình máy học “5. Save Model”
Bước 7: Chức năng tải các mô hình máy học đã lưu vào optionmenu xổ xuống như hình
Bước 8: Chức năng nạp mô hình máy học lên bộ nhớ để sử dụng khi khách hàng chọn mô hình máy học được train trong option menu
Bước 9: Chức năng dự báo giá nhà “7. Prediction House Pricing”
Bây giờ ta đi vào từng bước:
Bước 1: Thiết kế giao diện người dùng
Ta tạo class HousePricePredictionUI và viết mã lệnh cho hàm create_ui() như dưới đây:
def do_train(self):
ratio=self.training_rate.get()/100
self.df = pd.read_csv(self.selectedFileName.get())
self.X = self.df[['Avg. Area Income', 'Avg. Area House Age',
'Avg. Area Number of Rooms','Avg. Area Number of Bedrooms',
'Area Population']]
self.y = self.df['Price']
self.X_train, self.X_test, self.y_train, self.y_test = (
train_test_split(self.X, self.y, test_size=1-ratio, random_state=101))
self.lm = LinearRegression()
self.lm.fit(self.X_train, self.y_train)
self.status.set("Trained is finished")
messagebox.showinfo("infor","Trained is finished")
Bước 5: Chức năng đánh giá chất lượng mô hình “4.Evaluate Model”
Hàm này khá phức tạp, vì Tui muốn nó cập nhật dữ liệu cột trong bảng dữ liệu, tín hheje số coeff và hiển thị chi tiết lên giao diện:
Bước 6: Chức năng lưu mô hình máy học “5. Save Model”
def do_save_model(self):
#create name of new trained model
filename = "housingmodel_{}.zip".format(datetime.now().strftime("%Y-%m-%d_%H-%M-%S"))
#update trained model to option menu:
self.model_menu.children["menu"].add_command(label=filename,
command=lambda md=filename: self.selected_model.set(md))
file_path = os.path.join("model", filename)
FileUtil.savemodel(self.lm,file_path)
messagebox.showinfo("infor","exported model to disk successful!")
Chương trình sẽ tạo file mô hình máy học theo quy tắc nối ngày thời gian để không bị trùng, sau đó nó được lưu xuống ổ cứng đồng thời hiển thị lên Option menu. Bước 7: Chức năng tải các mô hình máy học đã lưu vào optionmenu xổ xuống như hình
def load_model_files(self):
strPlease="----Select a trained machine learning model----"
if not os.path.exists("model"):
return [strPlease]
model_files = [f for f in os.listdir("model") if os.path.isfile(os.path.join("model", f))]
model_files.insert(0,strPlease)
print(model_files)
return model_files
Bước 8: Chức năng nạp mô hình máy học lên bộ nhớ để sử dụng khi khách hàng chọn mô hình máy học được train trong option menu
def do_load_model(self):
trainedModelName=self.selected_model.get()
if trainedModelName.__contains__(".zip") ==False:
messagebox.showwarning("Warning",
"You have to select a trained machine learning model")
return
self.lm = FileUtil.loadmodel(os.path.join("model", self.selected_model.get()))
messagebox.showinfo("infor", "loading model from disk successful!")
Khi người dùng chọn mô hình trong Option menu, rồi nhấn nút Load mô hình, lúc này phần mềm sẽ tải mô hình lên bộ nhớ để tái sử dụng.
Bước 9: Chức năng dự báo giá nhà “7. Prediction House Pricing”
Đây là tiện ích cuối cùng của phần mềm để dự báo giá nhà, coding như sau:
def do_prediction(self):
result = self.lm.predict([[self.area_income_value.get(),
self.area_house_age_value.get(),
self.area_number_of_rooms_value.get(),
self.area_number_of_bedrooms_value.get(),
self.area_population_value.get()]])
self.prediction_price_value.set(result[0])
Dưới đây là mã lệnh chi tiết và đầy đủ của “HousePricePredictionUI.py”:
import os
from datetime import datetime
from tkinter import *
from tkinter import messagebox, ttk
from tkinter.font import Font
from tkinter import filedialog as fd
from DataSetViewer import DataSetViewer
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn import metrics
from sklearn.linear_model import LinearRegression
from FileUtil import FileUtil
class HousePricePredictionUI:
fileName:""
def __init__(self):
pass
def create_ui(self):
self.root=Tk()
self.root.title("Trần Duy Thanh - House Pricing Prediction tool")
self.root.geometry("1200x750")
main_panel=PanedWindow(self.root)
main_panel["bg"]="yellow"
main_panel.pack(fill=BOTH,expand=True)
top_panel = PanedWindow(main_panel, height=80)
top_panel["bg"] = "blue"
main_panel.add(top_panel)
top_panel.pack(fill=X, side=TOP, expand=False)
font=Font(family="tahoma",size=18)
title_label=Label(top_panel,text='House Pricing Prediction',font=font)
title_label["bg"]="yellow"
top_panel.add(title_label)
center_panel=PanedWindow(main_panel)
main_panel.add(center_panel)
center_panel["bg"]="pink"
center_panel.pack(fill=BOTH,expand=True)
choose_dataset_panel=PanedWindow(center_panel,height=30)
center_panel.add(choose_dataset_panel)
choose_dataset_panel["bg"]="orange"
choose_dataset_panel.pack(fill=X)
dataset_label=Label(choose_dataset_panel,text="Select Dataset:")
self.selectedFileName = StringVar()
self.selectedFileName.set("dataset/USA_Housing.csv")
self.choose_dateset_entry=Entry(choose_dataset_panel,
textvariable=self.selectedFileName)
self.choose_dataset_button = Button(choose_dataset_panel,
text="1.Pick Dataset",
width=10,
command=self.do_pick_data)
self.view_dataset_button = Button(choose_dataset_panel,
text="2.View Dataset",
width=20,
command=self.do_view_dataset)
choose_dataset_panel.add(dataset_label)
choose_dataset_panel.add(self.choose_dateset_entry)
choose_dataset_panel.add(self.choose_dataset_button)
choose_dataset_panel.add(self.view_dataset_button)
self.view_dataset_button.pack(side=RIGHT, expand=False)
self.choose_dataset_button.pack(side=RIGHT, expand=False)
#Training Rate
training_rate_panel = PanedWindow(center_panel, height=30)
center_panel.add(training_rate_panel)
training_rate_panel.pack(fill=X)
training_rate_label = Label(training_rate_panel, text="Training Rate:")
self.training_rate = IntVar()
self.training_rate.set(80)
self.training_rate_entry = Entry(training_rate_panel,
textvariable=self.training_rate,width=20)
training_rate_panel.add(training_rate_label)
training_rate_panel.add(self.training_rate_entry)
percent_label=Label(text="%",width=20,anchor="w", justify=LEFT)
percent_label.pack(side=RIGHT,expand=False,fill=X)
training_rate_panel.add(percent_label)
self.train_model_button=Button(training_rate_panel,
text="3.Train Model",
width=20,
command=self.do_train)
training_rate_panel.add( self.train_model_button)
self.evaluate_model_button = Button(training_rate_panel,
text="4.Evaluate Model",
width=20,
command=self.do_evaluation)
training_rate_panel.add(self.evaluate_model_button)
self.status=StringVar()
self.train_model_result_label = Label(training_rate_panel,
text=self.status.get(),
textvariable=self.status)
training_rate_panel.add(self.train_model_result_label)
evaluate_panel=PanedWindow(center_panel,height=400)
evaluate_panel["bg"]="cyan"
center_panel.add(evaluate_panel)
evaluate_panel.pack(fill=X)
table_evaluate_panel=PanedWindow(evaluate_panel,height=400)
evaluate_panel.add(table_evaluate_panel)
# define columns
columns = ('Avg. Area Income', 'Avg. Area House Age',
'Avg. Area Number of Rooms','Avg. Area Number of Bedrooms',
'Area Population', 'Original Price', 'Prediction Price')
self.tree = ttk.Treeview(table_evaluate_panel,
columns=columns, show="headings")
self.tree.column("# 1", anchor=CENTER, stretch=NO, width=100)
self.tree.column("# 2", anchor=CENTER, stretch=NO, width=100)
self.tree.column("# 3", anchor=CENTER, stretch=NO, width=100)
self.tree.column("# 4", anchor=CENTER, stretch=NO, width=100)
self.tree.column("# 5", anchor=CENTER, stretch=NO, width=100)
self.tree.column("# 6", anchor=CENTER, stretch=NO, width=100)
self.tree.column("# 7", anchor=CENTER, stretch=NO, width=100)
# define headings
self.tree.heading("Avg. Area Income", text="Avg. Income")
self.tree.heading("Avg. Area House Age", text="Avg. House Age")
self.tree.heading("Avg. Area Number of Rooms", text="Avg. Area Room")
self.tree.heading("Avg. Area Number of Bedrooms", text="Avg. Area Bedroom")
self.tree.heading("Area Population", text="Area Population")
self.tree.heading("Original Price", text="Original Price")
self.tree.heading("Prediction Price", text="Prediction Price")
# self.tree.grid(row=0, column=0, sticky="nsew")
self.tree.pack(side=LEFT, fill=BOTH, expand=True)
scrollbar = ttk.Scrollbar(table_evaluate_panel,
orient=VERTICAL, command=self.tree.yview)
self.tree.configure(yscroll=scrollbar.set)
# scrollbar.grid(row=0, column=1, sticky="ns")
scrollbar.pack(side=RIGHT, fill=BOTH, expand=True)
coefficient_panel=PanedWindow(evaluate_panel)
coefficient_panel["bg"]="pink"
coefficient_panel.pack(side=RIGHT,fill=X,expand=False)
evaluate_panel.add(coefficient_panel)
coefficient_detail_label=Label(coefficient_panel,text="Coefficient:")
coefficient_panel.add(coefficient_detail_label)
coefficient_detail_label.pack(side=TOP,fill=X,expand=False)
coefficient_detail_panel=PanedWindow(coefficient_panel)
coefficient_panel.add(coefficient_detail_panel)
coefficient_detail_panel.pack(side=TOP,expand=False,fill=X)
self.coefficient_detail_text = (
Text(coefficient_detail_panel, height=12,width=50))
scroll = Scrollbar(coefficient_detail_panel)
self.coefficient_detail_text.configure(yscrollcommand=scroll.set)
self.coefficient_detail_text.pack(side=LEFT,expand=False,fill=X)
scroll.config(command=self.coefficient_detail_text.yview)
scroll.pack(side=RIGHT, fill=Y,expand=True)
metric_panel=PanedWindow(coefficient_panel,height=30)
coefficient_panel.add(metric_panel)
metric_panel.pack(side=TOP,fill=BOTH,expand=True)
self.mae_value=DoubleVar()
mae_label=Label(metric_panel,text="Mean Absolute Error(MAE):")
mae_label.grid(row=0,column=0)
mae_entry = Entry(metric_panel, text="",
width=20,textvariable=self.mae_value)
mae_entry.grid(row=0, column=1)
self.mse_value = DoubleVar()
mse_label = Label(metric_panel, text="Mean Square Error(MSE):")
mse_label.grid(row=1, column=0)
mse_entry = Entry(metric_panel, text="", width=20,textvariable=self.mse_value)
mse_entry.grid(row=1, column=1)
self.rmse_value = DoubleVar()
rmse_label = Label(metric_panel, text="Root Mean Square Error(RMSE):")
rmse_label.grid(row=2, column=0)
rmse_entry = Entry(metric_panel, text="",
width=20,textvariable=self.rmse_value)
rmse_entry.grid(row=2, column=1)
savemodel_button = Button(metric_panel,
text="5. Save Model",
width=20,
command=self.do_save_model)
savemodel_button.grid(row=3, column=1)
loadmodel_panel=PanedWindow(center_panel,height=20)
loadmodel_panel["bg"]="yellow"
loadmodel_panel.pack(fill=BOTH,side=TOP)
model_files = self.load_model_files()
print(model_files)
self.selected_model = StringVar(self.root)
self.selected_model.set(model_files[0])
self.model_menu = OptionMenu(loadmodel_panel,
self.selected_model,
*model_files)
self.model_menu.grid(row=0, column=0)
loadmodel_button = Button(loadmodel_panel,
text="6. Load Model",
command=self.do_load_model)
loadmodel_button.grid(row=0, column=1)
input_prediction_panel = PanedWindow(center_panel)
input_prediction_panel.pack(fill=BOTH, side=TOP,expand=True)
area_income_label = Label(input_prediction_panel,
text="Avg. Area Income:")
area_income_label.grid(row=0, column=0)
self.area_income_value=DoubleVar()
area_income_entry = Entry(input_prediction_panel,
text="",
width=40,
textvariable=self.area_income_value)
area_income_entry.grid(row=0, column=1)
area_house_age_label = Label(input_prediction_panel,
text="Avg. Area House Age:")
area_house_age_label.grid(row=1, column=0)
self.area_house_age_value = DoubleVar()
area_house_age_entry = Entry(input_prediction_panel,
text="",
width=40,
textvariable=self.area_house_age_value)
area_house_age_entry.grid(row=1, column=1)
area_number_of_rooms_label = Label(input_prediction_panel,
text="Avg. Area Number of Rooms:")
area_number_of_rooms_label.grid(row=2, column=0)
self.area_number_of_rooms_value=DoubleVar()
area_number_of_rooms_entry = Entry(input_prediction_panel,
text="", width=40,
textvariable=self.area_number_of_rooms_value)
area_number_of_rooms_entry.grid(row=2, column=1)
area_number_of_bedrooms_label = Label(input_prediction_panel,
text="Avg. Area Number of Bedrooms:")
area_number_of_bedrooms_label.grid(row=3, column=0)
self.area_number_of_bedrooms_value=DoubleVar()
area_number_of_bedrooms_entry = Entry(input_prediction_panel,
text="", width=40,
textvariable=self.area_number_of_bedrooms_value)
area_number_of_bedrooms_entry.grid(row=3, column=1)
area_population_label = Label(input_prediction_panel, text="Area Population:")
area_population_label.grid(row=4, column=0)
self.area_population_value = DoubleVar()
area_population_entry = Entry(input_prediction_panel,
text="", width=40,
textvariable=self.area_population_value)
area_population_entry.grid(row=4, column=1)
prediction_button=Button(input_prediction_panel,
text="7. Prediction House Pricing",
command=self.do_prediction)
prediction_button.grid(row=5, column=1)
prediction_price_label = Label(input_prediction_panel,
text="Prediction Price:")
prediction_price_label.grid(row=6, column=0)
self.prediction_price_value=DoubleVar()
prediction_price_entry = Entry(input_prediction_panel,
text="", width=40,
textvariable=self.prediction_price_value)
prediction_price_entry.grid(row=6, column=1)
designedby_panel = PanedWindow(main_panel, height=20)
designedby_panel["bg"] = "cyan"
designedby_panel.pack(fill=BOTH, side=BOTTOM)
designedby_label = Label(designedby_panel,
text="Designed by: Tran Duy Thanh")
designedby_label["bg"] = "cyan"
designedby_label.pack(side=LEFT)
def show_ui(self):
self.root.mainloop()
def do_pick_data(self):
filetypes=(("Dataset CSV","*.csv"),
("All Files","*.*")
)
s=fd.askopenfilename(
title="Choose dataset",
initialdir="/",
filetypes=filetypes)
self.selectedFileName.set(s)
def do_view_dataset(self):
viewer= DataSetViewer()
viewer.create_ui()
viewer.show_data_listview(self.selectedFileName.get())
viewer.show_ui()
def do_train(self):
ratio=self.training_rate.get()/100
self.df = pd.read_csv(self.selectedFileName.get())
self.X = self.df[['Avg. Area Income', 'Avg. Area House Age',
'Avg. Area Number of Rooms','Avg. Area Number of Bedrooms',
'Area Population']]
self.y = self.df['Price']
self.X_train, self.X_test, self.y_train, self.y_test = (
train_test_split(self.X, self.y, test_size=1-ratio, random_state=101))
self.lm = LinearRegression()
self.lm.fit(self.X_train, self.y_train)
self.status.set("Trained is finished")
messagebox.showinfo("infor","Trained is finished")
def do_evaluation(self):
# print the intercept
print(self.lm.intercept_)
insert_text=self.lm.intercept_
self.coeff_df = pd.DataFrame(self.lm.coef_, self.X.columns, columns=['Coefficient'])
print(self.coeff_df)
self.coefficient_detail_text.insert(END, self.coeff_df)
predictions = self.lm.predict(self.X_test)
print(predictions)
print("self.X_test")
print(self.X_test)
print("self.y_test:")
print(self.y_test)
y_test_array=np.asarray(self.y_test)
for i in range(0,len(self.X_test)):
values = [self.X_test.iloc[i][0], self.X_test.iloc[i][1],
self.X_test.iloc[i][2], self.X_test.iloc[i][3],
self.X_test.iloc[i][4], y_test_array[i],predictions[i]]
print(values)
self.tree.insert('', END, values=values)
print('MAE:', metrics.mean_absolute_error(self.y_test, predictions))
print('MSE:', metrics.mean_squared_error(self.y_test, predictions))
print('RMSE:', np.sqrt(metrics.mean_squared_error(self.y_test, predictions)))
self.mae_value.set(metrics.mean_absolute_error(self.y_test, predictions))
self.mse_value.set(metrics.mean_squared_error(self.y_test, predictions))
self.rmse_value.set(np.sqrt(metrics.mean_squared_error(self.y_test, predictions)))
self.status.set("Evaluation is finished")
messagebox.showinfo("infor", "Evaluation is finished")
def do_save_model(self):
#create name of new trained model
filename = "housingmodel_{}.zip".format(datetime.now().strftime("%Y-%m-%d_%H-%M-%S"))
#update trained model to option menu:
self.model_menu.children["menu"].add_command(label=filename,
command=lambda md=filename: self.selected_model.set(md))
file_path = os.path.join("model", filename)
FileUtil.savemodel(self.lm,file_path)
messagebox.showinfo("infor","exported model to disk successful!")
def load_model_files(self):
strPlease="----Select a trained machine learning model----"
if not os.path.exists("model"):
return [strPlease]
model_files = [f for f in os.listdir("model") if os.path.isfile(os.path.join("model", f))]
model_files.insert(0,strPlease)
print(model_files)
return model_files
def do_load_model(self):
trainedModelName=self.selected_model.get()
if trainedModelName.__contains__(".zip") ==False:
messagebox.showwarning("Warning",
"You have to select a trained machine learning model")
return
self.lm = FileUtil.loadmodel(os.path.join("model", self.selected_model.get()))
messagebox.showinfo("infor", "loading model from disk successful!")
def do_prediction(self):
result = self.lm.predict([[self.area_income_value.get(),
self.area_house_age_value.get(),
self.area_number_of_rooms_value.get(),
self.area_number_of_bedrooms_value.get(),
self.area_population_value.get()]])
self.prediction_price_value.set(result[0])
Tiếp theo ta viết mã lệnh cho “App.py” để thực thi phần mềm:
from HousePricePredictionUI import HousePricePredictionUI
if __name__ == '__main__':
ui=HousePricePredictionUI()
ui.create_ui()
ui.show_ui()
Như vậy Tui đã làm xong case study với dự án mẫu cho phần mềm tương tác người dùng, sử dụng mô hình máy học để dự báo giá nhà bằng Tkinter. Chạy phần mềm lên ta có giao diện như mong muốn:
Các bạn cố gắng thực hiện lại để chạy cho bằng được.
Ở bài học trước, Tui đã trình bày Tổng quan về tích hợp Mô hình Máy học vào hệ thống Kinh doanh – Quản lý, các bạn đã biết được chu trình cần thiết cho việc xây dựng một mô hình máy học rồi. Trong bài này chúng ta tiến hành coding, Tui sẽ dùng Hồi quy tuyến tính để tạo mô hình máy học dự báo giá nhà từ tập dữ liệu mẫu Kaggle (tải ở đây) được lưu dưới định dạng CSV, khoảng 5,000 dòng dữ liệu.
Lý thuyết về hồi quy tuyến tính được Anh Vũ Hữu Tiệp và Cộng Sự trình bày rất kỹ trên blog Machine Learning Cơ Bản nên các bạn đọc trực tiếp trên này, hoặc đọc từ Wikipedia, do đó Tui không có nhắc lại phần lý thuyết.
Part 1 này Tui đi trực tiếp vào ứng dụng giải thuật máy học được cung cấp từ một số thư viện trong Python để tạo mô hình máy học dự báo giá nhà cho tập dữ liệu Kaggle ở trên, sử dụng Pycharm (các bạn có thể dùng Jupyter bằng cách cài đặt Anaconda3) chạy dạng Console, Part 2 Tui sẽ hướng dẫn các bạn cách chạy trên giao diện tương tác người dùng.
Các bạn thực hiện theo các bước sau:
Bước 1: Tạo dự án tên “HousingPricePrediction” trong Pycharm
Trong Project tạo một thư mục dataset và tải dữ liệu rồi lưu vào thư mục này
Avg. Area Income: Thu nhập trung bình tại khu vực ngôi nhà đã bán
Avg. Area House Age: Trung bình tuổi của một ngôi nhà đã bán (số năm sử dụng)
Avg. Area Number of Rooms: Trung bình diện tích các phòng
Avg. Area Number of Bedrooms: Trung bình diện tích phòng ngủ
Area Population: Dân số tại khu vực bán nhà
Price: Giá ngôi nhà đã bán
Address: Địa chỉ ngôi nhà bán
Trong bài này ta không sử dụng thuộc tính Address.
Nhiệm vụ của chúng ta là xây dựng 1 mô hình máy học dựa trên tập dữ liệu này, khi người dùng nhập vào Area Income, House Age, Number of Rooms, Number of Bedroooms, Area Population thì mô hình sẽ dự báo Giá của căn nhà này là bao nhiêu.
Bước 2: Tạo một file Python “HousingPriceSimpleModel.py”:
Bước 3: Bổ sung các thư viện ở đầu file “HousingPriceSimpleModel.py”
# 01.Library for dataset processing
import pandas as pd
import numpy as np
# 02. Library for train model
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
# 03. Library for evaluation model
from sklearn import metrics
# 04. Library for saving model
import pickle
Ở trên Tui khai báo 4 nhóm thư viện bao gồm:
Nhóm thư viện xử lý dataset (01) : Đọc dữ liệu, tiền xử lý loại bỏ cột dữ liệu không sử dụng, trích lọc các biến độc lập (các cột thuộc tính), biến phụ thuộc (cột price)… Chúng ta dùng pandas, numpy
Nhóm thư viện để train model máy học (02): Bao gồm thư viện tách lọc tập train và test, và bài này chúng ta dùng hồi quy tuyến tính (LinearRegression)
Nhóm thư viện đánh giá chất lượng mô hình (03): chúng ta dùng thư viện metrics
Nhóm thư viện để xuất mô hình máy học được train xuống ổ cứng (04): Ta dùng thư viện pickle
Bước 4: Tiếp tục bổ sung mã lệnh đọc dữ liệu, xem các thông tin cũng như tạo ma trận X và mảng y
#use pandas to read CSV dataset
df = pd.read_csv('dataset/USA_Housing.csv')
#call functions about get dataset information:
print(df.head())
print(df.info())
print(df.describe())
print(df.columns)
Thực hiện các Lệnh ở trên ta có kết quả:
Avg. Area Income ... Address
0 79545.458574 ... 208 Michael Ferry Apt. 674\nLaurabury, NE 3701...
1 79248.642455 ... 188 Johnson Views Suite 079\nLake Kathleen, CA...
2 61287.067179 ... 9127 Elizabeth Stravenue\nDanieltown, WI 06482...
3 63345.240046 ... USS Barnett\nFPO AP 44820
4 59982.197226 ... USNS Raymond\nFPO AE 09386
[5 rows x 7 columns]
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 5000 entries, 0 to 4999
Data columns (total 7 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 Avg. Area Income 5000 non-null float64
1 Avg. Area House Age 5000 non-null float64
2 Avg. Area Number of Rooms 5000 non-null float64
3 Avg. Area Number of Bedrooms 5000 non-null float64
4 Area Population 5000 non-null float64
5 Price 5000 non-null float64
6 Address 5000 non-null object
dtypes: float64(6), object(1)
memory usage: 273.6+ KB
None
Avg. Area Income Avg. Area House Age ... Area Population Price
count 5000.000000 5000.000000 ... 5000.000000 5.000000e+03
mean 68583.108984 5.977222 ... 36163.516039 1.232073e+06
std 10657.991214 0.991456 ... 9925.650114 3.531176e+05
min 17796.631190 2.644304 ... 172.610686 1.593866e+04
25% 61480.562388 5.322283 ... 29403.928702 9.975771e+05
50% 68804.286404 5.970429 ... 36199.406689 1.232669e+06
75% 75783.338666 6.650808 ... 42861.290769 1.471210e+06
max 107701.748378 9.519088 ... 69621.713378 2.469066e+06
[8 rows x 6 columns]
Index(['Avg. Area Income', 'Avg. Area House Age', 'Avg. Area Number of Rooms',
'Avg. Area Number of Bedrooms', 'Area Population', 'Price', 'Address'],
dtype='object')
Process finished with exit code 0
Bước 5: Xây dựng và train mô hình dự báo giá nhà
Ta cần tách dữ liệu thành một ma trận X chứa các đặc trưng cần đào tạo (gọi là các biến độc lập) và một mảng y với biến mục tiêu (biến phụ thuộc), trong trường hợp này thì cột y chính là cột Giá(Price). Cột Địa chỉ (Address) sẽ được loại bỏ khỏi mô hình vì nó chỉ có thông tin văn bản mà mô hình hồi quy tuyến tính này không sử dụng. Điều đó có nghĩa:
#set X matrix
#df.columns[:5] meaning:
#['Avg. Area Income', 'Avg. Area House Age', 'Avg. Area Number of Rooms',
# 'Avg. Area Number of Bedrooms', 'Area Population']
X = df[df.columns[:5]]
y = df['Price']
# Printing for observation:
print(X)
print(y)
Thông thường ta cần chia tập dữ liệu ra làm 2: train và set. Tỉ lệ tùy thuộc vào dữ liệu cũng như kinh nghiệm. Giả sử ở đây ta chi theo tỉ lệ 80% cho train và 20% cho test.
Mã lệnh ở trên sẽ tách tập dataset ban đầu thành 2 tập, tập train và tập test với tỉ lệ lần lượt là 80% và 20%, sau đó dùng LinearRegression() để train mô hình máy học.
Bước 6: Thử nghiệm mô hình
Chúng ta có thể đánh giá mô hình sau đó thử nghiệm, ở bước này Tui sẽ thử nghiệm mô hình sau đó sẽ đánh giá lại để quyết định xem có nên xuất ra ổ cứng để sử dụng sau này hay không.
Thử nghiệm lần thứ 1: Lấy ngẫu nhiên tập dữ liệu thứ 0 trong iloc của X_test
Input 1:
[Avg. Area Income 66774.995817
Avg. Area House Age 5.717143
Avg. Area Number of Rooms 7.795215
Avg. Area Number of Bedrooms 4.320000
Area Population 36788.980327
Name: 1718, dtype: float64]
Housing Price prediction 1 = [1257919.729097]
So sánh với dữ liệu gốc, với các thông số input ở trên thì ta có dữ liệu giá gốc là (bạn tra lại dữ liệu gốc trong file CSV):
1251688.616
Còn mô hình ta tính ra được:
1257919.729097
Như vậy giá dự báo cũng khá sát với giá gốc
Thử nghiệm lần thứ 2, các giá trị đầu vào Tui sẽ lấy y chóc như lần thử nghiệm thứ 1, tuy nhiên Tui không dùng iloc[0] của X_test, mà Tui sẽ nhập trực tiếp:
-2640441.3997814017
Coefficient
Avg. Area Income 21.566696
Avg. Area House Age 165453.042478
Avg. Area Number of Rooms 120499.839093
Avg. Area Number of Bedrooms 1999.785336
Area Population 15.340604
Coeffient cho ta thấy:
Giả sử các thuộc tính khác không đổi, nếu Area Income tăng D đơn vị thì giá của căn nhà sẽ được bổ sung thêm D*21.5666696
Tương tự cho các thuộc tính khác. Như vậy dựa vào Cofficient ta biết được mức độ ảnh hưởng của các biến độc lập lên biến phụ thuộc. Ví dụ trong trường hợp này thì rõ ràng là tuổi thọ của căn nhà có tầm ảnh hưởng về giá của căn nhà lớn nhất, và dân số đóng vai trò thấp nhất về sự ảnh hưởng giá.
Ta có một số cách để đánh giá mô hình dự báo chạy bằng Hồi quy như sau:
Mean Absolute Error (MAE): MAE là một phương pháp đo lường sự khác biệt (độ chênh lệch giá trị) giữa hai biến liên tục. Giả sử rằng X và Y là hai biến liên tục thể hiện kết quả dự đoán của mô hình và kết quả thực tế, công thức:
Mean Squared Error (MSE): là giá trị trung bình của bình phương sai số (Hàm mất mát), là sự khác biệt giữa các giá trị được mô hình dự đoán và gía trị thực. MSE cũng được gọi là một hàm rủi ro, tương ứng với giá trị kỳ vọng của sự mất mát sai số bình phương hoặc mất mát bậc hai chỉ số này phổ biến hơn chỉ số MAE bên trên, công thức:
Root Mean Squared Error (RMSE): là căn bậc hai của giá trị trung bình của các sai số bình phương (MSE). Thông thường, ta thường dùng chỉ số này để xác định giá trị chênh lệch trung bình giữa giá dự đoán và giá trị test ban đầu, công thức:
Tùy vào lựa chọn tỉ lệ train mà các giá trị đo lường này có thể khác nhau.
Bước 8: Kết xuất mô hình máy học ra ổ cứng (file zip) để tái sử dụng
Khi mô hình được đánh giá là chạy tốt, ta nên lưu lại mô hình để các lần sau sử dụng chỉ cần nạp lại mô hình thay vì phải train lại (công đoạn train thường là tiêu tốn nhiều thời gian và nguồn lực).
Lưu mô hình, mô hình ở trên được đặt tên biến là lm, ta cần lưu mô hình lm này xuống ổ cứng để sử dụng cho lần sau, sử dụng thư viện pickle:
Thư thi lệnh trên ta sẽ có mô hình được lưu xuống ổ cứng với tên “housingmodel.zip”:
Source code đầy đủ của “HousingPriceSimpleModel.py”:
# 01.Library for dataset processing
import pandas as pd
import numpy as np
# 02. Library for train model
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
# 03. Library for evaluation model
from sklearn import metrics
# 04. Library for saving model
import pickle
#use pandas to read CSV dataset
df = pd.read_csv('dataset/USA_Housing.csv')
#call functions about get dataset information:
print(df.head())
print(df.info())
print(df.describe())
print(df.columns)
#set X matrix
#df.columns[:5] meaning:
#['Avg. Area Income', 'Avg. Area House Age', 'Avg. Area Number of Rooms',
# 'Avg. Area Number of Bedrooms', 'Area Population']
X = df[df.columns[:5]]
y = df['Price']
# Printing for observation:
print(X)
print(y)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=101)
lm = LinearRegression()
lm.fit(X_train, y_train)
print("Input 1:")
print([X_test.iloc[0]])
pre1 = lm.predict([X_test.iloc[0]])
print("Housing Price prediction 1 =", pre1)
print("Input 2:")
input2=[66774.995817, 5.717143, 7.795215, 4.320000, 36788.980327]
print(input2)
pre2 = lm.predict([input2])
print("Housing Price prediction 2 =", pre2)
print("Input 3:")
input3=[21.566696, 165453.0425, 120499.8391, 1999.785336, 15.340604]
print(input3)
pre3 = lm.predict([input3])
print("Housing Price prediction 3 =", pre3)
predictions = lm.predict(X_test)
print("Full Housing Price Predictions:")
print(predictions)
# print the intercept
print(lm.intercept_)
coeff_df = pd.DataFrame(lm.coef_, X.columns, columns=['Coefficient'])
print(coeff_df)
print('MAE:', metrics.mean_absolute_error(y_test, predictions))
print('MSE:', metrics.mean_squared_error(y_test, predictions))
print('RMSE:', np.sqrt(metrics.mean_squared_error(y_test, predictions)))
modelname = "housingmodel.zip"
pickle.dump(lm, open(modelname, 'wb'))
Bước 9: Sử dụng/Tái sử dụng mô hình máy học, tạo thêm 1 file mã lệnh Python “UseHousingPriceSimpleModel.py”
Bổ sung mã lệnh cho “UseHousingPriceSimpleModel.py”
import pandas as pd
import pickle
from pandas import Index
modelname="housingmodel.zip"
# Load Trained Machine Learning Model
trainedmodel=pickle.load(open(modelname, 'rb'))
features=Index(['Avg. Area Income', 'Avg. Area House Age', 'Avg. Area Number of Rooms',
'Avg. Area Number of Bedrooms', 'Area Population'],
dtype='object')
# Check coeff again if you want (no need)
coeff_df = pd.DataFrame(trainedmodel.coef_,features,columns=['Coefficient'])
print(coeff_df)
print("Input 1:")
input1=[66774.995817,5.717143,7.795215,4.320000,36788.980327]
print(input1)
prediction1=trainedmodel.predict([input1])
print("Housing Price Prediction 1=",prediction1)
print("-"*50)
input2=[[66774.995817,5.717143,7.795215,4.320000,36788.980327],
[80527.47208,8.093512681,5.0427468,4.1,47224.35984]]
print(input2)
prediction2=trainedmodel.predict(input2)
print("Housing Price Prediction 2=",prediction2)
Mã lệnh ở trên sẽ tải mô hình máy học đã được lưu trước đó “housingmodel.zip” và tiến hành tái sử dụng để predict giá nhà, chạy mã lệnh trên ta có kết quả:
Coefficient
Avg. Area Income 21.566696
Avg. Area House Age 165453.042478
Avg. Area Number of Rooms 120499.839093
Avg. Area Number of Bedrooms 1999.785336
Area Population 15.340604
Input 1:
[66774.995817, 5.717143, 7.795215, 4.32, 36788.980327]
Housing Price Prediction 1= [1257919.71744578]
--------------------------------------------------
[[66774.995817, 5.717143, 7.795215, 4.32, 36788.980327], [80527.47208, 8.093512681, 5.0427468, 4.1, 47224.35984]]
Housing Price Prediction 2= [1257919.71744578 1775665.87664153]
Như vậy tới đây Tui đã hướng dẫn xong các bạn cách thứ sử dụng thư viện Hồi quy tuyến tính để train một mô hình máy học đơn giản để dự báo giá nhà, các bạn biết cách/ôn tập pandas để đọc và tiền xử lý dữ liệu, biết cách dùng train_test_split, LinearRegression để train mô hình. Biết cách dùng metrics để đánh giá chất lượng mô hình cũng như dùng pickle để lưu mô hình và phục hồi lại mô hình để tái sử dụng trong tương lai.
Bài học sau Tui sẽ hướng dẫn các bạn thiết kế màn hình tương tác người dùng để train mô hình cũng như sử dụng mô hình máy học trên giao diện. Các bạn chú ý theo dõi
Trong chuỗi các bài học này Tui sẽ hướng dẫn các bạn cách thức lập trình các mô hình máy học và tích hợp mô hình máy học vào hệ thống quản lý, kinh doanh. Trước tiên là các bạn cần hiểu sơ qua về mô hình tổng quan của máy học, hiểu được các bước cần thiết khi xây dựng mô hình máy học, biết cách tích hợp nó vào các hệ thống đã có sẵn hoặc chưa có sẵn tùy thuộc vào nhu cầu sử dụng cũng như tùy thuộc vào cách thức thiết kế cấu trúc cơ sở dữ liệu và loại dữ liệu.
Máy học có rất nhiều ứng dụng cho từng trường hợp cụ thể, và nó lệ thuộc vào kinh nghiệm cũng như tư tưởng của kỹ sư thiết kế mô hình máy học, mỗi người có thể đưa ra các quy trình khác nhau, tuy nhiên nó cũng có các điểm chung cơ bản nhất khi xây dựng mô hình máy học.
Ta có thể ứng dụng máy học vào các bài toán như: Phân loại, Phân cụm, hồi quy. Chúng ta có thể áp dụng mô hình máy học vào các lĩnh vực như: Sản xuất, Chăm sóc sức khỏe và khoa học đời sống, Các dịch vụ tài chính, Các hệ thống bán lẻ, Truyền thông và giải trí, Cùng các lĩnh vực khác…
01. Đối với Lĩnh vực Sản xuất:
Máy học có thể hỗ trợ bảo trì dự đoán, kiểm soát chất lượng và nghiên cứu đổi mới trong lĩnh vực sản xuất. Công nghệ máy học cũng giúp các công ty cải thiện giải pháp hậu cần, bao gồm quản lý tài sản, chuỗi cung ứng và kho hàng.
02. Đối với lĩnh vực Chăm sóc sức khỏe và khoa học đời sống:
Sự phát triển như vũ bão của cảm biến và thiết bị có thể đeo được đã tạo ra một lượng lớn dữ liệu về sức khỏe. Các chương trình máy học có thể phân tích thông tin này và hỗ trợ bác sĩ chẩn đoán và điều trị trong thời gian thực.
03. Đối với lĩnh vực Dịch vụ tài chính:
Các dự án máy học về tài chính giúp cải thiện khả năng phân tích rủi ro và quy định. Công nghệ máy học có thể giúp các nhà đầu tư xác định cơ hội mới bằng cách phân tích hoạt động của thị trường chứng khoán, đánh giá các quỹ phòng hộ hoặc hiệu chỉnh danh mục tài chính
04. Đối với lĩnh vực Bán lẻ:
Nhà bán lẻ có thể sử dụng máy học để cải thiện dịch vụ khách hàng, quản lý hàng tồn kho, bán hàng gia tăng và tiếp thị đa kênh, dự báo doanh thu, dự báo nhu cầu tiêu dùng, dự báo xu hướng…
05. Đối với lĩnh vực Truyền thông và giải trí:
Các công ty giải trí tìm đến máy học để hiểu rõ hơn đối tượng mục tiêu của họ đồng thời cung cấp nội dung chân thực, được cá nhân hóa và theo nhu cầu của khách hàng. Thuật toán máy học được triển khai để giúp thiết kế trailer và các dạng quảng cáo khác, từ đó đề xuất nội dung được cá nhân hóa cho người tiêu dùng và thậm chí là hợp lý hóa quy trình sản xuất.
Ngoài ra đôi khi chúng ta cũng hay phân vân, bối rối giữa khái niệm về Trí tuệ nhân tạo và Máy học, thì dưới đây thì hãng AWS có bảng phân biệt 2 khái niệm này, Tui tổng hợp lại để các bạn hiểu thêm:
Trí tuệ nhân tạo
Máy học
Khái niệm
AI là thuật ngữ rộng cho các ứng dụng dựa trên máy móc bắt chước trí thông minh của con người. Không phải tất cả các giải pháp AI đều là ML.
ML là một phương pháp trí tuệ nhân tạo. Tất cả các giải pháp ML đều là các giải pháp AI.
Trường hợp sử dụng phù hợp nhất
AI là lựa chọn tốt nhất để hoàn thành một tác vụ phức tạp của con người một cách hiệu quả.
ML là lựa chọn tốt nhất để xác định các mẫu hình trong các tập dữ liệu lớn để giải quyết các vấn đề cụ thể.
Methods
AI có thể sử dụng các phương pháp khác nhau, như dựa trên quy tắc, mạng nơ-ron, thị giác máy tính, v.v.
Đối với ML, người ta tự chọn và trích xuất các tính năng từ dữ liệu thô và gán trọng số để đào tạo mô hình.
Implements
Việc triển khai AI phụ thuộc vào tác vụ. AI thường được xây dựng sẵn và truy cập thông qua các API.
Bạn đào tạo các mô hình ML mới hoặc hiện có cho trường hợp sử dụng cụ thể của bạn. Cũng có sẵn các API ML được xây dựng sẵn.
(source : AWS)
Và dưới đây là quan điểm cá nhân của Tui liên quan tới máy học hay trí tuệ nhân tạo, và nó có thể làm không ưng cái bụng của một số người:
Đừng bao giờ thần thánh hóa Trí tuệ nhân tạo hay Máy học. Chúng chỉ đóng góp một vai trò nhất định trong hệ thống, giúp người quản trị đưa ra các quyết định nhanh chóng và phù hợp hơn.
Muốn ứng dụng máy học thì trước tiên chúng ta phải có hệ thống quản trị tốt trước đã, và các dữ liệu nên được cấu trúc phù hợp.
Nỗi sợ trí tuệ nhân tạo, máy học hay Robot thông minh sẽ thay thế con người? Cướp công việc của con người?
Không bao giờ có điều đó xảy ra, mỗi một công nghệ mới xuất hiện thì nó sẽ tạo ra rất nhiều nhóm các ngành nghề mới, công việc mới cho Con người làm việc. Nó chỉ thay thế những STUPID JOB
“Lùa Gà” là một từ lóng mà chúng ta thường nghe, một số trung tâm, chuyên gia đào tạo… cố tình tạo nên nỗi sợ hoang đường để học viên đăng ký học, hay đăng ký mua sản phẩm liên quan.
Chúng ta học để hiểu biết, để ứng dụng trong thực tiễn vì kiến thức là vô cùng vô tận. Học để thích ứng với sự phát triển như vũ bão của công nghệ mới chứ không phải vì lo sợ nó CƯỚP công việc của mình.
Vì mỗi người mỗi quan điểm khác nhau, nhìn bài toán khách hàng gặp phải dưới các lăng kính khác nhau nên mỗi người sẽ có những quy trình xử lý khác nhau, nhưng suy cho cùng thì cũng cùng một mục đích là đem lại dịch vụ tốt nhất cho khách hàng. Dưới đây Tui đưa ra một quy trình chung cơ bản về thiết kế mô hình máy học và tích hợp vào hệ thống nói chung, các bạn có thể tham khảo (có thể hoàn toàn KHÔNG ĐỒNG Ý hoặc ĐỒNG Ý một PHẦN). Dĩ nhiên các chuỗi bài hướng dẫn xây dựng mô hình máy học và tích hợp vào hệ thống mà Tui hướng dẫn trên Blog này sẽ nhìn chung thực hiện theo các quy trình này. Tùy thuộc vào tình hình thực tế của bài toán mà các bạn đang giải quyết để có thể cải biên nó phù hợp hơn.
Và cũng cần lưu ý: Không có mô hình máy học nào sai, chỉ có mô hình máy học phù hợp hay chưa phù hợp. Mô hình máy học có thể chạy tốt với tập dữ liệu X nhưng chưa chắc chạy tốt với tập dữ liệu Y. Đó là lý do vì sao chúng ta cần cải tiến mô hình máy học thường xuyên khi nhu cầu hay dữ liệu bị thay đổi đáng kể.
Ta xem lại mô hình tổng quan:
Lưu đồ trên là việc tích hợp mô hình máy học vào một hệ thống đang vận hành. Dĩ nhiên có những trường hợp ta chưa có hệ thống (dữ liệu) nhưng ta có ý tưởng về mô hình máy học từ đó ta thiết kế hệ thống đáp ứng ý tưởng mô hình máy học . Và cũng có những trường hợp hệ thống có sẵn rồi, dữ liệu có sẵn rồi, bây giờ ta cần tích hợp mô hình máy học vào, hầu hết bài học Tui sẽ hướng dẫn trường hợp số 2 là hệ thống có sẵn.
Ở lưu đồ trên ta thấy, đa phần nó có khoảng 3 phiên chính trong xây dựng và tích hợp mô hình máy học: Phiên PREPARING DATA, Phiên BUILD MODEL và phiên USE MODEL.
PREPARING DATA: Là Bước chuẩn bị dữ liệu, tùy thuộc vào các bài toán khác nhau, hay dữ liệu khác nhau mà ta có các bước chuẩn bị dữ liệu chi tiết khác nhau, nhìn chung thì ta cần có các thao tác như “làm sạch và chuẩn hóa dữ liệu”, “Mô hình hóa hướng đối tượng cho dữ liệu” để phục vụ cho việc lập trình được dễ dàng hơn. Ta cần phải chuẩn bị dữ liệu thật tốt để Build Mô hình, vì Cơ sở dữ liệu lưu trữ không phải lúc nào cũng lưu trữ các dữ liệu tốt, tối ưu mà nó có thể lưu những dữ liệu không tốt, các dữ liệu không có ích trong quá trình Build mô hình. Mà chúng ta cần biết nguyên tắc “Garbage In – Garbage Out” nghĩ là dữ liệu không tốt thì cho mô hình không tốt.
Khi khách hàng ở bước (0) có các hoạt động trên hệ thống (1), chẳng hạn như tương tác sản phẩm, commments, review, đặt đơn hàng… thì các dữ liệu này sẽ được lưu vào Database (2). Database này chúng ta cần tiền xử lý cho tốt, nó sẽ nằm trong phiên PREPARING DATA.
Mỗi dữ liệu khác nhau, mỗi bài toán khác nhau mà bước (3) làm sạch và chuẩn hóa dữ liệu sẽ khác nhau, có thể thêm nhiều các bước con khác nhau, sử dụng các kỹ thuật khác nhau.
Mô hình hóa hướng đối tượng (4) có thể được áp dụng để giúp cho việc xử lý dữ liệu, mô hình được tốt hơn.
BUILD MODEL: Là các bước từ số (5) tới số (9). Phiên này sẽ build mô hình máy học, các bước bao gồm lọc và tải dữ liệu, lựa chọn giải thuật và các tham số cho mô hình, train mô hình, đánh giá và cải thiện mô hình, cuối cùng là xuất mô hình ra ổ cứng để tái sử dụng, tích hợp vào hệ thống.
Bước (5) “Filter and load data” có thể được xem là bước lọc và nạp dữ liệu để phục vụ cho train mô hình, ta cần chọn các thuộc tính/biến phù hợp cũng như tỉ lệ train/test khác nhau, nó ảnh hưởng tới chất lượng mô hình
Bước (6) “Select Algorithms” Bước này ta lựa chọn các giải thuật máy học phù hợp với bài toán, cũng với việc lựa chọn các tham số đầu vào để train mô hình. Ví dụ như bài toán Classfification thì nên dùng giải thuật nào, bài toán Clustering thì nên dùng giải thuật nào, các bài toán liên quan Time Series Data thì nên dùng giải thuật nào….. Cái này ứng với bài toán cụ thể ta sẽ dùng.
Bước (7) là bắt đầu train mô hình máy học, từ tập dữ liệu, giải thuật máy học, các tham số được lựa chọn phù hợp thì chương trình bày đầu train.
Bước (8) sau khi train mô hình xong thì chúng ta cần đánh giá mô hình có chất lượng hay không, nếu mô hình chất lượng (ta cho rằng) thì qua Bước (9) để xuất mô hình xuống ổ cứng để tái sử dụng, để tích hợp vào hệ thống mà khách hàng yêu cầu. Nếu mô hình không chất lượng thì ta có nhiều giải pháp, ở trên thì Tui đưa ra 2 giải pháp: Hoặc là chúng ta quay lại bước (5) hoặc là chúng ta quay lại phiên PREPARING DATA. Vì cả 2 nơi này đều là nguyên dẫn có thể dẫn tới mô hình không đạt chất lượng mong muốn.
Bước (9) là bước xuất mô hình ra ổ cứng (lưu), vì ta không thể khi chạy dịch vụ ví dụ như Khách hàng đang sử dụng hệ thống sàn thương mại điện tử, ta muốn gợi ý các sản phẩm mà khách hàng có khả năng mua cao thì ta lại chạy lại mô hình được (vì nó rất tốn thời gian, training mô hình rất lâu, khách hàng không thể ngồi chờ). do đó Bước (9) là lưu mô hình rồi thì các lần sau sử dụng ta chỉ cần tải lại mô hình này rồi tích hợp vào hệ thống thôi.
USE MODEL: Là các bước (10), (11). Các bước này nạp và tích hợp mô hình máy học vào hệ thống và sử dụng mô hình máy học.
Bước (10) là nạp mô hình đã lưu từ bước (9), ví dụ khách hàng đăng nhập vào hệ thống sàn thương mại điện tử, ta muốn gợi ý các sản phẩm mà khách hàng có khả năng mua cao nhất thì ta sẽ đọc mô hình máy học ở Bước (9) để sử dụng, tích hợp nó vào hệ thống ở bước (11)
Bước (11) Sau khi mô hình máy học được tích hợp vào hệ thống, chương trình sẽ triệu gọi mô hình máy học, gọi các hàm predict để đưa ra các kết quả phù hợp cho khách hàng. Và hiển nhiên Khách hàng có thể tiếp tục tương tác trên hệ thống ở bước (0) như vậy chúng ta có một vòng tròn khép kín, mỗi lần khách hàng tương tác thì hệ thống lại lưu lại cơ sở dữ liệu, và theo thời gian thì chúng ta biết rằng có thể sở thích khách hàng sẽ thay đổi theo thời gian (khả năng cao, ví dụ tháng 01 bạn thích ăn Dưa leo, nhưng qua tháng 02 bạn lại thích Dưa chuột) như vậy có thể dẫn tới mô hình máy học không còn chất lượng nữa, ta cần có cách đánh giá lại mô hình, có thể build lại. Cứ thế tiếp tục cải tiến mô hình để có được một dịch vụ tốt nhất cho khách hàng.
Trên đây là tổng quan về máy học, trí tuệ nhân tạo, cách áp dụng mô hình máy học vào các lĩnh vực khác nhau như: Sản xuất, Chăm sóc sức khỏe và khoa học đời sống, Các dịch vụ tài chính, Các hệ thống bán lẻ, Truyền thông và giải trí, Cùng các lĩnh vực khác…
Đặc biệt Tui đưa ra mô hình tổng quan chung cơ bản về xây dựng và tích hợp mô hình máy học vào hệ thống quản lý, giải thích ý nghĩa của từng bước. Và nó phụ thuộc vào bài toán của khách hàng, phụ thuộc vào dữ liệu, phụ thuộc vào lăng kính của kỹ sư máy học mà mỗi người có thể cải biên flow chart khác nhau, tuy nhiên về cơ bản thì các chức năng, các bước cốt lõi là như nhau.
Bài học sau Tui sẽ hướng dẫn cụ thể bài Dự báo giá nhà dùng hồi quy tuyến tính. Xây dựng mô hình máy học và chạy thử nghiệm trên giao diện Python PyQt6. Các bạn chú ý theo dõi