Botnoi-Classroom : Rod-Kaidee Car price prediction
หลังจากที่ได้เรียนรู้เกี่ยวกับ กระบวนการทางด้าน Data Science กับทีมงาน Data Scientist ของ Botnoi ก็ได้รับความรู้มากมายจากทั้งโปรเจคที่ทำ และ จากประสบการณ์ที่ทีมงานได้แชร์ให้
โดยโปรเจคสุดท้ายที่ได้ทำคือโปรเจค car price prediction จาก data ของ website Kaidee.com (Source : https://rod.kaidee.com/c11-auto-car/ )
เรามาดูกันดีกว่าครับว่าโปรเจคนี้เป็นอย่างไร
โดยสามารถ download Notebook ได้ตามลิ้งด้านล่าง
Colab :https://colab.research.google.com/drive/1CKXByvAKiwiDKUM08n9C2hDHzHF8EP_0?usp=sharing
Data :https://github.com/BankNatchapol/Data-Science/raw/master/BotNoi/
Load Data
ในส่วนแรกจะเป็นการ Load Data มาซึ่งตัว Data มีลักษณะดังนี้
ใน Data นี้เป็น Data ของรถ ซึ่ง Labels คือ price ของรถ
โดยข้อมูลแต่ละตัวมีความหมายดังนี้
- price (Y) : ราคาของรถ (บาท)
- desc : คำอธิบายของรถ
- ad_id : product id ของรถ
- location : จังหวัดที่อยู่ ของเจ้าของ
- timestamp : เวลาที่โพสขาย
- mileage : ระยะไมล์ของรถ (กม.)
- brand : ยี่ห้อของรถ
- model : รุ่นของรถ
- year : ปีที่ซื้อรถ
- fuel : ประเภทของน้ำมัน ที่รถใช้
- transmission : ประเภทของรถ
- color : สีของรถ
- car_type : ประเภทของรถ
Preprocess Data
เริ่มทำการ preprocess data
โดยทำการดูว่ามีข้อมูล Nan ใน dataset หรือไม่
data.isna().sum()
ทำการจัดการกับข้อมูล Nan
เริ่มจาก feature desc
จากการ Explore Data พบว่าข้อมูลที่มีคำอธิบายยาวกว่า จะมีราคาเฉลี่ยที่มากกว่า ดังนั้น ความยาวของคำอธิบาย น่าจะมีความสัมพันธ์กับ price
จึงทำการเปลี่ยน data จาก ข้อมูลคำอธิบาย String เป็น ความยาวของคำอธิบาย
data['desc'] = data['desc'].str.len()
ทำการ fill ข้อมูล Nan ด้วยค่า 0 เนี่องจากการที่ไม่มีคำอธิบายของรถ เหมือนกับ ความยาวเป็น 0
data['desc'] = data['desc'].fillna(0.0)
จัดการกับ feature ad_id
จากการ research พบว่า ad_id เป็น feature ที่มีความหมายถึงเลข product id ซึ่งเลข product id เป็นค่าแบบสุ่ม ดังนั้น feature ad_id น่าจะไม่มีความสัมพันธ์กับ feature price
ทำการตัด column ad_id ออก
data = data.drop('ad_id', axis = 1)
จัดการกับ feature mileage
จากการ Explore feature mileage พบว่ามีข้อมูลที่ผิดปกติ
ทำการจัดการข้อมูลที่ผิดปกติ โดยการ replace “x” ด้วย “0" และ ตัด “.” ออก
data['mileage'][~mileage_nan] = notNan_data.str.split('.',1)
.apply(lambda x:x[0])
.str.replace('x','0')
.str.replace(',','')
จากนั้นทำการ fill ค่า Nan ใน feature mileage
จากที่ mileage มีค่า Nan จำนวนมาก จึงตรวจสอบ price mean ของกลุ่ม Nan เทียบกับกลุ่มที่ ไม่ใช่ Nan
พบว่าค่า price mean ของกลุ่มที่มีค่า mileage เป็น Nan จะมี price ที่ต่ำกว่า กลุ่มที่ค่า mileage ไม่ใช่ Nan
ทำการหาค่า mileage mean ของ กลุ่มรถราคาต่ำ และ กลุ่มรถราคาสูง
แทนค่า Nan ใน mileage ด้วย mileage ของ กลุ่มราคาต่ำ
lowerMean = mileage_data['price'].astype(float) < mileage_data['price'].astype(float).mean()lower25P = mileage_data[lowerMean]['mileage'].astype(float).mean()data['mileage'] = data['mileage'].fillna(lower25P)
จัดการกับ feature transmission และ color
ทำการแทนค่า Nan ใน feature transmission และ color ด้วยค่า mode
transMode = data['transmission'].mode()[0] data['transmission'] = data['transmission'].fillna(transMode)colorMode = data['color'].mode()[0]
data['color'] = data['color'].fillna(colorMode)
ทำ dummies กับข้อมูลที่เป็น categorical
โดย feature ที่ต้องทำ dummy คือ ‘location’, ‘brand’, ‘model’, ‘fuel’, ‘transmission’, ‘color’, ‘car_type’ และ ทำการ drop feature เดิมก่อน dummy
dummiesList = ['location', 'brand', 'model', 'fuel', 'transmission', 'color', 'car_type']for dummy in dummiesList: dummiesTemp = pd.get_dummies(data[[dummy]]) data = pd.concat([data,dummiesTemp ],axis=1)data.drop(dummiesList,axis=1,inplace=True)
แบ่ง train/test , data/label
MinMaxScaler
ทำการ Scale ข้อมูลด้วย MinMaxScaler เพื่อให้ข้อมูลอยู่ใน range 0 ถึง 1
mx = all_data_x.max(axis=0)mi = all_data_x.min(axis=0)train_set_x = (train_set_x - mi)/(mx - mi)test_set_x = (test_set_x - mi)/(mx - mi)
Train
สร้าง train_model function เพื่อใช้ train ข้อมูลที่ต้องการ ให้สามารถปรับ hyperparameters ได้ง่าย
Evaluate
ทำการ Evaluate เพื่อดูผลการทดลอง
GBR_params = { 'learning_rate' : 0.13, 'n_estimators' :65, 'max_depth' : 8, 'alpha' : 0.2, 'subsample':1.0, 'max_features':'auto', 'random_state':552 }model = train_model('GradientBoostingRegressor',train_set_x, train_set_y,GBR_params)score = model.score(train_set_x, train_set_y)print('train_set score = ',score)score = model.score(test_set_x, test_set_y)print('test_set score = ',score)
Pipeline
รวมกระบวนการที่ทำมาทั้งหมดเป็น function เพื่อทำเป็น Pipeline
ทำการ run pipeline
params = { 'learning_rate' : 0.13, 'n_estimators' :65, 'max_depth' : 8, 'alpha' : 0.2, 'subsample':1.0, 'max_features':'auto', 'random_state':552 }acc = []for i in range(1): score, model = pipeline(train_set, test_set, params); print( 'score : ',score) acc.append(score)