สกัดใจความสำคัญของข้อความด้วยเทคนิคการประมวลผลทางภาษาเบื้องต้น: TF-IDF, Part 2
สำหรับบทความนี้ เราจะมาลองเขียนโค้ดอย่างง่ายๆ เพื่อใช้งาน TF-IDF ที่ได้อธิบายไปในบทความที่แล้วกันครับ โดยทั่วไปแล้วข้อมูลข้อความที่สามารถนำมาวิเคราะห์นั้นสามารถนำมาได้จากหลากหลายแหล่งไม่ว่าจะเป็นจากไฟล์เอกสารที่มีอยู่หรือข้อความจากเว็บไซต์/โซเชียลมีเดีย (อ่านเพิ่มเติมได้ที่นี่) ข้อมูลที่เราจะนำมาใช้สำหรับตัวอย่างนี้จะเป็นข้อมูลตัวอย่างข่าวจากคลังข้อความ BEST Corpus ที่ได้ถูกพัฒนาโดย NECTEC สำหรับในขั้นตอนแรกเราจะทำการอ่านข้อความจากตัวอย่างข่าวทุกไฟล์ เข้ามาก่อนด้วยโค้ดทางด้านล่างโดยเราจะนำข้อความจากแต่ละไฟล์ไปใส่ลงในภายใน list
#import library ที่จำเป็น
import pandas as pd
import numpy as np
import string
#อ่านไฟล์ข่าวที่มีอยู่เข้ามา(มีอยู่ทั้งหมด 96 ไฟล์)
texts = []
for i in range(1,97):
f = open("BEST/BEST-TrainingSet/news/news_"+"{:05d}.txt".format(i),mode="r", encoding='utf-8')
texts.append(f.read())
f.close()
มา preprocess ข้อมูลกันก่อน
โดยทั่วไปแล้ว ก่อนที่เราจะสามารถนำเอาเทคนิคการประมวลผลภาษาธรรมชาติ (Natural Language Processing: NLP) มาใช้กับภาษาไทยได้นั้น อุปสรรคหลักอย่างหนึ่ง คือ ภาษาไทยไม่ได้มีการเว้นวรรคระหว่างคำเหมือนหลายภาษาอื่น (เช่น ภาษาอังกฤษ) ดังนั้น การ “ตัดคำ” หรือการแยกข้อความภาษาไทยออกเป็นคำเดี่ยวๆ จึงเป็นสิ่งที่จำเป็นแรกที่ต้องทำ ในปัจจุบัน ถึงแม้ว่าการประมวลผลภาษาไทยได้มีความก้าวหน้าจนสามารถทำได้ดีพอสมควรพร้อมทั้งได้มีการพัฒนา library ต่างๆ เช่น PyThaiNLP เพื่อช่วยในการทำงานแล้วนั้น การตัดคำภาษาไทยก็ยังไม่สามารถทำได้ถูกต้องสมบูรณ์ 100%
นอกจากการตัดคำแล้วนั้น ก่อนที่จะนำข้อความมาใช้วิเคราะห์ได้นั้นเราควรจะทำการเตรียมข้อมูลเพิ่มเติมเพื่อให้การวิเคราะห์มีประสิทธิภาพมากขึ้น ในตัวอย่างนี้เราจะใช้การเตรียมข้อมูลเบื้องต้นที่เพิ่มเติมเล็กน้อยโดยจะทำการกำจัดคำที่ไม่มีนัยสำคัญ (stop words), กำจัดตัวเลขและเครื่องหมายวรรคตอน, กำจัดช่องว่าง (white space) และเปลี่ยนตัวอักษรภาษาอังกฤษให้เป็นตัวพิมพ์เล็ก อย่างไรก็ตาม โดยปกตินั้น อาจยังมีการเตรียมข้อมูลรูปแบบอื่นที่สามารถทำได้อีกหลายหลายวิธีไม่ว่าจะเป็น การทำ Part of Speech Tagging (POS), Name Entity Recognition (NER), การจับกลุ่มคำที่มักปรากฏด้วยกัน, การหาความสัมพันธ์ของคำ, รวมไปถึงการเลือกกำจัดคำบางคำที่ไม่มีความสำคัญกับการวิเคราะห์ และอื่นๆ
ต่อไปเราจะมาพิจารณาข้อความจากไฟล์หนึ่ง (text[0]) ที่อ่านเข้ามาก่อน
'http://www.bangkokhealth.com/healthnews _ htdoc/healthnews _ detail.asp?Number=10506|nสงสัย|
ติด|หวัด|นก| |อีก|คน|ยัง|น่า|ห่วง|nตาม|ที่|<NE>นางประนอม ทองจันทร์</NE>| |กับ| |<NE>ด.ช.กิตติพงษ์ แหลมผักแว่น</NE>|
|และ| |<NE>ด.ญ.กาญจนา กรองแก้ว</NE>| |ป่วย|สงสัย|ติด|เชื้อ|ไข้|ขณะ|นี้|ยัง|ไม่|ดี|ขึ้น|nหลัง|เข้า|เยี่ยม|ดู|อาการ|ผู้|
ป่วย|แล้ว| |<NE>น.พ.จรัล</NE>|ประชุม|ร่วม|กับ|เจ้าหน้าที่|ทุก|
…
ปีก| |ได้|ทุก|พื้นที่| |ถ้า|เกิด|สงสัย|ว่า|ใน|พื้นที่|ใด|มี|สัตว์|ปีก|ป่วย|ตาย| |ซึ่ง|อาจ|ติด|เชื้อ|ไข้|หวัด|นก|ที่|กำลัง|ระบาด|
หนัก|อยู่|ใน|ขณะ|นี้|nหนังสือพิมพ์|ไทยรัฐ| |ปี|ที่| |55| |ฉบับ|ที่| |17052| |9|/|28|/|2004|
nhttp://www.bangkokhealth.com/healthnews _ htdoc/healthnews _ detail.asp?Number=10175|
nตรวจ|แนว|รบ|อาหาร|ปลอด|ภัย| |หลัง|ผ่าน|วิกฤต| |"|ไข้|หวัด|นก|"|nอาหาร|ถือ|เป็น|สิ่ง|ที่|จำเป็น|ต่อ|มนุษย์| |และ|
อาหาร|ที่|ปลอด|ภัย|เท่า|นั้น|จึง|จะ|ให้|คุณค่า|ต่อ|ร่างกาย|
…
รอง|ปลัด|<NE>กระทรวงสาธารณสุข</NE>|(|<NE>สธ.</NE>|)|ใน|ฐานะ|ผู้|อำนวย|การ|ศูนย์|ไข้|หวัด|นก| |
<NE>กระทรวงสาธารณสุข</NE>| |ให้|สัมภาษณ์|ว่า| |ใน|วัน|นี้| |(| |2| |<AB>มี.ค.</AB>|)|ไม่|มี|รายงาน|ผู้|ป่วย|
ยืนยัน|เป็น|ไข้|หวัด|นก| |และ|ผู้|สงสัย|ไข้|หวัด|นก|เพิ่ม| |มี|ผู้|ป่วย|ที่|ยืนยัน|เป็น|ไข้
…
สำหรับตัวอย่างนี้นั้น ข้อมูลจาก BEST Corpus ได้ถูกออกแบบมาสำหรับใช้พัฒนาโปรแกรมในการตัดคำอยู่แล้ว ดังนั้นเราจะสังเกตเห็นได้ว่าข้อความข่าวนี้ได้ถูกแยกเป็นคำๆ ไว้ให้แล้วโดยคั่นด้วยเครื่องหมาย “|” ซึ่งช่วยให้เราไม่ต้องเสียเวลาทำการแยกข้อความด้วยตัวเอง นอกจากนี้เรายังสังเกตได้ว่าในข้อมูลชุดนี้ คำบางคำมีสัญลักษณ์เพื่อบ่งบอกลักษณะของมันได้ด้วยเช่น <NE></NE> ระบุถึงคำที่เป็นชื่อเฉพาะ และ <AB></AB> ระบุถึงคำที่เป็นตัวอักษรย่อ อย่างไรก็ดี สำหรับตัวอย่างการวิเคราะห์เบื้องต้นในบทความนี้ เราจะไม่นำข้อมูลเพิ่มเติมเหล่านี้มาประกอบการพิจารณา
ข้อสังเกตอีกอย่างหนึ่งที่เราเห็นได้จากข้อมูลในไฟล์นี้คือ ข้อความภายในไฟล์มีบทความข่าวอยู่หลายบทความโดยจุดเริ่มต้นของแต่ละบทความจะเป็น URL ของเว็บไซต์ที่มาของบทความนั้นๆ เราจึงจะเขียน code ง่ายๆ เพื่อแยกบทความข่าวจากทุกไฟล์ที่อ่านเข้ามาออกจากกัน พร้อมทั้งทำการแยกคำต่างๆ ภายในบทความนั้นๆ ออกจากกันเลย
#ใช้ loop เพื่อให้ code ง่ายแก่การอ่าน
articles = []
for text in texts:
ar = []
for token in text.split("|"): #แบ่งคำด้วยเครื่องหมาย "|"
if ("www" in token.lower()):
if(len(ar)>0):
articles.append(ar)
ar =[]
else:
ar.append(token)
articles.append(ar)
เราจะพบว่าจำนวนบทความข่าวทั้งหมดมีอยู่ 1702 บทความด้วยกัน โดยที่ข้อมูลของแต่ละบทความตอนนี้มีลักษณะเป็น list ของคำต่างๆ เช่น
['nสงสัย', 'ติด', 'หวัด', 'นก', ' ', 'อีก', 'คน', 'ยัง', 'น่า', 'ห่วง', 'nตาม',
'ที่', '<NE>นางประนอม ทองจันทร์</NE>', ' ', …]
ในลำดับต่อไป เราจะทำการเปลี่ยนตัวอักษรภาษาอังกฤษให้เป็นตัวเล็ก, กำจัด marker <NE></NE> และ <AB></AB> , กำจัดตัวเลข ช่องว่างและเครื่องหมายวรรคตอน พร้อมทั้งคำที่ไม่มีนัยสำคัญออก ทั้งนี้คำที่ไม่มีนัยสำคัญในภาษาไทยจำนวนหนึ่งได้ถูกรวบรวมไว้ใน PyThaiNLP library
from pythainlp.corpus import thai_stopwords
stop_words= thai_stopwords()
print(stop_words)
ตัวอย่างของคำที่ไม่มีนัยสำคัญในภาษาไทย:
frozenset({'บอก', 'ต่างหาก', 'ควร', 'เขียน', 'ทำๆ', 'คราวๆ', 'มักจะ', 'เรียก',
'พวกคุณ', 'ใช้', 'ด้วยว่า', 'บางครั้ง', 'มอง', 'แต่ไร', 'ข้า', 'ยอมรับ', 'หากแม้',
'จน', 'การ', 'ทัน', 'ไง', 'เท่านี้', 'นอกเหนือ', 'แม้ว่า', 'เคย', 'หลาย', 'บ่อยๆ',
'สั้นๆ', 'ดั่งเก่า', 'ถึงเมื่อ', 'ส่วนน้อย', 'อย่างยิ่ง', 'ตามๆ', 'ช้านาน', 'หมดสิ้น', 'เสียนี่', 'โดย', …]
เราจึงเขียน function เพื่อกำจัดสิ่งที่กล่าวมาเหล่านี้ในด้านล่าง
def perform_removal(word):
#กำจัด marker <NE>, </NE>, <AB>, </AB>
for pair in (('<NE>', ''), ('</NE>', ''),('<AB>', ''), ('</AB>',''),('<POEM>',''), ('</POEM>','')):
word =word.replace(*pair)
#กำจัดช่องว่างก่อน/หลังคำ
word = word.strip()
#เปลี่ยนภาษาอังกฤษเป็นตัวอักษรตัวเล็ก
word = word.lower()
#กำจัดเครื่องหมายวรรคตอน
word = word.translate(str.maketrans('','', string.punctuation))
#กำจัด stop words และตัวเลขโดดๆ
if(word.isdigit() or (word in stop_words)):
return ""
else:
return word
จากนั้นเราจะนำ function นี้ไปใช้กับทุกคำในทุกบทความข่าว ผลลัพธ์ที่ได้อาจมีบางคำเป็น empty string เราจึง filter คำเหล่านั้นออกไปด้วย
docs = []
for article in articles:
doc = list(map(perform_removal,article))
doc = list(filter(lambda word: (word!=''),doc))
docs.append(doc)
สุดท้ายแล้ว docs จะเป็นใช้เก็บข้อมูลบทความต่างๆ ที่ได้ผ่านการเตรียมเรียบร้อยแล้วโดยแต่ละบทความจะอยู่ในรูปของ list ของคำดังที่แสดงให้ดูด้านล่าง
['สงสัย', 'ติด', 'หวัด', 'นก', 'คน', 'ห่วง', 'นางประนอม ทองจันทร์',
'ดชกิตติพงษ์ แหลมผักแว่น', 'ดญกาญจนา กรองแก้ว', 'ป่วย', 'สงสัย', 'ติด',
'เชื้อ', 'ไข้', 'ดี', 'เยี่ยม', 'ดู', 'อาการ', 'ป่วย', 'นพจรัล', 'ประชุม', …]
คำนวณหาค่า TF-IDF
ต่อไป เราจะคำนวณหาค่า TF-IDF ของแต่ละคำในแต่ละเอกสาร เนื่องจากค่าดังกล่าวนั้นถูกใช้อย่างแพร่หลายจึงมี library ที่ถูกสร้างและสามารถใช้งานเพื่อคำนวณได้ทันที ดังนั้นถึงแม้ว่าการเขียน code เพื่อคำนวณจะสามารถทำได้ไม่ยาก แต่เพื่อความรวดเร็วเราจะคำนวณโดยใช้ TfidfVectorizer จาก sklearn library
from sklearn.feature_extraction.text import TfidfVectorizer
TfidfVectorizer นั้นถูกออกแบบมาเพื่อให้ใช้งานได้ง่ายกับข้อความภาษาอังกฤษ ดังนั้นมันจึงมาพร้อมกับตัวแบ่งคำ (tokenizer) และ preprocessor สำหรับใช้เตรียมข้อความภาษาอังกฤษ แต่เนื่องจากข้อมูลที่เราจะนำมาใช้เป็นภาษาไทยและเราได้ทำการเตรียมข้อมูลเบื้องต้นและเปลี่ยนให้อยู่ในรูปแบบ list เรียบร้อยแล้ว เราจะไม่ใช้งานความสามารถเหล่านี้ ดังนั้นเราจะสร้าง identity function (function ที่ส่ง input ออกเป็น output ทันทีโดยไม่ได้ทำอะไร) ขึ้นมาอันหนึ่งเพื่อให้ TfidfVectorizer ใช้เป็น tokenizer และ preprocessor แทนอันที่เป็นค่า default
def identity_fun(text):
return text
จากนั้นเราก็สร้าง TfidfVectorizer แล้วทดลองสุ่มใช้กับเอกสาร 5 อันก่อน
tfidf_vectorizer = TfidfVectorizer(analyzer = 'word', #this is default
tokenizer=identity_fun, #does no extra tokenizing
preprocessor=identity_fun, #no extra preprocessor
token_pattern=None)
#สุ่มช่วงของ 5 เอกสารที่ติดกันมาทดลองใช้งาน
tfidf_vector= tfidf_vectorizer.fit_transform(docs[637:642])
tfidf_array = np.array(tfidf_vector.todense())
#แปลงเป็น DataFrame เพื่อง่ายแก่การอ่าน
df = pd.DataFrame(tfidf_array,columns=tfidf_vectorizer.get_feature_names())
df
จะได้ DataFrame ที่มีลักษณะดังรูปด้านล่าง

เราจะเห็นว่าในแต่ละบทความจะมีค่า TF-IDF ของแต่ละคำภายในแสดงอยู่ ต่อไปเราจะลองดูคำที่มีค่า TF-IDF สูงที่สุด 10 คำแรกของแต่ละบทความกัน
# คำที่มีค่า TF-IDF สูงที่สุด 10 คำแรกของแต่ละบทความ
print(df.apply(lambda s: s.nlargest(10).index.tolist(), axis=1).ravel())
จะได้ผลลัพธ์ดังต่อไปนี้
[list(['นายพชร', 'พรรค', 'ถาม', 'สอบสวน', 'พิจารณา', 'คดี', 'อัยการ', 'กรรมการ', 'เมือง', 'ดำเนิน'])
list(['เอสเอ็มแอล', 'ทำ', 'งบ', 'อำเภอ', 'บ้าน', 'โอกาส', 'ชุมชน', 'สัมมนา', 'หมู่', 'แก้'])
list(['พรรค', 'ลา', 'ถาม', 'ทำ', 'กติกา', 'คน', 'งาน', 'เลือกตั้ง', 'พรรคไทยรักไทย', 'นายก'])
list(['ญัตติ', 'วุฒิสภา', 'ประชุม', 'สว', 'สรรหา', 'เสนอ', 'กกต', 'รัฐธรรมนูญ', 'ฉวย', 'วิสามัญ'])
list(['เรียน', 'ปัญหา', 'เด็ก', 'โรง', 'ทำร้าย', 'พฤติกรรม', 'เลียน', 'ตบตี', 'กิจกรรม', 'เยาวชน'])]
จากผลลัพธ์ที่ได้เราจะลองมาพิจารณาเนื้อหา บทความที่ 4 (ตรงกับบทความหมายเลข 640) ดูเหมือนจะเกี่ยวข้องกับการสรรหาสมาชิกวุฒิสภาหรือ กกต. เมื่อพิจารณาบทความข่าวนั้น
<AB>สว.</AB>ร่างทรงฉวยโอกาสเสนอที่ประชุมเลือก<AB>กก.</AB>สรรหา<NE>กกต.</NE>
<AB>ส.ว.</AB>ร่างทรง ฉวยโอกาสหารือเสนอที่ประชุมเลือกกรรมการสรรหา <NE>กกต.</NE> ?<NE>สุชน</NE>? ไม่รับลูก บอกไม่เข้าข่ายยื่นเป็นญัตติ
(26<AB>มิ.ย.</AB>) เวลา 14.10<AB>น.</AB> ภายหลังหมดวาระการประชุมตามปกติแล้ว <NE>นายประเกียรติ นาสิมมา</NE>
รักษาการ <AB>ส.ว.</AB><NE>ร้อยเอ็ด</NE> และ<NE>นายนิคม เชาว์กิตติโสภณ</NE> รักษาการ <AB>ส.ว.</AB><NE>ลำปาง</NE>
ได้เสนอญัตติด่วน เพื่อขอให้ที่ประชุม<NE>วุฒิสภา</NE> พิจารณาเรื่องการแต่งตั้ง กรรมการการเลือกตั้ง (<NE>กกต.</NE>)ในส่วนที่ว่างลง
2 ตำแหน่ง โดยให้เหตุผลว่า ประธาน<NE>วุฒิสภา</NE> จะต้องปฏิบัติตามรัฐธรรมนูญ มาตรา 136 ,138 และ168 แต่การที่ประธาน
<NE>วุฒิสภา</NE> ยุติการสรรหา <NE>กกต.</NE> จึงไม่น่าจะชอบด้วยรัฐธรรมนูญ และน่าจะหมิ่นเหม่ว่า จะทำผิดรัฐธรรมนูญ
จึงขอให้ที่ประชุม<NE>วุฒิสภา</NE> ได้พิจารณาญัตติตามที่พวกตนได้เสนอด้วย
…
พบว่าเป็นข่าวเกี่ยวกับการสรรหากกต. ของสมาชิกวุฒิสภา ส่วนบทความที่ 5 (ตรงกับบทความหมายเลข 641) ดูเหมือนจะเกี่ยวข้องกับปัญหาความรุนแรงในโรงเรียนโดยอาจเป็นเรื่องของการตบตีกันของเยาวชน เมื่อพิจารณาบทความข่าวนั้น
จิตแพทย์ชี้<AB>นร.</AB>หญิงตบตีกัน เกิดจากพฤติกรรมเลียนแบบ
<NE>กรมสุขภาพจิต</NE>ชี้ปัญหานักเรียนหญิงตบตีกัน เกิดจากพฤติกรรมเลียนแบบ ระบุ พ่อแม่อย่าตีกันให้ลูกเห็น
แนะโรงเรียนจัดกิจกรรมสานสามัคคี ด้าน?<NE>จาตุรนต์</NE>? วอน อย่าเสนอข่าวมากเกินไป หวั่นเกิดพฤติกรรมเลียนแบบ
(26<AB>มิ.ย.</AB>) <NE>นพ.มล.สมชาย จักรพันธุ์</NE> อธิบดี<NE>กรมสุขภาพจิต</NE> กล่าวกรณีคลิปวิดีโอจาก
โทรศัพท์มือถือที่นักเรียนหญิงชั้น <AB>ปวช.</AB>3โรงเรียนพานิชย์แห่งหนึ่งใน <NE>จ.ชลบุรี</NE> ตอบตีรุ่นน้องชั้น
<AB>ปวช.</AB>ปี 1 ทั้งใช้มือจิกกระชากผมจับศีรษะโขกพื้น ใช้รองเท้าตีศีรษะและบังคับให้กราบขอโทษว่าการที่เด็กตบตีกัน
ภายในโรงเรียนทางครูอาจารย์คงปฏิเสธไม่ได้ ปัญหาการใช้ความรุนแรงส่วนหนึ่งเกิดจากพฤติกรรมเลียนแบบ โดยเฉพาะจากพ่อแม่
ซึ่งเป็นต้นแบบของเด็ก หากพ่อแม่ทะเลาะตบตีกันให้เด็กเห็นเด็กก็อาจมีพฤติกรรมเลียนแบบเกิดขึ้นได้
…
จะเห็นว่าเป็นเรื่องดังกล่าวตรงตามที่โปรแกรมได้ประเมินมาให้
ต่อไปเราจะทำการคำนวณค่า TF-IDF ของทุกบทความที่เรามี
tfidf_vector2 = tfidf_vectorizer.fit_transform(docs)
tfidf_array2 = np.array(tfidf_vector2.todense())
df2 = pd.DataFrame(tfidf_array2,columns=tfidf_vectorizer.get_feature_names())
print(df2.iloc[637:642,:].apply(lambda s: s.nlargest(10).index.tolist(), axis=1).ravel())
เมื่อพิจารณา 5 บทความเดิมจะเห็นว่าคำที่มีค่า TF-IDF สูงสุด 10 คำแรกและลำดับของบางคำมีการเปลี่ยนแปลงไปบ้าง
[list(['นายพชร', 'พรรค', 'ถาม', 'พิจารณา', 'อัยการ', 'สำนวน', 'ยุบ', 'กรรมการ', 'สอบสวน', 'พรรคไทยรักไทย'])
list(['เอสเอ็มแอล', 'อำเภอ', 'งบ', 'สัมมนา', 'กองทุนหมู่บ้าน', 'ชุมชน', 'บ้าน', 'ทำ', 'โอกาส', 'ยากจน'])
list(['พรรค', 'ลา', 'กติกา', 'พลอชัยสิทธิ์', 'ถาม', 'เลือกตั้ง', 'พรรคไทยรักไทย', 'นายพงศ์เทพ', 'กกต', 'นายก'])
list(['ญัตติ', 'วุฒิสภา', 'ประชุม', 'สว', 'กกต', 'รัฐธรรมนูญ', 'สรรหา', 'เสนอ', 'วิสามัญ', 'ฉวย'])
list(['เรียน', 'ตบตี', 'เลียน', 'ปัญหา', 'เด็ก', 'เยาวชน', 'กิจกรรม', 'ทำร้าย', 'พฤติกรรม', 'โรง'])]
เมื่อดูที่บทความสุดท้าย (ตรงกับบทความหมายเลข 641) จะเห็นว่าคำที่มีเนื้อหาเฉพาะเจาะจงกับบทความเช่นคำว่า “ตบตี” จะมีค่าของ TF-IDF ที่สูงมากขึ้นเมื่อเทียบกับคำอื่นๆ และคำที่มีแนวโน้มจะปรากฏในบทความอื่นๆ เช่นคำว่า “ทำร้าย” หรือ “พฤติกรรม” จะมีค่าลดลง
ตัวอย่างด้านบนเป็นการยกตัวอย่างให้เห็นประโยชน์อย่างหนึ่งในการนำเทคนิคพื้นฐานในการประมวลผลด้านภาษามาใช้ประโยชน์ นอกจากนี้การใช้ TF-IDF ยังสามารถถูกประยุกต์ใช้งานได้ด้านอื่นๆ ได้ด้วย เช่นใช้เป็นเทคนิคตรวจสอบการคัดลอก (Plagiarism) เบื้องต้นเพื่อหาบทความที่มีลักษณะคล้ายคลึงกันมากได้ในระดับนึงด้วย อย่างไรก็ดี การทำ TF-IDF นั้นจะเป็นการวิเคราะห์ข้อความโดยพิจารณาเพียงองค์ประกอบของคำภายในเอกสารต่างๆ เท่านั้น ซึ่งแม้ว่าจะสามารถนำผลลัพธ์มาใช้ประโยชน์ได้ ในหลายๆ ครั้ง เราอาจจะต้องการทำการวิเคราะห์ให้ละเอียดลงไปถึงบริบทและความหมายของเอกสาร ในกรณีเช่นนี้ เรามีความจำเป็นต้องใช้เทคนิคที่มีความซับซ้อนสูงมากกว่านี้เช่นการทำ Word-embedding ซึ่งผู้อ่านสามารถติดตามได้จากบทความของ bigdata.go.th ได้ในอนาคตครับ