Professional Documents
Culture Documents
ĐỒ ÁN MÔN HỌC
CHUYÊN ĐỀ CHUYÊN SÂU VỀ KHOA HỌC DỮ LIỆU 1
PHÂN TÍCH THỊ TRƯỜNG CHỨNG KHOÁN
VÀ
SOFT MOBILE-MUA BÁN
ĐỒ ÁN MÔN HỌC
CHUYÊN ĐỀ CHUYÊN SÂU VỀ KHOA HỌC DỮ LIỆU 1
PHÂN TÍCH THỊ TRƯỜNG CHỨNG KHOÁN
VÀ
SOFT MOBILE-MUA BÁN
NHIỆM VỤ ĐỒ ÁN
Họ và tên: Lương Công Thuận MSSV: 2100011144
Chuyên ngành: KHOA HỌC DỮ LIỆU Lớp: 21DTH2C
Email: luongcongthuann@gmail.com SĐT : 039418613
Tên đề tài: Phân tích thị trường chứng khoáng và soft mobile-mua bán
Giảng viên giảng dạy: Hà Minh Tân
Thời gian thực hiện: 9/10/2023 đến 18/1/2024
Nhiệm vụ/nội dung (mô tả chi tiết nội dung, yêu cầu, phương pháp… ):
LỜI MỞ ĐẦU
Trong thời đại công nghệ ngày nay, tiền điện tử đang ngày càng trở thành một phần quan
trọng của hệ thống tài chính toàn cầu, với Bitcoin nổi bật như một biểu tượng tiêu biểu.
Được sáng tạo bởi Satoshi Nakamoto vào năm 2009, Bitcoin đã trải qua một hành trình
đầy biến động, từ sự chấp nhận ban đầu đến sự quan tâm đối với những biến động giá
không ngừng.
Đồ án này không chỉ là một nỗ lực để hiểu rõ hơn về cơ chế hoạt động của thị trường
Bitcoin mà còn nhằm mục tiêu dự đoán giá của nó trong tương lai. Sự khảo sát sâu rộng
về các yếu tố ảnh hưởng đến giá Bitcoin, từ các yếu tố kỹ thuật như cung và cầu đến
những ảnh hưởng ngoại vi như chính trị và kinh tế, sẽ được thực hiện để xây dựng một
mô hình dự đoán chính xác và đáng tin cậy.
Với lòng tò mò và sự hứng thú với sự phức tạp của thị trường tiền điện tử, chúng tôi bắt
đầu hành trình này với niềm tin rằng nắm bắt được xu hướng giá của Bitcoin không chỉ là
một thách thức mà còn là cơ hội để hiểu sâu hơn về bản chất của tiền tệ số và tác động
của nó đối với thế giới tài chính.
Với sự phát triển ngày càng mạnh mẽ của trí tuệ nhân tạo. Nó đã đem lại những ứng dụng
to lớn trong nhiều lĩnh vực khác nhau như xử lý ngôn ngữ tự nhiên, tự động hoá, thị giác
máy tính, …. Trí tuệ nhân tạo ngày càng trờ thành một phần không thể thiếu của cuộc
sống. Sự tồn tại và phát triển của một doanh nghiệp, cơ quan, tổ chức nhà nước,…Không
thể thiếu sự trợ giúp của trí tuệ nhân tạo. Trong việc thu nhận và xử lý thông tin với khối
lượng ngày càng lớn, nhiều lúc với những việc thủ công không đem lại hiệu quả mong
muốn, lại tốn nhiều công sức và thời gian. Nhằm đem lại sự nhanh chóng và chính xác,
giảm thiểu công sức của con người. Nhóm em đã chọn đề tài “PHÂN TÍCH THỊ
TRƯỜNG CHỨNG KHOÁNG VÀ SOFT MOBILE – MUA BÁN” để nghiên cứu và
viết báo cáo.
LỜI CẢM ƠN
Để thực hiện và hoàn thành bài đề tài này, em đã nhận được sự hỗ trợ, giúp đỡ cũng như
là quan tâm, động viên từ quý Thầy cô trường Đại học Nguyễn Tất Thành, đặc biệt là
khoa Công nghệ thông tin, đã tận tình hướng dẫn, giúp đỡ. Trước hết, em xin bày tỏ tấm
lòng biết ơn sâu sắc với Th.S Hồ Khôi – giảng viên bộ môn “Deep Learning trong khoa
học dữ liệu” người trực tiếp hướng dẫn, cung cấp cho em những kiến thức, kỹ năng cần
thiết để hoàn thành đề tài đã cung cấp một số tài liệu liên quan đến đề tài mà em đang
nghiên cứu và nhắc nhở em đến tiến độ thực hiện đồ án này, mặc dù lịch giảng dạy dày
nhưng luôn dành nhiều thời gian, công sức hướng dẫn em trong suốt quá trình thực hiện
nghiên cứu và hoàn thành đề tài này. Xin gửi lời cảm ơn chân thành đến thầy cô khoa
CNTT, với sự quan tâm, dạy dỗ, chỉ bảo tận tình chu đáo thầy cô đã truyền đạt những
kiến thức quý báu cho em trong suốt thời gian vừa qua. Giúp em hiểu thêm nhiều kiến
thức bổ ích, tinh thần học tập hiệu quả và nghiêm túc, để hoàn thành được đồ án môn học
này. Tuy có nhiều cố gắng trong bài tiểu luận môn học nhưng em còn nhiều hạn chế và bỡ
ngỡ nên không tránh khỏi những thiếu sót. Em rất mong nhận được những ý kiến đóng
góp, giúp đỡ của thầy để bài tiểu luận của em được hoàn thiện hơn đồng thời tạo điều
kiện để em bổ sung, nâng cao ý thức và trình độ chuyên môn của mình trong lĩnh vực
này.
TRƯỜNG ĐẠI HỌC NGUYỄN TẤT THÀNH KỲ THI KẾT THÚC HỌC PHẦN
TRUNG TÂM KHẢO THÍ HỌC KỲ I NĂM HỌC 2023 - 2024
Đề tài tiểu luận/báo cáo của sinh viên :PHÂN TÍCH VÀ DỰ ĐOÁN GIÁ BITCOIN
Phần đánh giá của giảng viên (căn cứ trên thang rubrics của môn học):
Tiêu chí (theo Điểm tối Điểm đạt
Đánh giá của GV
CĐR HP) đa được
Cấu trúc của Gồm 7 chương
1
báo cáo
Nội dung
• Các nội
dung thành Chương 2, 3, 4, 5, 6 và 7 5
phần
• Lập luận
2
Chương 1
• Kết luận
1
Trình bày
Theo chuẩn format luận văn font chữ 13, canh trái, 1
phải,…
TỔNG ĐIỂM 10
Giảng viên chấm thi
(ký, ghi rõ họ tên)
CHƯƠNG 1
GIỚI THIỆU
Dự đoán giá Bitcoin là một đề tài quan trọng trong lĩnh vực tài chính và tiền điện tử, đặc
biệt là trong bối cảnh Bitcoin trở thành một phần quan trọng của hệ thống tài chính toàn
cầu. Giá của Bitcoin biến đổi mạnh mẽ theo thời gian và được ảnh hưởng bởi nhiều yếu
tố khác nhau, bao gồm cầu và cung, sự quan tâm từ phía các nhà đầu tư, tin tức và sự kiện
thị trường, cũng như tình hình kinh tế toàn cầu.
Dự đoán giá Bitcoin là một nhiệm vụ phức tạp đòi hỏi sự hiểu biết về nền kinh tế, thị
trường tài chính, và công nghệ blockchain. Các nhà nghiên cứu và chuyên gia tài chính
đã áp dụng nhiều phương pháp khác nhau để cố gắng dự đoán giá của loại tiền điện tử
này, bao gồm phân tích kỹ thuật, phân tích cơ bản, mô hình hóa toán học, và sử dụng trí
tuệ nhân tạo.
Đề tài này có ý nghĩa lớn trong việc đánh giá rủi ro và cơ hội đầu tư trong lĩnh vực tiền
điện tử. Chúng ta hy vọng rằng việc nghiên cứu về dự đoán giá Bitcoin sẽ đóng góp vào
sự hiểu biết về tiền điện tử và tiền tệ kỹ thuật số giúp người dùng đưa ra quyết định thông
minh trong việc quản lý tài sản và đầu tư trong thị trường này.
Lý do chọn đề tài "Dự đoán giá Bitcoin" là để hiểu biết thêm về tiền điện tử, cách thức
hoạt động cũng những ảnh hưởng đến tiền điện tử, giúp hiểu rõ thị trường tiền điện tử và
tài chính kỹ thuật số. Nó có thể giúp đối tượng nghiên cứu và người đầu tư đưa ra quyết
định thông minh, tối ưu hóa lợi nhuận và giảm rủi ro trong môi trường đầu tư đầy thách
thức này.
Phương pháp kết hợp các khía cạnh của phân tích kỹ thuật, phân tích cơ bản, mô hình
toán học và trí tuệ nhân tạo có thể giúp tạo ra các dự đoán giá Bitcoin đáng tin cậy và hữu
ích cho người dùng cuối trong việc đưa ra quyết định đầu tư.
Sử dụng dữ liệu lịch sử từ năm 2010-2023 về giá Bitcoin, giao dịch, cầu và cung, và các
yếu tố thị trường liên quan để phát triển mô hình dự đoán.
Sử dụng phân tích kỹ thuật, phân tích cơ bản, mô hình toán học, và trí tuệ nhân tạo để xây
dựng các mô hình dự đoán giá Bitcoin.
CHƯƠNG 2
ỨNG DỤNG VÀ THUẬT TOÁN
2.1Giới thiệu bài toán
RNN (Mạng Nơ-ron Hồi Quy): Sử dụng kiến trúc vòng lặp để duy trì thông tin trạng thái
trước đó. RNN có thể xử lý thông tin dạng chuỗi (sequence/ time-series), có thể mang
thông tin của frame (ảnh) từ state trước tới các state sau, rồi ở state cuối là sự kết hợp của
tất cả các ảnh để dự đoán hành động.
LSTM (Long Short-Term Memory): Cải tiến của RNN, giải quyết vấn đề vanishing
gradient bằng cách sử dụng các cổng (gates) để kiểm soát luồng thông tin.
Dự đoán giá Bitcoin là một thách thức quan trọng trong thị trường tài chính và tiền điện
tử. Bài toán này đặt ra để hứng thú nhà đầu tư, giao dịch viên, và những người quan tâm
đến thị trường tiền điện tử.
2.2 Mô tả thuật toán
Tại mỗi bước t , giá trị kích hoạt và đầu ra được biểu diễn như sau:
= + + ) và = + )
Với , , , , là các hệ số được chia sẻ tạm thời và là các hàm kích hoạt.
2.2.2 Phân loại bài toán RNN
- One to one: mẫu bài toán cho Neural Network (NN) và Convolutional Neural Network
(CNN), 1 input và 1 output, ví dụ với CNN input là ảnh và output là ảnh được segment.
- One to many: bài toán có 1 input nhưng nhiều output, ví dụ: bài toán caption cho ảnh,
input là 1 ảnh nhưng output là nhiều chữ mô tả cho ảnh đấy, dưới dạng một câu.
- Many to one: bài toán có nhiều input nhưng chỉ có 1 output, ví dụ bài toán phân loại
hành động trong video, input là nhiều ảnh (frame) tách ra từ video, ouptut là hành động
trong video
- Many to many: bài toán có nhiều input và nhiều output, ví dụ bài toán dịch từ tiếng anh
sang tiếng việt, input là 1 câu gồm nhiều chữ: “I love Vietnam” và output cũng là 1 câu
gồm nhiều chữ “Tôi yêu Việt Nam”.
Trong đó và là các véc-tơ trung bình chuyển động, và là các ước lượng được điều
chỉnh, là tỉ lệ học, và là các hệ số trọng số, là gradient, là một giá trị nhỏ để tránh chia
cho 0.
- Gradient Descent (GD):
Trong đó là vector tham số tại bước thời gian là tỉ lệ học, là đạo hàm của hàm mất mát
theo
Trong đó là một chỉ số ngẫu nhiên, thường được chọn từ tập dữ liệu đào tạo.
• Hàm mất mát
Các hàm mất mát (loss function) được sử dụng để đo lường sự chênh lệch giữa giá trị dự
đoán của mô hình và giá trị thực tế của dữ liệu. Mục tiêu chính của một mô hình máy học
là tối thiểu hóa giá trị của hàm mất mát, tức là làm cho dự đoán của mô hình càng gần giá
trị thực tế càng tốt.
Các hàm mất mát thường dùng :
- Mean Squared Error (MSE):
Với là giá trị thực tế , là giá trị dự đoán ứng với mẫu thứ trong dữ liệu
- Mean Absolute Error (MAE):
Với là giá trị thực tế , là giá trị dự đoán ứng với mẫu thứ trong dữ liệu
2.2.4 GRU/LSTM
- GRU: Là một kiến trúc mạng nơ-ron hồi quy (RNN) được thiết kế để giải quyết vấn đề
gradient biến mất. Sử dụng các cổng (gates) để kiểm soát dòng thông tin qua thời gian và
giữ cho mô hình có khả năng học các phụ thuộc dài hạn trong dữ liệu tuần tự.
= tanh([ ⋆ , ] + )
= ⋆ +(1-)⋆
- LSTM: Là một mô hình RNN nâng cao, được thiết kế để giải quyết vấn đề gradient biến
mất. Trong mỗi bước thời gian, LSTM sử dụng một ô nhớ để lưu trữ thông tin quan trọng
và sử dụng cổng đầu vào, cổng đầu ra và cổng quên để kiểm soát luồng thông tin qua thời
gian, hiệu quả trong việc xử lý các chuỗi dài và các phụ thuộc dài hạn.
= tanh([ ⋆ , ] + ) = ⋆ + ⋆
= ⋆
2.2.5 Các biến thể RNNs
- Bidirectional Recurrent Neural Network (BRNN) là một kiến trúc mạng nơ-ron hồi quy
(RNN) đặc biệt thiết kế để xử lý dữ liệu theo cả hai hướng: từ trái sang phải (forward) và
từ phải sang trái (backward). Mục đích chính của BRNN là cung cấp thông tin từ cả hai
hướng để cải thiện khả năng hiểu và dự đoán trong các nhiệm vụ liên quan đến chuỗi dữ
liệu. BRNN có khả năng hiểu thông tin từ cả hai hướng, giúp nó nắm bắt được các mối
quan hệ phức tạp trong dữ liệu tuần tự.Trong một số tình huống, thông tin từ quá khứ và
tương lai đều quan trọng để dự đoán một giá trị tại một thời điểm cụ thể. BRNN giúp cải
thiện khả năng dự đoán trong các tình huống như vậy.
=[ ; ]
Trong đó là trạng thái ẩn từ hướng trái sang phải và là trạng thái ẩn từ hướng phải sang
trái.
- Deep RNN mô hình mạng nơ-ron hồi quy (RNN) mà có nhiều tầng (layers) hơn so với
RNN thông thường. Mỗi tầng trong mạng thường tương ứng với một lớp RNN. Ý tưởng
là sử dụng nhiều tầng để học các mức biểu diễn phức tạp và hierarchical từ dữ liệu đầu
vào.
CHƯƠNG 3
XÂY DỰNG ỨNG DỤNG NGÔN NGỮ PYTHON
3.1 Xây dựng ứng dụng và giải thích
3.1.1 Lên kế hoạch thiết kế
Mục tiêu: thiết kế ứng dụng dùng thuật toán RNN / LSTM để dự đoán giá cổ phiếu của
ngày tiếp theo
- Thiết kế UI bằng tkinter và customtkinter
- Cho phép chọn file dữ liệu (csv) hoặc nhập mã để lấy dữ liệu từ internet
- Hiển thị biểu đồ tổng quan
- Thiết kế model ( batch size, epoch, optimizer, loss function, layer, unit per layer)
- Hiển thị biểu đồ huấn luyện
-Dự đoán giá cho ngày tiếp theo
import os
import yfinance as yf
import numpy as np
import pandas as pd
import plotly.graph_objects as plot
import tkinter.ttk
from tkinter import ttk, filedialog, messagebox, Tk, StringVar
import customtkinter as tk
from PIL import Image
from tkcalendar import DateEntry
import keras
from sklearn.preprocessing import MinMaxScaler
from keras.models import Sequential
from keras.layers import Dense, Dropout, LSTM
# Set appearance
tk.set_appearance_mode('dark')
tk.set_default_color_theme('blue')
def on_closing():
if messagebox.askokcancel("Quit", "Do you want to quit?"):
path_1 = os.getcwd() + '\\fig1.jpeg'
path_2 = os.getcwd() + '\\fig2.jpeg'
if os.path.exists(path_1):
os.remove(path_1)
if os.path.exists(path_2):
os.remove(path_2)
window.destroy()
# Closing window
window.protocol("WM_DELETE_WINDOW", on_closing)
window.mainloop()
Khởi tạo một cửa sổ tên là ‘window’ với 1280 x 720 pixel và phần tiêu đề là ‘Predict
MaketPlace’
Hàm on_closing sẽ được thực hiện khi đóng chương trình và trong ứng dụng này nó sẽ
xóa những hình biểu đồ khi thoát chương trình
- Thành phần đưa dữ liệu vào:
+ Bảng dữ liệu
# Data Table for view data
table = ttk.Treeview(frame_data)
# vertical scrollbar
vsb = ttk.Scrollbar(frame_data, orient="vertical", command=table.yview)
vsb.pack(side='right', fill='y')
# Table style
table_style = ttk.Style()
table_style.theme_use('default')
# - for heading
table_style.configure("Treeview.Heading",
background='#162236',
foreground='black',
fieldbackground='#162236')
table.pack(fill='both',expand=False)
Tạo table với scrollbar bằng tkinter Treeview nằm trong frame_data
Sửa lại định dạng và kiểu mẫu của table bằng tkinter Style
Vì phải sửa lại heading (dòng đầu của bảng) và phần dữ liệu hiển thị nên sẽ cần 2 câu
lệnh configure
Định dạng lại cho table để chỉ sử dụng không gian bên trong frame_data mà không ảnh
hưởng đến kích thước cửa sổ
+ Nút và đường dẫn file dữ liệu
# Show data_name choise
input_name = tk.CTkLabel(master=frame_data,height=20,width=200,text='')
input_name.pack()
def show_table():
global df
# Get header
table['column'] = list(df.columns)
table['show'] = 'headings'
# Show header
for col in table['column']:
table.heading(col,text=col)
table.column(col,width=100,anchor=tk.CENTER, stretch=True)
# Show data
df_rows = df.to_numpy().tolist()
for row in df_rows:
table.insert("","end", values=row)
# Editing data
try:
df = replace_comma(df)
except Exception as e:
print(e)
df['Date'] = df['Date'].astype('datetime64[ns]')
df = df.sort_values(by='Date', ascending=True)
Tạo một lable rỗng (chưa có text) dùng để hiện đường dẫn file
Tạo một nút để mở cửa sổ chọn file
Để thực hiện việc chọn file và xử lý dữ liệu ta tạo 2 hàm:
file_input() cho việc lấy dữ liệu từ file và xử lý dữ liệu để đưa dữ liệu về dạng phù hợp
cho chương trình (được lưu dưới biến toàn cục df )
show_table() dùng cho việc chuyển dữ liệu trong biến toàn cục df biểu diễn dưới dạng
bảng
+ Lấy dữ liệu từ internet
return stock_data
# Token
label_name = tk.CTkLabel(master=frame_input,text="ID")
label_name.pack()
input_label_name = tk.CTkTextbox(master=frame_input,height=20)
input_label_name.pack()
# Date
label_cal_start = tk.CTkLabel(master=frame_input,text="Date start")
label_cal_start.pack()
cal_start = DateEntry(frame_input, width=12, year=2019, month=6, day=22,
background='darkblue', foreground='white', borderwidth=2)
cal_start.pack(padx=10, pady=10)
date_start = cal_start.get_date()
date_end = cal_end.get_date()
def get_date_from_cal():
global date_start,date_end,df
date_start = date_start.strftime("%Y-%m-%d")
date_end = date_end.strftime("%Y-%m-%d")
try:
df = get_stock_data(input_label_name.get(1.0, "end-
1c"),date_start,date_end)
output_resurt.configure(text="Get data success.",
text_color='#21ed28')
except Exception as e:
output_resurt.configure(text = ("Get data failure. " +
str(e)),text_color='#e8132b' )
show_table()
Để lấy dữ liệu từ internet thông qua thư viện yfinance ta cần 3 thành phần bao gồm:
Tên -> input_label_name : Dùng Textbox để nhận dữ liệu
Ngày bắt đầu -> date_start -> cal_start: Dùng DateEntry từ thư viện tkcalendar
Ngày kết thúc -> date_end -> cal_end: Dùng DateEntry từ thư viện tkcalendar
Hai hàm get_stock_data() và get_date_from_cal() dùng để lấy dữ liệu từ
input_label_name, date_start và date_end chuyển dữ liệu date thành dạng phù hợp và bắt
đầu lấy dữ liệu và gán vào df cuối cùng là gọi hàm show_table() để biểu diễn dữ liệu dưới
dạng bảng
+ Xử lý dữ liệu:
def convert_mark(x):
if x.endswith("M"):
x = x.replace("M",' ')
x = float(x) * 1000000
return x
elif x.endswith("K"):
x = x.replace("K",' ')
x = float(x) * 1000
return x
elif x.endswith("B"):
x = x.replace("B",' ')
x = float(x) * 1000000000
return x
else:
return x
def to_list2d(data):
d = []
for i in data:
d.append(i[0])
return d
def replace_comma(df):
vol = []
for i in df["Vol."]:
vol.append(convert_mark(i))
df["Vol."] = vol
df["Price"] = df["Price"].str.replace(',', '').astype(float).fillna(0.0)
df["Open"] = df["Open"].str.replace(',', '').astype(float).fillna(0.0)
df["High"] = df["High"].str.replace(',', '').astype(float).fillna(0.0)
df["Low"] = df["Low"].str.replace(',', '').astype(float).fillna(0.0)
return df
Đôi khi sẽ có những dữ liệu do số quá lớn nên trên các nền tảng dữ liệu họ sẽ chuyển các
con số thành những chữ cái như K để biểu thị cho nghìn, M cho hàng triệu và B cho hàng
tỷ. Ngoài ra họ còn có thể thêm các dấu chấm hoặc phẩy để biểu diễn các con số cho dễ
nhìn hơn.
Nhưng như thế thì mô hình máy học không thể hiểu được và sẽ gặp lỗi khi huấn luyện
vậy nên ta cần chuyển các chữ cái và ký tự đó về dạng phù hợp
Vì cần biểu diễn hai phần khác nhau một phần sẽ biểu diễn biểu đồ phần còn còn lại sẽ là
phần huấn luyện và dự đoán nên ta sẽ chia phần bên dưới thành hai tab: ‘Plot’ và
‘Predict’
- Biểu đồ dữ liệu:
# Tab
tab_display = tk.CTkTabview(master=window)
# Config tab
tab_display.add('Plot')
tab_display.add('Predict')
# Set first tab display
tab_display.set('Plot')
frame_display = tk.CTkFrame(master=tab_display.tab('Plot'))
def show_input_plot_interactive(df):
try:
fig = plot.Figure(data=[plot.Candlestick(x=df['Date'],
open=df['Open'],
high=df['High'],
low=df['Low'],
close=df['Price'],
name = 'Candlestick'),
plot.Scatter(x = df['Date'],
y = df['Price'],
name = 'Price',
visible='legendonly',
line=dict(color='#3b24d1'))])
fig.update_layout(xaxis_rangeslider_visible=False,title_text = "")
fig.show()
except Exception as e:
print(str(e))
fig.write_image('fig1.jpeg')
global img
img = tk.CTkImage(light_image=Image.open('fig1.jpeg'),size=(700, 500))
img_label.configure(image=img)
img_label.image = img
except Exception as e:
print(str(e))
img_label.grid(row=1,column=0,columnspan=2)
frame_display.grid(row=2,sticky='EW',columnspan = 2)
Tạo hai nút với hai cách tạo biểu đồ khác nhau từ thư viện plotly
- Dự đoán :
Xác định các biến cần sử dụng và khởi tạo giá trị mặc định
+ Optimizer: Cho phép chọn các optimizer để huấn luyện và dự đoán
# Label Optimizer
# Label
optimizer_name = tk.CTkLabel(master=frame_predict,text='Optimizer')
optimizer_name.grid(column = 0, row = 0)
# function to get choicen optimizer
def get_optimizer(choice):
global optimizer
optimizer = choice
# Option of optimizer
optimizer_menu = tk.CTkOptionMenu(frame_predict,
values=['SGD','RMSprop','Adam',
'AdamW','Adadelta','Adagrad',
'Adamax','Adafactor','Nadam','Ftrl'],
command=get_optimizer)
optimizer_menu.grid(column = 0, row = 1)
'mean_squared_logarithmic_error'],
command=get_loss)
loss_menu.grid(column = 0, row = 3)
+ Batch size : Cho phép tùy chỉnh kích thước mỗi batch
# Epochs Label
def get_epochs(value):
global epochs
epochs =int(np.round(value))
var_epoch.set('Epochs: '+str(epochs))
epochs_label = tk.CTkLabel(master=frame_predict,textvariable=var_epoch)
epochs_label.grid(column = 0, row = 6)
epochs_slider = tk.CTkSlider(frame_predict, from_=1, to=100,
command=get_epochs ,width=500)
epochs_slider.grid(column = 0, row = 7)
+ Layer : Có thể thêm số lượng các lớp LSTM tối thiểu là 1 tối đa là 15 ( trong lớp mô
hình đã có sẵn 1 lớp)
# Layer config
def get_layer(value):
global layer
layer =int(np.round(value))
var_layer.set('Number of hiden layer: '+ str(layer))
layer_label = tk.CTkLabel(master=frame_predict,textvariable=var_layer)
layer_label.grid(column = 0, row = 8)
layer_slider = tk.CTkSlider(frame_predict, from_=1, to=15,
command=get_layer ,width=500)
layer_slider.grid(column = 0, row = 9)
unit_label = tk.CTkLabel(master=frame_predict,textvariable=var_unit)
unit_label.grid(column = 0, row = 10)
+ Checkbox: Tùy chọn xem biểu đồ huấn luyện mô hình ( Có chọn: Mở xem ở browser,
Không chọn: Xem dưới dạng ảnh)
# Show plot
checkbox_plot = tk.CTkCheckBox(master=frame_predict, variable=fig_state,
onvalue=1,offvalue=0, text="Show interative figure")
checkbox_plot.grid(column = 0, row = 12)
+ Nút bắt đầu huấn luyện: Thực hiện quá trình huấn luyện bằng hàm run_predict()
begin = tk.CTkButton(master=frame_predict,text='Run',command=lambda :
run_predict())
begin.grid(column = 0,row=13)
Predict_price = tk.CTkLabel(master=frame_predict,textvariable=predict_price)
Predict_price.grid(column =0 , row = 15)
+ img_predict: Vùng hiển thị ảnh quá trình huấn luyện nếu checkbox được chọn
img_pred = tk.CTkImage(light_image=Image.open('base.jpeg'),size=(700,500))
img_predict = tk.CTkLabel(master=frame_predict,image=img_pred, text="Notthing
to show")
img_predict.grid(column = 1, row = 0, rowspan = 26)
+ Hàm run_predict()
def run_predict():
global optimizer, loss, epochs, batch_size, img_predict,
fig_state,layer ,unit
Processbar.configure(maximum = epochs)
Processbar['value'] = 0
cur_run = LSTMclass(df, optimizer, loss, epochs, batch_size, layer,
fig_state.get(),unit)
values = cur_run.run()
predict_price.set("Predict values : " + str(values))
Đặt giá trị tối đa của processbar bằng số epoch và đưa giá trị processbar về 0
Khởi tạo LSTMclass bằng các thông số df, optimizer, loss, epochs, batch_size, layer,
fig_state.get(),unit và gán vào cur_run
Vì LSTMclass.run() sẽ trả về giá trị dự đoán nên ta gán giá trị đó vào values và thay đổi
Predict_price bằng giá trị values
Sau đó hiển thị ảnh trên img_predict
3.2 Tiến hành áp dụng thuật toán và chạy chương trình
- Áp dụng thuật toán
Xây dựng lớp LSTMclass
class LSTMclass:
def __init__(self,data,opt,los,epo,batch_si,nlayer,fig_stat,nunit):
self.df = data
self.optimizer = opt
self.loss = los
self.epoch = epo
self.batch = batch_si
self.layer = nlayer
self.unit_p_layer = int(nunit)
self.fig_state = fig_stat
self.test_end = self.df.iloc[0]["Date"]
self.test_start = self.df.iloc[60]["Date"]
Hàm run()
Thêm cột Tomorrow vào df
# training data
x_train = [] # Input data
y_train = [] # Target data
# build model
model = Sequential()
# Input layer
model.add(LSTM(units=50, return_sequences=True, input_shape=(x_train.shape[1],
1)))
model.add(Dropout(0.2))
model.add(LSTM(units=50, return_sequences=True))
model.add(Dropout(0.2))
# Hidden layer
for i in range(0,self.layer):
model.add(LSTM(units=self.unit_p_layer, return_sequences=True))
model.add(Dropout(0.2))
#output layer
model.add(LSTM(units=20))
model.add(Dropout(0.2))
model.add(Dense(units=1))
# Begin training
model.fit(x_train, y_train, epochs=self.epoch,
batch_size=self.batch ,callbacks=[CustomCallback()])
x_test = []
x_test = np.array(x_test)
x_test = np.reshape(x_test, (x_test.shape[0], x_test.shape[1], 1))
Chuẩn bị dữ liệu cho dự đoán ngày tiếp theo (tiếp sau ngày có trong bộ dữ liệu huấn
luyện)
- Chạy thử
Hình 11 Sau khi nhấn ‘Show plot in this window (static image)’
Chương 4
Kết luận
Chương 5
MVC TRONG FLUTTER VÀ NHỮNG WIDGET CƠ BẢN
5.1 MVC trong Flutter
Hình MVC trong Flutter, một framework phát triển ứng dụng di động đa nền tảng. Mô
hình này chia ứng dụng Flutter thành ba thành phần chính:
5.1.1 Model
-Lớp Model: Chứa dữ liệu và logic xử lý dữ liệu của ứng dụng.
Ví dụ: Lớp UserModel lưu trữ thông tin về người dùng, bao gồm tên, email, mật khẩu,
v.v.
5.1.2 View
-Widget: Các thành phần giao diện người dùng (UI) được xây dựng bằng các widget của
Flutter.
Ví dụ: Widget Text hiển thị văn bản, widget TextField cho phép người dùng nhập liệu,
v.v.
5.1.3 Controller
-Lớp State: Quản lý trạng thái của widget và tương tác với Model để lấy dữ liệu.
Ví dụ: Lớp UserState quản lý trạng thái của widget UserView, bao gồm dữ liệu người
dùng hiện tại, trạng thái đăng nhập, v.v.
5.1.4 Mối quan hệ của các thành phần
-Model: Cung cấp dữ liệu cho View thông qua Controller.
-View: Hiển thị dữ liệu từ Model và nhận tương tác từ người dùng.
-Controller: Xử lý tương tác từ người dùng và lấy dữ liệu từ Model để cập nhật View.
Lợi ích của mô hình MVC trong Flutter:
-Dễ dàng bảo trì: Việc tách biệt logic xử lý dữ liệu khỏi giao diện người dùng giúp cho
việc bảo trì ứng dụng dễ dàng hơn.
-Khả năng mở rộng cao: Mô hình MVC cho phép dễ dàng thêm các tính năng mới cho
ứng dụng mà không ảnh hưởng đến các phần khác của ứng dụng.
-Tái sử dụng code: Các widget có thể được tái sử dụng trong các ứng dụng khác.
Ví dụ về mô hình MVC trong Flutter:
Ứng dụng Todo List:
-Model: Lớp Todo lưu trữ thông tin về một việc cần làm.
-View: Widget TodoList hiển thị danh sách các việc cần làm.
-Controller: Lớp TodoController quản lý trạng thái của widget TodoList, bao gồm danh
sách các việc cần làm, thêm việc mới, v.v.
5.2 Những Widget cơ bản trong Flutter
Flutter hiện đang là framework moblie app đang được quan tâm trong thời gian gần đây
bởi nó vừa có thể giảm thời gian phát triển và chi phí ( thứ mà native framework không
có được ) hay đảm bảo performance ( một điểm yếu của react native). Flutter framework
giống như một tập hợp của rất nhiều widget, và widget giống như một loại vật liệu để xây
dựng lên app của bạn. Khi bạn xây dựng một màn hình hiển thị trên app bằng Flutter
cũng giống như bạn đang chơi một trò chơi xếp hình, công việc của bạn là phải tìm được
widget phù hợp để lắp ghép vào chỗ trống cho hoàn hảo nhất
5.2.1 Text
Đây là widget cơ bản giúp bạn format text trong ứng dụng của bạn, và thuộc tính quan
trọng nhất.
Text(
'Hello World',
style: TextStyle(
color: Colors.black,
fontSize: 40,
backgroundColor: Colors.white,
fontWeight: FontWeight.bold,
)
)
columnn(
MainAxisAlignment : MainAxisAlignment.start,
Children : [
SizedBox
height: 40,
),
Text(
'Hello World!',
Style : TextStyle(
fontSize: 30,
fontWeight: Fontweight.bold,
color: Colors.blacks,
),
),
SizedBox(
height: 40,
),
Text(
'This is Sample App',
style: TextStyle(
fontSize: 30,
colo,r : Colors.grey,
)
),
],
),
5.2.3 Stack
Cũng giống như Column hay Row, Stack cũng là 1 tập hợp các widget, tuy nhiên điểm
khác biệt là các widget con trong stack có thể chồng lên nhau. Thường đi kèm với widget
này là widget Positioned để căn chỉnh vị trí của từng widget trong Stack, hãy theo dõi ví
dụ dưới để hiểu hơn về stack:
5.2.4 Container
Container(
width: 200,
height: 200,
decoration: BoxDecoration(
color: Color.amber,
border: border.all(width: 1, Color: colors.black26),
borderRadius: borderRadius.circular(10)
),
padding: EdgeInsets.all(50)
child:FlutterLogo(
Size: 50,
),
),
5.2.5 SizedBox
Đây là widget mình hay sử dụng để tạo khoảng cách giữa các widget hơn là việc layout
một view:
columnn(
MainAxisAlignment : MainAxisAlignment.start,
Children : [
SizedBox
height: 20,
),
Text(
'Hello World!',
Style : TextStyle(
fontSize: 30,
fontWeight: Fontweight.bold,
color: Colors.blacks,
),
),
SizedBox(
height: 20,
),
Text(
'This is Sample App',
style: TextStyle(
fontSize: 20,
colo,r : Colors.grey,
)
),
],
),
5.2.6 SingleChildScrollView
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: column(
children: [
LogoBox(),
LogoBox(),
LogoBox(),
LogoBox(),
LogoBox(),
LogoBox(),
]
),
),
5.2.7 Expanded
Đây là widget hay được sử dụng để chia bố cục của widget cha thành các phân với tỉ lệ
tương ứng:
Column(
children:[
Expanded(
flex: 2,
child: container(color: Colors.green),
),
Expanded(
flex: 3,
child:container(color: Colors.blue),
),
Expanded(
child: Container(color: Color.grey),
),
],
),
assets
• icon: Lưu trữ biểu tượng SVG sử dụng trong ứng dụng.
• images: Lưu trữ hình ảnh được sử dụng trong ứng dụng.
lib
• main.dart: File gốc, chứa widget chính như AppBar, BottomAppBar.
• data.dart: Quản lý dữ liệu sản phẩm và các hàm xử lý dữ liệu.
• constants.dart: Lưu trữ các hằng số thường được sử dụng.
screen
- cart: Lưu trữ trang giỏ hàng.
- category: Lưu trữ trang danh mục sản phẩm.
- favorite: Lưu trữ trang danh mục yêu thích.
- home:
+ home_screen.dart: Trang chính hiển thị sản phẩm.
+ list_item.dart: Cấu trúc widget chung được sử dụng cho các trang.
- product:
+ product.dart: Lưu cấu trúc dữ liệu sản phẩm và các cấu trúc dữ liệu khác.
+ product_main.dart: Trang chính của chi tiết sản phẩm.
- receipt:
+ receipt_list.dart: Trang chính hiển thị danh sách hóa đơn.
+ receipt_model.dart: Các widget cho trang hóa đơn.
pubspec.yaml : File cấu hình cho ứng dụng, bao gồm các dependencies và các tùy chọn
khác.
6.2 Các Trang Và Chức Năng Chính
6.2.1 Trang main.dart định hình MyAppBar_Home, MyAppBar_Page và
BottomNavBar cho App
- Thanh MyAppBar_Home
main.dart:
<Wigget> MyAppBar_Home
AppBar
|-- leading: IconButton
| |-- icon: SvgPicture.asset
|-- title: Container
| |-- child: TextField
| |-- decoration: InputDecoration
|-- actions:
|-- IconButton
| |-- icon: SvgPicture.asset
|-- IconButton
|-- onPressed: () { Navigator.pushNamed(context, '/cart'); }
|-- icon: SvgPicture.asset
• Nút quay về trang trước (leading): IconButton này có biểu tượng mũi tên quay
về. Khi nhấn, nó sử dụng Navigator.pop để quay về trang trước đó, giống như việc
quay lại từ chi tiết sản phẩm hoặc từ trang tìm kiếm.
• Ô tìm kiếm sản phẩm (title): Container này chứa một ô tìm kiếm để người dùng
có thể nhập từ khóa để tìm kiếm sản phẩm trong cửa hàng.
• Nút hành động (actions):
• Nút thông báo: IconButton chứa biểu tượng thông báo
• Nút giỏ hàng: IconButton này chứa biểu tượng giỏ hàng. Khi nhấn, nó sử dụng
Navigator.pushNamed để chuyển đến trang giỏ hàng ('/cart').
- MyAppBar_Page
<Wigget> MyAppBar_Page
AppBar
|-- leading: IconButton
| |-- icon: SvgPicture.asset
| |-- onPressed: () { Navigator.pop(context); }
|-- title: Container
| |-- child: TextField
| |-- decoration: InputDecoration
|-- actions:
|-- IconButton
| |-- icon: SvgPicture.asset
|-- IconButton
|-- onPressed: () { Navigator.pushNamed(context, '/cart'); }
|-- icon: SvgPicture.asset
• Nút quay về trang trước (leading): IconButton này có biểu tượng mũi tên quay
về. Khi nhấn, nó sử dụng Navigator.pop để quay về trang trước đó, giống như việc
quay lại từ chi tiết sản phẩm hoặc từ trang tìm kiếm.
• Ô tìm kiếm sản phẩm (title): Container này chứa một ô tìm kiếm để người dùng
có thể nhập từ khóa để tìm kiếm sản phẩm trong cửa hàng.
• Nút hành động (actions):
- Nút thông báo hoặc hoạt động tùy chọn khác: IconButton này có thể chứa biểu
tượng thông báo hoặc các tùy chọn khác, tùy thuộc vào yêu cầu của ứng dụng bán
hàng.
- Nút giỏ hàng: IconButton này chứa biểu tượng giỏ hàng. Khi nhấn, nó sử dụng
Navigator.pushNamed để chuyển đến trang giỏ hàng ('/cart').
- BottomNavBar
<Wigget> MyBottomNavBar
final int currentIndex;
final ValueChanged<int> onTap;
BottomNavigationBar
|-- currentIndex: currentIndex
|-- selectedItemColor: Colors.deepOrangeAccent
|-- unselectedItemColor: Colors.black
|-- onTap: onTap
|-- items:
|-- BottomNavigationBarItem 1
| |-- icon: SvgPicture.asset("assets/icon/house-chimney.svg", color: Colors.black)
| |-- label: "Home"
|-- BottomNavigationBarItem 2
| |-- icon: SvgPicture.asset("assets/icon/receipt.svg", color: Colors.black)
| |-- label: "Receipt"
|-- BottomNavigationBarItem 3
|-- icon: SvgPicture.asset("assets/icon/heart.svg", color: Colors.black)
|-- label: "Favorites"
• currentIndex: Tham số này xác định mục nào sẽ được chọn khi thanh điều hướng
được vẽ lần đầu tiên. Nó thường được giữ bởi một biến được quản lý để theo dõi
trạng thái hiện tại của ứng dụng.
• selectedItemColor: Màu sắc của mục hiện đang được chọn (active).
• unselectedItemColor: Màu sắc của các mục không được chọn (inactive).
• onTap: Hàm xử lý sự kiện được gọi khi một mục được nhấn. Thông thường, bạn
sẽ cập nhật currentIndex dựa trên mục được chọn.
• items: Danh sách các mục trong thanh điều hướng. Mỗi mục được đại diện bởi
một BottomNavigationBarItem. Mỗi mục bao gồm:
• icon: Biểu tượng của mục, ở đây là một hình vector (SVG).
• label: Nhãn hiển thị bên cạnh biểu tượng, ví dụ: "Home", "Receipt",
"Favorites".
Hình 28 BottomNavBar
<file> List_item.dart:
<Wigget> ProductContainer
final product_card product;
final void Function()? onTap;
return GestureDetector
|-- onTap: onTap
|-- Container
|-- padding: EdgeInsets.symmetric(vertical: 10)
|-- decoration: BoxDecoration
|-- color: Colors.grey[100]
|-- border: Border (bottom)
|-- BorderSide
|-- color: Colors.grey
|-- width: 1.0
|-- Row
|-- Image.asset (product.imageUrl, height: 80)
|-- Column
|-- Container (product title)
|-- Text (product.title)
|-- Row (product rating)
|-- Text (product.rating)
|-- SvgPicture.asset ('assets/icon/star.svg', width: 12)
|-- Text ('\${product.price}')
<Wigget> Adbanner_content:
final Adbanner_data addata;
return GestureDetector
|-- onTap: ()
|--Navigator.push
|-- MaterialPageRoute
|--builder: (context) => product_item(item:
data().get_product_by_id(addata.id))
|-- Container
|-- margin: EdgeInsets.only(top: 10)
|-- height: 100
|-- width: 400
|-- child: Image.asset(addata.imageurl)
Hình 33 Sản phẩm trong Adbanner
<Wigget> category_wigget:
final category_base category;
return GestureDetector
|-- onTap: ()
|--Navigator.push
|-- MaterialPageRoute( builder: (context) =>
|--category_main (category: data().getCategory(category.id),)
|-- Container
|-- padding: EdgeInsets.symmetric(vertical: 10)
|-- height: 50
|-- child: Column
|-- SvgPicture.asset (category.icon, height: 20, width: 20)
|-- Spacer (flex: 5)
- Thanh AppBar:
• App bar hiển thị tiêu đề và icon của trang chính.
• Phần thân của trang sử dụng Consumer để lắng nghe và cập nhật dữ liệu từ data
provider.
• Sử dụng ListView.builder để hiển thị danh sách sản phẩm từ productList trong data
provider.
• Mỗi sản phẩm được hiển thị bằng ProductItemCard.
- Danh Sách Sản Phẩm:
• Sử dụng HomeScreen để hiển thị danh sách sản phẩm.
• Sử dụng ProductItemCard để tạo card cho mỗi sản phẩm trong danh sách.
• Sử dụng Consumer để lắng nghe thay đổi trong dữ liệu và cập nhật giao diện.
- Thanh Điều Hướng (BottomNavigationBar):
• Hiển thị thanh điều hướng dưới cùng với các tùy chọn Home, Receipt và Favorite.
• Sử dụng MyBottomNavBar để tạo thanh điều hướng.
- ProductContainer Widget:
• Dùng để hiển thị thông tin của từng sản phẩm trong danh mục.
• Sử dụng GestureDetector để xử lý sự kiện khi người dùng chọn một sản phẩm.
• Khi sản phẩm được chọn, chuyển đến trang chi tiết sản phẩm (product_item.dart).
Trang Hóa Đơn cung cấp quản lý danh sách hóa đơn và chi tiết hóa đơn
- Danh Sách Hóa Đơn:
• Mỗi hóa đơn được hiển thị thông qua widget receipt_card, chứa các thông tin như
hình ảnh sản phẩm, tên, số lượng, giá trị, trạng thái, và nút chuyển hướng đến
trang chi tiết sản phẩm khi nhấn vào.
- Chức Năng Yêu Cầu Hoàn Tiền và Nhận Hàng:
• Cho phép người dùng yêu cầu hoàn tiền và xác nhận đã nhận hàng.
• Nếu hóa đơn đã hoàn thành, hiển thị thông báo "Giao Hàng Thành Công !" hoặc
trạng thái hiện tại của hóa đơn.
- Chức Năng Yêu Cầu Hoàn Tiền và Đã Nhận Hàng (ElevatedButton):
• Nếu hóa đơn chưa hoàn thành, hiển thị hai nút "Yêu cầu hoàn tiền" và "Đã Nhận
được hàng" để người dùng thực hiện các hành động.
Chương 7
Tổng kết và hướng phát triển
Dữ liệu về ứng dụng Android là một phần quan trọng của cả hệ sinh thái di động, đóng vai
trò quyết định trong trải nghiệm người dùng và xu hướng công nghệ hiện đại. Theo dõi và
phân tích dữ liệu này mang lại cái nhìn sâu sắc về sự phát triển và ảnh hưởng của ứng
dụng trên nền tảng Android.Thị trường ứng dụng Android đã chứng kiến sự tăng trưởng
đáng kể, với hàng triệu ứng dụng được phát triển để đáp ứng nhu cầu ngày càng đa dạng
của người dùng. Dữ liệu về lượt tải về, đánh giá, và sử dụng ứng dụng là những chỉ số
quan trọng, cho thấy sự ưa chuộng và độ phổ biến của từng ứng dụng.
Khám phá xu hướng trong dữ liệu ứng dụng cũng là chìa khóa để hiểu rõ hơn về sở thích
và nhu cầu của người dùng. Sự thay đổi trong ưu tiên của họ, từ ứng dụng giáo dục đến
giải trí và công việc, đều được phản ánh qua dữ liệu sử dụng ứng dụng.Tính an toàn và
bảo mật của ứng dụng Android cũng là một điểm quan trọng cần xem xét. Dữ liệu về các
lỗ hổng bảo mật, cập nhật phần mềm, và phản ứng của người dùng đối với các vấn đề an
ninh là yếu tố quyết định đến sự tin cậy và sự thành công của một ứng dụng.
Tóm lại, dữ liệu ứng dụng Android không chỉ là tập hợp các con số, mà là nguồn thông tin
quý giá về sự phát triển của nền tảng di động này. Việc hiểu rõ về xu hướng và thách thức
từ dữ liệu này không chỉ hỗ trợ nhà phát triển ứng dụng mà còn giúp định hình hình ảnh
toàn cầu của thế giới di động.
[1] Nguyễn Thanh Tuấn (2009), Deeplearning cơ bản The Legrand Orange Book
Template by Mathias Legrand is used : https://nttuan8.com/sach-deep-learning-co-ban/
[2] Ths.Hồ Khôi (2022) ,Lecturer in deep learning at the Faculty of Information
Technology, Nguyen Tat Thanh University.
[3] Wikipedia, Long short – term memory (29-11-2023),
https://en.wikipedia.org/wiki/Long_short-term_memory
[4] Wikipedia, Recurrent neural network (27-11-2023) ,
https://en.wikipedia.org/wiki/Recurrent_neural_network
[5] Giảng viên Hà Minh Tân (2023), Lecturer in deep learning at the Faculty of
Information Technology, Nguyen Tat Thanh University. (28 – 12 – 2023)
[6] Flutter documentation, https://docs.flutter.dev/ (10 – 1 – 2024)
[7] Github: Phân tích thị trường chứng khoáng: https://github.com/FuryGox/Predict-
marketplace
[8] Github: Soft- mobile (shoppe_f): https://github.com/FuryGox/shoppe_f
[9] Google Drive:
https://drive.google.com/drive/folders/1QoKMZkrPhikPAmqnD_vpbiJsJ5ImfrNC?
usp=sharing