این پست، دومین قسمت از تجربیات من در زمینه تحلیل داده در تیم جذب و استخدام هست. اگر قسمت اول رو نخوندین پیشنهاد می کنم اول از طریق این لینک اون پست رو بخونید و بعد ادامهی این مقاله رو مطالعه کنید.
همون طور که توی مقالهی قبلی توضیح دادم، برای حل مشکلاتی که توی کار با داده بهشون برخورد کردم از 4 مرحله استفاده کردم: کشف داده، دگرگونی داده، بارگذاری داده و بصریسازی داده.
توی این پست به دومین مرحله از این چهار مرحله میپردازم و در مورد دگرگونی دادهها صحبت میکنم.
دگرگونی دادهها (Transformation of data)، پروسهی تغییر یا تبدیل داده ها از تایپ، فرمت، یا ساختاری به مدل دیگه ایه. این فرآیند ممکنه با عملیات ریاضی، تغییر مقادیر، یا تمیزسازی و تغییر ساختار دادهها انجام بشه. این دگرگونیها به ما کمک میکنه تا در نهایت دادهها رو بهتر و بهینه تر بتونیم تحلیل کنیم و توی ساختار دیتابیس بیاریم.
در ادامه روشهایی رو که برای دگرگونی دادهها به کار گرفتم رو توضیح میدم.
روش های Joins و Unions دو روش برای یکی کردن دادهها از جداول مختلف هست.
روش Unions، ردیفهای دو یا چند جدول رو با همدیگه ادغام میکنه. این دو جدول باید تعداد ستونهای برابر و تایپهای دادهی یک شکل داشته باشن. برای مثال دو جدول از دو ریکروتر داریم که هر کدوم دادههای مربوط به خودشون رو به صورت زیر وارد کردن. برای اینکه دادهها رو یکپارچه داشته باشیم از ادغام به روش Unions استفاده میکنیم:
روش Joins، ستونهای دو یا چند جدول رو با توجه به ستون مرتبط بین اونها، ادغام میکنه. برای مثال یک جدول داریم که اطلاعات مصاحبه رو با کد اختصاصی هر کاندید مشخص کرده و یک جدول دیگه هم اطلاعات تماس اون کاندید رو با توجه به همون کد اختصاصی داره. برای اینکه این دو جدول رو به صورت یکپارچه داشته باشیم از ادغام به روش Joins استفاده میکنیم:
نرمالسازی و غیر نرمالسازی، دو تکنیک ساختاربندی داده در دیتابیس هستند.
نرمال سازی، به صورت خیلی ساده و کلی، دادهها رو به جداول مختلف برای کاهش افزونگی (Redundancy)، ناسازگاری (Inconsistency) و بهبود یکپارچگی دادهها (Data Intergrity)، تقسیم میکنه. این مکانیسم معمولا برای سیستمهایی به کار میره که روی سرعت فرآیند هایی مثل Insert, Delete and Update تاکید دارن. مثل سیستمهای OLTP. (این سیستم که مخفف Online Transaction Process هست برای مدیریت اپلیکیشنهای تراکنش-محور کاربرد داره.)
غیرنرمال سازی، دادههای جداول مختلف رو توی یک جدول ادغام میکنه. این کار باعث میشه خوندن اطلاعات سریعتر بشه و معمولا توی سیستمهایی استفاده میشه که روی سرچ سریع و روی موارد تحلیلی تاکید دارن مثل سیستم های OLAP. ولی این متد، باعث ایجاد افزونگی میشه و حفظ یکپارچگی دادهها رو هم دشوار میکنه. (OLAP یا Online Analytical Process معمولا برای سیستمهایی که نیاز به گزارش های چند وجهی دارن مثل گزارشهای مالی یا پیشبینیها استفاده میشه)
در ادامه، فرآیند نرمالسازی دیتابیس رو با مثالهای عملی جلو میبرم و سطوح مختلف فرم نرمال رو توضیح میدم:
نرمالسازی سطح های مختلفی داره. بعضی دیتابیسها، نرمالسازی شون خیلی کامل هست و بعضیها مقدماتی. میتونیم بهش مثل یک سری استاندارد نگاه کنیم و بهش سطح بدیم. مثلا بگیم سطح نرمال بودن این فرم سطح 1 هست. یا سطح 2 هست یا همینطوری ادامه بدیم.
5 سطح برای فرمهای نرمال در نظر گرفته شده که سطح 1 پایینترین سطح و سطح 5 بالاترین سطح فرم نرمال هست.
قوانین 1NF:
قانون اول: استفاده از از ترتیب ردیفها برای نشون دادن اطلاعات مجاز نیست
فکر کنید میخوایم توی ثبت مصاحبهها نشون بدیم کدوم مصاحبه زودتر از مصاحبهی دیگه بوده. توی فرم اینطوری تعیین میکنیم که هر ردیفی بعد از ردیف دیگه نوشته شد یعنی اون مصاحبه بعد از مصاحبهی قبلی بوده:
این فرم شاید از نگاه ما به نظر معنی دار بیاد، ولی چیزی به اسم "ترتیب ردیف" توی پایگاههای دادهی رابطهای وجود نداره و این جدول اولین قانون فرم نرمال سطح یک رو نقض کرده. برای اینکه ترتیب مصاحبه رو نشون بدیم باید دقیق باشیم و فرم رو با اضافه کردن ستون تاریخ به صورت زیر تغییر بدیم:
با استفاده از این جدول میفهمیم که ترتیب مصاحبهها چطور هست.
قانون دوم: میکس کردن تایپهای مختلف داده در یک ستون مجاز نیست
توی Spreadsheet ها مثل اکسل و گوگل شیت این اجازه رو میدن که تایپهای مختلف داده توی یک ستون بشینه ولی این نقض قانون دوم فرم نرمال سطح اول هست. توی هر ستون فقط و فقط باید تایپ مخصوص اون ستون توش وارد بشه و دیتابیس اجازه نمیده که تایپ دیگری از داده توی اون ستون بشینه (توی Spreadsheet ها باید حواسمون به این مورد باشه). توی مثال بالا فقط ردیف 1 و 2 "عدد صحیح" یا به صورت تایپ [integer] هست و بقیه ردیفها "رشته" یا به صورت تایپ [string] هستن.
مثال مرسوم بعدی برای نقض این مورد:
توی تاریخها باید خیلی حواسمون باشه که اگر به صورت دستی تاریخ ها رو وارد می کنیم مدل تایپ تاریخمون مثل هم باشه و اگر میخوایم مدل دیگهای نمایشش بده بعد از یکسان بودن تایپ داده از طریق Format شیوهی نمایشش رو تغییر بدیم. توی مثال بالا فقط موارد سبز رنگ درست وارد شدن و موارد دیگه با فرمتی که برای این ستون در نظر گرفته شده همخونی ندارن و نقض قانون دوم فرم نرمال سطح اول هست.
قانون سوم: وجود یک جدول بدون داشتن کلید اصلی (Primary Key) مجاز نیست.
کلید اصلی (Primary Key) یک ستون (یا ترکیبی از ستونها) هست که ردیفها رو به صورت یکتا از هم جدا میکنه.
توی این مثال، همونطور که میبینید پوزیشن "Java Developer" دو بار تکرار شده. این 2 پوزیشن متفاوت بوده ولی از دید دیتابیس برای یک مقدار (Java Developer)، دو تاریخ متفاوت برای تاریخ بستن پوزیشن ثبت شده که منطقا درست نمیتونه باشه. این فرم نقض کنندهی قانون سوم فرم نرمال سطح اول هست. به صورت زیر میتونیم این مورد رو برطرف کنیم:
با اختصاص ستونی با عنوان Position ID که نقش Primary Key رو داره، دیگه هر ردیف، ردیف یکتایی هست و قانون سوم رو هم رعایت میکنه.
قانون چهارم: تکرار کردن گروهها مجاز نیست.
تصور کنید میخوایم ثبت کنیم برای هر کاندید چه مصاحبههایی انجام شده و نتیجهاش چی بوده
همون طور که میبینید توی هر ردیف یه تعداد گروه تکرار شدن. با این مدل طراحی تقریبا هیچ مدل فیلتر بهینه و استخراج دیتایی نمیشه انجام داد و کوئری پذیر نیست. مثلا فکر کنید میخوایم ببینیم چه تعدادی از کاندیدها مصاحبه مرحله 2 رو انجام دادن؟ چه تعدادی اکسپت شدن؟ توی هر تاریخ چه تعداد مصاحبه داشتیم؟ با این جدول نمیتونیم این کار رو انجام بدیم.
شاید به نظرمون بیاد که خوب اینطوری طراحی کنیم جدولمون رو:
ولی این هم محدودیت هایی داره، برای مثال فقط تا 3 مصاحبه میتونیم ساپورت داشته باشیم. یا به تفکیک تاریخ کلی نمیتونیم فیلتر کنیم. فرمهایی مثل این فرم که یک گروه مشابه از آیتم ها در یک ردیف قرار میگیره نقض فرم نرمال سطح اول هست. پس چطور میتونیم طراحی داشته باشیم که با استاندارد فرم نرمال اول هم پیش بره؟ اینطوری:
همونطور که میبینید از این جدول تمام خصوصیاتی که میخوایم رو میتونیم گزارش بگیریم. و از اونجا که ترکیب Candidate و Interview Type همیشه ترکیب منحصر به فردی هست، Primary Keyمون ترکیب این دو با هم خواهد بود و همیشه یکتا خواهد بود و قوانین قبلی هم رعایت میکنه.
بیاین فرض کنیم میخوایم جدول رو کاملتر کنیم و محلی که فرد از اونجا برامون رزومه فرستاده هم برای هر مصاحبه بیاریم:
هر کاندید سورس یکتایی داره، به همین دلیل هر بار که فردی نوشته میشه باید همون سورس هم جلوش نوشته بشه. توی کار با دیتابیس به چند تا مشکل میتونیم برخورد کنیم:
فکر کنید بنا به دلیلی، ردیفی که کاندید Roya مصاحبه داشته از جدول حذف میشه. دیگه ما نمیتونیم سورس Roya رو داشته باشیم. به این حالت میگن Deletion Anomaly
دلیلی که باعث شده این مشکل پیش بیاد این هست که فرم ما توی سطح دوم نرمال قرار نداره.
قانون فرم نرمال دوم: هر ستونی که به عنوان Primary Key تعیین نشده باید وابستگی به کل Primary Key داشته باشد.
این به چه معنیه؟ بیاید توی جدول بالا این مورد رو بررسی کنیم. ستون های آبی رنگ (Candidate, Interview Type)، کلید های اصلی (Primary Key) های ما هستند. Non-key Attributeها Status و Source هستند. آیا Status به کل Primary Key وابسته هست؟ بله، هر کاندید در حل مرحله یک Status دارد. آیا Source به Primary Key وابسته هست؟ نه، فقط به Candidate وابسته هست. به خاطر همین مساله هست که این فرم توی سطح دوم نرمال نیست و ممکنه مشکلات بالا براش پیش بیاد. چطور میتونیم این مساله رو بر طرف کنیم؟
مشکل از جایی شروع شد که ما یک ستون به جدولی اضافه کردیم که متعلق به اون نیست و متعلق به جدول دیگهایه. از اونجا که دیدیم Source متعلق به هر Candidate هست، پس Candidate یک موجودیت مهم هست و باید براش یه جدول جداگانه در نظر بگیریم و این مورد رو توی جدول Candidate بیاریم:
و جدول قبلیمون هم به حالت قبل از اضافه کردن ستون سورس بر میگردونیم:
سطوح دیگر فرم نرمال رو فقط به صورت خلاصه مینویسم و بیشتر در دیتابیسهای تخصصی کاربرد داره و تا همین سطح فرمها نرمال باشه گزارشهایی که میخوایم رو در حد خوبی میتونیم بگیریم.
فرم نرمال سطح سوم (3rd Normal Form یا 3NF):
فرم نرمال سطح چهارم (4th Normal Form یا 4NF):
فرم نرمال سطح پنجم (5th Normal Form یا 5NF):
- اگر علاقه داشتید بیشتر در مورد سطوح دیگه ی فرم نرمال بدونید، میتونید به این لینک مراجعه کنید.
خیلی وقتها، موردی که باهاش برخورد میکنیم این هست که ما معمولا برای جمعآوری داده از صفر نمیخوایم شروع کنیم و احتمالا از قبل یک سری دادهی آماده داریم. اگر قواعد کار با داده و مواردی که توی کار با داده مهم هست رو ندونیم احتمالا دادههای ما برای آنالیز نیاز به ویرایشهایی داره. به دادههایی که برای تجزیه و تحلیل نیاز و گزارش گیری مناسب نیستن و نیاز به ویرایش دارن اصطلاحا دادههای کثیف میگن و به فرآیندهایی که انجام میشه تا این دادهها به دادههای درست و قابل گزارشگیری تبدیل بشن، تمیز کردن داده یا دیتا کلینینگ یا پاکسازی داده گفته میشه.
پاکسازی داده فرآیند شناسایی و تصحیح (یا حذف) رکوردهای غلط یا غیر دقیق از یک مجموعه رکورد، جدول یا پایگاه داده است و به شناسایی قسمتهای ناقص، نادرست، نادقیق یا نامربوط از دادهها و سپس جایگزینی، اصلاح یا حذف آن اشاره دارد.
پاکسازی دادهها به چند دلیل مهمه. یکی از مزایای پاکسازی دادهها اینه که تجزیه و تحلیل رو دقیقتر میکنه. در تجزیه و تحلیل دادهها، پاکسازی دادهها برای اطمینان از صحت و اعتبار دادههای جمع آوری شده ضروریه. این فرآیند قبل از بارگذاری دادهها انجام میشه تا کسبوکارها بتونن اطلاعات مهم رو راحتتر تفسیر کنن. داشتن دادههای تمیز در نهایت بهرهوری کلی رو افزایش میده و اطلاعاتِ با بالاترین کیفیت رو در تصمیمگیری شما فراهم میکنه.
اگر داده از قبل وجود داشته باشه ما حتما برای تجزیه تحلیل باید داده ها رو بررسی و تمیز کنیم.
تمیز کردن داده معمولا توی ابتدای کار، بیشترین زمان رو از یک دیتا آنالیست در تحلیل داده میگیره
بعد از تمیز کردن داده ها باید از روشهایی استفاده کنیم که از اون به بعد وارد کردن دادهی کثیف رو به حداقل برسونه. موردی که همیشه باهاش برخورد کردم این بود که چون به یک دیتاست، معمولا چند نفر دسترسی دارن و داده رو افراد مختلف توی شیتها وارد میکنن و این وارد کردن داده به صورت دستی احتمالا به خاطر دلایل مختلف میتونه با خطا همراه بشه؛ پس این دادهی کثیف همیشه تولید میشه و هر چقدر بخوایم توی وارد کردن داده دقت و حساسیت داشته باشیم ممکنه اشتباه دادهای رو وارد کنیم. ما به عنوان طراح فرم باید طوری فرم رو طراحی کنیم و به افرادی که به فرم دسترسی دارن آموزش بدیم که در نهایت کار خودمون برای تجزیه تحلیل داده ساده بشه و به کمترین تمیز سازی داده نیاز داشته باشیم و با این کار هم زمان زیادی از ما ذخیره میشه هم گزارش هامون، گزارش های درست و صحیحی خواهد بود.
در ادامه اول از تمیز کردن یک دیتاست نمونه و دادههای کثیف مرسوم توی اون و روشهای تمیز کردن اونها میگم و بعد در مورد این صحبت میکنم که از چه روشهایی برای طراحی فرمها استفاده کردم تا ورود دادهی کثیف توسط کاربر به حداقل برسه.
انتخاب روش و استراتژی ای که میخوایم برای تمیز کردن داده ها استفاده کنیم، خیلی وقت ها وابستگی مستقیمی به حجم دادهها داره. ما میخوایم به بهینه ترین حالت ممکن از زمان و انرژیمون برای رسیدن به بهترین نتیجه استفاده کنیم. خیلی وقتها که حجم داده کم هست، تمیز کردن داده به صورت دستی و ردیف به ردیف و ستون به ستون میتونه روش خیلی خیلی سریع تری نسبت به فرمولها و روشهای دیگهی تمیز کردن داده که در ادامه میگم باشه. برای خود من اوایلی که با داده کار می کردم این مورد پیش میومد که برای تمیز کردن یک دیتاست با حجم کم وقت خیلی زیادی میذاشتم که حتما با فرمول و قواعد پیچیدهای که میشناختم این دادهها تمیز بشه. این مورد زمان و انرژی زیادی ازم میگرفت. در صورتی که اگر این داده ها رو به صورت دستی و ردیف به ردیف ادیت می کردم زمان خیلی کمتری ازم گرفته می شد.
پس این که استراتژی ادیت دادههاتون چطور باشه خیلی زیاد به حجم داده مرتبط هست و الزاما نیاز نیست که از روشهای پیچیده برای تمیز کردن هر مدل دیتاست استفاده بشه.
دیتای نمونهی زیر رو نگاه کنید:
** کمی نگاش کنید و ببینید چه ایراداتی توش میبینید و بعد پایینتر بیاید
همون طور که میبینید مواردی توی جدول هست که ظاهرا مشخصه ایراد داره و برای تحلیل درست باید اصلاح بشه. موارد مرسوم دادههای کثیف رو در ادامه میگم و توی جدول درستشون می کنیم:
Missing values
مواردی که جا افتاده و باید به دیتابیس اضافه بشه. هیچ ردیف خالی ای نباید در دیتابیس وجود داشته باشه
Duplicate data
هیچ دو ردیف یکسانی نباید در جدول وجود داشته باشه (بعضی وقت ها توی مرج کردن جدول ها این مورد به وجود میاد) و باید داده های تکراری حذف بشن
Irrelevant data
داده های نامرتبط باید از جدول حذف بشن همون طور که میبینید توی جدول ردیف های نامرتبطی وجود داره
Data type conversion
اگر تایپ یک ستون باید عدد صحیح باشد باید اون رو به صورت عدد صحیح بنویسیم و یا اگر 2 متغیره هست فقط باید از همون 2 متغیر استفاده کنیم.
Standardizing data (data-time formats, units, etc)
فرمت داده ها و مقیاس ها باید مشابه باشد. برای مثال توی این جدول تاریخ ها به صورت های مختلف نوشته شده. همینطور عددی که با عنوان عدد حقوق نوشته شده هم تایپش مشکل داره هم مقیاسش که باید یکسان سازی بشه
Syntax errors (white spaces, extra spaces, typos, and formats)
اسپیس های اضافه باید از دیتابیس حذف بشه (با استفاده از دستو Trim میتونیم این کار رو کنیم) همین طور مدل نوشتاری اسم ها باید یکسان باشه (همونطور که میبینید اسم ها به صورت صحیح نوشته نشده) با دستور Proper میتونیم این مورد رو درست کنیم
Outliers
داده های پَرت باید از دیتابیس خارج بشن یا در نظر گرفته نشن. خیلی وقت ها این داده ها به خاطر اشتباه وارد کردن اون هاست. همون طور که میبینید توی ستون Salary یک داده پَرت وجود داره که اشتباه تایپ شده
در نهایت با تصحیح موارد فوق به این جدول می رسیم:
اکسل و گوگل شیت برای راحتی و درستی وارد کردن داده ها ابزارهایی تحت عنوان Data validation دارن. برای اینکه دادههای ما اونطور که میخوایم و به صورت صحیح وارد بشه و کمترین نیاز رو به پاکسازی داشته باشه میتونیم از این ابزارها استفاده کنیم. اصلیترین هاش که من توی فرم هام هم ازشون استفاده می کنم میگم:
توی Google Sheet از طریق منوی Data و بعد Data Validation میتونیم به گزینه های این قابلیت دسترسی داشته باشیم
Dropdown list
از این قابلیت برای انتخاب گزینه های تکراری از لیست استفاده می کنم. باعث می شه غلط تایپی توی وارد کردن داده وجود نداشته باشه و دیگه نیاز به تایپ مجدد اون مورد هم نیست
Data validation formulas
برای دیتا ولیدیشن میتونید علاوه بر فرمولهایی که توی گوگل شیت هست، از فرمولهای دلخواه هم استفاده کنید. مثلا من توی این قسمت برای وارد کردن حقوق از فرمول isnumber استفاده کردم که اگر دادهی وارد شده عدد نبود پیام خطا بده و یا داده رو قبول نکنه و یا پیام دلخواهی رو به کاربر نشون بده.
Checkbox
برای متغیر های True/False میتونید از این قابلیت استفاده کنید و دیگه نیازی به تایپ وضعیت نباشه
Keyboard shortcuts
یک سری کیبورد شورتکات وجود داره که میتونیم برای وارد کردن صحیح و سریع اطلاعات ازش استفاده کنیم. مثلا اینجا من از شورتکات Ctrl + ; برای وارد کردن تاریخ کامل الان استفاده میکنم که به صورت صحیح و کامل تاریخ وارد میشه و نیاز به تایپ هربارهی این مورد نیست.
Custom formulas
برای راحتی کار و سرعت می تونید از فرمول های مختلف استفاده کنید. من برای وارد نکردن چندبارهی اطلاعات تکراری از vlookup خیلی استفاده می کنم. به این صورت که یک جدول دارم که اطلاعتی که همیشه باهاشون سر و کار دارم رو دارم و یک کد بهش اختصاص دادم (همون Primary key که قبلتر در موردش صحبت کردیم) و با لوکاپ اون کد تمام اطلاعت دیگه ای رو که میخوام در جدول میارم و نیاز به تایپ چندباره ی موارد تکراری نیست. (البته توی مقاله بعدی و بحث بارگذاری داده و دیتا مدلینگ بیشتر از ارتباط جدول ها می گم)
گوگل شیت یک مدل فرمول داره به اسم arrayformula. با استفاده از این فرمول دیگه نیاز نیست توی تمام ردیف ها فرمول رو دوباره وارد کنید و فقط توی سطر اول وارد می کنید و اتومات توی ردیف های دیگه این فرمول استفاده میشه.
فکر کنید دادههایی که میخواید تمیز کنید رو به صورت دورهای از منابع مختلفی دارید جمع آوری میکنید که خودتون به اون منابع دسترسی ویرایش ندارید و همیشه یک مدل فرمت خاص دادهها رو میگیرید که نیاز به ادیت داره. اگر بخوایم هر باره این داده ها رو تمیز کنیم، زمان و انرژی زیادی از ما میگیره و ممکنه خطا توش پیش بیاد. اکسل یک قابلیت فوق العاده به اسم Power Query داره که انجام این کار رو به شدت راحت میکنه. به این صورت که شما با استفاده از آپشنهایی که داره، یکبار دادهی خودتون رو تمیز و ذخیره میکنید و مراحلی که داده رو تمیز کردید توش ذخیره میشه. بعد از اون با بارگذاری دادهی جدید شما میتونید با یک کلیک مراحل تمیز کردن دادهی قبلی رو روی دادهی جدید اجرا کنید و دیتاتون بدون هیچ زحمتی مثل دادهی قبلی تمیز میشه. خیلی باحاله نه؟ یک سری قواعد داره که توضیحش از حوصلهی این مقاله خارج هست. برای اینکه بیشتر در مورد Power Query بدونید میتونید توی اینترنت سرچ کنید یا این ویدیو رو توی یوتیوب ببینید.
امیدوارم مطالب بالا به دردتون خورده باشه. خوشحال میشم اگر شما هم روشهای برای دگرگونی دادهها، تمیز کردن دادهها یا ولیدیشن کردن دادهها داشتید توی کامنتها به من بگید.
توی مقالهی بعدی به مرحلهی بارگذاری داده میپردازم و بیشتر در موردش توضیح میدم.