AI Engineering Academy · บทเรียน

การดึงข้อมูลแบบหนาแน่นเทียบกับแบบเบาบาง: จุดแลกเปลี่ยน

ทำความเข้าใจว่าเมื่อใดเวกเตอร์ฝังแบบหนาแน่นพลาดคำสำคัญที่ตรงกันทุกประการ และเมื่อใด BM25 พลาดการถอดความเชิงความหมาย รวมถึงเหตุใดการใช้ทั้งสองแบบร่วมกันจึงให้ผลดีกว่าแต่ละแบบอย่างสม่ำเสมอ

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

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

สัญญาณการค้นคืนสองแบบที่แตกต่างกันโดยพื้นฐาน

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

การทำงานของเวกเตอร์แทนความหมายแบบหนาแน่น

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

from openai import OpenAI
import numpy as np

client = OpenAI()

def embed(text: str) -> list[float]:
    resp = client.embeddings.create(
        model='text-embedding-3-small',
        input=text,
    )
    return resp.data[0].embedding

def cosine_similarity(a, b):
    a, b = np.array(a), np.array(b)
    return float(np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b)))

q = embed('How do I cancel my subscription?')
d = embed('Steps to unsubscribe from the service')
print(cosine_similarity(q, d))  # high similarity despite different words

จุดที่การค้นคืนแบบหนาแน่นล้มเหลว

โมเดลแบบหนาแน่นทำงานได้ไม่ดีเมื่อพบ คำที่พบได้ยาก ซึ่งมีสัดส่วนน้อยระหว่างการฝึกตัวเข้ารหัส คำค้นที่มีหมายเลขรุ่นผลิตภัณฑ์เฉพาะอย่าง RTX-4090-Ti-OC ชื่อยาทางการแพทย์ หรือตัวระบุภายในที่เป็นกรรมสิทธิ์ มักไม่ตรงกับเอกสารที่ถูกต้อง เพราะตัวเข้ารหัสไม่มีการแทนค่าลำดับโทเคนนั้นที่เรียนรู้ไว้ เวกเตอร์จึงไปอยู่ในตำแหน่งที่ไม่เป็นประโยชน์ในปริภูมิเวกเตอร์แทนความหมาย

การทำงานของการค้นคืนแบบเบาบาง BM25

BM25 (Best Matching 25) เป็นฟังก์ชันจัดอันดับเชิงความน่าจะเป็นที่ให้คะแนนเอกสารตามความถี่ที่คำค้นปรากฏในเอกสาร โดยปรับตามความยาวเอกสารและลดผลของการอิ่มตัวของความถี่คำ ผลลัพธ์คือ เวกเตอร์คะแนนแบบเบาบาง ซึ่งมิติส่วนใหญ่เป็นศูนย์ เพราะเอกสารมีคำศัพท์เพียงส่วนน้อยของคลังคำศัพท์ทั้งหมด

# BM25 scoring formula (conceptual)
# score(D, Q) = sum over query terms t of:
#   IDF(t) * (tf(t,D) * (k1 + 1)) / (tf(t,D) + k1 * (1 - b + b * |D|/avgdl))

# k1 controls term frequency saturation (typically 1.2-2.0)
# b controls document length normalization (typically 0.75)
# IDF(t) = log((N - df(t) + 0.5) / (df(t) + 0.5))

# N = total documents, df(t) = documents containing term t
# tf(t,D) = frequency of t in document D, |D| = doc length, avgdl = average doc length

จุดแข็งของ BM25: คำตรงและศัพท์เฉพาะ

BM25 โดดเด่นกับคำค้นที่มี ศัพท์เทคนิค ชื่อผลิตภัณฑ์ รหัสข้อผิดพลาด และตัวระบุที่เป็นตัวเลขแบบตรงกันทุกประการ ซึ่งควรจับคู่ให้แม่นยำ คำค้น ORA-01017 (รหัสข้อผิดพลาดของ Oracle) จะจัดอันดับเอกสารที่มีสตริงตรงกันนี้ไว้สูงกว่าเอกสารที่เพียงพูดถึงการตรวจสอบสิทธิ์ฐานข้อมูลโดยทั่วไปอย่างมาก สิ่งนี้เป็นไปไม่ได้สำหรับโมเดลแบบหนาแน่นที่ไม่เคยพบรหัสดังกล่าวมาก่อน

from rank_bm25 import BM25Okapi

corpus = [
    'Oracle database ORA-01017 invalid username or password logon denied',
    'Database authentication and connection troubleshooting guide',
    'How to resolve login errors in Oracle and MySQL databases',
]

tokenized_corpus = [doc.lower().split() for doc in corpus]
bm25 = BM25Okapi(tokenized_corpus)

query = 'ORA-01017 error fix'
scores = bm25.get_scores(query.lower().split())
print(dict(zip(range(len(corpus)), scores)))
# doc 0 scores highest because it contains ORA-01017

จุดที่ BM25 ล้มเหลว: การถอดความและคำพ้องความหมาย

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

from rank_bm25 import BM25Okapi

corpus = [
    'automobile engine repair and maintenance tips',
    'car motor maintenance guide for beginners',
    'vehicle powertrain service intervals',
]
tokenized = [doc.split() for doc in corpus]
bm25 = BM25Okapi(tokenized)

scores = bm25.get_scores(['car', 'motor', 'maintenance'])
print(scores)
# doc 1 scores high, doc 0 and 2 score lower despite being semantically related

หลักฐานจากการทดสอบมาตรฐาน: แบบผสมชนะอย่างสม่ำเสมอ

การทดสอบมาตรฐานบน BEIR, MS MARCO และชุดข้อมูลถาม-ตอบระดับองค์กรแสดงอย่างสม่ำเสมอว่า การค้นคืนแบบผสมมีประสิทธิภาพเหนือกว่าการค้นคืนแบบหนาแน่นหรือแบบเบาบางเพียงอย่างเดียว 5-15 เปอร์เซ็นต์ในด้าน NDCG@10 การปรับปรุงมีมากที่สุดในชุดข้อมูลที่ผสมคำค้นเพื่อค้นหาข้อเท็จจริง (ซึ่ง BM25 ช่วยได้) กับคำค้นแบบถอดความ (ซึ่งเวกเตอร์แทนความหมายแบบหนาแน่นช่วยได้) ไม่มีวิธีค้นคืนใดวิธีเดียวที่เด่นที่สุดสำหรับคำค้นทุกประเภท

การวิเคราะห์ประเภทคำค้น: เครื่องมือค้นคืนใดชนะ

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

# Query type heuristics
def predict_retriever_advantage(query: str) -> str:
    tokens = query.split()
    has_numbers = any(t[0].isdigit() for t in tokens)
    has_uppercase_acronyms = any(t.isupper() and len(t) > 2 for t in tokens)
    is_short = len(tokens) <= 4

    if has_numbers or has_uppercase_acronyms:
        return 'BM25 likely wins (exact terms)'
    elif is_short:
        return 'Dense likely wins (semantic matching needed)'
    else:
        return 'Hybrid recommended (mixed signals)'

ปัญหาคะแนนเข้ากันไม่ได้

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

การตัดสินใจเชิงปฏิบัติ: ควรใช้แต่ละวิธีเมื่อใด

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

ข้อแลกเปลี่ยนด้านประสิทธิภาพและโครงสร้างพื้นฐาน

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

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

ทดสอบความเข้าใจของคุณเกี่ยวกับข้อแลกเปลี่ยนระหว่างการค้นคืนแบบหนาแน่นและแบบเบาบางจากบทเรียนนี้

สรุปบทเรียน

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

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

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

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

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

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

บทเรียน “การดึงข้อมูลแบบหนาแน่นเทียบกับแบบเบาบาง: จุดแลกเปลี่ยน” ฟรีหรือไม่

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

คุณจะเรียนรู้อะไรในบทเรียน “การดึงข้อมูลแบบหนาแน่นเทียบกับแบบเบาบาง: จุดแลกเปลี่ยน”

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

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

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

บทเรียน “การดึงข้อมูลแบบหนาแน่นเทียบกับแบบเบาบาง: จุดแลกเปลี่ยน” ใช้เวลานานแค่ไหน

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

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

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

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

  1. การดึงข้อมูลแบบหนาแน่นเทียบกับแบบเบาบาง: จุดแลกเปลี่ยน
  2. การสร้างการค้นหาด้วยคำสำคัญ BM25
  3. การรวมอันดับแบบผกผันเพื่อผสานคะแนน
  4. การค้นหาแบบผสมใน Pinecone และ pgvector
← กลับไปที่ AI Engineering Academy