داده‌ گمشده یا ناموجود (Missing Data) در R – روش های پاکسازی داده ها

۲۰۱۴ بازدید
آخرین به‌روزرسانی: ۶ خرداد ۱۴۰۲
زمان مطالعه: ۷ دقیقه
دانلود PDF مقاله
داده‌ گمشده یا ناموجود (Missing Data) در R – روش های پاکسازی داده ها

مسئله «مقادیر گمشده» (Missing Values) در «علم داده» (Data Science) و بخصوص «داده‌کاوی» (Data Mining)، زمانی رخ می‌دهد که یک یا چند مشاهده دارای مقدارهایی ثبت نشده یا ناموجود در ستون‌های «چارچوب اطلاعاتی» (Data Frame) هستند. در چنین حالت می‌گوییم آن مشاهده دارای «مقدار گمشده» (Missing Value) یا «مقدار ناموجود» است. در این حالت این مجموعه‌ داده را دارای «داده‌ گمشده» (Missing Data) یا داده‌های گمشده می‌گوییم. به منظور تحلیل‌های آماری روی مجموعه‌های اطلاعاتی با داده گمشده، باید مشخص کنیم که نقش چنین مشاهداتی در محاسبات مربوط به تحلیل آماری چگونه است. در این نوشتار با استفاده از کتابخانه dplyrdplyr از زبان برنامه نویسی R، بعضی از روش‌های مدیریت داده‌های گمشده را بررسی خواهیم کرد.

997696

مدیریت داده‌ گمشده یا ناموجود

روش‌های مختلفی برای برخورد با چارچوب های اطلاعاتی و مشاهداتی که دارای داده گمشده هستند، وجود دارد. این مقدارها در محیط نرم‌افزاری R به صورت NA ثبت یا نشان داده می‌شوند.

دو رویکرد برای مدیریت داده گمشده می‌توان در نظر گرفت.

  • خروج مشاهدات یا متغیرها با مقدارهای گمشده از محاسبات و تحلیل‌های آماری
  • جایگزنی داده‌های گمشده با مقدار جایگزین (مثلا میانگین یا میانه مقدارهای متغیر)

تصویر زیر اموری که باید قبل از انجام «تحلیل داده‌» (Data Analysis) صورت بگیرد را نشان می‌دهد. این مراحل به عنوان گام‌های اولیه در داده‌کاوی شناخته می‌شوند. همانطور که مشخص است، ستون اول عملیات مربوط به «تبدیلات داده‌» (Data Manipulation) و ستون دوم، مرحله «پاک‌سازی داده‌» (Cleaning Data) و ستون سوم نیز مربوط به مرحله «نمایش داده‌» (Data Visualization) است که دو مرحله اول می‌تواند بوسیله توابع کتابخانه dplyrdplyr انجام پذیرد. در ادامه با چند تابع از این کتابخانه آشنا می‌شویم که براساس آن‌ها می‌توانیم مقدارهای NA را شناسایی کرده و نقش آن‌ها را در تحلیل‌های آماری تعیین کنیم.

Data Processing stages

تابع mutate()mutate() و تابع replace.na()replace.na()

یکی از توابع موثر در R که برای کار روی داده گمشده مناسب است، تابع mutate()mutate() از کتابخانه dplyrdplyr است. کار با این تابع بسیار ساده بوده و پارامترهای محدودی دارد. بنابراین ابتدا با این توابع آشنا می‌شویم. به کمک تابع mutate()mutate() می‌توانید یک متغیر جدید براساس محاسبات تعیین شده، ایجاد کنید. شکل دستوری این تابع و پارامترهای آن در ادامه دیده می‌شود.

1mutate(df, name_variable_1 = condition, ...)
2arguments:
3-df: Data frame used to create a new variable
4-name_variable_1: Name and the formula to create the new variable
5-...: No limit constraint. Possibility to create more than one variable inside mutate()
  • df: پارامتر اول همان مجموعه داده یا  df است که باید عملیات مورد نظر روی آن اجرا شود.
  • name_variable_1: پارامتر دوم نیز نام متغیر و فرمولی است که متغیر جدید باید براساس آن ساخته شود.

نکته: در ادامه پارامتر دوم می‌توانید از پارامترهای دیگری هم استفاده کنید تا امکان محاسبه متغیرهای جدید هم فراهم آید.

به منظور جایگزینی مقدارهای NA باید از تابع دیگری به نام replace.na()replace.na() استفاده کرد. این تابع نیز دارای شکل دستوری و پارامترهای ساده‌ای است که در ادامه به بررسی آن‌ها می‌پردازیم.

1replace_na(data, replace, ...)
2arguments:
3
4data:A data frame or vector.
5replace:If data is a data frame, a named list giving the value to replace NA with for each column. If data is a vector, a single value used for replacement.
6...	
7Additional arguments for methods. Currently unused.

مشخص است که پارامتر اول همان مجموعه داده یا برداری است که باید مقدار NA‌ در آن جایگزین شود و پارامتر دوم نیز مقدار جایگزین شده را مشخص می‌کند. به این ترتیب اگر بخواهیم متغیرهایی که دارای مقدار NA هستند را با مقدار جدید (مثلا ۰) جایگزین کنیم باید از شکلی دستوری زیر کمک بگیریم. در اینجا فرض کرده‌ایم که مجموعه داده، ترکیبی از متغیرهای x و y و z است که دارای مقدارهای عددی، متنی و همچنین NA هستند. برای ترکیب آن‌ها و تشکیل یک مجموعه داده از تابع tibble()tibble() استفاده شده است.

1library(dplyr)
2library(tidyr)
3df <- tibble(x = c(1, 2, NA), y = c("a", NA, "b"), z = list(1:5, NULL, 10:20))
4df
5df_nona=df %>% mutate(x = replace_na(x, 0))
6df_nona

همانطور که مشخص است از دو کتابخانه dplyrdplyr برای تابع mutate()mutate() و tidyrtidyr برای تابع replace_na()replace\_na() استفاده کرده‌ایم. به این ترتیب با ترکیب این دو تابع امکان جایگزینی مقدار NA با هر مقدار دیگری وجود دارد. همچنین خروجی حاصل از این کد، یک چارچوب داده به نام df_nona است که هیچ مقدار NA ندارد.

نکته: ممکن است زمانی بخواهید در یک متغیر مقدار خاصی را به مقدار NA تبدیل کنید. در این حالت از تابع replace_with_na()replace\_with\_na() می‌توانید کمک بگیرید که در کتابخانه naniarnaniar قرار دارد.

خارج کردن داده‌ گمشده از مجموعه داده

اگر می‌خواهید داده‌ گمشده از مجموعه اطلاعاتی خارج شود و در تحلیل‌های آماری نقشی نداشته باشد، کافی است از تابع na.omit()na.omit() استفاده کنید. کد زیر برای انجام این امور نوشته شده است. در این کد از یک فایل اطلاعاتی برای انجام مراحل کار استفاده خواهیم کرد. در ادامه نیز برای اجرای دستورات و توابع دیگر از همین فایل کمک می‌گیریم.

1PATH <- "https://raw.githubusercontent.com/thomaspernet/data_csv_r/master/data/titanic_csv.csv"
2df_titanic <- read.csv(PATH, sep = ",")
3# Return the column names containing missing observations
4list_na <- colnames(df_titanic)[ apply(df_titanic, 2, anyNA) ]
5list_na

هنگام اجرای این کد باید به اینترنت متصل باشید تا مجموعه داده متنی titanic_csv که با قالب متنی csv ثبت شده، روی دستگاه شما بارگذاری شود. این مجموعه داده در متغیری با نام df_titanic ذخیره می‌شود. در انتها نیز لیست ستون‌هایی که دارای مقدار گمشده هستند به عنوان خروجی ظاهر می‌شود.

1## [1] "age"  "fare"

مشخص است که دستور colnames(df...)colnames(df...)، اسامی ستون‌های این مجموعه داده را ظاهر کرده است. برای حذف مقدارهای گمشده داده‌ها از کدهای زیر کمک می‌گیریم.

1library(dplyr)
2# Exclude the missing observations
3df_titanic_drop <-df_titanic %>%
4na.omit()		
5dim(df_titanic_drop)

همانطور که می‌بینید تابع na.omit()na.omit() باعث حذف مقدارهای گمشده شده است و ابعاد مجموعه داده کاهش یافته است. این ابعاد به کمک تابع dim()dim() محاسبه شده و نتیجه 1045 سطر و ۱۳ ستون را نشان می‌دهد.

1## [1] 1045   13

در تصویر زیر مقایسه‌ای بین مشاهدات اولیه و مشاهدات پس از حذف مقدارهای گمشده صورت گرفته است. به منظور مقایسه بهتر تصاویر مربوط به خروجی حالت قبل از حذف و بعد از آن در کنار هم دیده می‌شوند. اگر می‌بینید که مشاهده ۶۰ام به مشاهده ۴۲ام در حالت بعد از حذف تبدیل شده است، علت کنار گذاشته شدن مشاهدات با مقدارهای NA در مجموعه داده اولیه است. به این ترتیب تعداد مشاهدات کاهش یافته و شماره ردیف‌ها تغییر می‌کند.

ReplaceMissings before and after

جایگزین مقدار برای داده‌ گمشده

در بعضی از تحلیل‌های آماری به دلیل کمبود مشاهدات، گاهی داده گمشده را با میانگین (Mean) یا میانه (Median) جایگزین می‌کنند تا تعداد نمونه، کاهش نیابد.

در قسمت قبلی، اسامی متغیرهایی که دارای داده گمشده بودند استخراج شد. حال از این لیست برای جایگزینی مقدار داده‌ گمشده استفاده می‌کنیم. این کار را در سه مرحله انجام می‌دهیم.

  1. از لیست متغیرهای دارای مقدار گمشده، برای انتخاب متغیرهای مورد نیاز استفاده می‌کنیم. این لیست در مثال ما با نام list_nalist\_na مشخص شده است.
  2. از تابع apply()apply() برای محاسبه میانگین یا شاخص‌های دیگر برای ستون‌هایی با مقدار NA استفاده می‌کنیم. در این حالت از پارامتر na.rm=TRUEna.rm=TRUE در تابع apply()apply() کمک می‌گیریم.
  3. مقدار محاسبه شده در مرحله ۲ را جایگزین مقدارهای گمشده برای هر متغیر می‌کنیم.

کد زیر با جایگزین کردن میانگین به جای مقدارهای گمشده، عمل پاک‌سازی داده‌ را انجام می‌دهد. مشخص است که با اجرای تابع mutate()mutate() متغیر جدیدی برای هر دو متغیر انتخابی، با نام‌های replace_mean_age و replace_mean_fare ایجاد شده.

1# Create mean
2average_missing <- apply(df_titanic[,colnames(df_titanic) %in% list_na],
3                         2,
4                         mean,
5                         na.rm =  TRUE)
6average_missing
7# Create a new variable with the mean and median
8df_titanic_replace <- df_titanic %>%
9  mutate(replace_mean_age  = ifelse(is.na(age), average_missing[1], age),
10         replace_mean_fare = ifelse(is.na(fare), average_missing[2], fare))

در قسمت اول کد، در تابع apply()apply() چهار پارامتر مقدار دهی شده است.

df: این پارامتر با [df_titanic[,colnames(df_titanic)df\_titanic[,colnames(df\_titanic)%in% list_na مقدار دهی شده است که بیان می‌کند باید از مجموعه داده، ستون‌هایی که نامشان در لیست list_na قرار دارد استفاده شود. به این ترتیب فقط ستون‌های age و fare به کار گرفته می‌شوند.

مقدار 2: محاسبه تابع میانگین برای ستون‌ها مجموعه داده (متغیرهای انتخابی age و fare)

mean: تابع محاسباتی توسط apply()apply() که در اینجا میانگین انتخاب شده است.

na.rm: این پارامتر تعیین می‌کند که آیا داده گمشده هنگام محاسبه میانگین نادیده گرفته شود؟ TRUE به معنی حذف و FALSE به معنی حفظ داده گمشده در محاسبات است. مشخص است که در محاسبه میانگین فقط تعداد داده‌ گمشده دخیل خواهد بود. به این ترتیب مشخص است که که کد زیر داده گمشده برای متغیر سن (age) را با 29.88113 جایگزین می‌کند

replace_mean_age = ifelse(is.na(age, average_missing[1], age)

همچنین برای متغیر هزینه سفر (fare) نیز کدی که در زیر نمایش داده شده، مقدار 33.29548 را به جای داده گمشده قرار خواهد داد.

replace_mean_fare = ifelse(is.na(fare), average_missing[2],fare)

همانطور که می‌توان محاسبه کرد، 263 داده گمشده با مقدار میانگین جایگزین شده است.

1sum(is.na(df_titanic_replace$age))
2
3## [1] 263

اگر می‌خواهید که به جای میانگین از میانه متغیرها به عنوان مقدار جدید برای داده‌ گمشده استفاده کنید، کافی است کد زیر را اجرا کنید.

1median_missing <- apply(df_titanic[,colnames(df_titanic) %in% list_na],
2      2,
3      median,
4      na.rm =  TRUE)
5df_titanic_replace <- df_titanic %>%
6            mutate(replace_median_age  = ifelse(is.na(age), median_missing[1], age), 
7            replace_median_fare = ifelse(is.na(fare), median_missing[2], fare))
8head(df_titanic_replace)

در این حالت خروجی به صورت زیر در خواهد آمد.

ReplaceMissings output

ممکن است که در مجموعه داده، متغیرهای زیادی دارای مقدارهای گمشده باشند و اجرای کدهای بالا برای تک تک آن‌ها با مشکل مواجه شود. به منظور سرعت بخشیدن به عملیات جایگزینی و محاسبات شاخص‌های آماری، کد زیر تهیه شده است. همانطور که دیده می‌شود برای انجام این کار از تابع sapply()sapply() استفاده شده است که متاسفانه یک چارچوب داده ایجاد نمی‌کند. به همین علت با تابع data.frame()data.frame() نتایج حاصل از آن را تبدیل به «چارچوب داده» (Data Frame) کرده‌ایم.

1# Quick code to replace missing values with the mean
2df_titanic_impute_mean < -data.frame(
3    sapply(
4        df_titanic,
5        function(x) ifelse(is.na(x),
6            mean(x, na.rm = TRUE),
7            x)))

خلاصه

در این نوشتار، رویکرد ما برای داده‌ گمشده به دو صورت بیان شد: «حذف» (Deletion) یا «جایگزینی» (Imputation) با مقدار دلخواه. جدول‌های زیر به بررسی توابع و عملکرد آن‌ها به این منظور پرداخته است.

حذف
کتابخانهشرحکد
baseنمایش مشاهدات گمشدهcolnames(df)[apply(df, 2, anyNA)]
dplyrحذف داده‌های گمشده از چارچوب داده (df)na.omit(df)
جایگزینی
تابعشرحمزایامعایب
apply()apply()بررسی ستون‌ها با مقدار گمشده و محاسبه شاخص‌های آماریوضوح محاسبات انجام شده و خروجی به صورت چارچوب دادهزمان زیاد برای اجرا روی چند ستون یا متغیر
sapply()sapply()بررسی ستون‌ها با مقدار گمشده و محاسبه شاخص دلخواهسرعت انجام محاسبات و اجرای همزمان برای چندین ستونبدون ایجاد چارچوب داده

اگر این مطلب برایتان مفید بوده است، آموزش‌های که در ادامه آمده‌اند نیز به شما پیشنهاد می‌شوند:

^^

بر اساس رای ۵ نفر
آیا این مطلب برای شما مفید بود؟
اگر بازخوردی درباره این مطلب دارید یا پرسشی دارید که بدون پاسخ مانده است، آن را از طریق بخش نظرات مطرح کنید.
نظر شما چیست؟

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *