ใน ep ก่อน ๆ เราได้เห็นตัวอย่างการนำ Machine Learning, Deep Learning มาประยุกต์ใช้งานเกี่ยวกับวิเคราะห์รูปภาพ วิเคราะห์ข้อความ ทั้งหมดถือว่าเป็นข้อมูลแบบ Unstructure Data แต่งานประมวลผลข้อมูลส่วนใหญ่ในปัจจุบันจะเป็น ข้อมูลแบบมีโครงสร้าง Structure Data เช่น ตาราง เป็นหลัก แล้วเราจะนำ Deep Learning มาประยุกต์ใชักับงานเหล่านี้อย่างไร

ตัวอย่างข้อมูลแบบตาราง ในภาคธุรกิจ

tabular data 01 from Excel Screenshot
tabular data 01 from Excel Screenshot

เรามาเริ่มกันเลย

Open In Colab

เคสก่อน ๆ เราได้นำ Deep Neural Networks มาประยุกต์ใช้กับงาน รูปภาพ Vision, ข้อความ NLP ได้ผลลัพธ์ออกมาน่าพอใจ แต่ในเคสนี้เราจะนำ Deep Neural Networks มาประยุกต์ใช้กับงานที่เรียกได้ว่าใกล้เคียงกับงานที่เราทำประจำวันมากที่สุด ก็คือ ข้อมูลแบบตาราง

ไม่ว่าจะเป็น Excel, Relational Database, SQL, CSV เราก็สามารถนำ Deep Neural Networks มาประยุกต์ใช้ได้ และในบางโปรแกรมก็เริ่มมี Feature นี้มาให้ในตัวแล้ว เช่น ML.PREDICT ใน Bigquery ของ Google Cloud Platform

0. Magic Commands

In [0]:
%reload_ext autoreload
%autoreload 2
%matplotlib inline

1. Import Library

In [0]:
from fastai import *
from fastai.tabular import *

2. ข้อมูล

เคสนี้เราจะใช้ Dataset ตารางรายได้สำมะโมประชากร Census Income จาก Adult Data Set

เราจะให้โมเดลทำนายว่ารายได้ของบุคคล จะสูงหรือต่ำกว่า 50,000 USD ต่อปี จากข้อมูลประกอบต่าง ๆ เช่น การศึกษา อาชีพ สถานะสมรส เพศ สีผิว เชื้อขาติ etc.

In [0]:
path = untar_data(URLs.ADULT_SAMPLE)
path
Out[0]:
PosixPath('/home/jupyter/.fastai/data/adult_sample')

ls ดูว่ามีไฟล์อะไรบ้าง

In [0]:
path.ls()
Out[0]:
[PosixPath('/home/jupyter/.fastai/data/adult_sample/export.pkl'),
 PosixPath('/home/jupyter/.fastai/data/adult_sample/adult.csv'),
 PosixPath('/home/jupyter/.fastai/data/adult_sample/models')]

โหลดไฟล์ adult.csv ขึ้นมาดู

In [0]:
dataframe = pd.read_csv(path/'adult.csv')

เปิดดู 5 แถวแรก

In [0]:
dataframe.head()
Out[0]:
ageworkclassfnlwgteducationeducation-nummarital-statusoccupationrelationshipracesexcapital-gaincapital-losshours-per-weeknative-countrysalary
049Private101320Assoc-acdm12.0Married-civ-spouseNaNWifeWhiteFemale0190240United-States>=50k
144Private236746Masters14.0DivorcedExec-managerialNot-in-familyWhiteMale10520045United-States>=50k
238Private96185HS-gradNaNDivorcedNaNUnmarriedBlackFemale0032United-States<50k
338Self-emp-inc112847Prof-school15.0Married-civ-spouseProf-specialtyHusbandAsian-Pac-IslanderMale0040United-States>=50k
442Self-emp-not-inc822977th-8thNaNMarried-civ-spouseOther-serviceWifeBlackFemale0050United-States<50k

ดูสถิติของข้อมูล สังเกต

  1. count แต่ละ Column ไม่เท่ากัน แสดงว่ามีข้อมูลขาดไป
  2. unique คือ จำนวนหมวดหมู่ของข้อมูลแบบ Category แต่ละ Column
  3. top, freq คือ ค่าและจำนวนครั้ง ของข้อมูลที่ปรากฎบ่อยที่สุด
  4. mean, std, min, ... max ข้อมูลสถิติ ของข้อมูลตัวเลข
In [0]:
dataframe.describe(include='all')
Out[0]:
ageworkclassfnlwgteducationeducation-nummarital-statusoccupationrelationshipracesexcapital-gaincapital-losshours-per-weeknative-countrysalary
count32561.000000325613.256100e+043256132074.000000325613204932561325613256132561.00000032561.00000032561.0000003256132561
uniqueNaN9NaN16NaN715652NaNNaNNaN422
topNaNPrivateNaNHS-gradNaNMarried-civ-spouseProf-specialtyHusbandWhiteMaleNaNNaNNaNUnited-States<50k
freqNaN22696NaN10501NaN149764073131932781621790NaNNaNNaN2917024720
mean38.581647NaN1.897784e+05NaN10.079815NaNNaNNaNNaNNaN1077.64884487.30383040.437456NaNNaN
std13.640433NaN1.055500e+05NaN2.572999NaNNaNNaNNaNNaN7385.292085402.96021912.347429NaNNaN
min17.000000NaN1.228500e+04NaN1.000000NaNNaNNaNNaNNaN0.0000000.0000001.000000NaNNaN
25%28.000000NaN1.178270e+05NaN9.000000NaNNaNNaNNaNNaN0.0000000.00000040.000000NaNNaN
50%37.000000NaN1.783560e+05NaN10.000000NaNNaNNaNNaNNaN0.0000000.00000040.000000NaNNaN
75%48.000000NaN2.370510e+05NaN12.000000NaNNaNNaNNaNNaN0.0000000.00000045.000000NaNNaN
max90.000000NaN1.484705e+06NaN16.000000NaNNaNNaNNaNNaN99999.0000004356.00000099.000000NaNNaN

3. เตรียมข้อมูล

เราต้องบอก Databunch ว่า Column ไหนเป็นข้อมูลชนิดอะไร

  1. dependent_variable คือ ข้อมูลที่เราจะทำนาย
  2. category_column_names คือ Column ข้อมูลแบบหมวดหมู่ ไม่ต่อเนื่อง มีจำนวนเป็นไปได้จำกัด
  3. continuous_column_names คือ Column ข้อมูลตัวเลข แบบค่าต่อเนื่อง มีจำนวนเป็นไปได้ไม่จำกัด
  4. preprocesses คือ เราจะเตรียมข้อมูลอย่างไร ก่อนป้อนให้โมเดล เช่น FillMissing ใส่ค่าที่ขาดไป, Categorify สร้าง Embedding สำหรับข้อมูล Category, Normailze สำหรับข้อมูลตัวเลข

เรื่อง Normalize, Embedding เราจะอธิบายต่อไป

In [0]:
dependent_variable = 'salary'
category_column_names = ['workclass', 'education', 
                         'marital-status', 'occupation', 
                         'relationship', 'race']
continuous_column_names = ['age', 'fnlwgt', 'education-num']

preprocesses = [FillMissing, Categorify, Normalize]

Split Dataset แบ่งข้อมูล Training Set / Validation Set ให้ Record ที่ 800-1000 เอาไว้เป็น Validation Set

In [0]:
tabularlist_test = TabularList.from_df(dataframe.iloc[800:1000].copy(), 
                           path=path, 
                           cat_names=category_column_names, 
                           cont_names=continuous_column_names, 
                           procs=preprocesses)

สร้าง Databunch จากการกำหนดค่าด้านบน

In [0]:
databunch = (TabularList.from_df(dataframe, path=path, 
                                 cat_names=category_column_names, 
                                 cont_names=continuous_column_names, 
                                 procs=preprocesses)
                           .split_by_idx(list(range(800,1000)))
                           .label_from_df(cols=dependent_variable)
                           .add_test(tabularlist_test)
                           .databunch())

สำรวจข้อมูล

ดึงข้อมูลจาก Dataset ออกมาจำนวน 1 Batch ขนาดตาม Batch Size ที่กำหนด

เราสามารถรัน cell นี้หลายครั้ง เพื่อเรียกดู batch ต่อ ๆ ไป ได้เรื่อย ๆ เป็นการสำรวจข้อมูล

In [0]:
databunch.show_batch(rows=10)
workclasseducationmarital-statusoccupationrelationshipraceeducation-num_naagefnlwgteducation-numtarget
PrivateSome-collegeNever-marriedExec-managerialOwn-childWhiteFalse-1.4357-1.4029-0.0312<50k
PrivateSome-collegeDivorcedExec-managerialNot-in-familyWhiteFalse0.54340.5833-0.0312<50k
Private11thMarried-civ-spouseSalesHusbandWhiteFalse1.4229-0.3983-1.2046<50k
?Some-collegeNever-married?Own-childWhiteFalse-1.3624-0.1423-0.0312<50k
Private10thMarried-spouse-absentProtective-servNot-in-familyAsian-Pac-IslanderFalse1.4962-0.4868-1.5958<50k
Local-govDoctorateMarried-civ-spouseExec-managerialHusbandWhiteFalse1.1297-1.46852.3157>=50k
PrivateHS-gradMarried-civ-spouseHandlers-cleanersHusbandWhiteFalse-0.84930.1757-0.4224<50k
PrivateBachelorsMarried-civ-spouseExec-managerialHusbandWhiteFalse1.34960.09681.1422>=50k
PrivateSome-collegeMarried-civ-spouseSalesHusbandWhiteFalse2.00931.5243-0.0312<50k
PrivateBachelorsMarried-civ-spouseExec-managerialHusbandWhiteFalse-0.18960.10811.1422<50k

สังเกตตัวเลข อายุมีค่าเป็นติดลบ เนื่องจากการ Normailze จะทำให้ Mean = 0, Standard Deviation = 1 และ มี Column ใหม่ คื education-num_na ขึ้นมาเพื่อบอกว่า มีการเติมค่าที่หายไปให้กับ Record นี้

In [0]:
databunch.classes
Out[0]:
['<50k', '>=50k']

4. สร้างโมเดล

เนื่องจากตารางเล็ก ๆ ไม่ซับซ้อน เราจะสร้างโมเดล ที่ประกอบด้วย Dense Layer ที่ Deep แค่ 2 Hidden Layer โดยที่เหลือใช้ค่า Default ทั้งหมด เรื่องชนิดของ Layer เช่น Dense ไว้เราจะอธิบายต่อไป

In [0]:
learner = tabular_learner(databunch, layers=[256, 128], 
                          metrics=accuracy, 
                          callback_fns=ShowGraph)

5. เริ่มต้นเทรนโมเดล

เทรนด้วยค่า Default ไป 1 Cycle สามารถใช้ Learning Rate สูง ๆ ได้เลย

In [0]:
learner.fit_one_cycle(1, 2e-1)
epochtrain_lossvalid_lossaccuracytime
00.3512730.3782200.84000000:03

สำเร็จแล้ว

เพียงแค่เวลา 3 วินาที เราเทรน Model ได้ accuracy ประมาณ 0.84 หรือ ความแม่นยำประมาณ 84%

In [0]:
learner.save("05a-tabular")
In [0]:
learner.load("05a-tabular");

6. ดูผลลัพธ์

ลองดูข้อมูล Record ที่ 850

In [0]:
row = dataframe.iloc[850]
row
Out[0]:
age                           30
workclass              Local-gov
fnlwgt                    352542
education              Bachelors
education-num                 13
marital-status          Divorced
occupation                   NaN
relationship           Unmarried
race                       White
sex                       Female
capital-gain                   0
capital-loss                   0
hours-per-week                40
native-country     United-States
salary                      <50k
Name: 850, dtype: object

ให้โมเดลทำนายกัน

In [0]:
learner.predict(row)
Out[0]:
(Category <50k, tensor(0), tensor([0.9325, 0.0675]))

โมเดลทำนายได้ถูกต้อง

7. สรุป

  1. การเทรนโมเดลหลัก ๆ จะคล้าย ๆ กัน แต่สำหรับข้อมูลแบบตาราง จะมีประเด็นด้านข้อมูลไม่สมบูรณ์ กรอกไม่ครบ ข้อมูลขาดหาย และเนื่องจากโมเดลรับได้แต่ตัวเลข จึงจำเป็นต้องมีการทำ Preprocessing และ Feature Engineering เตรียมข้อมูลก่อนเทรน
  2. เราสามารถสร้าง โมเดล Classification จากข้อมูลแบบตารางได้ไม่ยาก ใช้เวลาเทรนไม่นาน ไม่จำเป็นต้องใช้ GPU
  3. โมเดลแบบนี้ สามารถนำไปประยุกต์ใช้ในระบบงานออฟฟิศทั่วไป ได้อย่างหลากหลาย เพราะข้อมูลในภาคธุรกิจส่วนใหญ่ก็จะอยู่ในรูปแบบตารางแบบนี้อยู่แล้ว
In [0]:
 

แชร์ให้เพื่อน:

Keng Surapong on FacebookKeng Surapong on GithubKeng Surapong on Linkedin
Keng Surapong
Project Manager at Bua Labs
The ultimate test of your knowledge is your capacity to convey it to another.

Published by Keng Surapong

The ultimate test of your knowledge is your capacity to convey it to another.

Enable Notifications    Ok No thanks