ข้ามไปยังเนื้อหาหลัก
โครงการนี้อยู่ในช่วงเบต้า พบข้อผิดพลาด? สร้าง GitHub Issue มีคำถามหรือไอเดีย? ถามใน Discussions — ยินดีรับฟังความคิดเห็น!
คุณภาพการแปลในหน้านี้เป็นอย่างไร?

Rimay Quantum Feature Extraction - Qiskit Function โดย Kipu Quantum

ดู API reference

หมายเหตุ

Qiskit Functions เป็นฟีเจอร์เชิงทดลองที่ใช้ได้เฉพาะผู้ใช้ IBM Quantum® Premium Plan, Flex Plan และ On-Prem (ผ่าน IBM Quantum Platform API) Plan เท่านั้น ฟีเจอร์นี้อยู่ในสถานะ preview release และอาจมีการเปลี่ยนแปลง

ภาพรวม​

Rimay เสริม pipeline machine learning แบบคลาสสิกด้วยฟีเจอร์ที่สร้างบนฮาร์ดแวร์ควอนตัม function รับข้อมูลตารางแบบคลาสสิกและคืนชุดฟีเจอร์ที่แปลงด้วยควอนตัม เมื่อระบบควอนตัมประมวลผลข้อมูล จะสร้างฟีเจอร์ที่สมบูรณ์ซึ่งจับความสัมพันธ์แบบไม่เชิงเส้นระหว่าง input ได้ คุณใช้ฟีเจอร์ที่สร้างขึ้นเดี่ยว ๆ หรือรวมกับฟีเจอร์เดิมของคุณเพื่อฝึกโมเดลคลาสสิกใดก็ได้ บนชุดข้อมูลขนาดเล็กถึงกลาง ฟีเจอร์ที่แปลงด้วยควอนตัมสามารถช่วยให้คุณภาพการทำนายดีขึ้นเมื่อเทียบกับ baseline แบบคลาสสิกล้วน

function นี้สร้างมาสำหรับผู้ใช้ต่อไปนี้:

  • ทีม data science ที่มี pipeline machine learning อยู่แล้วบนชุดข้อมูลตารางขนาดเล็กถึงกลาง ซึ่งคุณภาพการทำนายหยุดนิ่ง คุณเพิ่ม Rimay เป็นขั้นตอนประมวลผลก่อนเพิ่มเติมหนึ่งขั้น โดยไม่ต้องสร้าง quantum circuit เอง

  • นักวิจัยที่สำรวจวิธีควอนตัมสำหรับงาน machine learning

คำอธิบาย​

อัลกอริทึมการสกัดฟีเจอร์เชิงควอนตัม [1] รวมหลักการสองอย่างของ quantum machine learning เข้าด้วยกัน อย่างแรกคือ quantum feature maps ซึ่งฝังข้อมูลลงในปริภูมิฮิลเบิร์ตมิติสูง จึงได้การแทนข้อมูลที่แสดงออกได้มากขึ้น อย่างที่สองคือ quantum reservoir computing ซึ่งใช้พลวัตของระบบควอนตัมหลายส่วนเป็นการแปลงแบบไม่เชิงเส้นของอินพุต

Rimay เข้ารหัสค่าฟีเจอร์และข้อมูลร่วมกัน (mutual information) ระหว่างฟีเจอร์ลงในสนามเฉพาะที่และสัมประสิทธิ์การคับเปิลของแฮมิลโทเนียนแบบสปินกลาส พลวัตควอนตัมแบบ counterdiabatic จะพัฒนาระบบไปสู่สถานะพลังงานต่ำ ซึ่งมีส่วนผสมแบบไม่เชิงเส้นของสหสัมพันธ์ในข้อมูลอินพุต Rimay สกัดสหสัมพันธ์เหล่านี้ด้วยการวัดค่าคาดหวังของหนึ่งส่วนและสองส่วน ค่าคาดหวังเหล่านี้คือฟีเจอร์ที่ผ่านการแปลงเชิงควอนตัมซึ่งคุณป้อนเข้าโมเดล machine learning ของคุณ

เวิร์กโฟลว์​

Rimay workflow: The training data defines the Hamiltonian, every sample becomes one circuit, and the measured expectation values are returned as quantum-transformed data

  1. ประมวลผลข้อมูลตารางล่วงหน้าเหมือนที่ทำกับ machine learning แบบคลาสสิก Rimay ต้องใช้ฟีเจอร์ที่เป็นตัวเลข ดังนั้นให้แปลงฟีเจอร์เชิงหมวดหมู่เป็นตัวเลข เช่น ใช้ OneHotEncoder ของ scikit-learn

  2. แบ่งข้อมูลเป็นชุดฝึกและชุดทดสอบ แล้วอัปโหลดทั้งสองชุดไปยังฟังก์ชัน ตามที่แสดงในส่วน ตัวอย่าง

  3. Rimay ใช้ข้อมูลฝึกสร้างแฮมิลโทเนียนที่แทนข้อมูล ฟีเจอร์แต่ละตัวสอดคล้องกับหนึ่ง qubit และชุดฝึกทั้งหมดเป็นตัวกำหนดว่าฟีเจอร์ใด และ qubit ใด จะมีปฏิสัมพันธ์กัน Rimay เก็บโครงสร้างนี้ไว้เพื่อแมปข้อมูลทดสอบและข้อมูลสำหรับ inference ภายหลังด้วยแฮมิลโทเนียนเดียวกัน

  4. สำหรับแต่ละตัวอย่าง ค่าฟีเจอร์จะกำหนดสนามเฉพาะที่ของแฮมิลโทเนียน และข้อมูลร่วมระหว่างฟีเจอร์จะกำหนดสัมประสิทธิ์การคับเปิลของโครงสร้างจากขั้นตอนที่ 3 Rimay แปลงวิวัฒนาการแบบ counterdiabatic ของแฮมิลโทเนียนนี้เป็นดิจิทัลในรูปแบบ circuit แล้วรัน circuit เหล่านั้นบน QPU

  5. Rimay วัดบิตสตริงที่ได้ แล้วคำนวณค่าคาดหวังหนึ่งส่วนและค่าคาดหวังสองส่วนของ qubit ที่คับเปิลกันทางกายภาพ

  6. คุณดาวน์โหลดค่าคาดหวังในรูปแบบที่ป้อนเข้าโมเดลได้โดยตรง หรือนำไปรวมกับฟีเจอร์เดิมของคุณ

หมายเหตุ

เนื่องจากโครงสร้างนี้ จำนวน qubit ที่การรันต้องใช้จึงเท่ากับจำนวนฟีเจอร์ และจำนวน circuit ที่ส่งเท่ากับจำนวนตัวอย่าง

หลังจากฟิตการแมปแล้ว คุณสามารถแมปข้อมูลใหม่ผ่านการแมปนั้นได้ เช่น สำหรับ inference จากนั้น Rimay จะดึงแฮมิลโทเนียนที่สร้างไว้ระหว่างการฟิต แล้วสร้าง circuit สำหรับตัวอย่างใหม่จากมัน

นำ Rimay ไปใช้ใน machine learning pipeline ของคุณ​

Pipeline with Rimay inserted between the train-test split and the classical machine learning model

เช่นเดียวกับ pipeline แบบคลาสสิก คุณเริ่มจากประมวลผลข้อมูลดิบล่วงหน้า เช่น ทำ one-hot encoding ให้ฟีเจอร์เชิงหมวดหมู่ แล้วแบ่งเป็นชุดฝึกและชุดทดสอบ แทนที่จะป้อนทั้งสองชุดเข้าโมเดลโดยตรง ให้ป้อนเข้า Rimay ก่อน แล้วฝึกโมเดลของคุณด้วยฟีเจอร์ที่ผ่านการแปลงเชิงควอนตัม

เบนช์มาร์ก​

Kipu Quantum ทดสอบ Rimay กับชุดข้อมูล German credit จาก OpenML [2] ซึ่งจัดประเภทผู้ขอสินเชื่อ 1000 ราย เป็นความเสี่ยงด้านเครดิตดีหรือไม่ดี ชุดข้อมูลมีแอตทริบิวต์เชิงหมวดหมู่ 13 รายการและเชิงตัวเลขเจ็ดรายการ การทำ one-hot encoding กับแอตทริบิวต์เชิงหมวดหมู่ได้ฟีเจอร์ตัวเลข 48 ตัว เบนช์มาร์กกันตัวอย่าง 20% ไว้เป็นชุดทดสอบ

เป็นค่าพื้นฐาน มีการฝึกโมเดลคลาสสิกหลายตัวด้วยฟีเจอร์คลาสสิก สำหรับ Rimay มีการฝึก random forest สองแบบ คือด้วยฟีเจอร์ที่ผ่านการแปลงเชิงควอนตัมเพียงอย่างเดียว (Random forest Q) และด้วยฟีเจอร์ที่ผ่านการแปลงเชิงควอนตัมรวมกับฟีเจอร์คลาสสิก (Random forest H ย่อมาจาก hybrid) ตารางแสดงเฉพาะ random forest เพราะทำงานได้ดีที่สุดกับฟีเจอร์ที่ผ่านการแปลงเชิงควอนตัม

ModelFeaturesAccuracyAUCF1 scorePrecisionRecall
CatBoostClassical0.7750.7810.8500.7950.914
Random forestClassical0.7650.7810.8460.7820.921
XGBoostClassical0.7600.7580.8350.8030.871
LightGBMClassical0.7700.7510.8400.8180.864
Random forest QQuantum0.7500.7930.8400.7620.936
Random forest HHybrid0.7700.7980.8540.7700.957

ฟีเจอร์แบบ hybrid ช่วยปรับปรุงทุกเมตริกของ random forest ยกเว้น precision และ random forest แบบ hybrid ได้ AUC, F1 score และ recall สูงกว่า CatBoost ที่ใช้ฟีเจอร์คลาสสิก ผลที่เด่นที่สุดอยู่ที่ recall ซึ่งเพิ่มจาก 0.921 เป็น 0.957 ฟีเจอร์ที่ผ่านการแปลงเชิงควอนตัมเพียงอย่างเดียวไม่ถึงระดับ precision ของโมเดลคลาสสิก

ข้อควรระวัง

ชุดทดสอบมีเพียง 200 ตัวอย่าง ดังนั้นการทำนายถูกเพิ่มอีกหนึ่งตัวอย่างจะทำให้ accuracy เปลี่ยนไป 0.005 ให้อ่านความแตกต่างเหล่านี้เป็นแนวโน้มที่ต้องตรวจสอบเพิ่มเติม ไม่ใช่ผลที่มีนัยสำคัญ ความแม่นยำของการทำนายยังอาจขึ้นกับสัญญาณรบกวนจากฮาร์ดแวร์ในฟีเจอร์ที่สกัดได้ ดังนั้นให้ใช้ shot มากพอที่ shot noise จะไม่จำกัดผลลัพธ์

เบนช์มาร์กใช้ทรัพยากรดังต่อไปนี้

ExampleNumber of qubitsNumber of samplesNumber of shotsTotal time (min)QPU usage (min)Processor
German credit48100050002322ibm_boston
German credit481000500032ibm_phoenix

จำนวนตัวอย่าง ซึ่งก็คือจำนวน circuit เป็นตัวกำหนดเวลา QPU ให้ใช้โปรเซสเซอร์ประเภท Nighthawk r2 เพราะช่วยลดเวลา QPU ที่ต้องใช้ได้มาก

อินพุต​

mode เป็นตัวกำหนดว่าการรันต้องใช้พารามิเตอร์ใดบ้าง สำหรับคำอธิบายของพารามิเตอร์อินพุตทุกตัว ดู API reference

ไฟล์อินพุต​

  • อัปโหลดทุกไฟล์ด้วย catalog.file_upload() ก่อนรันฟังก์ชัน

  • การอัปโหลดจะแทนที่ไฟล์ชื่อเดียวกันที่มีอยู่ก่อน แม้จะเป็นของ job ที่คุณส่งไปแล้วแต่ยังไม่เริ่มก็ตาม หากต้องการรันหลาย job พร้อมกัน ให้ตั้งชื่อไฟล์ของแต่ละ job ไม่ซ้ำกัน เช่น run1_x_train.csv และ run2_x_train.csv

  • ทุกไฟล์เป็นไฟล์ CSV ที่มีแถวส่วนหัว แต่ละคอลัมน์ของไฟล์ฟีเจอร์คือฟีเจอร์หนึ่งตัว และทุกค่าต้องเป็นตัวเลข

  • y_train มีคอลัมน์ตัวเลขเพียงหนึ่งคอลัมน์พอดี โดยมีหนึ่งป้ายกำกับต่อหนึ่งแถวของ x_train ให้แมปป้ายกำกับเชิงหมวดหมู่เป็นตัวเลข เช่น good และ bad เป็น 1 และ 0

  • x_test และ x_inference ต้องมีคอลัมน์เหมือนกับ x_train และเรียงลำดับเดียวกัน

เก็บ mapping_id และ backend_name ไว้

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

ข้อจำกัด​

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

  • ตัวอย่างแต่ละตัวกลายเป็นหนึ่ง circuit และการรันนับตัวอย่างฝึกและทดสอบรวมกัน การรันหนึ่งครั้งมีตัวอย่างได้สูงสุด 15,000 ตัวอย่าง

  • job เดียวขอรันได้สูงสุด 10 ล้านครั้ง ดังนั้นจำนวนตัวอย่างคูณ shots ต้องไม่เกิน 10 ล้าน

  • job ต้องเสร็จภายใน 24 ชั่วโมง รวมเวลาที่ circuit รอในคิวของโปรเซสเซอร์ด้วย job ที่ใช้เวลานานกว่านั้นจะถูกหยุดโดยไม่มีผลลัพธ์ บนโปรเซสเซอร์ที่คิวยาว ให้เก็บชุดข้อมูลขนาดใหญ่ไว้ต่ำกว่าขีดจำกัดเหล่านี้พอสมควร

เอาต์พุต​

job.result() คืนค่าเป็น dictionary ตัวฟีเจอร์ที่ผ่านการแปลงเชิงควอนตัมเองจะถูกเขียนเป็นไฟล์ CSV ที่คุณดาวน์โหลดด้วย catalog.file_download() สำหรับคำอธิบายของทุกคีย์ใน dictionary ดู API reference สำหรับเวลาที่แต่ละเฟสของการรันใช้ ดู เมทาดาทาของการรัน

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

เมทาดาทาของการรัน​

resource_usage มีหนึ่งรายการสำหรับแต่ละเฟสการทำงานที่การรันผ่าน ได้แก่ "RUNNING: MAPPING", "RUNNING: POST_PROCESSING" และบน QPU มักมี "RUNNING: WAITING_FOR_QPU" ด้วย แต่ละรายการมี CPU_TIME ซึ่งเป็นเวลาจริง (wall-clock) ของเฟสเป็นวินาที และ QPU_TIME ซึ่งเป็นเวลา QPU เป็นวินาที บน QPU เวลา QPU ที่ IBM เรียกเก็บจะบันทึกไว้ใต้ "RUNNING: MAPPING" ซึ่งเป็นเฟสที่ circuit รัน

"RUNNING: WAITING_FOR_QPU" คือเวลาที่ job ของคุณรอในคิวของ IBM การรันดึงเวลานี้จาก timestamp ของ job ที่ IBM ให้มา และไม่นับรวมใน "RUNNING: MAPPING" หาก IBM ไม่รายงาน timestamp เหล่านั้นสำหรับทุก job รายการนี้จะไม่มี และเวลารอจะรวมอยู่ใน "RUNNING: MAPPING"

IBM® คำนวณการใช้งานเสร็จหลังจาก job จบไประยะหนึ่ง การรันจะรอได้นานประมาณหนึ่งนาที การใช้งานที่ยังคำนวณอยู่หลังจากเวลานั้นจะไม่รวมใน QPU_TIME และการใช้งานสุดท้ายจะแสดงบน IBM Quantum Platform หากการรันอ่านข้อมูลการใช้งานจาก IBM ไม่ได้ QPU_TIME จะเป็น None

ตัวอย่างเช่น

"metadata": {
"version": "0.3.0",
"resource_usage": {
"RUNNING: MAPPING": {"CPU_TIME": 12.4, "QPU_TIME": 6.0},
"RUNNING: WAITING_FOR_QPU": {"CPU_TIME": 28.8, "QPU_TIME": 0.0},
"RUNNING: POST_PROCESSING": {"CPU_TIME": 0.3, "QPU_TIME": 0.0},
},
}

เริ่มต้นใช้งาน​

ยืนยันตัวตนด้วย IBM Quantum Platform API key ของคุณ และเลือก Qiskit Function ดังนี้

หมายเหตุ

โค้ดต่อไปนี้สมมติว่าคุณบันทึกข้อมูลรับรองไว้แล้ว หากยังไม่ได้บันทึก ให้ทำตามขั้นตอนใน ติดตั้งไคลเอนต์ Qiskit Functions Catalog เพื่อบันทึกบัญชีของคุณด้วย API key

# Added by doQumentation — installs the packages this notebook needs if they are missing
import importlib.util

_needed = {"pandas": "pandas", "qiskit_ibm_catalog": "qiskit-ibm-catalog"}
_missing = [pip for module, pip in _needed.items()
if importlib.util.find_spec(module) is None]
# One at a time, so a package that fails to install does not block the others
for _pip in _missing:
%pip install -q {_pip}
if not _missing:
print("\u2713 All required packages are installed")
from qiskit_ibm_catalog import QiskitFunctionsCatalog

catalog = QiskitFunctionsCatalog(channel="ibm_quantum_platform")

# Verify that you have access to the function
catalog.list()
[QiskitFunction(kipu-quantum/rimay)]
# Access function
rimay = catalog.load("kipu-quantum/rimay")

ขนาดของฟังก์ชัน​

ทุก job รันที่ขนาดใดขนาดหนึ่ง ได้แก่ S, M หรือ L หากขนาดที่ระบุเล็กเกินไป job จะถูกปฏิเสธ หากขนาดใหญ่เกินความจำเป็น job จะรันบนโปรไฟล์การประมวลผลที่ใหญ่กว่างานต้องการ

ขนาดของ job Rimay ขึ้นกับจำนวนตัวอย่างที่มันแมป ได้แก่ แถวของ x_train และ x_test สำหรับ fit-transform และแถวของ x_inference สำหรับ transform ป้ายกำกับใน y_train ไม่นับ และการรัน delete ไม่แมปตัวอย่างใดเลย

SizeSamples per jobCompute profilevCPURAM
SUp to 2,9998x32832 GB
M3,000 to 9,9998x32832 GB
L10,000 to 15,00016x12816128 GB

จำนวนตัวอย่างเป็นเกณฑ์เดียว ขนาดไม่เปลี่ยนอะไรนอกจากโปรไฟล์การประมวลผล ข้อจำกัด เรื่องฟีเจอร์ ตัวอย่าง และ shot เหมือนกันทุกขนาด S และ M รันบนโปรไฟล์การประมวลผลเดียวกัน และต่างกันที่จำนวนตัวอย่างที่แต่ละขนาดรองรับ

ค่าเริ่มต้นคือ M ซึ่งใช้เมื่อ job ไม่ได้ขอขนาด ดังนั้น job ที่มีตัวอย่างมากกว่า 9,999 ตัวอย่างต้องขอ L

คุณยังอ่านการแมปจากตัวฟังก์ชันได้ด้วย rimay.sizes_map และอ่านขนาดที่ job รันเมื่อไม่ได้ขอขนาดได้ด้วย rimay.default_size

คำนวณขนาดก่อนส่ง​

รันสิ่งนี้กับอินพุตของคุณเอง มันแค่อ่านอินพุตและไม่ทำอย่างอื่น ไม่มีการส่ง job และไม่มีการจองอะไร คุณจึงเรียกใช้กี่ครั้งก็ได้

ส่งชุดข้อมูลเอง ไม่ใช่ชื่อไฟล์ โดยเรียงลำดับเดียวกับ input_file พร้อมกับ mode ของการรัน ขั้นตอนที่ 2 ของตัวอย่าง แสดงการเรียกใช้

from os import PathLike
from typing import Any, Literal, Sequence, Sized

Size = Literal["S", "M", "L"]

# Upper bounds (inclusive) in samples.
_SMALL = 2_999
_MEDIUM = 9_999

FIT_TRANSFORM, TRANSFORM, DELETE = "fit-transform", "transform", "delete"

# Which positions of input_file hold samples, per mode. The labels in
# y_train submit no circuits of their own, so they are not counted.
SAMPLE_POSITIONS = {FIT_TRANSFORM: (0, 2), TRANSFORM: (0,)}

def calculate_function_size(problem: Sequence[Sized], **kwargs: Any) -> Size:
"""Return the size ("S", "M" or "L") required to run the function."""
metrics = _measure(problem, **kwargs)
if _is_small(metrics):
return "S"
if _is_medium(metrics):
return "M"
return "L"

def _measure(problem: Sequence[Sized], **kwargs: Any) -> dict:
"""The samples the job submits."""
return {"samples": count_samples(problem, kwargs.get("mode"))}

def count_samples(problem: Sequence[Sized], mode: Any) -> int:
"""Rows across the data sets of ``problem`` that carry samples."""
if mode == DELETE:
return 0
if mode not in SAMPLE_POSITIONS:
raise ValueError(f"cannot size mode {mode!r}")
if _is_name(problem) or (
isinstance(problem, (list, tuple))
and any(_is_name(data) for data in problem)
):
raise TypeError(
"pass the data, not the file name: read each input_file, e.g. with "
"pandas.read_csv, and pass the data sets in input_file order"
)
if not isinstance(problem, (list, tuple)):
raise TypeError(
"pass a list of data sets in input_file order, e.g. [x_train, y_train], "
f"not a single {type(problem).__name__}"
)
return sum(
len(problem[i]) for i in SAMPLE_POSITIONS[mode] if i < len(problem)
)

def _is_name(value: Any) -> bool:
"""A file name or path rather than data."""
return isinstance(value, (str, bytes, PathLike))

def _is_small(metrics: dict) -> bool:
"""Determine if the metrics fit T-size 'S'."""
return metrics["samples"] <= _SMALL

def _is_medium(metrics: dict) -> bool:
"""Determine if the metrics fit T-size 'M'."""
return metrics["samples"] <= _MEDIUM

หากขนาดเล็กเกินไป job จะล้มเหลวด้วยข้อผิดพลาด 4600 และข้อความจะระบุขนาดที่ควรใช้แทน หากขนาดใหญ่เกินความจำเป็น job จะรันตามปกติและบันทึกเหตุการณ์คำแนะนำ 4601

ตัวอย่าง​

ตัวอย่างนี้แสดงวิธีอัปโหลดข้อมูล รันฟังก์ชัน และดึงฟีเจอร์ที่ผ่านการแปลงเชิงควอนตัม สำหรับตัวอย่างแบบครบวงจรที่รวมการประมวลผลล่วงหน้าและการฝึกโมเดลคลาสสิก ดูบทแนะนำ

1. อัปโหลดข้อมูล​

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

from pathlib import Path

Path("x_train.csv").write_text("""f0,f1,f2,f3
0.7227,1.3355,1.9595,2.5562
0.2731,0.5779,0.8983,1.1624
0.1139,0.1817,0.2163,0.2426
0.0341,0.1311,0.0854,0.09
0.8996,1.6951,2.497,3.3407
0.9669,1.8906,2.7705,3.6569
0.6366,1.2821,1.8793,2.4602
0.7718,1.4979,2.2223,2.933
0.5465,1.1008,1.67,2.2195
0.9475,1.9423,2.8942,3.8199
0.8829,1.6842,2.4703,3.2865
0.0675,0.0365,0.0705,0.0162
""")
Path("y_train.csv").write_text("label\n1\n0\n0\n0\n1\n1\n0\n1\n0\n1\n1\n0\n")
Path("x_test.csv").write_text("""f0,f1,f2,f3
0.543,1.0786,1.5684,2.0607
0.9928,1.9037,2.9302,3.8422
0.2269,0.3637,0.4628,0.597
0.9896,1.9511,2.8913,3.8208
""")
Path("x_inference.csv").write_text("""f0,f1,f2,f3
0.2708,0.542,0.8506,1.0897
0.3585,0.6025,0.9517,1.2609
0.8871,1.6559,2.4577,3.2992
""")
95

อัปโหลดไฟล์ฝึกและไฟล์ทดสอบ คุณจะอัปโหลด x_inference.csv ในขั้นตอนที่ 4

for file_name in ("x_train.csv", "y_train.csv", "x_test.csv"):
catalog.file_upload(file_name, rimay)

2. รันฟังก์ชัน​

คำนวณขนาดของการรันจากข้อมูลที่คุณอัปโหลด ด้วยตัวคำนวณจาก ขนาดของฟังก์ชัน

import pandas as pd

x_train = pd.read_csv("x_train.csv")
y_train = pd.read_csv("y_train.csv")
x_test = pd.read_csv("x_test.csv")

size = calculate_function_size(
[x_train, y_train, x_test], mode="fit-transform"
)
print(size)
S

เลือกโปรเซสเซอร์ที่มี qubit อย่างน้อยเท่ากับจำนวนฟีเจอร์ในข้อมูลของคุณ และรันฟังก์ชันในโหมด fit-transform ด้วยขนาดนั้น ข้อมูลตัวอย่างมีฟีเจอร์สี่ตัว ดังนั้นโปรเซสเซอร์ IBM Quantum ตัวใดก็รันได้

backend = catalog.least_busy(operational=True, simulator=False)

job = rimay.run(
mode="fit-transform",
input_file=["x_train.csv", "y_train.csv", "x_test.csv"],
backend_name=backend.name,
shots=5000,
function_size=size,
)
print(job.job_id)
85dabc9f-a769-4f4a-8e92-f3be73f85ca2

ตรวจสอบสถานะของ workload หรือรับผลลัพธ์ดังนี้

# Monitor the job status
job.status()
'DONE'
result = job.result()

# Keep both: the mapping_id is the only handle on the mapping this run
# fitted, and the mapping runs only on the processor it was fitted on.
mapping_id = result["mapping_id"]
fit_backend_name = result["backend_name"]

3. ดึงผลลัพธ์​

ดาวน์โหลดฟีเจอร์ที่ผ่านการแปลงเชิงควอนตัม ส่ง target_name เพื่อให้แต่ละไฟล์ถูกบันทึกภายใต้ชื่อของตัวเอง

for file_name in result["output_files"]:
catalog.file_download(file_name, rimay, target_name=file_name)
693iB [00:00, 171kiB/s]
254iB [00:00, 111kiB/s]

4. แมปข้อมูลใหม่​

หลังจากฝึกโมเดลแล้ว ให้แมปข้อมูลใหม่ด้วยการแมปที่ฟิตไว้ เช่น เพื่อรัน inference ตัวอย่างนี้แมป x_inference.csv ซึ่งเซลล์แรกของตัวอย่างนี้เขียนไว้ ส่ง mapping_id ที่การฟิตคืนมา เพื่อให้แถวใหม่ถูกแมปด้วยการแมปเดิมแทนที่จะสร้างใหม่

การแมปถูกสร้างสำหรับผัง qubit ของโปรเซสเซอร์หนึ่งตัว ดังนั้นให้ส่ง backend_name เดียวกับการฟิต ซึ่งการฟิตคืนมาใน result["backend_name"] อย่าใช้ least_busy() เลือกโปรเซสเซอร์ เพราะอาจคืนตัวอื่น Rimay จะปฏิเสธโปรเซสเซอร์อื่นก่อนส่งอะไรทั้งสิ้น จำนวน shot ก็มาจากการฟิตเช่นกัน

catalog.file_upload("x_inference.csv", rimay)

x_inference = pd.read_csv("x_inference.csv")
size = calculate_function_size([x_inference], mode="transform")

job = rimay.run(
mode="transform",
input_file=["x_inference.csv"],
# The processor the mapping was fitted on
backend_name=fit_backend_name,
shots=5000,
mapping_id=mapping_id,
function_size=size,
)
# Monitor the job status
job.status()
'DONE'
result = job.result()

for file_name in result["output_files"]:
catalog.file_download(file_name, rimay, target_name=file_name)
202iB [00:00, 73.5kiB/s]

5. ลบการแมป​

เมื่อคุณไม่ต้องการการแมปที่ฟิตไว้แล้ว ให้ลบมัน การรัน delete ไม่ทำงานควอนตัมใดๆ จึงไม่ต้องใช้โปรเซสเซอร์ ไม่ต้องมี shot และไม่ต้องมีขนาดของฟังก์ชัน คุณยกเลิกการลบไม่ได้ หลังจากลบ mapping_id จะไม่อ้างถึงอะไรอีก และการรัน transform ด้วยมันจะล้มเหลว

job = rimay.run(mode="delete", mapping_id=mapping_id)
job.result()
{'output_files': [],
'mode': 'delete',
'deleted': True,
'mapping_id': '30L40joyUPYfnvgwo2d7MXXSzqvHkggR-Kzn81wfIYw',
'metadata': {'version': '0.6.0', 'resource_usage': {}}}

ดึงข้อความแสดงข้อผิดพลาด​

หากสถานะ workload ของคุณเป็น ERROR ให้ใช้ job.error_message() เพื่อดึงข้อความแสดงข้อผิดพลาด ดังนี้

job = rimay.run(
mode="fit-transform",
input_file=["x_train.csv", "y_train.csv"],
backend_name=backend.name,
shots=0,
)
job.error_message()

ทุกข้อผิดพลาดที่ Rimay รายงานมีรหัสจากรหัสข้อผิดพลาดของ IBM Quantum ข้อความ และวิธีแก้ที่ระบุค่าที่คุณส่งและค่าที่อนุญาต ตารางต่อไปนี้แสดงข้อผิดพลาดที่พบบ่อยที่สุด

CodeCause
1221พารามิเตอร์หายไปหรือมีชนิดผิด, mode ไม่ถูกต้อง, ไฟล์ที่ระบุใน input_file ไม่ได้อัปโหลด, ไฟล์ไม่สอดคล้องกัน, ฟีเจอร์ไม่ใช่ตัวเลข หรือ mapping_id ไม่ตรงกับการแมปที่เก็บไว้
1221การรัน "transform" ระบุ backend_name ต่างจากการฟิตที่สร้างการแมปของมัน
1216อินสแตนซ์ของคุณไม่มีโปรเซสเซอร์ที่ใช้ backend_name ที่คุณส่ง วิธีแก้จะแสดงรายการโปรเซสเซอร์ที่มี
1200API key ของคุณไม่มีสิทธิ์เข้าถึงอินสแตนซ์ที่ job รันอยู่
3200backend_name ไม่ได้ขึ้นต้นด้วย ibm_
4500ข้อมูลมีฟีเจอร์มากกว่าจำนวน qubit ของโปรเซสเซอร์
6000จำนวนตัวอย่างคูณ shots เกิน 10 ล้านครั้ง
6001shots น้อยกว่า 1
6002ข้อมูลมีตัวอย่างมากกว่าที่การรันหนึ่งครั้งอนุญาต

กรณีการใช้งาน​

ในการจัดประเภทข้อมูลตารางบนชุดข้อมูลขนาดเล็กถึงกลาง Kipu Quantum ได้ใช้การสกัดฟีเจอร์เชิงควอนตัมกับงานต่อไปนี้

นอกจากข้อมูลตาราง neural network ที่ถูกตรึง (frozen) สามารถแปลงรูปภาพเป็นฟีเจอร์ตัวเลข ซึ่งการสกัดฟีเจอร์เชิงควอนตัมจะแมปต่อเป็นฟีเจอร์ที่ผ่านการแปลงเชิงควอนตัม

ขอความช่วยเหลือ​

หากต้องการความช่วยเหลือ ติดต่อ support@kipu-quantum.com

ขั้นตอนถัดไป​

เอกสารอ้างอิง​

[1] Simen, A., et al. (2025). Digitized Counterdiabatic Quantum Feature Extraction. arXiv preprint arXiv:2510.13807.

[2] Hofmann, H. (1994). Statlog (German Credit Data). OpenML dataset 31.

[3] Zhang, Q., et al. (2026). Quantum-enhanced satellite image classification. arXiv preprint arXiv:2602.18350.

ข้อมูลเพิ่มเติม​

Rimay เป็นคำในภาษาเกชัว (Quechua) แปลว่า "อธิบาย"