<jupyter_start><jupyter_text>เคสก่อน ๆ เราได้นำ Deep Neural Networks มาประยุกต์ใช้กับงาน [รูปภาพ Vision](https://www.bualabs.com/archives/530/machine-learning-ai-skin-disease-classification-custom-dataset-how-to-build-model-resnet50-deep-learning-python-image-classification-ep-4/), ข้อความ [NLP](https://www.bualabs.com/archives/926/sentiment-analysis-imdb-movie-review-ulmfit-sentiment-analysis-ep-1/) ได้ผลลัพธ์ออกมาน่าพอใจ แต่ในเคสนี้เราจะนำ Deep Neural Networks มาประยุกต์ใช้กับงานที่เรียกได้ว่าใกล้เคียงกับงานที่เราทำประจำวันมากที่สุด ก็คือ ข้อมูลแบบตาราง ไม่ว่าจะเป็น Excel, Relational Database, SQL, CSV เราก็สามารถนำ Deep Neural Networks มาประยุกต์ใช้ได้ และในบางโปรแกรมก็เริ่มมี Feature นี้มาให้ในตัวแล้ว เช่น ML.PREDICT ใน Bigquery ของ Google Cloud Platform  0. Magic Commands<jupyter_code>%reload_ext autoreload
%autoreload 2
%matplotlib inline<jupyter_output><empty_output><jupyter_text>1. Import Library<jupyter_code>from fastai import *
from fastai.tabular import *<jupyter_output><empty_output><jupyter_text>2. ข้อมูลเคสนี้เราจะใช้ Dataset ตารางรายได้สำมะโมประชากร Census Income จาก Adult Data Setเราจะให้โมเดลทำนายว่ารายได้ของบุคคล จะสูงหรือต่ำกว่า 50,000 USD ต่อปี จากข้อมูลประกอบต่าง ๆ เช่น การศึกษา อาชีพ สถานะสมรส เพศ สีผิว เชื้อขาติ etc.* คุณลักษณะ Dataset:  หลายตัวแปร* จำนวนข้อมูล: 48,842 Record* สาขา: สังคม* รูปแบบข้อมูล: หมวดหมู่ [Categorical](https://www.bualabs.com/archives/2175/categorize-prepare-categorical-data-one-hot-encoding-map-feedforward-machine-learning-preprocessing-ep-3/), [ตัวเลข Integer](https://www.bualabs.com/archives/1468/what-is-cardinal-ordinal-nominal-numbers-different-compare-operator/)* จำนวน Column: 14* วันที่ 1996-05-01* งานที่เกี่ยวข้อง: [Classification](https://www.bualabs.com/archives/469/how-to-deep-learning-pets-cats-dogs-image-classification-with-fastai-v1-ep-1/)* มี[ข้อมูลไม่ครบ](https://www.bualabs.com/archives/2085/what-is-preprocessing-handle-missing-value-fill-na-null-nan-before-feedforward-machine-learning-preprocessing-ep-1/)? Yes<jupyter_code>path = untar_data(URLs.ADULT_SAMPLE)
path<jupyter_output><empty_output><jupyter_text>ls ดูว่ามีไฟล์อะไรบ้าง<jupyter_code>path.ls()<jupyter_output><empty_output><jupyter_text>โหลดไฟล์ adult.csv ขึ้นมาดู<jupyter_code>dataframe = pd.read_csv(path/'adult.csv')<jupyter_output><empty_output><jupyter_text>เปิดดู 5 แถวแรก<jupyter_code>dataframe.head()<jupyter_output><empty_output><jupyter_text>ดูสถิติของข้อมูล สังเกต1. count แต่ละ Column ไม่เท่ากัน แสดงว่ามีข้อมูลขาดไป2. unique คือ จำนวนหมวดหมู่ของข้อมูลแบบ Category แต่ละ Column3. top, freq คือ ค่าและจำนวนครั้ง ของข้อมูลที่ปรากฎบ่อยที่สุด4. mean, std, min, ... max ข้อมูลสถิติ ของข้อมูลตัวเลข<jupyter_code>dataframe.describe(include='all')<jupyter_output><empty_output><jupyter_text>3. เตรียมข้อมูล เราต้องบอก [Databunch](https://www.bualabs.com/archives/2318/databunch-learner-refactor-neural-network-training-loop-neural-network-ep-9/) ว่า Column ไหนเป็นข้อมูลชนิดอะไร1. dependent_variable คือ ข้อมูลที่เราจะทำนาย2. [category_column_names](https://www.bualabs.com/archives/2175/categorize-prepare-categorical-data-one-hot-encoding-map-feedforward-machine-learning-preprocessing-ep-3/) คือ Column ข้อมูลแบบหมวดหมู่ ไม่ต่อเนื่อง มีจำนวนเป็นไปได้จำกัด3. continuous_column_names คือ Column ข้อมูลตัวเลข แบบค่าต่อเนื่อง มีจำนวนเป็นไปได้ไม่จำกัด4. preprocesses คือ เราจะเตรียมข้อมูลอย่างไร ก่อนป้อนให้โมเดล เช่น [FillMissing](https://www.bualabs.com/archives/2085/what-is-preprocessing-handle-missing-value-fill-na-null-nan-before-feedforward-machine-learning-preprocessing-ep-1/) ใส่ค่าที่ขาดไป, [Categorify](https://www.bualabs.com/archives/2175/categorize-prepare-categorical-data-one-hot-encoding-map-feedforward-machine-learning-preprocessing-ep-3/) สร้าง [Embedding](https://www.bualabs.com/archives/996/visualization-embedding-deep-learning-model-deep-neural-networks-tensorboard-ep-2/) สำหรับข้อมูล Category, Normailze สำหรับข้อมูลตัวเลข*เรื่อง Normalize, Embedding เราจะอธิบายต่อไป*<jupyter_code>dependent_variable = 'salary'
category_column_names = ['workclass', 'education', 
                         'marital-status', 'occupation', 
                         'relationship', 'race']
continuous_column_names = ['age', 'fnlwgt', 'education-num']

preprocesses = [FillMissing, Categorify, Normalize]<jupyter_output><empty_output><jupyter_text>Split Dataset แบ่งข้อมูล [Training Set / Validation Set](https://www.bualabs.com/archives/532/what-is-training-set-why-train-test-split-training-set-validation-set-test-set/) ให้ Record ที่ 800-1000 เอาไว้เป็น Validation Set<jupyter_code>tabularlist_test = TabularList.from_df(dataframe.iloc[800:1000].copy(), 
                           path=path, 
                           cat_names=category_column_names, 
                           cont_names=continuous_column_names, 
                           procs=preprocesses)<jupyter_output><empty_output><jupyter_text>สร้าง Databunch จากการกำหนดค่าด้านบน<jupyter_code>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())<jupyter_output><empty_output><jupyter_text>สำรวจข้อมูล ดึงข้อมูลจาก Dataset ออกมาจำนวน 1 Batch ขนาดตาม [Batch Size](https://www.bualabs.com/archives/729/what-is-batch-size-in-deep-neural-networks-how-to-adjust-machine-learning-model-accuracy-deep-learning-hyperparameter-tuning-ep-2/) ที่กำหนด*เราสามารถรัน cell นี้หลายครั้ง เพื่อเรียกดู batch ต่อ ๆ ไป ได้เรื่อย ๆ เป็นการสำรวจข้อมูล*<jupyter_code>databunch.show_batch(rows=10)<jupyter_output><empty_output><jupyter_text>สังเกตตัวเลข อายุมีค่าเป็นติดลบ เนื่องจากการ [Normailze](https://www.bualabs.com/archives/2100/what-is-normalization-feature-scaling-rescaling-normalization-standardization-feedforward-train-machine-learning-preprocessing-ep-2/) จะทำให้ Mean = 0, Standard Deviation = 1 และ มี Column ใหม่ คื education-num_na ขึ้นมาเพื่อบอกว่า มีการเติมค่าที่หายไปให้กับ Record นี้<jupyter_code>databunch.classes<jupyter_output><empty_output><jupyter_text>4. สร้างโมเดลเนื่องจากตารางเล็ก ๆ ไม่ซับซ้อน เราจะสร้างโมเดล ที่ประกอบด้วย Dense Layer ที่ Deep แค่ 2 Hidden Layer โดยที่เหลือใช้ค่า Default ทั้งหมด เรื่องชนิดของ Layer เช่น Dense ไว้เราจะอธิบายต่อไป<jupyter_code>learner = tabular_learner(databunch, layers=[256, 128], 
                          metrics=accuracy, 
                          callback_fns=ShowGraph)<jupyter_output><empty_output><jupyter_text>5. เริ่มต้นเทรนโมเดลเทรนด้วยค่า Default ไป [1 Cycle](https://www.bualabs.com/archives/2452/schedule-hyperparameter-train-machine-learning-deep-neural-network-one-cycle-learning-rate-neural-network-ep-13/) สามารถใช้ [Learning Rate](https://www.bualabs.com/archives/618/learning-rate-deep-learning-how-to-hyperparameter-tuning-ep-1/) สูง ๆ ได้เลย<jupyter_code>learner.fit_one_cycle(1, 2e-1)<jupyter_output><empty_output><jupyter_text>สำเร็จแล้ว เพียงแค่เวลา 3 วินาที เราเทรน Model ได้ [accuracy](https://www.bualabs.com/archives/1968/what-is-metrics-confusion-matrix-accuracy-precision-recall-f1-score-difference-metrics-ep-1/) ประมาณ 0.84 หรือ ความแม่นยำประมาณ 84%<jupyter_code>learner.save("05a-tabular")
learner.load("05a-tabular");<jupyter_output><empty_output><jupyter_text>6. ดูผลลัพธ์ ลองดูข้อมูล Record ที่ 850<jupyter_code>row = dataframe.iloc[850]
row<jupyter_output><empty_output><jupyter_text>ให้โมเดลทำนายกัน<jupyter_code>learner.predict(row)<jupyter_output><empty_output><jupyter_text>โมเดลทำนายได้ถูกต้อง  7. สรุป 1. การเทรนโมเดลหลัก ๆ จะคล้าย ๆ กัน แต่สำหรับข้อมูลแบบตาราง จะมีประเด็นด้านข้อมูลไม่สมบูรณ์ กรอกไม่ครบ [ข้อมูลขาดหาย](https://www.bualabs.com/archives/2085/what-is-preprocessing-handle-missing-value-fill-na-null-nan-before-feedforward-machine-learning-preprocessing-ep-1/) และเนื่องจากโมเดลรับได้แต่ตัวเลข จึงจำเป็นต้องมีการทำ [Preprocessing](https://www.bualabs.com/archives/2693/data-block-api-data-pipeline-machine-learning-supervised-learning-preprocessing-ep-5/) และ [Feature Engineering](https://www.bualabs.com/archives/1495/what-is-feature-engineering-machine-learning-rms-titanic-survival-prediction-deep-learning-tabular-data-ep-2/) เตรียมข้อมูลก่อนเทรน2. เราสามารถสร้าง โมเดล Classification จากข้อมูลแบบตารางได้ไม่ยาก ใช้เวลาเทรนไม่นาน ไม่จำเป็นต้องใช้ [GPU](https://www.bualabs.com/archives/1426/why-gpu-require-train-deep-learning-compare-cpu-vs-gpu-deep-neural-network-hardware-ep-2/)3. โมเดลแบบนี้ สามารถนำไปประยุกต์ใช้ในระบบงานออฟฟิศทั่วไป ได้อย่างหลากหลาย เพราะข้อมูลในภาคธุรกิจส่วนใหญ่ก็จะอยู่ในรูปแบบตารางแบบนี้อยู่แล้ว  Credit * [FastAI: Practical Deep Learning for Coders, v3 - Lesson 4](https://course.fast.ai/videos/?lesson=4)* [Adult Data Set](https://archive.ics.uci.edu/ml/datasets/adult)<jupyter_code><jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1522921522921523, 'fraction_numerical': 0.02197802197802198, 'mean_word_length': 5.784638554216867, 'pattern_counts': {'":': 0, '<': 73, '<?xml version=': 0, '>': 73, 'https://': 23, 'lorem ipsum': 0, 'www.': 21, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 3, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '18', 'dir': 'jupyter-structured-clean-dedup', 'id': '99145', 'license': 'MIT', 'n_tokens_mistral': 4695, 'n_tokens_neox': 4823, 'n_words': 355, 'path': 'nbs/05a-tabular-adult-nn.ipynb', 'repo_name': 'gnoparus/bualabs', 'size': '9009'}