01ภาพรวมของกราฟนี้
Word frequency bar เรียงคำตามความถี่แล้ววาดเป็นแท่งแนวนอน เป็นทางเลือกที่ตอบคำถามเดียวกับ word cloud แต่อ่านค่าได้แม่นกว่ามาก เพราะเข้ารหัสด้วยความยาวซึ่งเป็นช่องทางที่คนอ่านแม่นที่สุดรองจากตำแหน่ง
เปรียบเทียบให้เห็นภาพ
เหมือนตารางคะแนนที่เรียงจากมากไปน้อย ซึ่งอ่านง่ายและเถียงกันไม่ได้
ใช้ที่ไหนบ้าง — วิเคราะห์คำที่พบบ่อยในรีวิวลูกค้า หัวข้อที่ถูกพูดถึงในโซเชียล หรือคำค้นที่ผู้ใช้ค้นบ่อย
สร้างอย่างไร
- ขั้นที่ 1ตัดคำหยุดและรวมรูปคำ
- ขั้นที่ 2เรียงจากความถี่มากไปน้อย
- ขั้นที่ 3ตัดให้เหลือสิบถึงยี่สิบอันดับแรก
- ขั้นที่ 4วาดแท่งแนวนอนพร้อมตัวเลขที่ปลายแท่ง
ตัวอย่างคลาสสิก · กฎของ Zipf ในความถี่ของคำ
เมื่อเรียงคำตามความถี่ในข้อความภาษาธรรมชาติ จะพบรูปแบบที่คงเส้นคงวาคือความถี่ของคำอันดับที่สองประมาณครึ่งหนึ่งของอันดับแรก และอันดับที่สามประมาณหนึ่งในสาม รูปแบบนี้เห็นได้ทันทีจากกราฟแท่งเรียงอันดับ แต่ word cloud กลบมันไปหมด
02อธิบายภาษาคนเข้าใจง่าย ๆ
เมื่อคำถามคือคำไหนพบบ่อยที่สุดและบ่อยกว่ากันเท่าไร คำตอบที่ดีที่สุดคือกราฟแท่งแนวนอนธรรมดา
เหตุผลคือความยาวของแท่งเป็นช่องทางที่คนอ่านได้แม่นที่สุดรองจากตำแหน่งบนแกนร่วม ต่างจากขนาดตัวอักษรที่คนอ่านได้แย่มาก
การวางแนวนอนสำคัญเพราะคำมีความยาวไม่เท่ากัน การวางแนวตั้งจะบังคับให้ชื่อเอียงหรือถูกตัด ซึ่งทำให้อ่านช้าลงมาก
สิ่งที่ต้องทำก่อนเสมอคือตัดคำหยุด เพราะคำอย่าง "ที่" และ "และ" พบบ่อยกว่าคำที่มีความหมายหลายเท่า และจะครองอันดับต้นทั้งหมดถ้าไม่ตัดออก
ข้อจำกัดที่เหลือคือมันบอกแค่ว่าคำไหนพบบ่อย ไม่ได้บอกว่าคำนั้นถูกใช้ในบริบทอย่างไร ซึ่งคำว่า "ไม่แพง" กับ "แพง" นับแยกกันแต่ความหมายตรงข้าม
เมื่อบริบทสำคัญ ต้องใช้ kwic-view ควบคู่ หรืออย่างน้อยก็นับเป็นวลีแทนที่จะนับเป็นคำเดี่ยว
03ข้อมูลที่ต้องใช้
คอลัมน์ที่ต้องเตรียม
| คอลัมน์ | ทำหน้าที่ | ชนิด | เข้ารหัสด้วย | จำนวนค่าที่เหมาะ | หมายเหตุ |
|---|---|---|---|---|---|
word | คำ | ข้อความ | y | 5–30 คำที่แสดง | วางแนวนอนเพื่อให้อ่านคำได้ |
count | ความถี่ | จำนวนนับ | length | บวกเท่านั้น | ความยาวของแท่ง |
ต้องเตรียมข้อมูลอย่างไรก่อนวาด
- ★ ตัดคำหยุดออกให้หมด
- รวมรูปคำที่ความหมายเดียวกัน
- พิจารณานับเป็นวลีเมื่อคำเดี่ยวกำกวม
ค่าที่หายไป — คำที่ถูกตัดออกต้องระบุจำนวนและสัดส่วนที่เหลือ
สเกลของแกน — แกนความถี่ต้องเริ่มที่ศูนย์เสมอเพราะเข้ารหัสด้วยความยาว
กราฟจะเริ่มพังเมื่อไร
เกิน 40 คำ แท่งบางจนอ่านชื่อยาก
หน้าตาไฟล์ที่ต้องเตรียม
word,count
ส่งเร็ว,331
ราคา,179
…04อ่านแล้วเห็นอะไร
สิ่งที่เห็นได้จากภาพ
- คำที่พบบ่อยที่สุดและบ่อยกว่าอันดับรองเท่าไร
- ระยะห่างระหว่างอันดับ
- คำที่ไม่คาดคิดว่าจะติดอันดับ
สิ่งที่กราฟนี้ตอบไม่ได้
- ★ บริบทของการใช้คำ ซึ่งทำให้คำที่มีคำปฏิเสธนำหน้าถูกนับรวมกับคำเดิม
- ความสัมพันธ์ระหว่างคำ
- การเปลี่ยนแปลงตามเวลา
อ่านตามลำดับนี้
- ดูแท่งบนสุดซึ่งคือคำที่พบบ่อยที่สุด
- ดูระยะห่างระหว่างแท่งเพื่อรู้ว่าอันดับต่างกันมากไหม
- ตรวจว่าตัดคำหยุดออกแล้วหรือยัง
คำถามที่ตอบได้
- คำไหนพบบ่อยที่สุด
- อันดับหนึ่งบ่อยกว่าอันดับสองกี่เท่า
- มีคำที่ไม่คาดคิดติดอันดับไหม
สัญญาณว่ามีอะไรผิด
- มีคำหยุดติดอันดับต้น
- แกนไม่เริ่มที่ศูนย์
- ไม่เรียงตามความถี่
- ไม่บอกว่าแสดงกี่คำจากทั้งหมด
05เหมาะกับการนำเสนอแบบไหน
ทำอย่างไรให้คนอ่านได้ข้อสรุปโดยไม่ต้องบรรยาย
- ใส่ตัวเลขที่ปลายแท่งทุกแท่ง
- ระบุว่าแสดงกี่คำจากทั้งหมดกี่คำ
- ระบุว่าตัดคำหยุดอะไรออกบ้าง
รูปแบบชื่อกราฟที่ควรใช้
คำที่พบบ่อย <จำนวน> อันดับแรก โดย <คำ> พบ <จำนวน> ครั้ง
06เอาไปใช้ต่อ
โค้ดทุกชิ้นอ่านไฟล์ word-frequency-bar-sample.csv ชุดเดียวกับที่ Playground ใช้ และตัวเลขในโค้ดเปลี่ยนตามค่าที่คุณปรับด้านล่าง
# ติดตั้ง: pip install "matplotlib==3.10.*" "pandas==2.*"
# ดาวน์โหลด word-frequency-bar-sample.csv จากหน้านี้ แล้ววางไว้ข้างสคริปต์
import matplotlib
matplotlib.use("Agg") # รันแบบไม่มีหน้าจอ ถ้ารันในเครื่องตัวเองลบบรรทัดนี้ได้
import matplotlib.pyplot as plt
import pandas as pd
C1, C2, C3 = "#2a78d6", "#eb6834", "#1baf7a" # palette ของคลัง เปลี่ยนเป็นสีองค์กรได้
INK, SURFACE = "#0b0b0b", "#fcfcfb"
df = pd.read_csv("word-frequency-bar-sample.csv")
df["count"] = pd.to_numeric(df["count"], errors="coerce")
NOTE = "compare" # ← ค่าจาก Playground
fig, ax = plt.subplots(figsize=(7.6, 4.2), facecolor=SURFACE)
ax.set_facecolor(SURFACE)
d = df.nlargest(15, "count").sort_values("count") # แนวนอน: มากสุดอยู่บน
bars = ax.barh(d["word"], d["count"], color=C1, height=0.72)
ax.bar_label(bars, fmt="%d", padding=4, fontsize=9)
ax.set_xlabel("จำนวนครั้ง")
ax.set_xlim(0, d["count"].max() * 1.12) # ★ เริ่มที่ 0 เสมอ
ax.spines[["top", "right"]].set_visible(False)
ax.spines[["top", "right"]].set_visible(False) # ลดเส้นที่ไม่ได้ให้ข้อมูล
fig.tight_layout()
fig.savefig("word-frequency-bar.png", dpi=160)
print("เขียน word-frequency-bar.png แล้ว ·", len(df), "แถว")07ลองเล่นเพื่อเข้าใจ
ต้องตัด stop word และรวมรูปแปรของคำก่อน ไม่อย่างนั้นอันดับจะเต็มไปด้วยคำที่ไม่มีความหมาย
ดูข้อมูลเป็นตาราง (12 แถว)
| คำ | ความถี่ |
|---|---|
| ส่งเร็ว | 331 |
| ราคา | 179 |
| คุณภาพ | 126 |
| บริการ | 95.0 |
| แพ็กเกจ | 89.0 |
| คุ้มค่า | 62.0 |
| สวย | 61.0 |
| ช้า | 54.0 |
| ใช้ง่าย | 54.0 |
| พัง | 48.0 |
| แนะนำ | 45.0 |
| ร้านตอบไว | 45.0 |
ลองแล้วจะเห็นอะไร
- สังเกตอะไร: เปิดหน้า word-cloud ที่ใช้ข้อมูลชุดเดียวกันเทียบดู จะเห็นว่าที่นี่บอกได้ว่าอันดับหนึ่งมากกว่าอันดับสองกี่เท่า ส่วนที่นั่นบอกไม่ได้
ข้อควรระวัง
- ไม่ตัดคำหยุดออก ทำให้อันดับต้นเต็มไปด้วยคำที่ไม่มีความหมาย
- ตั้งแกนไม่เริ่มที่ศูนย์ ทำให้ความยาวแท่งโกหก
- แสดงคำมากเกินไปจนแท่งบางและอ่านชื่อยาก
- นับคำเดี่ยวทั้งที่บริบทเปลี่ยนความหมาย เช่น คำปฏิเสธนำหน้า
เมื่อไหร่ไม่ควรใช้กราฟนี้
- ต้องการภาพที่ดึงดูดสายตาสำหรับผู้ชมทั่วไป→ใช้แทน: word-cloud พร้อมตารางประกอบ
- ต้องเทียบข้ามเอกสารหลายชุด→ใช้แทน: term-document-heatmap
- ต้องดูบริบทการใช้คำ→ใช้แทน: kwic-view