You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ML-For-Beginners/translations/th/7-TimeSeries/2-ARIMA
leestott c796f3dda8
🌐 Update translations via Co-op Translator
3 weeks ago
..
solution 🌐 Update translations via Co-op Translator 3 weeks ago
working 🌐 Update translations via Co-op Translator 3 weeks ago
README.md 🌐 Update translations via Co-op Translator 3 weeks ago
assignment.md 🌐 Update translations via Co-op Translator 3 weeks ago

README.md

การพยากรณ์อนุกรมเวลาโดยใช้ ARIMA

ในบทเรียนก่อนหน้านี้ คุณได้เรียนรู้เกี่ยวกับการพยากรณ์อนุกรมเวลาและโหลดชุดข้อมูลที่แสดงการเปลี่ยนแปลงของโหลดไฟฟ้าในช่วงเวลาหนึ่ง

Introduction to ARIMA

🎥 คลิกที่ภาพด้านบนเพื่อดูวิดีโอ: บทนำสั้น ๆ เกี่ยวกับโมเดล ARIMA ตัวอย่างในวิดีโอใช้ R แต่แนวคิดสามารถนำไปใช้ได้ทั่วไป

แบบทดสอบก่อนเรียน

บทนำ

ในบทเรียนนี้ คุณจะได้เรียนรู้วิธีเฉพาะในการสร้างโมเดลด้วย ARIMA: AutoRegressive Integrated Moving Average โมเดล ARIMA เหมาะอย่างยิ่งสำหรับการปรับข้อมูลที่แสดง non-stationarity

แนวคิดทั่วไป

เพื่อที่จะทำงานกับ ARIMA มีแนวคิดบางอย่างที่คุณจำเป็นต้องรู้:

  • 🎓 Stationarity. ในบริบททางสถิติ Stationarity หมายถึงข้อมูลที่การแจกแจงไม่เปลี่ยนแปลงเมื่อเลื่อนเวลา ข้อมูลที่ไม่เป็น Stationary จะแสดงการเปลี่ยนแปลงเนื่องจากแนวโน้มที่ต้องแปลงเพื่อวิเคราะห์ ตัวอย่างเช่น Seasonality สามารถทำให้เกิดการเปลี่ยนแปลงในข้อมูลและสามารถกำจัดได้โดยกระบวนการ 'seasonal-differencing'

  • 🎓 Differencing. การ Differencing ข้อมูลในบริบททางสถิติ หมายถึงกระบวนการแปลงข้อมูลที่ไม่เป็น Stationary ให้เป็น Stationary โดยการลบแนวโน้มที่ไม่คงที่ "Differencing ช่วยลบการเปลี่ยนแปลงในระดับของอนุกรมเวลา กำจัดแนวโน้มและ Seasonality และทำให้ค่าเฉลี่ยของอนุกรมเวลามีเสถียรภาพ" บทความโดย Shixiong et al

ARIMA ในบริบทของอนุกรมเวลา

มาทำความเข้าใจส่วนต่าง ๆ ของ ARIMA เพื่อให้เข้าใจว่าโมเดลนี้ช่วยเราในการสร้างแบบจำลองอนุกรมเวลาและช่วยในการพยากรณ์ได้อย่างไร

  • AR - AutoRegressive. โมเดล AutoRegressive ตามชื่อ หมายถึงการมองย้อนกลับไปในเวลาเพื่อวิเคราะห์ค่าก่อนหน้าในข้อมูลของคุณและทำการสันนิษฐานเกี่ยวกับค่าเหล่านั้น ค่าก่อนหน้าเหล่านี้เรียกว่า 'lags' ตัวอย่างเช่น ข้อมูลที่แสดงยอดขายดินสอรายเดือน ยอดขายรวมของแต่ละเดือนจะถือว่าเป็น 'ตัวแปรที่เปลี่ยนแปลง' ในชุดข้อมูล โมเดลนี้ถูกสร้างขึ้นโดย "ตัวแปรที่เปลี่ยนแปลงที่สนใจถูกวิเคราะห์กับค่าก่อนหน้าของตัวเอง" wikipedia

  • I - Integrated. แตกต่างจากโมเดล 'ARMA' ที่คล้ายกัน 'I' ใน ARIMA หมายถึงลักษณะ integrated ข้อมูลจะถูก 'integrated' เมื่อมีการใช้ขั้นตอน Differencing เพื่อกำจัด non-stationarity

  • MA - Moving Average. ลักษณะ moving-average ของโมเดลนี้หมายถึงตัวแปรผลลัพธ์ที่ถูกกำหนดโดยการสังเกตค่าปัจจุบันและค่าก่อนหน้าของ lags

สรุป: ARIMA ถูกใช้เพื่อสร้างโมเดลที่ปรับให้เข้ากับรูปแบบพิเศษของข้อมูลอนุกรมเวลาให้ใกล้เคียงที่สุด

แบบฝึกหัด - สร้างโมเดล ARIMA

เปิดโฟลเดอร์ /working ในบทเรียนนี้และค้นหาไฟล์ notebook.ipynb

  1. รัน notebook เพื่อโหลดไลบรารี Python statsmodels; คุณจะต้องใช้ไลบรารีนี้สำหรับโมเดล ARIMA

  2. โหลดไลบรารีที่จำเป็น

  3. ตอนนี้โหลดไลบรารีเพิ่มเติมที่มีประโยชน์สำหรับการสร้างกราฟข้อมูล:

    import os
    import warnings
    import matplotlib.pyplot as plt
    import numpy as np
    import pandas as pd
    import datetime as dt
    import math
    
    from pandas.plotting import autocorrelation_plot
    from statsmodels.tsa.statespace.sarimax import SARIMAX
    from sklearn.preprocessing import MinMaxScaler
    from common.utils import load_data, mape
    from IPython.display import Image
    
    %matplotlib inline
    pd.options.display.float_format = '{:,.2f}'.format
    np.set_printoptions(precision=2)
    warnings.filterwarnings("ignore") # specify to ignore warning messages
    
  4. โหลดข้อมูลจากไฟล์ /data/energy.csv ลงใน Pandas dataframe และดูข้อมูล:

    energy = load_data('./data')[['load']]
    energy.head(10)
    
  5. สร้างกราฟข้อมูลพลังงานทั้งหมดที่มีตั้งแต่เดือนมกราคม 2012 ถึงเดือนธันวาคม 2014 ไม่มีอะไรน่าประหลาดใจเพราะเราเห็นข้อมูลนี้ในบทเรียนที่แล้ว:

    energy.plot(y='load', subplots=True, figsize=(15, 8), fontsize=12)
    plt.xlabel('timestamp', fontsize=12)
    plt.ylabel('load', fontsize=12)
    plt.show()
    

    ตอนนี้มาสร้างโมเดลกัน!

สร้างชุดข้อมูลสำหรับการฝึกและการทดสอบ

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

  1. กำหนดช่วงเวลาสองเดือนตั้งแต่วันที่ 1 กันยายนถึง 31 ตุลาคม 2014 ให้เป็นชุดข้อมูลสำหรับการฝึก ชุดข้อมูลสำหรับการทดสอบจะรวมช่วงเวลาสองเดือนตั้งแต่วันที่ 1 พฤศจิกายนถึง 31 ธันวาคม 2014:

    train_start_dt = '2014-11-01 00:00:00'
    test_start_dt = '2014-12-30 00:00:00'
    

    เนื่องจากข้อมูลนี้สะท้อนการบริโภคพลังงานรายวัน มีรูปแบบตามฤดูกาลที่ชัดเจน แต่การบริโภคมีความคล้ายคลึงกับการบริโภคในวันล่าสุดมากที่สุด

  2. สร้างกราฟเปรียบเทียบ:

    energy[(energy.index < test_start_dt) & (energy.index >= train_start_dt)][['load']].rename(columns={'load':'train'}) \
        .join(energy[test_start_dt:][['load']].rename(columns={'load':'test'}), how='outer') \
        .plot(y=['train', 'test'], figsize=(15, 8), fontsize=12)
    plt.xlabel('timestamp', fontsize=12)
    plt.ylabel('load', fontsize=12)
    plt.show()
    

    training and testing data

    ดังนั้น การใช้ช่วงเวลาที่ค่อนข้างเล็กสำหรับการฝึกข้อมูลควรเพียงพอ

    หมายเหตุ: เนื่องจากฟังก์ชันที่เราใช้ในการปรับโมเดล ARIMA ใช้การตรวจสอบภายในตัวอย่างระหว่างการปรับ เราจะละเว้นข้อมูลการตรวจสอบ

เตรียมข้อมูลสำหรับการฝึก

ตอนนี้คุณต้องเตรียมข้อมูลสำหรับการฝึกโดยการกรองและปรับขนาดข้อมูล กรองชุดข้อมูลของคุณเพื่อรวมเฉพาะช่วงเวลาที่ต้องการและคอลัมน์ที่จำเป็น และปรับขนาดเพื่อให้แน่ใจว่าข้อมูลถูกฉายลงในช่วง 0,1

  1. กรองชุดข้อมูลต้นฉบับเพื่อรวมเฉพาะช่วงเวลาที่กล่าวถึงต่อชุดและรวมเฉพาะคอลัมน์ 'load' และวันที่ที่จำเป็น:

    train = energy.copy()[(energy.index >= train_start_dt) & (energy.index < test_start_dt)][['load']]
    test = energy.copy()[energy.index >= test_start_dt][['load']]
    
    print('Training data shape: ', train.shape)
    print('Test data shape: ', test.shape)
    

    คุณสามารถดูรูปร่างของข้อมูล:

    Training data shape:  (1416, 1)
    Test data shape:  (48, 1)
    
  2. ปรับขนาดข้อมูลให้อยู่ในช่วง (0, 1)

    scaler = MinMaxScaler()
    train['load'] = scaler.fit_transform(train)
    train.head(10)
    
  3. สร้างกราฟเปรียบเทียบข้อมูลต้นฉบับกับข้อมูลที่ปรับขนาด:

    energy[(energy.index >= train_start_dt) & (energy.index < test_start_dt)][['load']].rename(columns={'load':'original load'}).plot.hist(bins=100, fontsize=12)
    train.rename(columns={'load':'scaled load'}).plot.hist(bins=100, fontsize=12)
    plt.show()
    

    original

    ข้อมูลต้นฉบับ

    scaled

    ข้อมูลที่ปรับขนาด

  4. ตอนนี้คุณได้ปรับเทียบข้อมูลที่ปรับขนาดแล้ว คุณสามารถปรับขนาดข้อมูลสำหรับการทดสอบ:

    test['load'] = scaler.transform(test)
    test.head()
    

ใช้ ARIMA

ถึงเวลาที่จะใช้ ARIMA! ตอนนี้คุณจะใช้ไลบรารี statsmodels ที่คุณติดตั้งไว้ก่อนหน้านี้

ตอนนี้คุณต้องทำตามขั้นตอนหลายขั้นตอน

  1. กำหนดโมเดลโดยเรียก SARIMAX() และส่งพารามิเตอร์ของโมเดล: พารามิเตอร์ p, d, และ q และพารามิเตอร์ P, D, และ Q
  2. เตรียมโมเดลสำหรับข้อมูลการฝึกโดยเรียกฟังก์ชัน fit()
  3. ทำการพยากรณ์โดยเรียกฟังก์ชัน forecast() และระบุจำนวนขั้นตอน (หรือ horizon) ที่ต้องการพยากรณ์

🎓 พารามิเตอร์เหล่านี้มีไว้เพื่ออะไร? ในโมเดล ARIMA มี 3 พารามิเตอร์ที่ใช้ช่วยสร้างแบบจำลองลักษณะสำคัญของอนุกรมเวลา: seasonality, trend, และ noise พารามิเตอร์เหล่านี้คือ:

p: พารามิเตอร์ที่เกี่ยวข้องกับลักษณะ auto-regressive ของโมเดล ซึ่งรวมค่าที่ผ่านมา d: พารามิเตอร์ที่เกี่ยวข้องกับส่วน integrated ของโมเดล ซึ่งมีผลต่อจำนวน differencing (🎓 จำ differencing ได้ไหม 👆?) ที่จะใช้กับอนุกรมเวลา q: พารามิเตอร์ที่เกี่ยวข้องกับส่วน moving-average ของโมเดล

หมายเหตุ: หากข้อมูลของคุณมีลักษณะตามฤดูกาล - ซึ่งข้อมูลนี้มี - เราใช้โมเดล ARIMA ตามฤดูกาล (SARIMA) ในกรณีนี้คุณต้องใช้ชุดพารามิเตอร์อีกชุดหนึ่ง: P, D, และ Q ซึ่งอธิบายความสัมพันธ์เดียวกันกับ p, d, และ q แต่สอดคล้องกับส่วนตามฤดูกาลของโมเดล

  1. เริ่มต้นโดยตั้งค่าค่าของ horizon ที่คุณต้องการ ลองใช้ 3 ชั่วโมง:

    # Specify the number of steps to forecast ahead
    HORIZON = 3
    print('Forecasting horizon:', HORIZON, 'hours')
    

    การเลือกค่าที่ดีที่สุดสำหรับพารามิเตอร์ของโมเดล ARIMA อาจเป็นเรื่องท้าทายเนื่องจากเป็นเรื่องที่ค่อนข้างอัตวิสัยและใช้เวลามาก คุณอาจพิจารณาใช้ฟังก์ชัน auto_arima() จากไลบรารี pyramid

  2. สำหรับตอนนี้ลองเลือกค่าด้วยตนเองเพื่อค้นหาโมเดลที่ดี

    order = (4, 1, 0)
    seasonal_order = (1, 1, 0, 24)
    
    model = SARIMAX(endog=train, order=order, seasonal_order=seasonal_order)
    results = model.fit()
    
    print(results.summary())
    

    ตารางผลลัพธ์จะถูกพิมพ์ออกมา

คุณได้สร้างโมเดลแรกของคุณแล้ว! ตอนนี้เราต้องหาวิธีประเมินมัน

ประเมินโมเดลของคุณ

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

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

หมายเหตุ: คุณควรรักษาหน้าต่างชุดข้อมูลสำหรับการฝึกให้คงที่เพื่อการฝึกที่มีประสิทธิภาพมากขึ้น เพื่อให้ทุกครั้งที่คุณเพิ่มการสังเกตใหม่ลงในชุดข้อมูลสำหรับการฝึก คุณจะลบการสังเกตจากจุดเริ่มต้นของชุดข้อมูล

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

การตรวจสอบแบบ walk-forward เป็นมาตรฐานทองคำของการประเมินโมเดลอนุกรมเวลาและแนะนำสำหรับโครงการของคุณเอง

  1. ก่อนอื่น สร้างจุดข้อมูลการทดสอบสำหรับแต่ละขั้นตอน HORIZON

    test_shifted = test.copy()
    
    for t in range(1, HORIZON+1):
        test_shifted['load+'+str(t)] = test_shifted['load'].shift(-t, freq='H')
    
    test_shifted = test_shifted.dropna(how='any')
    test_shifted.head(5)
    
    load load+1 load+2
    2014-12-30 00:00:00 0.33 0.29 0.27
    2014-12-30 01:00:00 0.29 0.27 0.27
    2014-12-30 02:00:00 0.27 0.27 0.30
    2014-12-30 03:00:00 0.27 0.30 0.41
    2014-12-30 04:00:00 0.30 0.41 0.57

    ข้อมูลจะถูกเลื่อนในแนวนอนตามจุด horizon

  2. ทำการพยากรณ์ในข้อมูลการทดสอบของคุณโดยใช้วิธี sliding window ในลูปที่มีขนาดเท่ากับความยาวของข้อมูลการทดสอบ:

    %%time
    training_window = 720 # dedicate 30 days (720 hours) for training
    
    train_ts = train['load']
    test_ts = test_shifted
    
    history = [x for x in train_ts]
    history = history[(-training_window):]
    
    predictions = list()
    
    order = (2, 1, 0)
    seasonal_order = (1, 1, 0, 24)
    
    for t in range(test_ts.shape[0]):
        model = SARIMAX(endog=history, order=order, seasonal_order=seasonal_order)
        model_fit = model.fit()
        yhat = model_fit.forecast(steps = HORIZON)
        predictions.append(yhat)
        obs = list(test_ts.iloc[t])
        # move the training window
        history.append(obs[0])
        history.pop(0)
        print(test_ts.index[t])
        print(t+1, ': predicted =', yhat, 'expected =', obs)
    

    คุณสามารถดูการฝึกที่เกิดขึ้น:

    2014-12-30 00:00:00
    1 : predicted = [0.32 0.29 0.28] expected = [0.32945389435989236, 0.2900626678603402, 0.2739480752014323]
    
    2014-12-30 01:00:00
    2 : predicted = [0.3  0.29 0.3 ] expected = [0.2900626678603402, 0.2739480752014323, 0.26812891674127126]
    
    2014-12-30 02:00:00
    3 : predicted = [0.27 0.28 0.32] expected = [0.2739480752014323, 0.26812891674127126, 0.3025962399283795]
    
  3. เปรียบเทียบการพยากรณ์กับโหลดจริง:

    eval_df = pd.DataFrame(predictions, columns=['t+'+str(t) for t in range(1, HORIZON+1)])
    eval_df['timestamp'] = test.index[0:len(test.index)-HORIZON+1]
    eval_df = pd.melt(eval_df, id_vars='timestamp', value_name='prediction', var_name='h')
    eval_df['actual'] = np.array(np.transpose(test_ts)).ravel()
    eval_df[['prediction', 'actual']] = scaler.inverse_transform(eval_df[['prediction', 'actual']])
    eval_df.head()
    

    ผลลัพธ์

    timestamp h prediction actual
    0 2014-12-30 00:00:00 t+1 3,008.74 3,023.00
    1 2014-12-30 01:00:00 t+1 2,955.53 2,935.00
    2 2014-12-30 02:00:00 t+1 2,900.17 2,899.00
    3 2014-12-30 03:00:00 t+1 2,917.69 2,886.00
    4 2014-12-30 04:00:00 t+1 2,946.99 2,963.00

    สังเกตการพยากรณ์ข้อมูลรายชั่วโมง เทียบกับโหลดจริง ความแม่นยำเป็นอย่างไร?

ตรวจสอบความแม่นยำของโมเดล

ตรวจสอบความแม่นยำของโมเดลของคุณโดยทดสอบค่า mean absolute percentage error (MAPE) จากการพยากรณ์ทั้งหมด

🧮 แสดงคณิตศาสตร์

MAPE

MAPE ใช้เพื่อแสดงความแม่นยำของการพยากรณ์ในรูปแบบอัตราส่วนที่กำหนดโดยสูตรด้านบน ความแตกต่างระหว่างค่าจริงและค่าที่พยากรณ์
ถูกหารด้วยค่าจริง
"ค่าที่เป็นบวกในสูตรนี้จะถูกนำมารวมกันสำหรับทุกจุดที่พยากรณ์ในช่วงเวลา และหารด้วยจำนวนจุดที่พอดี n" wikipedia

  1. แสดงสมการในโค้ด:

    if(HORIZON > 1):
        eval_df['APE'] = (eval_df['prediction'] - eval_df['actual']).abs() / eval_df['actual']
        print(eval_df.groupby('h')['APE'].mean())
    
  2. คำนวณ MAPE ของการพยากรณ์หนึ่งขั้น:

    print('One step forecast MAPE: ', (mape(eval_df[eval_df['h'] == 't+1']['prediction'], eval_df[eval_df['h'] == 't+1']['actual']))*100, '%')
    

    MAPE ของการพยากรณ์หนึ่งขั้น: 0.5570581332313952 %

  3. แสดงผล MAPE ของการพยากรณ์หลายขั้น:

    print('Multi-step forecast MAPE: ', mape(eval_df['prediction'], eval_df['actual'])*100, '%')
    
    Multi-step forecast MAPE:  1.1460048657704118 %
    

    ตัวเลขที่ต่ำถือว่าดี: พิจารณาว่าการพยากรณ์ที่มี MAPE เท่ากับ 10 หมายถึงค่าที่พยากรณ์ผิดไป 10%

  4. แต่เช่นเคย การวัดความแม่นยำแบบนี้จะเห็นได้ง่ายขึ้นเมื่อดูภาพ ดังนั้นมาลองพล็อตกราฟกัน:

     if(HORIZON == 1):
        ## Plotting single step forecast
        eval_df.plot(x='timestamp', y=['actual', 'prediction'], style=['r', 'b'], figsize=(15, 8))
    
    else:
        ## Plotting multi step forecast
        plot_df = eval_df[(eval_df.h=='t+1')][['timestamp', 'actual']]
        for t in range(1, HORIZON+1):
            plot_df['t+'+str(t)] = eval_df[(eval_df.h=='t+'+str(t))]['prediction'].values
    
        fig = plt.figure(figsize=(15, 8))
        ax = plt.plot(plot_df['timestamp'], plot_df['actual'], color='red', linewidth=4.0)
        ax = fig.add_subplot(111)
        for t in range(1, HORIZON+1):
            x = plot_df['timestamp'][(t-1):]
            y = plot_df['t+'+str(t)][0:len(x)]
            ax.plot(x, y, color='blue', linewidth=4*math.pow(.9,t), alpha=math.pow(0.8,t))
    
        ax.legend(loc='best')
    
    plt.xlabel('timestamp', fontsize=12)
    plt.ylabel('load', fontsize=12)
    plt.show()
    

    โมเดลซีรีส์เวลา

🏆 กราฟที่ดูดีมาก แสดงให้เห็นว่าโมเดลมีความแม่นยำสูง ยอดเยี่ยมมาก!


🚀ความท้าทาย

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

แบบทดสอบหลังบทเรียน

ทบทวนและศึกษาด้วยตัวเอง

บทเรียนนี้ครอบคลุมเพียงพื้นฐานของการพยากรณ์ซีรีส์เวลาด้วย ARIMA ใช้เวลาเพิ่มเติมเพื่อเพิ่มพูนความรู้ของคุณโดยสำรวจ repository นี้ และโมเดลประเภทต่าง ๆ เพื่อเรียนรู้วิธีอื่น ๆ ในการสร้างโมเดลซีรีส์เวลา

งานที่ได้รับมอบหมาย

โมเดล ARIMA ใหม่


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