Model
จัดระเบียบ fact, dimension, entity และเวลา
OLAP → FEATURE ENGINEERING → FEATURE STORAGE
OLAP มอบประวัติศาสตร์ ขนาด และ analytical operator ที่ Feature Engineering ต้องใช้ ส่วน Feature Storage เปลี่ยนผลลัพธ์ที่เลือกแล้วให้เป็น data product ที่คงทน สร้าง training ซ้ำได้ มีประสิทธิภาพสำหรับ batch scoring และเมื่อจำเป็นก็เร็วพอสำหรับ online prediction
จัดระเบียบ fact, dimension, entity และเวลา
สร้าง window และ point-in-time feature ในระดับใหญ่
Materialize ประวัติศาสตร์และค่าล่าสุดอย่างมีเจตนา
เลือก storage ให้เหมาะกับ batch หรือ online latency
01 · REFERENCE ARCHITECTURE
Data Plane เคลื่อนย้ายและคำนวณค่า ส่วน Control Plane นิยามว่าค่าเหล่านั้นหมายถึงอะไร ใครเป็นเจ้าของ ควรสดเพียงใด และมีโมเดลใดพึ่งพาอยู่
02 · WHY OLAP IS A STRONG FEATURE SOURCE
OLAP ไม่ได้ถูกต้องสำหรับ ML โดยอัตโนมัติ แต่การออกแบบเชิงกายภาพและตรรกะใกล้กับงานคำนวณ Feature มากกว่าฐานข้อมูลระบบงาน
Fact, snapshot และ slowly changing dimension ช่วยสร้างสถานะในอดีตซ้ำ แทนการเขียนทับ
ตาราง orders, line items, sessions และ customer-day ระบุชัดว่าหนึ่งแถวหมายถึงอะไร
อ่านเฉพาะคอลัมน์ ตัด partition ที่ไม่เกี่ยวข้อง และบีบอัดค่าซ้ำในการ scan ขนาดใหญ่
Distributed engine คำนวณหลาย entity และ time window พร้อมกันได้
Conformed dimension และ metric ที่ review แล้วลดการตีความ source ซ้ำ
ตรวจยอดและ coverage ของ Feature เทียบกับ fact ที่กำกับดูแลแล้วก่อนเผยแพร่
03 · HOW OLAP SEES DATA
OLAP จัดข้อมูลเพื่อเปรียบเทียบข้ามเวลา สินค้า ลูกค้า ภูมิศาสตร์ ช่องทาง และสถานการณ์ Warehouse และ Lakehouse สมัยใหม่ทำ Cube-like Analysis ด้วย Columnar Table และ Distributed Engine
time = 2026-08market = SETinstrument = GOLDcell → SUM(volume), AVG(spread)กิจกรรมทองคำเดือนสิงหาคมข้ามทุกตลาด
ทองคำและเงิน ตลาดเอเชีย ช่วง Q1–Q2
ปี → ไตรมาส → วัน → รายการซื้อขาย
หลักทรัพย์ → Sector → ตลาด
ตลาดแยกเดือน แทนเดือนแยกตลาด
Rolling Demand, Growth และ Volatility
04 · FACT, DIMENSION AND GRAIN
ก่อน Aggregate ต้องระบุว่าหนึ่งแถวหมายถึงอะไร Grain รายวัน ระดับ Event และ Snapshot ตอบคนละคำถามและมีต้นทุนต่างกันมาก
day · week · month · year
symbol · asset_class · sector
instrument × market × observation_time
price · volume · bid · ask · open_interest
exchange · country · session
actual · forecast · base · stress
ขนาดเล็กสำหรับ Portfolio Research แต่สร้าง Intraday Order Book ซ้ำไม่ได้
รองรับ Microstructure แต่ใช้ Storage, Ordering และ Compute สูงมาก
เหมาะกับ Exposure Trend แต่ไม่เห็นการเปลี่ยนแปลงระหว่าง Snapshot
05 · WHERE OLAP IS USED
Analytical Model เดียวกันรองรับ Dashboard, Investigation, Planning, Feature Engineering, Control และ Audit
Liquidity, Exposure, Credit, Fraud, Treasury และ Scenario
Sales Mix, Basket, Promotion, Inventory และ Cohort
Yield, Downtime, Quality, Energy และ Maintenance
Traffic, Congestion, Quality, Churn และ Incident
Capacity, Waiting, Pathway และ Cost ภายใต้ Privacy Control
Demand Curve, Generation, Outage, Weather และ Price
งบประมาณ การให้บริการ ภูมิศาสตร์ โครงการ และ Outcome
Funnel, Retention, Experiment และ Unit Economics
OLAP จะมีประโยชน์เมื่อเราระบุการตัดสินใจให้ชัด “วิเคราะห์ลูกค้า” กว้างเกินไป แต่ “ทุกวันจันทร์ ลูกค้าคนใดมีแนวโน้มหยุดซื้อภายใน 30 วัน” ระบุ entity, observation time, horizon และ action ได้ หลักคิดเดียวกันใช้ได้ทุกอุตสาหกรรม
Grain ที่ใช้ได้ เช่น account-day, instrument-minute, customer-week และ basket-line โดยต้องระบุหน่วยเงิน สกุลเงิน venue และ event time ให้ชัด
แยก Grain ระดับ machine-cycle, production-batch, asset-hour และ meter-interval ออกจากกัน การยุบรวมทำให้ค่าเฉลี่ยหลอกและซ่อน downtime
Grain ระดับ network-event, subscriber-hour, session และ experiment-assignment ตอบคนละคำถาม ต้องเก็บเวลา assignment เพื่อไม่ให้ Feature ของ experiment ปนกัน
Grain ระดับ encounter, patient-day, facility-week, service-request และ project-month ต้องมีขอบเขตความเป็นส่วนตัวและ organizational dimension ที่เปลี่ยนตามเวลา
ณ [observation time] สำหรับ [entity] แต่ละราย ให้คำนวณ [measure/window] จาก event ที่ระบบรับรู้แล้วในเวลานั้น แยกตาม [dimensions] เพื่อสนับสนุน [decision] ภายใน [horizon]06 · GOLD DEMAND AND SUPPLY
Physical Flow, ETF Holding, Futures Positioning, Inventory และ Liquidity เกี่ยวข้องกันแต่ใช้แทนกันไม่ได้ OLAP รักษาหน่วย ความถี่ Source และ Publication Time ก่อน Feature Engineering นำมารวม
Physical Supply ลบ Demand โดยรักษา Publication Lag และ Revision
ETF Holding Change เทียบประวัติตนเอง ไม่ใช่ Physical Demand ทั้งหมด
สัญญาไกลเทียบสัญญาใกล้โดยควบคุม Roll Convention
Inventory Change พร้อม Availability Timestamp
ราคาที่สูงขึ้นไม่ได้พิสูจน์ตรง ๆ ว่า Physical Demand มากกว่า Supply เพราะความคาดหวัง ค่าเงิน อัตราดอกเบี้ย Liquidity และ Positioning มีผลต่อราคาเช่นกัน
ข้อมูลทองคำมาถึงด้วย Grain และรอบเผยแพร่ที่เข้ากันไม่ได้ Trade อาจละเอียดระดับเสี้ยววินาที ETF Holding รายวัน Inventory รายวันหรือรายสัปดาห์ และ Mine Production รายไตรมาสพร้อม revision ควรเก็บตารางต้นทางแต่ละชนิดก่อน แล้วจึงทำ point-in-time join ด้วยเวลาที่ข้อมูลพร้อมให้ใช้ ไม่ใช่ดูเพียงช่วงเวลาที่ข้อมูลอธิบาย
ที่ Grain รายไตรมาส แยก mine production และ recycling เป็น supply ส่วน jewellery, technology, bar/coin investment และ official-sector net purchase เป็น demand โดยรักษาหน่วย tonnes และ revision vintage
แปลง Holding ของกองทุนเป็นหน่วยโลหะเดียวกัน หาผลต่างตาม report date รวมหลัง align source แล้วจึง standardize เทียบประวัติย้อนหลัง
เลือกสัญญาใกล้และไกลตาม roll calendar ที่บันทึกไว้ ห้ามต่อรหัสสัญญาโดยไม่มีกฎ roll
เก็บ location, inventory category, unit, report date และ available_at พร้อมเก็บ correction เป็น data vintage ใหม่เพื่อสร้าง training ซ้ำได้
mine = 900 t, recycling = 300 t
jewellery = 520 t, technology = 80 t
investment = 410 t, official = 140 t
physical_balance = (900 + 300) - (520 + 80 + 410 + 140) = +50 t
ความหมาย: +50 t ภายใต้ classification และ data vintage นี้ ต้องตรวจว่ารายงานเผยแพร่ก่อน observation time แล้ว07 · STOCK DEMAND, SUPPLY AND LIQUIDITY
Supply เชิงโครงสร้างเกี่ยวข้องกับ Shares และ Free Float ส่วน Demand/Supply ที่พร้อม Execute ปรากฏเป็น Bid/Ask และ Trade แสดงเฉพาะ Activity ที่จับคู่แล้ว
สัดส่วน Displayed Bid/Ask ที่ Align ตาม Venue และเวลา
Quoted Spread หาร Mid-price เป็น Liquidity Descriptor หนึ่งตัว
Volume เทียบ Free Float ที่ปรับ Corporate Action
การกระจาย Return ในอดีต ไม่รับประกันความเสี่ยงอนาคต
หุ้นมี “Supply” หลายความหมาย Shares Outstanding คือหน่วยความเป็นเจ้าของที่ออกแล้ว Free Float ประมาณหุ้นที่หมุนเวียนซื้อขายได้มากกว่า Ask Book แสดงคำสั่งขายที่เปิดเผยในขณะนั้น ส่วน Executed Volume เก็บเฉพาะรายการที่จับคู่แล้ว ทั้งหมดควรอยู่คนละ fact table และคนละ time grain
เก็บ effective_from/effective_to ของ shares outstanding และ float พร้อมปรับ denominator ในอดีตเมื่อเกิด split, reverse split, rights, buyback และการออกหุ้นใหม่
Feature จาก Order Book ต้องมี venue, sequence number และ event time คำสั่งอาจถูกยกเลิกหรือซ่อน Displayed Depth จึงเป็นเจตนาที่สังเกตได้ ไม่ใช่ Demand ที่รับประกัน
Trade แสดงว่าผู้ซื้อและผู้ขายจับคู่กันแล้ว แต่ไม่เปิดเผยเจตนาที่ไม่ได้ execute ทั้งหมด ควร Aggregate ตาม instrument–venue–interval ก่อนเปรียบเทียบตลาด
ใช้ราคาที่ปรับ corporate action และกำหนด return interval ให้ชัด ช่วงข้อมูลหาย ตลาดปิด และการซื้อขายบางทำให้ความหมายของ volatility เปลี่ยน
best_bid = 101.50, bid_size = 4,300
best_ask = 102.00, ask_size = 3,100
mid = (101.50 + 102.00) / 2 = 101.75
relative_spread = 0.50 / 101.75 = 0.4914%
book_imbalance_l1 = (4,300 - 3,100) / (4,300 + 3,100) = 0.1622
ความหมาย: ขณะนี้ขนาดที่แสดงใน L1 เอนมาทาง Bid แต่ไม่ได้พิสูจน์ว่าราคาต้องขึ้น เพราะคำสั่งอาจถูกยกเลิก มี Hidden Liquidity และระดับลึกกว่านี้อาจให้ภาพตรงข้าม08 · OTHER FINANCIAL PATTERNS
ตัวอย่างนี้เป็น Data Product และ Feature ไม่ใช่การพยากรณ์กำไรหรือคำแนะนำลงทุน
net_exposure_7d · basis_change · cash_gap
utilization_3m · payment_ratio · missed_count_12m
sector_weight · duration · concentration · drawdown
velocity_1h · new_device_7d · circular_flow_score
claim_frequency · loss_ratio · reporting_delay
surprise_vs_consensus · revision_size · trend_3m
09 · SQL EXAMPLE: DAILY MARKET FEATURES
ข้อมูลจริงต่างกันตาม Venue, License, Session, Corporate-action Convention และ Timestamp Precision
WITH daily AS (
SELECT instrument_key, trading_date,
MAX(adjusted_close) AS close,
SUM(volume) AS volume,
AVG((ask-bid)/NULLIF((ask+bid)/2,0)) AS relative_spread
FROM analytics.fact_market_observation
WHERE available_at <= trading_date + INTERVAL '1 day'
GROUP BY instrument_key, trading_date
), returns AS (
SELECT *, LN(close/NULLIF(LAG(close) OVER
(PARTITION BY instrument_key ORDER BY trading_date),0)) AS return_1d
FROM daily
)
SELECT instrument_key, trading_date AS feature_date,
volume, relative_spread, return_1d,
AVG(volume) OVER (PARTITION BY instrument_key ORDER BY trading_date
ROWS BETWEEN 19 PRECEDING AND CURRENT ROW) AS avg_volume_20obs,
STDDEV_SAMP(return_1d) OVER (PARTITION BY instrument_key ORDER BY trading_date
ROWS BETWEEN 19 PRECEDING AND CURRENT ROW) AS volatility_20obs
FROM returns;
ต้องกำหนด Adjustment, Holiday, Missing Price, Listing, Delisting, Session, Revision และ Licensing เพราะ SQL ที่รันถูกยังสร้าง Data Product ที่ผิดได้
03 · BUILD A FEATURE SPINE
Entity Spine ยึดหนึ่ง entity ไว้กับหนึ่ง prediction time ทุก Feature ต้อง join เข้ากับแถวนั้นโดยไม่ใช้ข้อมูลที่มาถึงภายหลัง
1012026-08-01 09:002026-08-081012026-08-15 09:002026-08-22[orders_30d,
spend_90d,
days_since_last_order,
segment_v3]04 · FEATURE ENGINEERING LAYERS
ไม่ควรใส่ทุก transformation ไว้ใน Feature Query ขนาดใหญ่เพียงชุดเดียว การแบ่งชั้นทำให้เห็น ownership, testing, reuse และต้นทุน
Event ที่ไม่แก้ไขหรือ replay ได้ พร้อม source timestamp และ ingestion metadata
ชนิดข้อมูล deduplication, key, นโยบายข้อมูลมาช้า และ quality flag
Fact, dimension, entity-day aggregate และกฎธุรกิจที่ review แล้ว
Point-in-time window, encoding, default และ Feature Version
Historical offline row, batch snapshot และค่าล่าสุดแบบ online
05 · SQL LAB: MATERIALIZE FEATURES
ตารางที่ build แบบ incremental เป็นรูปแบบหนึ่งของ Offline Feature Store ส่วน syntax จริงขึ้นกับ Warehouse หรือ Lakehouse ที่ใช้
CREATE TABLE IF NOT EXISTS features.customer_activity_daily (
customer_id BIGINT NOT NULL,
feature_date DATE NOT NULL,
orders_30d INTEGER NOT NULL,
spend_30d DECIMAL(14,2) NOT NULL,
days_since_order INTEGER,
feature_version VARCHAR(30) NOT NULL,
computed_at TIMESTAMP NOT NULL,
PRIMARY KEY (customer_id, feature_date, feature_version)
);
-- Build only the affected feature_date partition.
INSERT INTO features.customer_activity_daily
SELECT
c.customer_id,
:feature_date,
COUNT(o.order_id),
COALESCE(SUM(o.net_amount), 0),
DATE_PART('day', :feature_date - MAX(o.order_date)),
'customer_activity_v1',
CURRENT_TIMESTAMP
FROM analytics.dim_customer c
LEFT JOIN analytics.fact_order o
ON o.customer_id = c.customer_id
AND o.order_date >= :feature_date - INTERVAL '30 days'
AND o.order_date < :feature_date
AND o.is_completed = TRUE
GROUP BY c.customer_id
ON CONFLICT (customer_id, feature_date, feature_version)
DO UPDATE SET
orders_30d=EXCLUDED.orders_30d,
spend_30d=EXCLUDED.spend_30d,
days_since_order=EXCLUDED.days_since_order,
computed_at=EXCLUDED.computed_at;หากไม่มีเวลา observation ค่า spend_30d จะสร้างซ้ำหรือเปรียบเทียบไม่ได้ การเก็บเฉพาะค่าล่าสุดอาจรองรับ online prediction แต่สร้าง historical training set ซ้ำไม่ได้
06 · WHY MATERIALIZED FEATURES CAN OUTRUN A VIEW
VIEW ปกติโดยทั่วไปเก็บ SQL ไม่ได้เก็บผลลัพธ์ ทุก query จึงอาจทำ join, filter, window และ aggregation ซ้ำ ส่วน Materialized Feature Table จ่ายต้นทุนตอน Build ทำให้การอ่านภายหลังแคบและคาดการณ์ได้มากกว่า
Materialized Feature อาจเร็วกว่า Logical VIEW ที่ซับซ้อนมาก เมื่อหลีกเลี่ยง scan และ join ซ้ำ แบ่ง partition ตรงกับรูปแบบการอ่าน และมีขนาดเหมาะสม แต่ไม่ได้เร็วกว่าเสมอ Database อาจ optimize หรือ cache VIEW ง่าย ๆ ได้ดี ตาราง materialized อาจเก่าหรือจัด cluster ไม่เหมาะ และการ Build Feature ที่ไม่มีผู้ใช้ยิ่งเปลืองกว่าสิ่งที่ประหยัดได้ ต้อง benchmark ด้วย query, ปริมาณข้อมูล, concurrency และ freshness target จริง
07 · PERFORMANCE LEVERS
การคำนวณล่วงหน้าเพียงอย่างเดียวยังไม่ใช่สถาปัตยกรรม ผลลัพธ์ที่เก็บต้องสอดคล้องกับเส้นทางการเข้าถึงและข้อจำกัดเชิงปฏิบัติ
แบ่ง Historical Feature ด้วย feature_date หรือขอบเขตเวลาหลัก เพื่อให้ training ข้ามประวัติศาสตร์ที่ไม่เกี่ยวข้อง
จัดแถวตาม entity และเวลา เพื่อลด block ที่ต้องอ่านใน point-in-time retrieval
อ่านเฉพาะคอลัมน์ Feature ที่ใช้ หลีกเลี่ยงตารางกว้างมากเมื่อแต่ละโมเดลใช้คนละกลุ่ม Feature
คำนวณเฉพาะวันที่และ entity ที่กระทบแทนทั้งประวัติศาสตร์ พร้อมนิยามว่าข้อมูลมาช้าเปิด partition เก่าอย่างไร
เก็บ customer-day หรือ entity-hour ขั้นกลาง เพื่อให้ rolling window หลายชุดใช้ input ที่เล็กลงร่วมกัน
สำหรับ online inference ให้ materialize เฉพาะ vector ล่าสุดที่อนุมัติ keyed ด้วย entity พร้อม atomic update และ TTL เมื่อเหมาะสม
Cache ช่วยการอ่านซ้ำที่ร้อน แต่ต้องมี invalidation, capacity และ correctness rule และไม่แทน Historical Storage
หลีกเลี่ยงไฟล์เล็กจำนวนมากใน Lakehouse การ compaction ช่วย metadata และประสิทธิภาพ scan
08 · STORE EACH FEATURE ON PURPOSE
นิยามควรยังเป็น concept เดียวที่กำกับดูแลได้ แม้ History, Batch Snapshot และ Online Value ใช้ Storage Engine ต่างกัน
ประวัติศาสตร์แบบ point-in-time สำหรับ training, evaluation, audit และ backfill
customer_id, feature_date, value, versionInput ที่ freeze สำหรับ campaign หรือ scoring run หนึ่งรอบ ช่วย reproducibility
run_id, customer_id, feature_vectorLookup ขนาดเล็ก latency ต่ำสำหรับ prediction request ส่วนประวัติศาสตร์ยังอยู่ offline
customer_id → {features, timestamp, version}09 · QUALITY, FRESHNESS AND COST
Materialization สร้าง data product ที่มี state ใหม่ จึงต้อง monitor จริงจังพอ ๆ กับ source และ model
10 · DECISION GUIDE
เลือก representation ที่เรียบง่ายที่สุดซึ่งยังตอบ correctness, reuse, freshness, latency และ recovery
ใช้เมื่อความสดสำคัญ แผน query มีประสิทธิภาพ และ compute ซ้ำมีต้นทุนต่ำ
ใช้กับ training ที่สร้างซ้ำ heavy window, หลายโมเดล หรือ batch scoring ที่คงที่
ใช้เมื่อ request รอ Warehouse Compute ไม่ได้ และ Sync ค่าล่าสุดได้อย่างเชื่อถือ
สร้าง Entity-Time Summary ที่ใช้ซ้ำ ก่อนสร้าง Feature คล้ายกันนับร้อย
THE CENTRAL IDEA