Untitled

BTVN TUẦN 5

WEB SCRAPING - CÀO DỮ LIỆU

Tổng quát về Web scraping

Web scraping là gì?

   Web scraping đề cập đến việc trích xuất dữ liệu từ một trang web. Thông tin này được thu thập và sau đó xuất thành định dạng hữu ích hơn cho người dùng (có thể là bảng tính hoặc API).

   Mặc dù web scraping có thể được thực hiện thủ công, nhưng trong hầu hết các trường hợp, các công cụ tự động được ưu tiên khi trích xuất dữ liệu web vì chúng ít tốn kém và hoạt động với tốc độ nhanh hơn.

   Nhưng trong hầu hết các trường hợp, web scraping không phải là một nhiệm vụ đơn giản. Các trang web có nhiều hình dạng và biểu mẫu, do đó, các web scraper (trình trích xuất dữ liệu web) khác nhau về chức năng và tính năng.

Web scraping hoạt động như thế nào

   Web scraper tự động hoạt động theo cách khá đơn giản nhưng cũng rất phức tạp. Rốt cuộc, các trang web được xây dựng cho con người hiểu chứ không phải máy móc. Đầu tiên, web scraper sẽ được cung cấp một hoặc nhiều URL để load trước khi trích xuất dữ liệu. Sau đó, scraper sẽ load toàn bộ code HTML cho trang đang đề cập. Những scraper nâng cao hơn sẽ kết xuất toàn bộ trang web, bao gồm các yếu tố CSS và Javascript.

Web scraping dùng để làm gì

   Đến thời điểm này, có lẽ bạn có thể nghĩ ra một số cách khác nhau để sử dụng web scraper.Dưới đây là một số công dụng phổ biến nhất:

• Trích xuất giá cổ phiếu vào API ứng dụng • Trích xuất dữ liệu từ YellowPages để tạo khách hàng tiềm năng • Trích xuất dữ liệu từ một công cụ định vị cửa hàng để tạo danh sách các địa điểm kinh doanh • Trích xuất dữ liệu sản phẩm từ các trang web như Amazon hoặc eBay để phân tích đối thủ cạnh tranh • Trích xuất dữ liệu trang web trước khi di chuyển trang web • Trích xuất chi tiết sản phẩm để so sánh khi mua sắm • Trích xuất dữ liệu tài chính để nghiên cứu thị trường

Dữ liệu USD/VND từ Investing.com

   Investing.com là một nền tảng cung cấp dữ liệu, bảng báo giá theo thời gian thực, biểu đồ, công cụ tài chính, tin nóng và các bài phân tích trên 250 sàn giao dịch trên khắp thế giới với 44 phiên bản ngôn ngữ. Với hơn 21 triệu người dùng hàng tháng và hơn 180 triệu phiên giao dịch, Investing.com là một trong ba trang web tài chính hàng đầu thế giới theo SimilarWeb và Alexa.

   Với hơn 300.000 công cụ tài chính, Investing.com cho phép người dùng truy cập không giới hạn và hoàn toàn miễn phí các công cụ hiện đại bậc nhất thị trường tài chính như báo giá và thông báo theo thời gian thực, danh mục đầu tư tùy chỉnh, thông báo cá nhân, lịch, công cụ tính và thông tin tài chính chuyên sâu.

   Ngoài thông tin về các Thị trường Chứng khoán trên toàn cầu, Investing.com còn cung cấp thông tin về Hàng hóa, Tiền điện tử, các Chỉ số quốc tế, Các loại tiền tệ trên thế giới, Trái phiếu, các Quỹ và Lãi suất, Hợp đồng tương lai và Quyền chọn của các Quỹ giao dịch ngoại hối (ETF)

   Trong bài này tôi sẽ giới thiệu với các bạn cách sử dụng gói rvest trong R để scrape dữ liệu lịch sử thị trường các loại tiền

Thông tin dữ liệu

   Tỷ giá hối đoán Việt Nam : tỷ lệ giá trị của đồng USD so với VND Giá của 1 USD = ? VND

Lấy dữ liệu từ trang web để tiến hành phân tích

dl <- paste0("https://www.investing.com/currencies/usd-vnd-historical-data")

Đọc dữ liệu từ web

url <- read_html(dl)
data <- url%>%html_table(fill = TRUE)
da = data[[2]]
head(da)
## # A tibble: 6 × 7
##   Date       Price    Open     High     Low      Vol.  `Change %`
##   <chr>      <chr>    <chr>    <chr>    <chr>    <lgl> <chr>     
## 1 07/14/2023 23,630.0 23,660.0 23,665.0 23,627.5 NA    -0.15%    
## 2 07/13/2023 23,665.0 23,630.0 23,677.5 23,625.0 NA    +0.02%    
## 3 07/12/2023 23,660.0 23,700.0 23,700.0 23,655.0 NA    -0.13%    
## 4 07/11/2023 23,690.0 23,635.0 23,715.0 23,628.5 NA    +0.21%    
## 5 07/10/2023 23,640.0 23,630.0 23,672.5 23,603.0 NA    +0.02%    
## 6 07/07/2023 23,635.0 23,712.5 23,717.5 23,640.0 NA    -0.32%
  • Giải thích các biến của dataset USD/VND:
  • Date: ngày.
  • Price: giá thị trường của USD/VND
  • Open: giá mở bán của USD/VND
  • High: giá cao nhất trong ngày của USD/VND
  • Low: giá thấp nhất trong ngày của USD/VND

Xử lý dữ liệu từ web

   Dữ liệu thô ban đầu được scraping từ web là một dữ liệu dạng “character” chứ không phải dạng vecto số “numberic”. Vì vậy chúng ta cần dùng hàm để biến đổi dữ liệu gốc thành dữ liệu số để thực hiện được phân tích.

price <- da$Price
daprice <- as.numeric(gsub(",", "", price))

   Dữ liệu ban đầu sau khi nhập từ web về là dữ liệu được xếp theo thứ tự ngày gần nhất đến ngày xa nhất. Vì thế ta cần sắp xếp lại chiều vector từ trái qua phải với thứ tự ngày xa nhất đếnngayf gần nhất.

daprice1 <- rev(daprice)
daprice1  
##  [1] 23525 23520 23520 23520 23505 23515 23515 23530 23520 23555 23569 23575
## [13] 23695 23700 23745 23710 23635 23640 23690 23660 23665 23630
  • Vẽ đồ thị giá theo thời gian
library(tseries)
plot.ts(daprice1, ylab= "Price", xlab= "Time" , main= "USD/VND")

Phân tích dữ liệu chuỗi thời gian

   Chuỗi thời gian (time series) là một chuỗi các điểm dữ liệu xảy ra theo thứ tự liên tiếp trong một khoảng thời gian. Một chuỗi thời gian sẽ theo dõi chuyển động của các điểm dữ liệu đã chọn trong một khoảng thời gian xác định.

Lập bảng thống kê mô tả

   Thống kê mô tả giúp mô tả và hiểu được các tính chất của một bộ dữ liệu cụ thể bằng cách đưa ra các tóm tắt ngắn về mẫu và các thông số của dữ liệu. Loại thống kê mô tả phổ biến nhất là các thông số xu hướng tập trung gồm: giá trị trung bình, trung vị và độ lệch chuẩn, độ lệch, độ nhọn.

library("fBasics")
## 
## Attaching package: 'fBasics'
## The following objects are masked from 'package:rugarch':
## 
##     qgh, qnig
## The following objects are masked from 'package:PerformanceAnalytics':
## 
##     kurtosis, skewness
## The following object is masked from 'package:TTR':
## 
##     volatility
basicStats(daprice)
##                   daprice
## nobs            22.000000
## NAs              0.000000
## Minimum      23505.000000
## Maximum      23745.000000
## 1. Quartile  23520.000000
## 3. Quartile  23663.750000
## Mean         23597.227273
## Median       23572.000000
## Sum         519139.000000
## SE Mean         17.084072
## LCL Mean     23561.699001
## UCL Mean     23632.755545
## Variance      6421.041126
## Stdev           80.131399
## Skewness         0.324885
## Kurtosis        -1.548571

   Nhưng nếu ta sử dụng dữ liệu về giá để thực hiện các phân tích thì sẽ không hợp lí vì đây là dữ liệu sẽ thay đổi theo thời gian - không có tính dừng. Và nếu thay đổi theo thời gian thì sẽ không thể chạy các mô hình khác được nữa vì cơ bản thì các mô hình dựa trên dự báo về giá trị trung bình và kiểm định thông qua giá trị trung bình và độ lệch chuẩn - Để khắc phục thì ta thực hiện việc kiểm tra tính dừng

Vẽ đồ thị

hist(daprice)

d1<- density(daprice)
plot(d1,type='l')

-> Biểu đồ cho thấy Không có sự liên quan đến nhau - chuỗi không có tính dừng

Kiểm tra tính dừng

  • Cách giải quyết: ta có thể lấy sai phân của logarit để tạo chuỗi dừng trong tình huống chuỗi không dừng. Sai phân của logarit được lựa chọn là do nó thể hiện phần trăm tăng trưởng của chuỗi qua thời gian.
rprice <- diff(log(daprice))
rprice
##  [1]  0.0014800722 -0.0002113048  0.0012671596 -0.0021128256 -0.0002115283
##  [6]  0.0031682358  0.0014750819 -0.0018969339 -0.0002109927 -0.0050772269
## [11] -0.0002545393 -0.0005941771 -0.0014869891  0.0004250797 -0.0006376873
## [16]  0.0000000000 -0.0004253509  0.0006379586  0.0000000000  0.0000000000
## [21]  0.0002125624

   -> Ta thấy ở số đầu tiên là 0,001 tức là 0,1% vì giá của đồng tiền tăng từ 23640 lên 23665.

  • Vẽ đồ thị để kiểm tra tính dừng
plot(rprice)

hist(rprice)

d2<- density(rprice)
plot(d2,type="l")

->

basicStats(rprice)
##                rprice
## nobs        21.000000
## NAs          0.000000
## Minimum     -0.005077
## Maximum      0.003168
## 1. Quartile -0.000594
## 3. Quartile  0.000425
## Mean        -0.000212
## Median      -0.000211
## Sum         -0.004453
## SE Mean      0.000355
## LCL Mean    -0.000952
## UCL Mean     0.000528
## Variance     0.000003
## Stdev        0.001626
## Skewness    -0.847489
## Kurtosis     2.014692

   -> Ta thấy median=-0,000211 mean=-0.00027-> đồ thị lệch, skewness là giá trị âm và kurtosis= 2,2-> phân phối xác suất gần chuẩn chứ chưa gọi là chuẩn vì còn một số giá trị cực đoan ở 2 đuôi và

Kiểm định phân phối chuẩn

   Kiểm định Jarque-Bera Giá trị kiểm định Jarque-Bera được xây dựng dựa trên hệ số skewness và kutorsis JB sẽ tuân theo qui luật phân phối khi bình phương bởi nó là tổng của bình phương 2 phân phối chuẩn. h0: là phân phối chuẩn ta có thể sử dụng p-value để so sánh với α=0.05 trong mức ý nghĩa thống kê 1−α=0.95 để kết luận bác bỏ H0 nếu p-value nhỏ hơn ngưỡng này.

normalTest(rprice,method = c("jb"))
## 
## Title:
##  Jarque - Bera Normalality Test
## 
## Test Results:
##   STATISTIC:
##     X-squared: 8.5051
##   P VALUE:
##     Asymptotic p Value: 0.01423

   p-value=0,007677 < mức ý nghĩa 0.05 -> bác bỏ h0. vậy không là phân phối chuẩn

Kiểm định tính dừng _ Dickey - Fuller

   Chúng ta sẽ so sánh giá trị ngưỡng kiểm định này với giá trị tới hạn của phân phối Dickey - Fuller để đưa ra kết luận về chấp nhận hoặc bác bỏ giả thuyết H0. Kiểm định tính dừng của chuỗi, sử dụng hàm adf.test() của package tseries. Trong các kiểm định thống kê của R, hầu hết các kết quả trả về đều có dạng xác xuất. Việc này sẽ thuận tiện hơn cho người dùng khi đưa ra kết luận vì ngưỡng tới hạn để bác bỏ giả thuyết luôn là 0.05. Do đó thay vì so sánh cặp giá trị kiểm định với giá trị tới hạn ta sẽ so sánh giá trị xác xuất kiểm định p-value với ngưỡng 0.05. Khi đã đọc nhiều kiểm định sẽ hình thành phản xạ rất nhanh khi so sánh với 0.05.

H0:Chuỗi không dừng được chấp nhận khi p-value > 0.05 H1:alternative hypothesis: stationary: có tính dừng khi p-value < 0.05.

library(tseries)
adf.test(daprice)
## 
##  Augmented Dickey-Fuller Test
## 
## data:  daprice
## Dickey-Fuller = -2.2214, Lag order = 2, p-value = 0.488
## alternative hypothesis: stationary

   Kết quả cho biết p-value > 5% không đủ cơ sở bác bỏ H0 vì thế ta kết luận không có tính dừng -> k đc đưa vào mô hình

Kiểm định KPSS

H0: Có tính dừng H1: Không có tính dừng

kpss.test(rprice)
## Warning in kpss.test(rprice): p-value greater than printed p-value
## 
##  KPSS Test for Level Stationarity
## 
## data:  rprice
## KPSS Level = 0.12417, Truncation lag parameter = 2, p-value = 0.1

   Kết quả cho biết p-value < 5% bác bỏ H0 vì thế ta kết luận có tính dừng

Kiểm định sự tự tương quan theo chuỗi

   Kiểm tra yếu tố tự tương quan của phần dư bằng đồ thị ACF thông qua hàm acf():

acf(rprice)

   Ta có thể thấy phần dư không có yếu tố tự tương quan do các giá trị tự tương quan không vượt quá ngưỡng tin cậy 95%.

   Các đường nét đứt màu xanh thể hiện cận trên và dưới của khoảng tin cậy 95% đối với kiểm định hệ số tương quan bằng 0. Trục tung là giá trị của hệ số tương quan trễ và trục hoành là các độ trễ tương ứng. Tại độ trễ bằng 0 hệ số tương quan đo lường chuỗi đó với chính nó nên giá trị bằng 1. Các độ trễ khác hệ số tương quan không vượt quá khoảng tin cậy 95% nên có thể thấy chuỗi nhiễu trắng không có hiện tượng tự tương quan.

Box.test(rprice,lag = 10)
## 
##  Box-Pierce test
## 
## data:  rprice
## X-squared = 3.6318, df = 10, p-value = 0.9624

Dự báo chuỗi thời gian

PriceForecasts <- HoltWinters(daprice1, gamma = FALSE)
coefficients <- PriceForecasts$coefficients
x <- data.frame(as.numeric(coefficients))
ketquadubao= sum(x)
ketquadubao
## [1] 23627.72

VIẾT 1 FUNCTION CHO CÔNG VIỆC

Dự báo giá để mua USD của 1 đồng tiền

Giả sử tôi muốn biết tỷ giá hối đoái giữa giá trị đơn vị tiền tệ của Hoa Kỳ(USD) với đơn vị tiền tệ của một quốc gia khác và sử dụng tỷ giá đó để tính toán giá trị của các giao dịch thương mại quốc tế, đầu tư nước ngoài và các hoạt động tài chính khác.

Vì vậy, để tính toán tỷ giá của đồng USD với đồng tiền của quốc gia khác một cách dễ dàng mà không mất nhiều thời gian nhưng vẫn đảm bào được độ chính xác, thì tôi chỉ cần tạo ra 1 function mẫu trong đó giá trị tiền tệ của các quốc gia khác sẽ được đặt là ẩn “x”. Như vậy, khi tôi cần tính tỷ giá của USD với đồng tiền nước khác thì tôi chỉ cần thay biến “x” bằng đồng tiền của quốc gia đó.

Để thực hiện ý tưởng đó, tôi cần tạo một function: get_data_currency(tigia) và khi ta cần tính toán tỷ giá thì ta chỉ cần thay biến tigia thành biến cần tính. Ví dụ ta cần tính: - USD/VND: cần bao nhiêu VND để mua một USD (usd-vnd) - USD/CNY: cần bao nhiêu Tệ để mua một USD (usd-cny)

Viết hàm dự báo

Thao tác với hàm mẫu

  • Tôi muốn biết cần bao nhiêu tiền VND để mua một USD vào ngày hôm sau, ở đây biến tigia của tôi là “usd-vnd”
get_data_currency("usd-vnd")
## [1] 23627.72
  • Tôi muốn biết phải cần bao nhiêu Tệ thì có thể mua một đô la Mỹ(USD) vào ngày hôm sau. Biến tigia của tôi là “usd-cny”
get_data_currency("usd-cny")
## [1] 7.119129

Kiểm định tính dừng của USD/đồng tiền của 1 nước

Tương tự như hàm dự báo ta có thể thực hiện việc viết một hàm để kiểm định tính dừng về tỷ giá hối đoái giữa đồng USD/đồng tiền nước khác

Ở trường hợp này, ta đặt ẩn là “tigia2” và khi cần kiểm định tính dừng giữa hai giá trị nào đó thì ta cũng chỉ cần thay thế biến đó vào “tigia2”

  • Tôi muốn biết giá của tỷ giá USD/VND có tính dừng hay không
get_data_currency2("usd-vnd")
## 
##  Augmented Dickey-Fuller Test
## 
## data:  P22
## Dickey-Fuller = -1.7325, Lag order = 2, p-value = 0.6743
## alternative hypothesis: stationary

Kết quả cho biết p-value > 5% không đủ cơ sở bác bỏ H0 vì thế ta kết luận giá của USD/VND không có tính dừng.