Data Engineering Guidelines
Under Construction
อัพเดทล่าสุดวันที่ 19 กรกฎาคม 2565 เพิ่มเนื้อหาเทคนิคและวิธีการทำ Data Anonymisation
การตั้งชื่อ
การตั้งชื่อตาราง
แนวคิดเบื้องต้นในการตั้งชื่อตาราง
ตารางควรใช้ภาษาอังกฤษ ไม่ควรใช้ภาษาอื่นๆ
ชื่อตารางควรจะมีรูปแบบดังนี้
department_datasetName_period
department
หมายถึง ชื่อย่อภาษาอังกฤษของหน่วยงานที่จัดทำชุดข้อมูล เช่นdpd
,ded
,pcd
datasetName
หมายถึง ชื่อของชุดข้อมูลที่เข้าใจง่าย ถ้ามีหลายคำให้ใช้ Snake Case เช่นict_assets
,load_profiles
period
หมายถึง ปีและเดือน ในกรณีที่ชุดข้อมูลแบ่งย่อยเป็นรายปี หรือ รายเดือน ในรูปแบบ YYYYMM เช่น202201
,202112
ตัวอย่าง
Good Bad ✅ dpd_ict_assets
❌ ict_assets
✅ dpd_ict_assets_202101
❌ dpd_ict_assets_january_2021
การตั้งชื่อคอลัมน์
ชื่อคอลัมน์ หรือ ฟิลด์ในตารางควรมีลักษณะดังนี้
เป็นภาษาอังกฤษ เช่น
contract_no
,error_text
หลีกเลี่ยงการใช้ชื่อฟิลด์ที่ไม่สื่อความหมาย ควรตั้งชื่อให้เข้าใจได้ง่าย เช่น
meter_id
,mea_no
,feeder_name
ใช้ตัวพิมพ์เล็กทั้งหมด เช่น
residential_area
หลีกเลี่ยงการใช้อักขระพิเศษ เช่น
#$%!
หลีกเลี่ยง Space ระหว่างคำ หากมีหลายคำให้ใช้
_
(Underscore) แทนตัวอย่าง
Good Bad ✅ contract
❌ vertrag
✅ profile_id
❌ Profile_ID
✅ employee_id
❌ รหัสพนักงาน
✅ district_code
❌ district code
✅ home_address
❌ address#home
✅ date
❌ utc7_date_from_system_logs_no_one_cares
การตั้งชื่อใน Apache Airflow
การตั้งชื่อ DAGs
ใช้แนวคิดพื้นฐานเดียวกันกับการตั้งชื่อตาราง
เป็นภาษาอังกฤษ
มีรูปแบบดังนี้
department_ingestingDataset_extraInformation
department
หมายถึง ชื่อย่อภาษาอังกฤษของหน่วยงานที่จัดทำชุดข้อมูล เช่นdpd
,ded
,pcd
ingestingDataset
หมายถึง ชื่อชุดข้อมูลที่กำลังนำเข้า เช่นpayment
,load_profiles
extraInformation
หมายถึงข้อมูลเพิ่มเติมอื่นๆที่อาจจะจำเป็น เช่นresidential
,industry
ตัวอย่าง
Good Bad ✅ dpd_ict_assets
❌ ict_assets_test_32
✅ dpd_ict_assets_history
❌ group99_dpd_ict_assets_january_2021_dev
การใส่ Metadata ใน DAG Source Code
ข้อมูล Metadata สำคัญที่ควรใส่ตอนพัฒนา DAGs
email
หมายถึง List ของ Emails วิศวกรที่จัดทำ DAG เช่น[jonathan_montgomery@mea.or.th, elizabeth_de_flansuar@mea.or.th]
เพื่อใช้ติดต่อในกรณีมีปัญหาหรือสอบถามowner
หมายถึง ชื่อย่อยภาษาอังกฤษของหน่วยงานที่จัดทำ DAG เป็นตัวพิมพ์เล็ก เช่นdpd
,pcd
description
หมายถึง คำอธิบาย DAGs เป็นภาษาอังกฤษสั้นๆ พอเข้าใจtags
หมายถึง List ของ คำที่ใช้ค้นหา DAGs หรือ คำที่ใช้สื่อถึงชุดข้อมูลที่กำลังนำเข้า ตามความเหมาะสม เช่นweather
,api
,external
,public
ตัวอย่างการใส่ข้อมูล Metadata
...
default_args = {
'owner': 'dpd',
'email': ['chatree.sr@mea.or.th'],
}
with DAG(
dag_id="dpd_outage_tweets",
default_args=default_args,
description="Collect tweets related to outage events within MEA AoR",
tags=['twitter', 'api', 'external'],
start_date=airflow.utils.dates.days_ago(6),
schedule_interval="@daily"
) as dag:
...
การบริหารจัดการข้อมูล
เพิ่มคำอธิบายตารางและฟิลด์
ทุกครั้งที่มีการสร้างตารางใน Hive หรือ Impala ควรจะใส่คำอธิบายเป็นภาษาอังกฤษหรือภาษาไทย กระชับ ด้วยคำสั่ง COMMENT
เพื่อให้เข้าใจข้อมูลได้ง่ายขึ้น ตัวอย่างการสร้าง External Table เช่น
CREATE EXTERNAL TABLE default.dpd_tweets (
tweet_id INTEGER COMMENT 'FIELD DESCRIPTION',
tweet_text STRING COMMENT 'FIELD DESCRIPTION'
)
COMMENT 'TABLE DESCRIPTION'
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
LOCATION '...'
โดย
FIELD DESCRIPTION
คือ คำอธิบายฟิลด์TABLE DESCRIPTION
คือ คำอธิบายตาราง
การจัดทำข้อมูลขนาดใหญ่
โปรดพิจารณาใช้ Partitioned Table ในกรณีดังนี้
- ตารางมีข้อมูลเยอะมาก จนกระทั่งการอ่านข้อมูลจากตารางใช้เวลานานเกินสมควร
- ตารางที่มีรูปแบบการ Query ซ้ำๆและคาดเดาได้ เช่น การ Query ข้อมูลตามเขต
SELECT * FROM mytable WHERE district_code='0001'
หรือ การ Query ข้อมูลรายเดือนSELECT * FROM mytable WHERE year=2021 AND month=3
การใช้งาน Partitioned Table ที่มีการออกแบบ Key ที่ดีจะช่วยให้การอ่านข้อมูลไม่จำเป็นต้อง Scan ข้อมูลทั้งตาราง แต่สามารถอ่านได้โดยตรงจาก Partition ที่เกี่ยวข้อง ทำให้ความเร็วในการเข้าถึงข้อมูลดีขึ้น
คุณจะได้เรียนรู้วิธีการสร้าง Partitioned Table ในหลักสูตร Data Engineering Bootcamp
การบีบอัดข้อมูล
พิจารณาบีบอัดข้อมูลก่อนเก็บลง Data Platform ปัจจุบัน Data Platform สนับสนุนการบีบอัดหลายรูปแบบ เช่น Parquet
และ ORC
คุณจะได้เรียนรู้ความแตกต่างของการบีบอัดแต่ละประเภทในหลักสูตร Data Engineering Bootcamp ข้อมูลที่คุณควรทราบก่อนตัดสินใจใช้งานฟอร์แมทต่างๆ
- ORC สนับสนุน ACID Transactions
- Apache Hive สนับสนุนทั้ง Vectorized ORC และ Vectorized Parquet แต่ผู้ผลิตแนะนำ ORC
- Apahce Impala สนับสนุนทั้ง Vectorized ORC และ Vectorized Parquet แต่ผู้ผลิตแนะนำ Parquet (เนื่องจาก Impala ไม่สนับสนุน Column Index ใน ORC)
- Apache Spark สนับสนุนทั้ง Vectorized ORC และ Vectorized Parquet
ประเภทและรูปแบบของข้อมูล
หลักการโดยทั่วไปคือ
- เลือกใช้ Data Type ให้เหมาะสมกับประเภทข้อมูล ไม่ควรใช้
STRING
สำหรับทุกประเภทข้อมูล - ข้อมูลตัวเลขเกี่ยวกับเงิน ควรจะใช้ Data Type ที่มีความแม่นยำเหมาะสมกับการใช้งาน
ข้อมูลบางประเภทมีการตกลงกันภายใน กฟน. แล้วให้ดำเนินการดังนี้
Data | Data Type | Format | Example |
---|---|---|---|
DATE | DATE | YYYY-MM-DD | 2021-12-03 |
TIME | TIME or STRING | HH:MM:SS | 23:45:00 |
การให้บริการข้อมูล
พิจารณาจัดทำ Views ที่คาดว่ามีประโยชน์สำหรับ Data Scientists, Data Analysts และ ผู้ใช้งานอื่น เช่น ข้อมูล AMR Meter มีขนาดใหญ่มาก การทำ Views เพิ่มเติมเป็นรายเดือน จะช่วยให้การวิเคราะห์ Load Profile ง่ายขึ้น เนื่องจาก Data Analysts ไม่จำเป็นต้องเขียน WHERE
Clause เอง ตัวอย่างการแบ่ง Views
ded_amr_loadprofile
ded_amr_loadprofile_202101
ded_amr_loadprofile_202102
ded_amr_loadprofile_202103
ded_amr_loadprofile_202104
...
Materialized Views
Data Platform สนับสนุนการทำ Materialized Views ใน Apache Hive
Data Anonymization
หลักการปกปิดข้อมูลส่วนบุคคลในฐานข้อมูล หลักการในคู่มือนี้เป็นหลักการเบื้องต้นเท่านั้น สามารถปรับเปลี่ยนได้ตามความเหมาะสม
Data Anonymisation Process
ขั้นตอนการปกปิดข้อมูลแบ่งออกเป็น 4 ขั้นตอนย่อยๆ ดังนี้
- เรียนรู้ข้อมูล ทั้งในด้านลักษณะของข้อมูลและการนำไปใช้ การที่เรารู้ว่าข้อมูลชิ้นนั้นๆ มีอะไรบ้าง ใครที่จะนำข้อมูลไปใช้ และจะถูกนำไปใช้อย่างไร จะทำให้เราวางแผนการปกปิดข้อมูลได้เหมาะสมมากยิ่งขึ้น เช่น การนำข้อมูลไปให้หน่วยงานภายในองค์กร เพื่อไปทำการตลาดแบบเจาะกลุ่มผู้ใช้ การที่เราปกปิดข้อมูลเพียงบางส่วน จะทำให้ผลลัพธ์การทำงานดีขึ้น เมื่อเทียบกับการปกปิดข้อมูลทั้งหมด ในขณะที่การนำข้อมูลให้บุคคลภายนอกใช้ การที่จะปกปิดข้อมูลเพียงบางส่วนนั้นจะมีความเสี่ยงต่อการรั่วไหลของข้อมูลมากเกินไป
- พิจารณาข้อมูลที่ต้องการทำการปกปิด เช่น ชื่อ นามสกุล เพศ ที่อยู่ อีเมล ความชอบในด้านต่างๆ ข้อมูลการเงิน เป็นต้น
- ทำการปกปิดข้อมูลด้วยวิธีการต่างๆ ตามความเหมาะสมของประเภทข้อมูลและการใช้งาน ซึ่งจะกล่าวถึงในบทความนี้
- ตรวจสอบข้อมูลว่า ข้อมูลที่ปกปิดมาแล้วมีความเสี่ยงที่จะถูกแกะรอยกลับเป็นข้อมูลส่วนตัวได้มากน้อยเพียงใด แล้วทำการปรับปรุงการปกปิดข้อมูลเพิ่มเติม ถ้าพบว่าข้อมูลยังสามารถย้อนกลับไปสู่ตัวตนของบุคคลนั้นๆ ได้
Data Identification
ลักษณะของข้อมูลที่สามารถระบุตัวตนได้มีอยู่ 2 แบบ
- ข้อมูลที่ระบุตัวตนทางตรง (Direct Identifiers) เป็นข้อมูลที่สามารถระบุตัวตนได้เลยโดยไม่ต้องมีการนำข้อมูลอื่นๆ มาประกอบการระบุตัวตน เช่น ชื่อ-นามสกุล เบอร์โทรศัพท์ อีเมล ที่อยู่(ในบางเคส) เป็นต้น
- ข้อมูลที่ระบุตัวตนทางอ้อม (Indirect Indentifiers) เป็นข้อมูลที่ต้องใช้ข้อมูลอื่นๆ มาประกอบกันแล้วจะสามารถระบุตัวตนได้ เช่น อายุ เพศ วันเกิด เงินเดือน ความชอบส่วนตัว เป็นต้น
Psudonymisation vs Anonymisation
- Pseudonymisation เป็นวิธีการปกปิดข้อมูลที่ยังสามารถนำมาใช้ระบุตัวตนได้โดยการนำข้อมูลอื่นๆ มาประกอบ เช่น การเข้ารหัสข้อมูล การปกปิดข้อมูลแบบไม่เต็ม 100% เช่น การเปลี่ยนเลขอายุเป็นช่วงอายุ เป็นต้น
- Anonymisation เป็นวิธีการปกปิดข้อมูลที่ไม่สามารถนำมาระบุตัวตนได้ด้วยวิธีการใดๆ เช่น การลบข้อมูลทิ้ง การเปลี่ยนข้อมูล การสลับข้อมูล เป็นต้น
Data Anonymisation Techniques
Joinable & Searchable
สำหรับข้อมูลที่ต้องการให้เชื่อมโยงกับตารางอื่นๆ ในฐานข้อมูลได้ หรือต้องการให้ข้อมูลสามารถค้นหาได้ ให้ใช้การเข้ารหัสข้อมูลด้วยอัลกอริทึ่มแบบต่างๆ ก่อนที่จะจัดเก็บลงในฐานข้อมูล โดยการเข้ารหัสข้อมูลจะถูกแบ่งเป็น 2 รูปแบบดังนี้
Reversible
เป็นการเข้ารหัสข้อมูลแบบที่มี Key ที่สามารถใช้ในการถอดรหัสข้อมูลให้กลับมาเป็นข้อมูลเดิมได้ วิธีการเข้ารหัสในลักษณะนี้เช่น AES, RSA, HS256 เป็นต้น
Irreversible
เป็นการเข้ารหัสข้อมูลแบบที่ไม่สามารถย้อนข้อมูลกลับมาได้ วิธีที่จะเปรียบเทียบข้อมูลคือนำข้อมูลที่จะเทียบมาเข้ารหัสแล้วจึงนำมาเทียบกันเท่านั้น วิธีการเข้ารหัสในลักษณะนี้เช่น MD5, SHA-2, HMAC เป็นต้น
ในระบบ กฟน ข้อมูลที่ต้องการให้ค้นหาหรือเชื่อมโยงได้ ให้ใช้การเข้ารหัสด้วยอัลกอรึทึ่ม MD5 โดยข้อมูลที่จะทำการ hash ควรแปลงให้อยู่ใน data type และ format ที่เป็นมาตรฐานเดียวกัน เพื่อให้สามารถ hash ออกมาโดยข้อมูลไม่ผิดเพี้ยน ใน กฟน. ได้มีการวางแบบแผนการ hash ข้อมูลบางประเภทไว้แล้วดังนี้
Data | Target Data Type | Target Format |
---|---|---|
รหัสมิเตอร์ | String | เติม 0 ข้างหน้าให้ครบ 10 หลัก |
CA | String | เติม 0 ข้างหน้าให้ครบ 10 หลัก |
BP | String | เติม 0 ข้างหน้าให้ครบ 10 หลัก |
รหัสพนักงาน | String | เติม 0 ข้างหน้าให้ครบ 8 หลัก |
ตัวอย่าง
ข้อมูล | ข้อมูลดิบ | ข้อมูลที่พร้อมทำการ Hash | MD5 |
---|---|---|---|
รหัสมิเตอร์ | 12345678 | 0012345678 | beede0fc97e6f9251c206a3d25540fa5 |
CA | 1234567 | 0001234567 | 34c9c14296451d0a27ce3fa296b93f69 |
BP | 1234567 | 0001234567 | 34c9c14296451d0a27ce3fa296b93f69 |
รหัสพนักงาน | 1234567 | 01234567 | 2e9ec317e197819358fbc43afca7d837 |
Unjoinable & Unsearchable
สำหรับข้อมูลที่ไม่มีความจำเป็นในการนำไปเชื่อมโยงหรือนำมาใช้เป็น keyword ในการค้นหา ให้ทำการ mask หรือลบข้อมูลแถวนั้นๆ ออกได้ ขึ้นอยู่กับลักษณะของข้อมูลและความต้องการของผู้ดูแลข้อมูล หรือสามารถใช้เทคนิคในการปกปิดข้อมูลแบบอื่นๆ ได้เช่นกัน ถ้าเห็นว่าเหมาะสม
Character Masking
Character masking คือการแปลงตัวอักษรบางส่วนหรือทั้งหมดของข้อมูลส่วนตัวให้เป็นตัวอักษรอื่นๆ เช่น x,* เป็นต้น ซึ่งอาจจะคงไว้ซึ่งความยาวของข้อมูลหรือเปลี่ยนแปลงความยาวของข้อมูลก็ได้
ตัวอย่างการใช้งาน Character Masking
ชื่อ-นามสกุล ใช้การแปลงตัวอักษรเป็น * ตั้งแต่ตัวที่ 4 เป็นต้นไป
กันย์ รักดี → กัน********
อีเมล ใช้การแปลงตัวอักษรเป็น * ตั้งแต่ตัวที่ 4 เป็นต้นไป เช่นเดียวกับชื่อ-นามสกุล
gun.rakdee@mea.or.th → gun*****************
ที่อยู่ ใช้การลบข้อมูลทิ้งทั้งหมด หรือคงเหลือไว้เฉพาะรหัสไปรษณีย์ในกรณีที่ต้องการนำข้อมูลไปทำ machine learning
การไฟฟ้านครหลวง อาคารวัฒนวิภาส เลขที่ 1192 ถนนพระรามที่ 4 แขวงคลองเตย เขตคลองเตย กรุงเทพมหานคร 10110 → 10110
เบอร์โทรศัพท์ ใช้การแปลงตัวอักษรเป็น * ตั้งแต่ตัวแรกจนถึง 3 ตัวสุดท้าย
0994446666 → *******666
Record Suppresion
Record Suppression คือการลบข้อมูลทั้งแถวนั้นออกไป ใช้ในกรณีที่ข้อมูลที่เก็บมีแต่ข้อมูลที่สามารถระบุตัวตนได้ และไม่สามารถปกปิดข้อมูลได้อีก เช่น การลบข้อมูลแถวที่เก็บไว้เฉพาะชื่อ นามสกุล เบอร์โทรศัพท์ เป็นต้น
Column Suppression
Column Suppression คือการลบ column ที่เป็ยข้อมูลส่วนตัวออกจากตาราง ใช้กับข้อมูลที่ไม่มีความจำเป็นในการนำไปใช้งานต่อ เช่น การลบคอลัมน์ที่เก็บชื่อออกจากตาราง เป็นต้น
Shuffling & Permutation
Shuffling, Permutation คือการสุ่มข้อมูลในแต่ละคอลัมน์ของแต่ละแถวเข้าด้วยกัน การปกปิดข้อมูลในลักษณะนี้จะยังคงข้อมูลไว้อยู่ แต่ตัวตนของข้อมูลจะถูกปกปิด ใช้ในกรณีที่ต้องการให้ข้อมูลยังมีลักษณะเป็นข้อมูลจริงอยู่ แต่ต้องการปกปิดความเป็นส่วนตัวของข้อมูล
ตัวอย่างการใช้งาน Shuffling & Permutation
ข้อมูลเริ่มต้น
ชื่อ | นามสกุล | เบอร์โทรศัพท์ | อีเมลล์ |
---|---|---|---|
John | Smith | 0959946664 | john.s@gmail.com |
Karen | Anderson | 0874569873 | kaander@gmail.com |
Silvia | Survana | 0605057708 | survana.sil@gmail.com |
ข้อมูลที่ผ่านการ Permutate
ชื่อ | นามสกุล | เบอร์โทรศัพท์ | อีเมลล์ |
---|---|---|---|
Karen | Smith | 0605057708 | john.s@gmail.com |
John | Survana | 0959946664 | kaander@gmail.com |
Silvia | Anderson | 0874569873 | survana.sil@gmail.com |
Perturbation
Data Perturbation เป็นการดัดแปลงข้อมูลที่เก็บด้วยหลักการบางอย่าง เช่น การนำเลขอายุไปคูณ 2 หรือการแทรกตัวอักษรเข้าไปในชื่อ เป็นต้น ซึ่งวิธีการดัดแปลงข้อมูลนี้จะสามารถถอดรหัสได้หากผู้รับข้อมูลรู้ถึงวิธีการที่ใข้ในการดัดแปลงข้อมูล ตัวอย่างเช่น
เพิ่มตัว "า" เข้าไปหลัง "ก" ชองชื่อ-นามสกุล
กันย์ รักดี → กัานย์ รักาดี
นำเลขอายุไปคูณ 2 แล้วลบ 5
age 23 → age 41
Aggregation
Data Aggregation คือการจัดเรียงข้อมูลในตารางแล้วนำมาสรุปเป็นตารางใหม่ ใช้สำหรับข้อมูลที่จัดกลุ่มได้ หรือข้อมูลที่เป็นตัวเลข เช่น อายุ ฐานเงินเดือน เป็นต้น เหมาะสำหรับนำไปใช้ในการทำ machine learning ต่อ
ตัวอย่างการใช้งาน Aggregation
ข้อมูลเริ่มต้น
ชื่อ | นามสกุล | อายุ | เงินเดือน |
---|---|---|---|
John | Smith | 25 | 23000 |
Karen | Anderson | 35 | 56000 |
Silvia | Survana | 27 | 37000 |
ข้อมูลที่ผ่านการ Aggregate
ช่วงเงินเดือน | จำนวน |
---|---|
20000-30000 | 1 |
30001-40000 | 1 |
40001-50000 | 0 |
50001-60000 | 1 |
ช่วงเงินเดือน | จำนวน |
---|---|
20-30 | 2 |
31-40 | 1 |
41-50 | 0 |
Re-identification Risks
Re-identification risk คือความเสี่ยงที่ข้อมูลที่ทำการปกปิดแล้วจะถูกนำมาถอดความและนำมาใช้ระบุตัวตนได้อีกครั้ง โดยการนำข้อมูลที่มีไปวิเคราะห์ประกอบกับข้อมูลอื่นๆ และนำมาซึ่งข้อมูลที่สามารถระบุตัวตนได้
ในการวิเคราะห์ความเสี่ยงที่ข้อมูลจะเปิดเผยตัวตน ต้องนำทั้งข้อมูลส่วนตัวทางตรงและทางอ้อมมาดูความเสี่ยงร่วมกัน เช่น
- ในส่วนของข้อมูลส่วนตัวทางตรง จำนวนตัวอักษรที่แสดง หรือการคงไว้ซึ่งจำนวนอักษรทั้งหมด ก็มีผลต่อความเสี่ยงในการเปิดเผยข้อมูลส่วนตัว
- ในส่วนของข้อมูลส่วนตัวทางอ้อม ความถี่ของข้อมูลก็มีผลต่อความเสี่ยงในการเปิดเผยข้อมูลได้
ตัวชี้วีดความเสี่ยงของการเปิดเผยข้อมูลอันหนึ่งคือค่า k-anonymity ซึ่งเป็นค่าที่ระบุว่า ในคอลัมน์ (หรือกลุ่มของคอลัมน์) หนึ่งๆ มีค่าที่มีข้อมูลซ้ำกันน้อยที่สุดอยู่เท่าไหร่ เช่น ในข้อมูลมีคนที่อายุ 25 อยู่ 10 คน และเลขอายุอื่นๆ มีจำนวนมากกว่าหรือเท่ากับ 10 คนทั้งหมด จะได้ว่าค่า k-value ของอาบุในข้อมูลชุดนี้คือ 10 ซึ่งค่า k-value ยิ่งน้อยแสดงว่าข้อมูลนั้นๆ สามารถนำมาใช้ระบุตัวตนได้ง่ายขึ้น ซึ่งเพิ่มความเสี่ยงในการถูกเปิดเผยตัวตนได้
ซึ่งค่า k-value ที่ได้จากข้อมูลแต่ละคอลัมน์จะต้องนำมาพิจารณาร่วมกันว่าควรจะจัดการกับการปกปิดข้อมูลอย่างไรต่อไป เช่น ถ้ามีข้อมูลที่ k-value น้อยๆ อยู่หลายคอลัมน์แสดงว่าข้อมูลโดยรวมทั้งหมดยังปกปิดได้ไม่ดีพอ แต่ถ้าคอลัมน์ที่ค่า k-value น้อยมีเพียงไม่กี่คอลัมน์ก็อาจจะพิจารณานำคอลัมน์นั้นออกไปได้เลย เป็นต้น
Data Anonymisation using Python
ตัวอย่างการทำ Data Anonymisation ในภาษา Python โดยใช้ข้อมูลดังต่อไปนี้
employee_id | name | surname | telephone | address | age | salary |
---|---|---|---|---|---|---|
0 | 2200331 | jonathan | morally | 0879943105 | 2299 ถ.ลาดพร้าว แขวงวังทองหลาง เขตวังทองหลาง กรุงเทพฯ 10310 | 25 |
1 | 2346464 | arthur | smith | 0953464108 | 1549 ถ.พหลโยธิน แขวงสามเสนใน เขตพญาไท กรุงเทพฯ 10400 | 32 |
2 | 1264610 | thomas | yorn | 0897976646 | 333 ถ.สมเด็จพระเจ้าตากสิน เขตธนบุรี กรุงเทพฯ 10600 | 26 |
3 | 1001010 | moores | lovelace | 0672205335 | 954 ถ.นครไชยศรี แขวงถนนนครไชยศรี เขตดุสิต กรุงเทพฯ 10300 | 50 |
4 | 2997755 | nolan | reeves | 0942025201 | 135 หมู่1 ถ.บางกรวย-ไทรน้อย อ.บางกรวย นนทบุรี 11130 | 37 |
Reversible Pseudonymisation
ในการทำการเข้ารหัสแบบ reversible นั้น นอกจากตัวข้อมูลแล้ว จะต้องมีส่วนประกอบอื่นๆ มาใช้ร่วมกันด้วย ขึ้นอยู่กับอัลกอรึทึ่มที่เลือกใช้ เช่น AES ต้องการ key(password) และ initilazation vector (iv) ส่วน RSA ต้องการ public key file และ private key file เป็นต้น
ในตัวอย่างนี้จะสาธิตการใช้ AES256 CTR Mode ในการเข้ารหัสพนักงาน
import pyaes, pbkdf2, binascii, os, secrets
password = "MEAPassword"
passwordSalt = os.urandom(16) #ใช้เป็น string คงที่ได้
key = pbkdf2.PBKDF2(password, passwordSalt).read(32)
aes_key = binascii.hexlify(key) # เก็บค่านี้เอาไว้ หรือตั้ง passwordSalt เป็นค่าคงที่ แล้วเก็บ password และ passwordSalt เอาไว้ แล้วไม่ต้องเก็บ aes key
iv = secrets.randbits(256) #เก็บค่านี้เอาไว้
aes = pyaes.AESModeOfOperationCTR(key, pyaes.Counter(iv))
df['employee_id_aes'] = df['employee_id'].map(lambda x: binascii.hexlify(aes.encrypt(x)))
ตัวอย่างการถอดรหัสข้อมูลข้างต้น
decrypt_key = binascii.unhexlify(aes_key)
aes = pyaes.AESModeOfOperationCTR(decrypt_key, pyaes.Counter(iv)) #key, iv เดิมจากตอนเข้ารหัส
employee_id_decrypt = df['employee_id_aes'].map(lambda x: aes.decrypt(binascii.unhexlify(x)))
Irreversible Pseudonymisation
ในตัวอย่างนี้จะใช้ MD5 ในการเข้ารหัสพนักงาน
import hashlib
df['employee_id_md5'] = df['employee_id'].map(lambda x: hashlib.md5(x.zfill(8).encode()).hexdigest())
Data Masking
ในตัวอย่างนี้จะทำการปกปิดข้อมูล ชื่อ นามสกุล ที่อยู่ และเบอร์โทรศัพท์
import re
df['name_masked'] = df['name'].map(lambda x: x[:3] + (len(x[3:]) * '*'))
df['surname_masked'] = df['surname'].map(lambda x: x[:3] + (len(x[3:]) * '*'))
df['telephone_masked'] = df['telephone'].map(lambda x: (len(x[3:]) * '*') + x[-3:])
df['address_masked'] = df['address'].map(lambda x: re.sub("[^0-9]", "", x.split(' ')[-1]))
Record Suppression
ในตัวอย่างนี้จะทำการลบข้อมูลของ Nolan Reeves ออกไป
df.drop(df[(df['name'] == 'nolan') & (df['surname'] == 'reeves')].index, inplace=True)
Column Suppression
ในตัวอย่างนี้จะทำการลบคอลัมน์เบอร์โทรศัพท์ออกไป
df.drop('telephone', axis=1, inplace=True)
Shuffling & Permutation
df = df.apply(lambda x: x.sample(frac=1).values)
Perturbation
ในตัวอย่างนี้จะแปลงคอลัมน์อายุด้วยการ *2 แล้ว -5
df['age_masked'] = df['age'].map(lambda x: 2*x-5)
Aggregation
ในตัวอย่างนี้จะทำการจัดกลุ่มฐานเงินเดือนในข้อมูล
salary_df = pd.cut(df['salary'], [0,20000,30000,40000,50000,60000,70000], labels=['0-20000','20001-30000','30001-40000','40001-50000','50001-60000','60001-70000'])
salary_df = salary_df.value_counts().sort_index().reset_index()
salary_df.rename(columns= {'index': 'salary_range', 'salary': 'count'}, inplace=True)