簡體   English   中英

如何根據R中的預測值和真值計算精度

[英]How to calculate accuracy based on predictor and true values in R

我試圖根據正確的響應(C列)計算參與者的反應(R列)的准確性。 一些數據以二進制形式(01010-例如參與者是錯誤的,正確的,錯誤的,正確的,錯誤的)和字母序列(即字母串中字母的正確位置)給出。

查看數據示例:

dput(example) 
structure(list(TRIAL = c("1", "2", "3", "4", "5", "6", "7", "8", 
"9", "10", "11", "12", "13", "14", "15"), EQ_C = c("0101", "1010", 
"1010", "00111", "01011", "01101", "100011", "010101", "001101", 
"0110011", "1101001", "1100101", "11100001", "11001010", "11001010"
), EQ_R = c("0101", "0010", "1010", "00111", "01011", "01101", 
"10101", "11010", "001101", "0100011", "1101001", "0100101", 
"11110001", "11001010", "11001010"), MEM_C = c("ZLHK", "RZKX", 
"DGWL", "BCJSP", "WRKTJ", "CHBXS", "HNDCWX", "SWVNDT", "WLDGPB", 
"DSHRKBV", "HCXLZWB", "HDNBVZC", "BCRHKVDM", "RVTBWKFS", "NWHVZFLD"
), MEM_R = c("ZLHK", "RZKX", "DGWL", "BCJSP", "WRKLTJ", "CHBXS", 
"HNDCWX", "SWVDTN", "WLDGPB", "DSHRKBV", "HCXLZWB", "HDNBVZC", 
"BCRHKVDM", "RVTBWKFS", "NWHVZFLD"), EQ_SUM = c(NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), MEM_SUM = c(NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA)), row.names             
 = c(NA, 
15L), class = "data.frame")

我為二進制數據(EQ)和字母(MEM)計算了需要計算的“和”/准確度分數的新列。

    OSPAN["EQ_SUM"] <- NA
    OSPAN["MEM_SUM"]<- NA

然后我嘗試根據另一個stackoverflow線程計算總和(使用預測器和實際值),但不知何故它不能識別我的變量。 我懷疑我的數據格式錯誤,因為它一直告訴我無法找到對象。

example$EQ_SUM <- round(100*rowMeans(EQ_C == EQ_R))

Error in is.data.frame(x) : object 'EQ_C' not found

我的問題是:如何將預測變量(C)和實際(R)值之間的准確度或同一性匹配/計算到總和列中? 例如,在第1行中,EQ_SUM將是1(或100%),而在#2中它將是0.75或75%,因為參與者選擇了錯誤的答案(0而不是1)。 因此,給出了部分信用評分,這不是絕對匹配/同余的問題。

先感謝您。 (我希望我沒有遺漏任何重要信息 - 這是我第一次發帖)。

計算預測准確性與實際值的簡單方法 - 或者在您的案例中參與者響應與實際響應 - 通常是這樣做的:

mean(EC_C == EC_R, na.rm = TRUE)

其中EC_C和EC_R是包含要為其計算精度的值的列。 您將收到0到1之間的值,后者表示100%的准確性。 注意,在這種情況下,每對單元可以是相同的也可以不相同。 以上計算的准確度將告訴您所有細胞對中有多少百分比是相同的。 如果你想比較每對單元格中的單個數字,這將不是一個合適的方法 - 但是現在我並不清楚你想要做什么。

更新

您可以在下面找到一種方法,但該方法僅適用於EC_CEC_R具有相同字符數的行。 如果repsondents留下答案,並且沒有記錄數字/字符串中缺少哪個數字,則實際上無法計算准確度,因為不再清楚哪個數字/字符對應於哪個問題數。 所以我的方法的基本假設是,在一個四位數字符串,例如EC_C = 1010EC_R = 1000在第一位EC_C映射到第一位EC_R 在的情況下EC_C = 1010EC_R = 101不清楚哪個數字在EC_R映射到哪個數字在EC_C 它可能是左邊的前三位數,精度為0.75,或者可能是右邊的前三位數,在這種情況下,精度等於0。

除了這個警告,我的方法應該適用於所有具有euqal字符數的行(假設映射是一致的)。 對於字符/數字不相同的所有行,我的函數將生成NA 如果您想使用這種方法來評估學生考試的結果,那么您需要查看已生成NA的每個考試,並找出遺漏問題的位置。 如果您在放置答案的位置插入一個特殊字符,它將在以后為您節省很多麻煩。

library(stringr)
example <-
  structure(list(TRIAL = c("1", "2", "3", "4", "5", "6", "7", "8",
                           "9", "10", "11", "12", "13", "14", "15"),
                 EQ_C = c("0101", "1010",
                          "1010", "00111", "01011", "01101", "100011", "010101", "001101",
                          "0110011", "1101001", "1100101", "11100001", "11001010", "11001010"),
                 EQ_R = c("0101", "0010", "1010", "00111", "01011", "01101",
                          "10101", "11010", "001101", "0100011", "1101001", "0100101",
                          "11110001", "11001010", "11001010"),
                 MEM_C = c("ZLHK", "RZKX", "DGWL", "BCJSP", "WRKTJ", "CHBXS", "HNDCWX", "SWVNDT",
                           "WLDGPB",  "DSHRKBV", "HCXLZWB", "HDNBVZC", "BCRHKVDM", "RVTBWKFS", "NWHVZFLD"),
                 MEM_R = c("ZLHK", "RZKX", "DGWL", "BCJSP", "WRKLTJ", "CHBXS",
                           "HNDCWX", "SWVDTN", "WLDGPB", "DSHRKBV", "HCXLZWB", "HDNBVZC",
                           "BCRHKVDM", "RVTBWKFS", "NWHVZFLD"),
                 EQ_SUM = c(NA, NA, NA, NA,NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
                 MEM_SUM = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA)),
            row.names = c(NA, 15L), class = "data.frame")

# Function to calculate accuracy
check_accuracy <- function(x,y) {

    # Calculate a matrix which checks if the position of a character in x is corresponding to position in y
    check_mtr = str_split_fixed(x, "", max(nchar(x))) == str_split_fixed(y, "", max(nchar(y)))

    # Calculate the sum of all matching positions
    accuracy_sum = rowSums(check_mtr)

    # Subtract the number of empty strings from accuarcy_sum
    accuracy_sum2 = accuracy_sum - (max(nchar(x)) - nchar(x))

    # Divide sum of all non-empty matching positions by number of non-empty characters
    accuracy_vec = accuracy_sum2 / nchar(x)

    if (any(nchar(x) != nchar(y))) {
    warning("Number of characters in x and y is not corresponding. NAs generated.")
    ifelse(nchar(x) != nchar(y), NA, accuracy_vec)
    } else {
    accuracy_vec
  }

}

example$EQ_SUM <- check_accuracy(example$EQ_C, example$EQ_R)
example$MEM_SUM <- check_accuracy(example$MEM_C, example$MEM_R)
example

更新2:請注意,此方法計算的准確度與使用某種字符串距離度量的方法不同。 當查看MEM_SUM中第8行的結果為0.5 ,這將是清楚的,因為響應者只得到了一半的答案:將SWVNDTSWVDTN進行比較,其中前三個答案SWV對應,后三個答案不對應。 但是,字符串距離的測量仍然認為最后三個字符是相關的( DTNNDT ),因為字母是相同的,只是順序是不同的。 此處的字符串距離度量顯示為0.67,這與0.5的准確度不對應。 此外,字符串距離方法還將評估答案,並給出答案(字符數不相同的情況)。 但是,如果沒有指出哪個答案被遺漏,則無法進行清晰的計算,這就是為什么我的方法在此指定NA和警告消息。

結果應該是這樣的

   TRIAL     EQ_C     EQ_R    MEM_C    MEM_R    EQ_SUM MEM_SUM
1      1     0101     0101     ZLHK     ZLHK 1.0000000     1.0
2      2     1010     0010     RZKX     RZKX 0.7500000     1.0
3      3     1010     1010     DGWL     DGWL 1.0000000     1.0
4      4    00111    00111    BCJSP    BCJSP 1.0000000     1.0
5      5    01011    01011    WRKTJ   WRKLTJ 1.0000000      NA
6      6    01101    01101    CHBXS    CHBXS 1.0000000     1.0
7      7   100011    10101   HNDCWX   HNDCWX        NA     1.0
8      8   010101    11010   SWVNDT   SWVDTN        NA     0.5
9      9   001101   001101   WLDGPB   WLDGPB 1.0000000     1.0
10    10  0110011  0100011  DSHRKBV  DSHRKBV 0.8571429     1.0
11    11  1101001  1101001  HCXLZWB  HCXLZWB 1.0000000     1.0
12    12  1100101  0100101  HDNBVZC  HDNBVZC 0.8571429     1.0
13    13 11100001 11110001 BCRHKVDM BCRHKVDM 0.8750000     1.0
14    14 11001010 11001010 RVTBWKFS RVTBWKFS 1.0000000     1.0
15    15 11001010 11001010 NWHVZFLD NWHVZFLD 1.0000000     1.0

這是使用stringdist包的方法。

library(stringdist)
library(dplyr)
example %>%
  mutate(EQ_RIGHT  = nchar(EQ_C) - stringdist(EQ_R, EQ_C, method = "lv"),
         EQ_SUM    = EQ_RIGHT / nchar(EQ_C),
         MEM_RIGHT = nchar(MEM_C) - stringdist(MEM_R, MEM_C, method = "lv"),
         MEM_SUM   = MEM_RIGHT / nchar(MEM_C))

'lv'方法似乎非常適合這里,但還有其他選擇。 Levenshtein距離:將字符串a轉換為字符串b所需的最少插入,刪除和替換次數。

   TRIAL     EQ_C     EQ_R    MEM_C    MEM_R    EQ_SUM   MEM_SUM EQ_RIGHT MEM_RIGHT
1      1     0101     0101     ZLHK     ZLHK 1.0000000 1.0000000        4         4
2      2     1010     0010     RZKX     RZKX 0.7500000 1.0000000        3         4
3      3     1010     1010     DGWL     DGWL 1.0000000 1.0000000        4         4
4      4    00111    00111    BCJSP    BCJSP 1.0000000 1.0000000        5         5
5      5    01011    01011    WRKTJ   WRKLTJ 1.0000000 0.8000000        5         4
6      6    01101    01101    CHBXS    CHBXS 1.0000000 1.0000000        5         5
7      7   100011    10101   HNDCWX   HNDCWX 0.6666667 1.0000000        4         6
8      8   010101    11010   SWVNDT   SWVDTN 0.6666667 0.6666667        4         4
9      9   001101   001101   WLDGPB   WLDGPB 1.0000000 1.0000000        6         6
10    10  0110011  0100011  DSHRKBV  DSHRKBV 0.8571429 1.0000000        6         7
11    11  1101001  1101001  HCXLZWB  HCXLZWB 1.0000000 1.0000000        7         7
12    12  1100101  0100101  HDNBVZC  HDNBVZC 0.8571429 1.0000000        6         7
13    13 11100001 11110001 BCRHKVDM BCRHKVDM 0.8750000 1.0000000        7         8
14    14 11001010 11001010 RVTBWKFS RVTBWKFS 1.0000000 1.0000000        8         8
15    15 11001010 11001010 NWHVZFLD NWHVZFLD 1.0000000 1.0000000        8         8

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM