library(tidyverse)
library(moments)
library(stats)

1 DỮ LIỆU

1.2 Giải thích dữ liệu

data <- read.csv("C:/Users/tranh/Downloads/toankinhte/household_power_consumption.txt", sep = ";", header = TRUE, col.names = c("Date", "Time", "P", "Q", "V", "I", "A1", "A2", "A3"))
data <- na.omit(data)
str(data)
## 'data.frame':    2049280 obs. of  9 variables:
##  $ Date: chr  "16/12/2006" "16/12/2006" "16/12/2006" "16/12/2006" ...
##  $ Time: chr  "17:24:00" "17:25:00" "17:26:00" "17:27:00" ...
##  $ P   : chr  "4.216" "5.360" "5.374" "5.388" ...
##  $ Q   : chr  "0.418" "0.436" "0.498" "0.502" ...
##  $ V   : chr  "234.840" "233.630" "233.290" "233.740" ...
##  $ I   : chr  "18.400" "23.000" "23.000" "23.000" ...
##  $ A1  : chr  "0.000" "0.000" "0.000" "0.000" ...
##  $ A2  : chr  "1.000" "1.000" "2.000" "1.000" ...
##  $ A3  : num  17 16 17 17 17 17 17 17 17 16 ...
##  - attr(*, "na.action")= 'omit' Named int [1:25979] 6840 6841 19725 19726 41833 61910 98255 98256 142589 190498 ...
##   ..- attr(*, "names")= chr [1:25979] "6840" "6841" "19725" "19726" ...
head(data)
##         Date     Time     P     Q       V      I    A1    A2 A3
## 1 16/12/2006 17:24:00 4.216 0.418 234.840 18.400 0.000 1.000 17
## 2 16/12/2006 17:25:00 5.360 0.436 233.630 23.000 0.000 1.000 16
## 3 16/12/2006 17:26:00 5.374 0.498 233.290 23.000 0.000 2.000 17
## 4 16/12/2006 17:27:00 5.388 0.502 233.740 23.000 0.000 1.000 17
## 5 16/12/2006 17:28:00 3.666 0.528 235.680 15.800 0.000 1.000 17
## 6 16/12/2006 17:29:00 3.520 0.522 235.020 15.000 0.000 2.000 17

Tập dữ liệu chứa các đo lường về tiêu thụ điện trong một hộ gia đình cụ thể. Nó có 2075259 hàng và 9 cột. Dữ liệu được lấy mẫu theo khoảng thời gian một phút và bao phủ một khoảng thời gian gần 4 năm.

  • Date: Ngày ở định dạng dd / mm / yyyy.

  • Time: thời gian ở định dạng hh: mm: ss.

  • Global_Active_Power (P): Đây là công suất hoạt động trung bình toàn cầu trong một phút của hộ gia đình, đo bằng kilowatt (kW). Công suất hoạt động, còn được gọi là công suất thực, là phần của công suất điện mà thực sự được sử dụng để thực hiện công việc.

  • Global_Reactive_Power (Q): Đây là công suất phản kháng trung bình toàn cầu trong một phút, đo bằng kilowatt (kW). Công suất phản kháng là công suất điện không thực hiện công việc nhưng tạo ra từ việc dịch chuyển pha giữa dòng và điện áp.

  • Voltage (v): Đây là điện áp trung bình trong một phút, đo bằng volt. Điện áp là một đại lượng điện học đo mức độ khác biệt tiềm năng giữa hai điểm trong mạch điện.

  • Global_Intensity (I): Đây là cường độ dòng điện trung bình toàn cầu trong một phút, đo bằng ampe. Cường độ dòng điện là lượng điện tích di chuyển qua một mặt cắt trong một đơn vị thời gian.

  • Sub_Metering_1 (A1): Đây là lượng năng lượng tiêu thụ trung bình theo giờ của các thiết bị trong bếp (chủ yếu là máy rửa chén, lò nướng và lò vi sóng; bếp không sử dụng điện mà sử dụng gas), đo bằng watt-hour.

  • Sub_Metering_2 (A2): Đây là lượng năng lượng tiêu thụ trung bình theo giờ của các thiết bị trong phòng giặt (bao gồm máy giặt, máy sấy, tủ lạnh và đèn), đo bằng watt-hour.

  • Sub_Metering_3 (A3): Đây là lượng năng lượng tiêu thụ trung bình theo giờ của các thiết bị điện nước và máy điều hòa nhiệt độ, đo bằng watt-hour.

2 Chuyển đổi dữ liệu

Có hai cách thực hiện chuyển đổi dữ liệu, do bộ dữ liệu khi lấy về không ở định dạng thích hợp nên ta phải thực hiện chuyển đổi:

  • Cách 1: Em dùng câu lệnh chỉ định trên từng cột dữ liệu
data$Date <- as.Date(data$Date, format = "%d/%m/%Y")
data$Time <- as.POSIXct(data$Time,format = "%H:%M:%S")
columns <- c("P", "Q", "V", "I", "A1", "A2", "A3")
data[columns] <- lapply(data[columns], as.numeric)
str(data)
## 'data.frame':    2049280 obs. of  9 variables:
##  $ Date: Date, format: "2006-12-16" "2006-12-16" ...
##  $ Time: POSIXct, format: "2023-07-24 17:24:00" "2023-07-24 17:25:00" ...
##  $ P   : num  4.22 5.36 5.37 5.39 3.67 ...
##  $ Q   : num  0.418 0.436 0.498 0.502 0.528 0.522 0.52 0.52 0.51 0.51 ...
##  $ V   : num  235 234 233 234 236 ...
##  $ I   : num  18.4 23 23 23 15.8 15 15.8 15.8 15.8 15.8 ...
##  $ A1  : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ A2  : num  1 1 2 1 1 2 1 1 1 2 ...
##  $ A3  : num  17 16 17 17 17 17 17 17 17 16 ...
##  - attr(*, "na.action")= 'omit' Named int [1:25979] 6840 6841 19725 19726 41833 61910 98255 98256 142589 190498 ...
##   ..- attr(*, "names")= chr [1:25979] "6840" "6841" "19725" "19726" ...
  • Cách 2: em tạo vòng lặp để thực hiện chuyển đổi.
columns <- c("Date", "Time", "P", "Q", "V", "I", "A1", "A2")
for (col in columns) {
  if (col %in% c("Date", "Time")) {
    if (col == "Date") {
      data[[col]] <- as.Date(data[[col]], format = "%d/%m/%Y")
    } else {
      data[[col]] <- as.POSIXct(data[[col]], format = "%H:%M:%S")
    }
  } else {
    data[[col]] <- as.numeric(data[[col]])
  }
}
str(data)
## 'data.frame':    2049280 obs. of  9 variables:
##  $ Date: Date, format: "2006-12-16" "2006-12-16" ...
##  $ Time: POSIXct, format: "2023-07-24 17:24:00" "2023-07-24 17:25:00" ...
##  $ P   : num  4.22 5.36 5.37 5.39 3.67 ...
##  $ Q   : num  0.418 0.436 0.498 0.502 0.528 0.522 0.52 0.52 0.51 0.51 ...
##  $ V   : num  235 234 233 234 236 ...
##  $ I   : num  18.4 23 23 23 15.8 15 15.8 15.8 15.8 15.8 ...
##  $ A1  : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ A2  : num  1 1 2 1 1 2 1 1 1 2 ...
##  $ A3  : num  17 16 17 17 17 17 17 17 17 16 ...
##  - attr(*, "na.action")= 'omit' Named int [1:25979] 6840 6841 19725 19726 41833 61910 98255 98256 142589 190498 ...
##   ..- attr(*, "names")= chr [1:25979] "6840" "6841" "19725" "19726" ...

3 Thêm cột biến mới

Từ bộ dữ liệu em thực hiện tạo thêm một cột mới có tên là Week chứa dữ liệu tương ứng với các ngày thuộc tuần tương ứng.

data <- data %>%
  mutate(Week = lubridate::week(Date))

4 Lọc dữ liệu

4.1 Lọc dữ liệu theo ngày

loc1 là em tạo một bộ data mới có các giá trị của quan sát thuộc ngày 16-12-2006 và loc2 để chứa các giá trị của ngày 16-12-2008. Nhằm để quan sát sự thay đổi của từng ngày hoặc trực quan hóa, tính toán dễ dàng hơn với bộ dữ liệu đó.

loc1 <- data %>% filter(Date == "2006-12-16")
head(loc1)
##         Date                Time     P     Q      V    I A1 A2 A3 Week
## 1 2006-12-16 2023-07-24 17:24:00 4.216 0.418 234.84 18.4  0  1 17   50
## 2 2006-12-16 2023-07-24 17:25:00 5.360 0.436 233.63 23.0  0  1 16   50
## 3 2006-12-16 2023-07-24 17:26:00 5.374 0.498 233.29 23.0  0  2 17   50
## 4 2006-12-16 2023-07-24 17:27:00 5.388 0.502 233.74 23.0  0  1 17   50
## 5 2006-12-16 2023-07-24 17:28:00 3.666 0.528 235.68 15.8  0  1 17   50
## 6 2006-12-16 2023-07-24 17:29:00 3.520 0.522 235.02 15.0  0  2 17   50
loc2 <- data %>% filter(Date =="2008-12-16")
head(loc2)
##         Date                Time     P Q      V   I A1 A2 A3 Week
## 1 2008-12-16 2023-07-24 00:00:00 0.344 0 244.24 1.6  0  0  0   51
## 2 2008-12-16 2023-07-24 00:01:00 0.346 0 244.18 1.6  0  0  0   51
## 3 2008-12-16 2023-07-24 00:02:00 0.346 0 244.14 1.6  0  0  0   51
## 4 2008-12-16 2023-07-24 00:03:00 0.346 0 244.08 1.6  0  0  0   51
## 5 2008-12-16 2023-07-24 00:04:00 0.350 0 244.54 1.6  0  0  0   51
## 6 2008-12-16 2023-07-24 00:05:00 0.352 0 244.78 1.6  0  0  0   51

4.2 Lọc dữ liệu theo ngày trong khoảng thời gian từ bao nhiêu giờ

loc3 <- data %>% filter(Date =="2008-12-16"&Time >= as.POSIXct("08:00:00", format = "%H:%M:%S") & Time <= as.POSIXct("12:00:00", format = "%H:%M:%S"))
head(loc3)
##         Date                Time     P     Q      V    I A1 A2 A3 Week
## 1 2008-12-16 2023-07-24 08:00:00 4.774 0.150 237.87 20.0  0  0 17   51
## 2 2008-12-16 2023-07-24 08:01:00 3.792 0.000 238.13 16.0  0  0 18   51
## 3 2008-12-16 2023-07-24 08:02:00 3.226 0.000 238.41 13.4  0  0 17   51
## 4 2008-12-16 2023-07-24 08:03:00 2.756 0.062 238.78 11.4  0  0 18   51
## 5 2008-12-16 2023-07-24 08:04:00 2.848 0.120 238.03 12.0  0  0 17   51
## 6 2008-12-16 2023-07-24 08:05:00 2.634 0.130 238.97 11.0  0  0 18   51
loc4 <- data %>% filter(Date =="2008-12-16"&Time >= as.POSIXct("13:00:00", format = "%H:%M:%S") & Time <= as.POSIXct("17:00:00", format = "%H:%M:%S"))
head(loc4)
##         Date                Time     P     Q      V   I A1 A2 A3 Week
## 1 2008-12-16 2023-07-24 13:00:00 1.812 0.320 241.55 7.6  0  2 18   51
## 2 2008-12-16 2023-07-24 13:01:00 1.808 0.320 241.44 7.6  0  1 18   51
## 3 2008-12-16 2023-07-24 13:02:00 1.810 0.320 241.59 7.6  0  2 18   51
## 4 2008-12-16 2023-07-24 13:03:00 1.780 0.278 241.57 7.4  0  1 18   51
## 5 2008-12-16 2023-07-24 13:04:00 1.738 0.216 241.54 7.2  0  1 17   51
## 6 2008-12-16 2023-07-24 13:05:00 1.740 0.218 241.86 7.2  0  2 18   51
loc5 <- data %>% filter(Date =="2008-12-16"&Time >= as.POSIXct("18:00:00", format = "%H:%M:%S") & Time <= as.POSIXct("22:00:00", format = "%H:%M:%S"))
head(loc5)
##         Date                Time     P Q      V   I A1 A2 A3 Week
## 1 2008-12-16 2023-07-24 18:00:00 0.854 0 241.58 3.4  0  0  0   51
## 2 2008-12-16 2023-07-24 18:01:00 0.800 0 241.90 3.2  0  0  0   51
## 3 2008-12-16 2023-07-24 18:02:00 0.796 0 241.30 3.2  0  0  0   51
## 4 2008-12-16 2023-07-24 18:03:00 0.798 0 241.63 3.2  0  0  0   51
## 5 2008-12-16 2023-07-24 18:04:00 0.798 0 241.88 3.2  0  0  0   51
## 6 2008-12-16 2023-07-24 18:05:00 0.796 0 241.15 3.2  0  0  0   51

4.3 Lọc dữ liệu theo tuần

Lọc ra tuần đầu tiên trong năm (loc6)

loc6 <- data %>%
  mutate(Week = lubridate::week(Date)) %>% filter(Week=="1")

Hoặc do phía trên em đã thêm trực tiếp cột Week vào trong bộ dữ liệu nên em có thể trực tiếp lọc từ cột biến Week

loc7 <- data %>% filter(Week=="53")

5 Tính toán thống kê

Đầu tiên em viết một function để tính toán các thống kê mô tả như sau:

  • mean: giá trị trung bình của biến, loại bỏ các giá trị NA (không có giá trị).

  • median: giá trị trung vị của biến, loại bỏ các giá trị NA.

  • sd: độ lệch chuẩn của biến, loại bỏ các giá trị NA.

  • min: giá trị nhỏ nhất của biến, loại bỏ các giá trị NA.

  • max: giá trị lớn nhất của biến, loại bỏ các giá trị NA.

  • skewness: độ nghiêng của phân phối biến.

  • kurtosis: độ nhọn của phân phối biến.

  • unique_values: số lượng giá trị duy nhất trong biến.

  • unique_values_pct: phần trăm giá trị duy nhất trong số tổng số giá trị của biến.

  • quantiles: các giá trị phân vị của biến tại các mức 25%, 50%, và 75%, loại bỏ các giá trị NA

analyze <- function(df, var) {
    # Kiểm tra xem đầu vào có phải là dataframe không
    if (is.data.frame(df) == FALSE) {
        stop("Input must be a data frame.")
    }
    variable <- df[[var]]
    descriptives <- list(
        mean = mean(variable, na.rm = TRUE),
        median = median(variable, na.rm = TRUE),
        sd = sd(variable, na.rm = TRUE),
        min = min(variable, na.rm = TRUE),
        max = max(variable, na.rm = TRUE),
        skewness = skewness(variable, na.rm = TRUE),
        kurtosis = kurtosis(variable, na.rm = TRUE),
        unique_values = length(unique(variable)),
        unique_values_pct = length(unique(variable)) / length(variable),
        quantiles = quantile(variable, probs = c(0.25, 0.5, 0.75), na.rm = TRUE))
    list(ketqua = descriptives)
}
analyze(data,"P")
## $ketqua
## $ketqua$mean
## [1] 1.091615
## 
## $ketqua$median
## [1] 0.602
## 
## $ketqua$sd
## [1] 1.057294
## 
## $ketqua$min
## [1] 0.076
## 
## $ketqua$max
## [1] 11.122
## 
## $ketqua$skewness
## [1] 1.786232
## 
## $ketqua$kurtosis
## [1] 7.218672
## 
## $ketqua$unique_values
## [1] 4186
## 
## $ketqua$unique_values_pct
## [1] 0.002042669
## 
## $ketqua$quantiles
##   25%   50%   75% 
## 0.308 0.602 1.528

Tính toán thống kê cho cột biến P (công suất hoạt động trung bình toàn cầu trong một phút của hộ gia đình, đo bằng kilowatt (kW)), ta thu được kết quả như sau:

  • Trung bình (mean): 1.091615

  • Trung vị (median): 0.602;

  • Độ lệch chuẩn (standard deviation): 1.057294;

  • Giá trị nhỏ nhất (min): 0.076;

  • Giá trị lớn nhất (max): 11.122;

  • Độ lệch đối xứng (skewness): 1.786232 (chỉ số này cho biết sự lệch của phân phối so với phân phối chuẩn, giá trị dương cho thấy đuôi dài về bên phải);

  • Độ nhọn (kurtosis): 7.218672 (chỉ số này đo sự nhọn hoặc độ phẳng của phân phối, giá trị lớn hơn 3 cho biết đuôi dài và nhọn hơn so với phân phối chuẩn);

  • Số giá trị duy nhất (unique_values): 4187; Tỷ lệ giá trị duy nhất (unique_values_pct): 0.002017579;

  • Các phân vị (quantiles): 25% (0.308), 50% (0.602), 75% (1.528)

Tương tự em có các tính toán thống kê cơ bản với cột biến “V” và “I” hoặc cũng có thể thực hiện cho tất cả cột biến còn lại.

analyze(data,"V")
## $ketqua
## $ketqua$mean
## [1] 240.8399
## 
## $ketqua$median
## [1] 241.01
## 
## $ketqua$sd
## [1] 3.239987
## 
## $ketqua$min
## [1] 223.2
## 
## $ketqua$max
## [1] 254.15
## 
## $ketqua$skewness
## [1] -0.3266647
## 
## $ketqua$kurtosis
## [1] 3.724702
## 
## $ketqua$unique_values
## [1] 2837
## 
## $ketqua$unique_values_pct
## [1] 0.001384389
## 
## $ketqua$quantiles
##    25%    50%    75% 
## 238.99 241.01 242.89
analyze(data,"I")
## $ketqua
## $ketqua$mean
## [1] 4.627759
## 
## $ketqua$median
## [1] 2.6
## 
## $ketqua$sd
## [1] 4.444396
## 
## $ketqua$min
## [1] 0.2
## 
## $ketqua$max
## [1] 48.4
## 
## $ketqua$skewness
## [1] 1.849099
## 
## $ketqua$kurtosis
## [1] 7.601229
## 
## $ketqua$unique_values
## [1] 221
## 
## $ketqua$unique_values_pct
## [1] 0.0001078428
## 
## $ketqua$quantiles
## 25% 50% 75% 
## 1.4 2.6 6.4

6 Phân cụm

Phân cụm là một phương pháp trong phân tích dữ liệu để gom nhóm các quan sát tương tự lại với nhau dựa trên các đặc trưng tương đồng. Mục đích chính của việc phân cụm là tìm ra sự tương tự và khác biệt trong dữ liệu, từ đó giúp hiểu rõ hơn về cấu trúc và tính chất của dữ liệu.

features <- data[, c("P", "Q", "V", "I")]
scaled_features <- scale(features)
k <- 3  # Số lượng cụm mong muốn
set.seed(123)  # Để đảm bảo kết quả phân cụm nhất quán
kmeans_result <- kmeans(scaled_features, centers = k)
cluster_labels <- kmeans_result$cluster
data$cluster <- cluster_labels
table(cluster_labels)
## cluster_labels
##       1       2       3 
##  518947 1217010  313323

7 Kiểm định

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

set.seed(123)
sample_data <- data[sample(nrow(data), 5000), ]
shapiro_test <- shapiro.test(sample_data$P)
shapiro_test
## 
##  Shapiro-Wilk normality test
## 
## data:  sample_data$P
## W = 0.80025, p-value < 2.2e-16

Chỉ số W được sử dụng để đánh giá mức độ phù hợp của dữ liệu với phân phối chuẩn. Giá trị của W nằm trong khoảng từ 0 đến 1, và một giá trị gần 1 cho thấy dữ liệu có độ tương đồng cao với phân phối chuẩn. Trên trường hợp này, giá trị W = 0.80781 cho thấy dữ liệu không có sự tương đồng cao với phân phối chuẩn. Dựa vào kết quả kiểm định Shapiro-Wilk, với giá trị p-value rất nhỏ (p-value < 2.2e-16), bác bỏ giả thuyết rằng dữ liệu tuân theo phân phối chuẩn.

7.2 Kiểm định Autocorrelation,Cross-correlation

Kiểm định Autocorrelation được sử dụng để xác định mức độ tương quan của một biến với chính nó trong các khoảng thời gian trước đó. Điều này giúp xác định mức độ tự tương quan của biến theo thời gian.

acf(data$V)

Kiểm định Cross-correlation được sử dụng để xác định mức độ tương quan giữa hai biến trong thời gian

ccf(data$P, data$I)

8 Phân tích sự biến đổi trung bình tiêu thụ điện năng của các thiết bị hàng ngày, hàng tuần

8.1 Hàng ngày

Tính toán trung bình tiêu thụ hàng ngày: Gom nhóm dữ liệu theo biến ngày và tính trung bình tiêu thụ năng lượng (ví dụ: A1, A2, A3) trong mỗi ngày. Điều này sẽ cho biết trung bình tiêu thụ năng lượng hàng ngày cho từng thiết bị.

data1 <- data %>%
  group_by(Date) %>%
  summarise(mean_A1_daily = mean(A1, na.rm = TRUE),mean_A2_daily = mean(A2, na.rm = TRUE),mean_A3_daily = mean(A3, na.rm = TRUE))
head(data1)
## # A tibble: 6 × 4
##   Date       mean_A1_daily mean_A2_daily mean_A3_daily
##   <date>             <dbl>         <dbl>         <dbl>
## 1 2006-12-16         0              1.38         12.4 
## 2 2006-12-17         1.41           2.91          9.26
## 3 2006-12-18         0.738          1.82          9.73
## 4 2006-12-19         0.583          5.28          4.30
## 5 2006-12-20         0              1.84          9.77
## 6 2006-12-21         1.23           1.82          7.25

8.2 Hàng tuần

Tính toán trung bình tiêu thụ hàng tuần: Gom nhóm dữ liệu theo biến tuần và tính trung bình tiêu thụ năng lượng (ví dụ: A1, A2, A3) trong mỗi tuần. Điều này sẽ cho biết trung bình tiêu thụ năng lượng hàng tuần cho từng loại thiết bị.

data2 <- data %>%
  mutate(Week = lubridate::week(Date)) %>%
  group_by(Week) %>%
  summarise(mean_A1_week = mean(A1, na.rm = TRUE),mean_A2_week = mean(A2, na.rm = TRUE),mean_A3_week = mean(A3, na.rm = TRUE))

head(data2)
## # A tibble: 6 × 4
##    Week mean_A1_week mean_A2_week mean_A3_week
##   <dbl>        <dbl>        <dbl>        <dbl>
## 1     1         1.06         1.54         6.39
## 2     2         1.69         1.33         7.79
## 3     3         1.56         1.61         8.55
## 4     4         1.41         1.58         8.03
## 5     5         1.27         1.67         9.40
## 6     6         1.39         1.51         8.33

9 Trực quan hóa dữ liệu

9.1 Tạo scatter plot

  • Đầu tiên em sẽ vẽ biểu đồ phân tán theo ngày trong toàn bộ quan sát thể hiện mối quan hệ hai biến điện áp trung bình trong một phút và công suất trung bình.
data %>% ggplot(aes(x=V,y=P))+
  geom_point(color="steelblue")+
  geom_smooth(method="lm",color="red")+
  labs(x="Voltage (v)",y="Global_Active_Power (P)")
## `geom_smooth()` using formula = 'y ~ x'

9.2 Tạo density plot

ggplot(data, aes_string(x = data$P)) +
        geom_density(fill = 'steelblue') +
        ggtitle(paste("Density plot of Global_Active_Power"))

ggplot(data, aes_string(x = data$Q)) +
        geom_density(fill = 'skyblue') +
        ggtitle(paste("Density plot of Global_Reactive_Power"))

ggplot(data, aes_string(x = data$V)) +
        geom_density(fill = 'yellow') +
        ggtitle(paste("Density plot of Voltage"))

9.3 Tạo biều đồ đường

Đầu tiên em sẽ tổng hợp dữ liệu theo ngày sau đó tính trung bình công suất hoạt động trong một ngày của hộ gia đình đó, sau đó vẽ được biểu đồ công suất hoạt động trung bình của hộ gia đình trong các năm khảo sát.

# Tổng hợp dữ liệu hàng ngày
daily_data <- data %>%
  group_by(Date) %>%
  summarise(mean_P = mean(P))

# Vẽ biểu đồ đường
ggplot(daily_data, aes(x = Date, y = mean_P)) +
  geom_line(color="steelblue") +
  xlab("Date") +
  ylab("Mean Global Active Power") +
  ggtitle("Daily Mean Global Active Power")

10 Mô hình hồi quy

Để tìm hiểu sự ảnh hưởng của biến V lên biến P em thực hiện mô hình hồi quy.

hq1 <- lm(P~V,data)
summary(hq1)
## 
## Call:
## lm(formula = P ~ V, data = data)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -3.1040 -0.6633 -0.2107  0.4671  8.5876 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 32.5098698  0.0503279   646.0   <2e-16 ***
## V           -0.1304529  0.0002089  -624.3   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.9691 on 2049278 degrees of freedom
## Multiple R-squared:  0.1598, Adjusted R-squared:  0.1598 
## F-statistic: 3.898e+05 on 1 and 2049278 DF,  p-value: < 2.2e-16

Mô hình hồi quy tuyến tính:

Hệ số hồi quy: Hệ số cho “V” là -0.1304529. Điều này nghĩa là, cho mỗi đơn vị tăng của “v”, giá trị dự kiến cho “P” giảm đi -0.1304529, giả sử tất cả các biến khác không thay đổi.

p-values cho cả hai hệ số đều rất nhỏ, điều này cho thấy cả hai hệ số đều có ý nghĩa thống kê.

R-squared: R-squared cho mô hình là 0.1598. Điều này có nghĩa là mô hình này giải thích được khoảng 15.98% sự biến động trong biến phụ thuộc “P”.

Tóm lại, dựa trên kết quả này, chúng ta có thể kết luận rằng “V” không có ảnh hưởng đáng kể đến “P”.

hq2 <- lm(P~V*I,data)
summary(hq2)
## 
## Call:
## lm(formula = P ~ V * I, data = data)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1.05605 -0.01384  0.00958  0.02715  0.06347 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  6.174e-02  3.319e-03   18.60   <2e-16 ***
## V           -3.386e-04  1.376e-05  -24.61   <2e-16 ***
## I           -1.060e-02  4.612e-04  -22.99   <2e-16 ***
## V:I          1.047e-03  1.934e-06  541.21   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.04502 on 2049276 degrees of freedom
## Multiple R-squared:  0.9982, Adjusted R-squared:  0.9982 
## F-statistic: 3.761e+08 on 3 and 2049276 DF,  p-value: < 2.2e-16