Pandas & NumPy Academy · บทเรียน

การทำความสะอาดข้อมูลและวิศวกรรมคุณลักษณะ

ใช้รายการตรวจสอบการทำความสะอาดขั้นสูง สร้างคุณลักษณะจากวันที่และคอลัมน์อัตราส่วน พร้อมตรวจสอบชุดข้อมูลที่สะอาดด้วยคำสั่งยืนยัน

บทเรียน 2 จาก 413 ขั้นตอน

การทำความสะอาดข้อมูลและวิศวกรรมคุณลักษณะ เป็นบทเรียน Pandas & NumPy Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Pandas & NumPy Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Pandas & NumPy Academy มีบทเรียนทั้งหมด 4 บทเรียน

การโหลดชุดข้อมูลที่ผ่านการตรวจสอบแล้ว

ในโครงงานสรุปยอด ให้โหลดจุดตรวจสอบ Parquet ที่สะอาดซึ่งบันทึกไว้ในขั้นตอนก่อนหน้า วิธีนี้จะแยกขั้นตอนการทำความสะอาดออกจากการนำเข้าข้อมูล คุณจึงปรับปรุงตรรกะการทำความสะอาดได้โดยไม่ต้องเรียกใช้การรวมข้อมูลและการแปลงรูปแบบที่ใช้เวลานานซ้ำ อ่าน clean_orders Parquet แล้วตรวจสอบว่าจำนวนแถวและชนิดข้อมูลตรงตามที่คาดไว้จากสรุปการตรวจสอบ ไฟล์ Parquet จะเก็บรักษาชนิดข้อมูลทั้งหมด รวมถึงคอลัมน์ประเภทหมวดหมู่ จึงไม่จำเป็นต้องแปลงชนิดข้อมูลซ้ำ

import pandas as pd

# Load from checkpoint
df = pd.read_parquet('output/clean_orders.parquet')
print(f'Loaded: {df.shape}')
print(df.dtypes)
print(f'Date range: {df["order_date"].min().date()} to {df["order_date"].max().date()}')

การใช้รายการตรวจสอบการทำความสะอาดขั้นสูง

เมื่อโหลดชุดข้อมูลที่รวมแล้ว ให้ใช้รายการตรวจสอบการทำความสะอาดขั้นสูง: ลบข้อมูลซ้ำทั้งแบบตรงกันทั้งหมดและแบบบางส่วนใน order_id, จำกัดค่าผิดปกติใน unit_price โดยใช้กรอบ IQR, ทำให้ค่า category ที่ไม่สอดคล้องกันมีรูปแบบมาตรฐาน (เช่น 'Electronics' กับ 'electronics' กับ 'ELECTRONIC') และตรวจสอบว่า quantity × unit_price เป็นค่าบวกเสมอสำหรับรายการสั่งซื้อปกติ แต่ละขั้นตอนเป็นฟังก์ชันที่รับและส่งคืน DataFrame ทำให้ไปป์ไลน์สามารถทดสอบและย้อนกลับได้

import pandas as pd
import numpy as np

def remove_duplicates(df):
    n_before = len(df)
    df = df.drop_duplicates(subset=['order_id'], keep='first')
    print(f'Duplicates removed: {n_before - len(df)}')
    return df

def standardise_categories(df):
    df['category'] = (df['category']
                      .astype(str)
                      .str.strip()
                      .str.title())
    return df

def cap_price_outliers(df):
    q1, q3 = df['unit_price'].quantile([0.25, 0.75])
    iqr = q3 - q1
    upper = q3 + 3 * iqr
    df['unit_price'] = df['unit_price'].clip(upper=upper)
    return df

df = remove_duplicates(df)
df = standardise_categories(df)
df = cap_price_outliers(df)
print('Cleaning complete.')

การสร้างคุณลักษณะวันที่

ดึงคุณลักษณะด้านเวลาจากวันที่สั่งซื้อโดยใช้ตัวเข้าถึง .dt สร้างคอลัมน์ year, month, quarter, day_of_week และ week_of_year คุณลักษณะเหล่านี้ใช้ในการวิเคราะห์ด้วย groupby (เช่น รายได้รายเดือน) การกรองตามเวลา (เฉพาะไตรมาสที่ 3) และการแสดงภาพข้อมูล นอกจากนี้ให้สร้างคอลัมน์สตริง year_month (เช่น '2024-06') เพื่อใช้เป็นป้ายกำกับช่วงเวลาที่มนุษย์อ่านเข้าใจได้สำหรับแกนของแผนภูมิ

import pandas as pd

df['year'] = df['order_date'].dt.year
df['month'] = df['order_date'].dt.month
df['quarter'] = df['order_date'].dt.quarter
df['day_of_week'] = df['order_date'].dt.dayofweek  # 0=Monday
df['week'] = df['order_date'].dt.isocalendar().week.astype('int32')
df['year_month'] = df['order_date'].dt.to_period('M').astype(str)

print('Date features created:')
print(df[['order_date', 'year', 'month', 'quarter', 'year_month']].head())

การคำนวณรายได้ต่อรายการ

คุณลักษณะที่เป็นพื้นฐานที่สุดในชุดข้อมูลการขายคือรายได้ต่อรายการ: revenue = quantity × unit_price ให้สร้างเป็นคอลัมน์ใหม่ นอกจากนี้ หากมีข้อมูลต้นทุน ให้สร้างคอลัมน์ gross_margin ด้วย: margin = (price - cost) / price คอลัมน์ที่คำนวณขึ้นเหล่านี้เป็นองค์ประกอบพื้นฐานของ KPI รายได้ทั้งหมด ควรใช้การดำเนินการกับคอลัมน์แบบเวกเตอร์เสมอแทนการใช้ลูป เพราะการกำหนดค่าให้คอลัมน์ทั้งหมดในครั้งเดียวเร็วกว่าการวนทีละแถวหลายระดับ

import pandas as pd

# Line-item revenue
df['revenue'] = (df['quantity'] * df['unit_price']).astype('float32')

# Gross margin (if unit_cost column exists)
if 'unit_cost' in df.columns:
    df['gross_margin'] = (df['unit_price'] - df['unit_cost']) / df['unit_price']

# Discount flag: orders with more than 20% off list price
if 'list_price' in df.columns:
    df['is_discounted'] = df['unit_price'] < df['list_price'] * 0.8

print('Revenue stats:')
print(df['revenue'].describe().round(2))

การกำหนดกลุ่มลูกค้า

กลุ่มลูกค้าคือกลุ่มลูกค้าที่มีลักษณะบางอย่างร่วมกัน โดยทั่วไปคือช่วงเวลาที่พวกเขาซื้อสินค้าเป็นครั้งแรก ให้กำหนดลูกค้าแต่ละรายให้อยู่ในกลุ่มลูกค้าตามช่วงเวลาที่ได้มาโดยค้นหาวันที่สั่งซื้อครั้งแรก ใช้ groupby('customer_id')['order_date'].min() เพื่อคำนวณวันที่สั่งซื้อครั้งแรกของลูกค้าแต่ละราย จากนั้นสร้างคอลัมน์ cohort_month โดยแปลงวันที่ดังกล่าวเป็นช่วงปี-เดือน ป้ายกำกับกลุ่มลูกค้านี้เป็นพื้นฐานของเมทริกซ์การรักษาลูกค้าในบทเรียนถัดไป

import pandas as pd

# First purchase date per customer
first_purchase = (
    df.groupby('customer_id')['order_date']
    .min()
    .dt.to_period('M')
    .astype(str)
    .rename('cohort_month')
)

# Merge back onto orders
df = df.merge(first_purchase, on='customer_id', how='left')
print('Cohort distribution (top 5):')
print(df['cohort_month'].value_counts().head())
print(f'Distinct cohorts: {df["cohort_month"].nunique()}')

คุณลักษณะมูลค่าตลอดอายุลูกค้า

คำนวณคุณลักษณะสรุประดับลูกค้า: จำนวนคำสั่งซื้อทั้งหมด รายได้ทั้งหมด มูลค่าคำสั่งซื้อเฉลี่ย จำนวนวันที่ผ่านไปนับจากการซื้อครั้งแรก/ครั้งล่าสุด และจำนวนหมวดหมู่ที่แตกต่างกันซึ่งมีการซื้อ จากนั้นรวมข้อมูลเหล่านี้กลับเข้ากับ DataFrame หลักเป็นคอลัมน์เสริมระดับลูกค้า คุณลักษณะเหล่านี้ใช้สำหรับการแบ่งกลุ่ม (เช่น ลูกค้ามูลค่าสูงเทียบกับลูกค้ามูลค่าต่ำ) และใช้เป็นข้อมูลนำเข้าสำหรับแบบจำลองการเรียนรู้ของเครื่องที่ทำนายการเลิกใช้บริการหรือความน่าจะเป็นในการซื้อสินค้าเพิ่มเติม

import pandas as pd

customer_stats = df.groupby('customer_id').agg(
    total_orders=('order_id', 'nunique'),
    total_revenue=('revenue', 'sum'),
    avg_order_value=('revenue', 'mean'),
    categories_purchased=('category', 'nunique'),
    first_order=('order_date', 'min'),
    last_order=('order_date', 'max')
).reset_index()

customer_stats['days_as_customer'] = (
    (customer_stats['last_order'] - customer_stats['first_order'])
    .dt.days
)

print(customer_stats.describe().round(2))

การตรวจสอบโครงสร้างข้อมูลด้วยการยืนยัน

หลังจากสร้างคุณลักษณะแล้ว ให้เรียกใช้การยืนยันการตรวจสอบโครงสร้างข้อมูลเพื่อยืนยันว่าข้อมูลเป็นไปตามที่คาดไว้ก่อนส่งต่อไปยังขั้นตอนการวิเคราะห์ ตรวจสอบว่ามีคอลัมน์ที่คาดไว้ทั้งหมด รายได้ไม่ติดลบสำหรับรายการสั่งซื้อปกติ cohort_month ไม่เป็นค่าว่าง และ year_month ตรงกับปีที่วิเคราะห์ การยืนยันเหล่านี้ทำหน้าที่เป็นข้อตกลง หากข้อใดข้อหนึ่งไม่ผ่าน ไปป์ไลน์จะหยุดทันทีพร้อมข้อความข้อผิดพลาดที่ชัดเจน แทนที่จะสร้างผลลัพธ์ที่ไม่ถูกต้องโดยไม่แจ้งให้ทราบ

import pandas as pd

def validate_clean_df(df):
    required_cols = ['order_id', 'customer_id', 'revenue', 'year_month',
                     'cohort_month', 'category', 'region', 'order_date']
    missing = [c for c in required_cols if c not in df.columns]
    assert not missing, f'Missing columns: {missing}'

    assert (df['revenue'] >= 0).all(), 'Negative revenue found'
    assert df['cohort_month'].notna().all(), 'Null cohort_month values'
    assert df['order_date'].notna().all(), 'Null order dates'
    print(f'Validation passed: {len(df):,} rows, {len(df.columns)} columns')

validate_clean_df(df)

การจัดการหมวดหมู่ที่มีความถี่ต่ำ

ในชุดข้อมูลจริง หมวดหมู่หรือภูมิภาคบางรายการอาจปรากฏเพียงไม่กี่ครั้ง ซึ่งน้อยเกินไปสำหรับการวิเคราะห์ที่มีความหมาย ให้แทนค่าที่มีความถี่ต่ำด้วย'Other'เพื่อหลีกเลี่ยงแผนภูมิที่เต็มไปด้วยหมวดหมู่ซึ่งมีคำสั่งซื้อเพียงรายการเดียวหลายสิบรายการ เกณฑ์ที่ใช้งานได้จริงคือ ค่าที่ปรากฏน้อยกว่า 0.5% ของแถวทั้งหมดจะถูกรวมเข้าด้วยกัน วิธีนี้สำคัญต่อการเรียนรู้ของเครื่องด้วย เพราะการเข้ารหัสแบบ one-hot สำหรับหมวดหมู่หายาก 200 รายการทำให้สิ้นเปลืองหน่วยความจำและเพิ่มสัญญาณรบกวน

import pandas as pd

def collapse_rare_values(df, col, min_pct=0.005):
    threshold = len(df) * min_pct
    counts = df[col].value_counts()
    rare = counts[counts < threshold].index
    n_rare = len(rare)
    df[col] = df[col].apply(lambda x: 'Other' if x in rare else x)
    print(f'{col}: collapsed {n_rare} rare values into "Other"')
    return df

df = collapse_rare_values(df, 'category', min_pct=0.005)
df = collapse_rare_values(df, 'region', min_pct=0.005)
print('Category distribution after collapsing:')
print(df['category'].value_counts())

การบันทึกชุดข้อมูลที่สร้างคุณลักษณะแล้ว

บันทึก DataFrame ที่ทำความสะอาดและสร้างคุณลักษณะเสร็จสมบูรณ์แล้วเป็นจุดตรวจสอบ Parquet นี่คือชุดข้อมูลพร้อมสำหรับการวิเคราะห์ ซึ่งเป็นผลลัพธ์จากขั้นตอนการนำเข้า การทำความสะอาด และการสร้างคุณลักษณะทั้งหมด ขั้นตอนถัดไปของไปป์ไลน์ (การคำนวณ KPI การแสดงภาพข้อมูล และการจัดทำรายงาน) จะอ่านข้อมูลจากจุดตรวจสอบนี้ จุดตรวจสอบยังทำหน้าที่เป็นผลงานส่งมอบด้วย โดยสามารถแบ่งปันให้สมาชิกทีม หรืออัปโหลดไปยังทะเลสาบข้อมูลเพื่อให้ผู้อื่นเรียกใช้ด้วย SQL หรือ Pandas

import pandas as pd

# Convert category columns back to Categorical for memory efficiency
for col in ['category', 'region', 'acquisition_channel']:
    if col in df.columns:
        df[col] = df[col].astype('category')

# Save analysis-ready dataset
df.to_parquet('output/analysis_ready.parquet', index=False)

# Also save customer stats for segmentation
customer_stats.to_parquet('output/customer_stats.parquet', index=False)

print(f'Analysis-ready dataset: {df.shape}')
print(f'Memory usage: {df.memory_usage(deep=True).sum()/1e6:.1f} MB')

สรุปการสร้างคุณลักษณะ

การสร้างคุณลักษณะที่ดีต้องสร้างสมดุลระหว่างการเพิ่มสัญญาณที่ช่วยในการพยากรณ์กับการทำให้ไปป์ไลน์เข้าใจและทดสอบได้ง่าย คุณลักษณะที่สร้างในขั้นตอนนี้ ได้แก่ รายได้ ส่วนประกอบของวันที่ cohort_month สถิติลูกค้า และหมวดหมู่ที่รวมแล้ว ล้วนขับเคลื่อนโดยเป้าหมายการวิเคราะห์ที่กำหนดไว้ในการตั้งค่าโครงงาน อย่าสร้างคุณลักษณะจำนวนมากโดยไม่มีเป้าหมายเพียงเพราะอาจมีประโยชน์ สำหรับคุณลักษณะแต่ละรายการ ให้ถามว่า คุณลักษณะนี้จะถูกใช้ใน KPI หรือการแสดงภาพข้อมูลอย่างน้อยหนึ่งรายการหรือไม่ หากไม่ใช่ ให้เลื่อนการสร้างออกไป รักษาชุดข้อมูลพร้อมสำหรับการวิเคราะห์ให้กระชับและมีจุดมุ่งหมาย

import pandas as pd

# Summary of engineered features
df = pd.read_parquet('output/analysis_ready.parquet')

original_cols = ['order_id', 'customer_id', 'order_date', 'quantity', 'unit_price']
engineered_cols = [c for c in df.columns if c not in original_cols]

print('Original columns:', original_cols)
print('Engineered features:', engineered_cols)
print(f'Total columns: {len(df.columns)}')
print(f'Total rows: {len(df):,}')

การบันทึกการตัดสินใจในโค้ด

สำหรับการตัดสินใจด้านการทำความสะอาดหรือการสร้างคุณลักษณะที่ไม่ชัดเจนทุกครั้ง ให้เพิ่มความคิดเห็นที่อธิบายเหตุผล คุณในอนาคต (หรือสมาชิกทีม) อาจจำไม่ได้ว่าเหตุใดจึงตั้งตัวคูณ IQR เป็น 3 แทนที่จะเป็น 1.5 หรือเหตุใดจึงใช้ 0.5% เป็นเกณฑ์ของหมวดหมู่หายาก ความคิดเห็นในโค้ดและบันทึกการตัดสินใจ (รายการง่าย ๆ ใน README ของโครงงานหรือไฟล์มาร์กดาวน์) ช่วยให้ดูแลรักษาและตรวจสอบไปป์ไลน์ได้ง่าย โค้ดที่สะอาดและมีเอกสารประกอบคือผลงานส่งมอบที่แท้จริง ส่วนไฟล์ผลลัพธ์เป็นเพียงผลที่ตามมา

# Engineering decisions log
DECISIONS = '''
# Data Cleaning & Feature Engineering Decisions

## Duplicate handling
Kept first occurrence of duplicate order_id (most likely the original order).

## Outlier capping
Unit price capped at Q3 + 3*IQR (not 1.5*IQR) because price distribution
has legitimate high-value enterprise orders that should not be removed.

## Rare category threshold: 0.5%
Values below 0.5% of total orders collapsed to "Other" to keep charts readable
and avoid spurious significance in category-level tests.

## Cohort assignment
Cohort = first purchase calendar month (not signup month), because many users
sign up but do not purchase until months later.
'''
print(DECISIONS)

ตรวจสอบความเข้าใจอย่างรวดเร็ว

ทดสอบความเข้าใจแนวคิดการวิเคราะห์ข้อมูลจากบทเรียนนี้

ทบทวนบทเรียน

ในบทเรียนนี้ คุณได้เรียนรู้ว่า ฟังก์ชันการทำความสะอาดแบบแยกส่วน (ลบข้อมูลซ้ำ จำกัดค่าผิดปกติ และทำให้หมวดหมู่มีรูปแบบมาตรฐาน) แต่ละฟังก์ชันรับและส่งคืน DataFrame เพื่อให้ทดสอบได้ง่าย, การสร้างคุณลักษณะสร้างส่วนประกอบของวันที่ รายได้ต่อรายการ กลุ่มลูกค้า และสถิติสรุป และการยืนยันการตรวจสอบโครงสร้างข้อมูลช่วยควบคุมการเปลี่ยนผ่านจากการทำความสะอาดไปสู่การวิเคราะห์ ขั้นต่อไป เราจะคำนวณ KPI หลักของโครงงาน ได้แก่ การรักษาลูกค้าตามกลุ่มรายเดือน รายได้ของผลิตภัณฑ์ และผู้ใช้งานที่ใช้งานอยู่แบบสะสม

เริ่มต้นได้ฟรี

เรียนรู้ Python ด้วย AI tutor — ฟรี

เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป

คอร์ส
30
บทเรียน
120

คำถามที่พบบ่อย

บทเรียน “การทำความสะอาดข้อมูลและวิศวกรรมคุณลักษณะ” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การทำความสะอาดข้อมูลและวิศวกรรมคุณลักษณะ” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Pandas & NumPy Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Pandas & NumPy Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การทำความสะอาดข้อมูลและวิศวกรรมคุณลักษณะ”

ใช้รายการตรวจสอบการทำความสะอาดขั้นสูง สร้างคุณลักษณะจากวันที่และคอลัมน์อัตราส่วน พร้อมตรวจสอบชุดข้อมูลที่สะอาดด้วยคำสั่งยืนยัน คุณปฏิบัติ Pandas & NumPy Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Pandas & NumPy Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Pandas & NumPy Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน

บทเรียน “การทำความสะอาดข้อมูลและวิศวกรรมคุณลักษณะ” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Pandas & NumPy Academy นี้ได้ไหม

ได้ บทเรียน Pandas & NumPy Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การตั้งค่าโครงการและการนำเข้าข้อมูล
  2. การทำความสะอาดข้อมูลและวิศวกรรมคุณลักษณะ
  3. การวิเคราะห์และการคำนวณ KPI
  4. การแสดงผลขั้นสุดท้ายและการส่งออกรายงาน
← กลับไปที่ Pandas & NumPy Academy