บทนำ
ในคู่มือนี้ เราจะมุ่งเน้นไปที่การนำ อัลกอริธึมการจัดกลุ่มแบบลำดับชั้นด้วย Scikit-Learn เพื่อแก้ปัญหาทางการตลาด
หลังจากอ่านคู่มือแล้วคุณจะเข้าใจ:
- เมื่อใดควรใช้การจัดกลุ่มแบบลำดับชั้น
- วิธีแสดงภาพชุดข้อมูลเพื่อให้เข้าใจว่าเหมาะสำหรับการจัดกลุ่มหรือไม่
- วิธีประมวลผลคุณสมบัติล่วงหน้าและออกแบบคุณสมบัติใหม่ตามชุดข้อมูล
- วิธีลดมิติของชุดข้อมูลโดยใช้ PCA
- วิธีใช้และอ่าน dendrogram เพื่อแยกกลุ่ม
- อะไรคือวิธีการเชื่อมโยงที่แตกต่างกันและการวัดระยะทางที่ใช้กับ dendrograms และอัลกอริธึมการจัดกลุ่ม
- กลยุทธ์การจัดกลุ่มแบบรวมกลุ่มและแบบแบ่งแยกคืออะไรและทำงานอย่างไร
- วิธีการใช้ Agglomerative Hierarchical Clustering ด้วย Scikit-Learn
- อะไรคือปัญหาที่พบบ่อยที่สุดเมื่อต้องรับมือกับคลัสเตอร์อัลกอริธึมและวิธีแก้ปัญหาเหล่านี้
หมายเหตุ คุณสามารถดาวน์โหลดสมุดบันทึกที่มีรหัสทั้งหมดในคู่มือนี้ โปรดคลิกที่นี่เพื่ออ่านรายละเอียดเพิ่มเติม.
แรงจูงใจ
ลองนึกภาพสถานการณ์ที่คุณเป็นส่วนหนึ่งของทีมวิทยาศาสตร์ข้อมูลที่ติดต่อกับแผนกการตลาด การตลาดได้รวบรวมข้อมูลการซื้อของลูกค้ามาระยะหนึ่งแล้ว และพวกเขาต้องการทำความเข้าใจตามข้อมูลที่รวบรวมหากมี ความเหมือนระหว่างลูกค้า. ความคล้ายคลึงกันเหล่านี้แบ่งลูกค้าออกเป็นกลุ่มๆ และให้กลุ่มลูกค้าช่วยในการกำหนดเป้าหมายของแคมเปญ โปรโมชัน คอนเวอร์ชั่น และสร้างความสัมพันธ์ที่ดีกับลูกค้า
มีวิธีใดบ้างที่คุณจะช่วยตัดสินว่าลูกค้ารายใดมีความคล้ายคลึงกัน มีกี่คนที่อยู่ในกลุ่มเดียวกัน? และมีกี่กลุ่มที่แตกต่างกัน?
วิธีหนึ่งในการตอบคำถามเหล่านั้นคือการใช้ a การจัดกลุ่ม อัลกอริธึม เช่น K-Means, DBSCAN, Hierarchical Clustering เป็นต้น โดยทั่วไป อัลกอริธึมการจัดกลุ่มจะค้นหาความคล้ายคลึงกันระหว่างจุดข้อมูลและจัดกลุ่ม
ในกรณีนี้ ข้อมูลการตลาดของเราค่อนข้างเล็ก เรามีข้อมูลลูกค้าเพียง 200 ราย เมื่อพิจารณาจากทีมการตลาดแล้ว สิ่งสำคัญคือเราต้องอธิบายให้พวกเขาทราบอย่างชัดเจนถึงวิธีการตัดสินใจโดยพิจารณาจากจำนวนคลัสเตอร์ ดังนั้นจึงเป็นการอธิบายให้พวกเขาฟังว่าอัลกอริทึมทำงานอย่างไร
เนื่องจากข้อมูลของเรามีขนาดเล็กและการอธิบายได้เป็นปัจจัยสำคัญเราสามารถใช้ประโยชน์จาก การจัดกลุ่มแบบลำดับชั้น เพื่อแก้ปัญหานี้ กระบวนการนี้เรียกอีกอย่างว่า การวิเคราะห์คลัสเตอร์แบบลำดับชั้น (HCA).
ข้อดีอย่างหนึ่งของ HCA คือสามารถตีความได้และทำงานได้ดีกับชุดข้อมูลขนาดเล็ก
อีกสิ่งหนึ่งที่ต้องคำนึงถึงในสถานการณ์นี้คือ HCA คือ an ไม่ได้รับการดูแล อัลกอริทึม เมื่อจัดกลุ่มข้อมูล เราจะไม่มีวิธีตรวจสอบว่าเราระบุได้อย่างถูกต้องว่าผู้ใช้อยู่ในกลุ่มใดกลุ่มหนึ่ง (เราไม่รู้จักกลุ่ม) ไม่มีป้ายกำกับให้เราเปรียบเทียบผลลัพธ์ของเรา หากเราระบุกลุ่มได้อย่างถูกต้อง ฝ่ายการตลาดจะได้รับการยืนยันในภายหลังในแต่ละวัน (ตามที่วัดโดยตัวชี้วัด เช่น ROI อัตราการแปลง ฯลฯ)
ตอนนี้เราเข้าใจปัญหาที่เรากำลังพยายามแก้ไขและวิธีแก้ปัญหาแล้ว เรามาเริ่มดูข้อมูลกันเลย!
การวิเคราะห์ข้อมูลเชิงสำรวจโดยย่อ
หมายเหตุ คุณสามารถดาวน์โหลดชุดข้อมูลที่ใช้ในคู่มือนี้ โปรดคลิกที่นี่เพื่ออ่านรายละเอียดเพิ่มเติม.
หลังจากดาวน์โหลดชุดข้อมูลแล้ว ให้สังเกตว่าเป็น CSV (ค่าที่คั่นด้วยจุลภาค) ไฟล์ชื่อ shopping-data.csv
. เพื่อให้ง่ายต่อการสำรวจและจัดการข้อมูล เราจะโหลดลงใน a DataFrame
ใช้หมีแพนด้า:
import pandas as pd
path_to_file = 'home/projects/datasets/shopping-data.csv'
customer_data = pd.read_csv(path_to_file)
การตลาดกล่าวว่าได้รวบรวมบันทึกลูกค้า 200 รายการ เราสามารถตรวจสอบว่าข้อมูลที่ดาวน์โหลดมานั้นสมบูรณ์ด้วย 200 แถวหรือไม่โดยใช้ปุ่ม shape
คุณลักษณะ. มันจะบอกเราว่าเรามีแถวและคอลัมน์กี่แถวตามลำดับ:
customer_data.shape
ผลลัพธ์นี้ใน:
(200, 5)
ยอดเยี่ยม! ข้อมูลของเราสมบูรณ์ด้วย 200 แถว (บันทึกลูกค้า) และเรายังมี 5 คอลัมน์ (คุณสมบัติ). หากต้องการดูลักษณะที่ฝ่ายการตลาดเก็บรวบรวมจากลูกค้า เราสามารถเห็นชื่อคอลัมน์ด้วยเครื่องหมาย columns
คุณลักษณะ. ในการทำเช่นนั้น ให้ดำเนินการ:
customer_data.columns
สคริปต์ด้านบนส่งคืน:
Index(['CustomerID', 'Genre', 'Age', 'Annual Income (k$)',
'Spending Score (1-100)'],
dtype='object')
ที่นี่เราเห็นว่าการตลาดสร้าง CustomerID
, รวบรวม Genre
, Age
, Annual Income
(เป็นพันดอลลาร์) และ a Spending Score
จาก 1 เป็น 100 สำหรับลูกค้า 200 ราย เมื่อถูกถามเพื่อความกระจ่าง พวกเขากล่าวว่าค่าใน Spending Score
คอลัมน์แสดงว่าคนใช้จ่ายเงินในห้างสรรพสินค้าบ่อยแค่ไหนในระดับ 1 ถึง 100 กล่าวอีกนัยหนึ่งถ้าลูกค้ามีคะแนน 0 บุคคลนี้ไม่เคยใช้จ่ายเงินและถ้าคะแนนเป็น 100 เราเพิ่งเห็น ใช้จ่ายสูงสุด
มาดูการแจกแจงคะแนนนี้กันอย่างรวดเร็วเพื่อตรวจสอบพฤติกรรมการใช้จ่ายของผู้ใช้ในชุดข้อมูลของเรา นั่นคือที่ที่หมีแพนด้า hist()
วิธีการเข้ามาเพื่อช่วย:
customer_data['Spending Score (1-100)'].hist()
เมื่อดูจากฮิสโตแกรมแล้ว เราจะพบว่าลูกค้ามากกว่า 35 รายมีคะแนนอยู่ระหว่าง 40
และ 60
แล้วน้อยกว่า 25 มีคะแนนระหว่าง 70
และ 80
. ลูกค้าส่วนใหญ่ของเราคือ การใช้จ่ายที่สมดุลรองลงมาคือผู้ใช้จ่ายปานกลางถึงมาก เรายังเห็นว่ามีเส้นหลัง 0
ทางด้านซ้ายของการแจกแจง และอีกบรรทัดก่อน 100 ทางด้านขวาของการแจกแจง ช่องว่างเหล่านี้อาจหมายความว่าการแจกแจงไม่มีผู้ไม่ใช้จ่าย ซึ่งจะมีคะแนน 0
และไม่มีผู้ใช้จ่ายสูงด้วยคะแนน 100
.
เพื่อตรวจสอบว่าเป็นจริงหรือไม่ เราสามารถดูค่าต่ำสุดและสูงสุดของการกระจายได้ ค่าเหล่านี้สามารถหาได้ง่ายโดยเป็นส่วนหนึ่งของสถิติเชิงพรรณนา ดังนั้นเราจึงสามารถใช้ describe()
วิธีทำความเข้าใจการแจกแจงค่าตัวเลขอื่น ๆ :
customer_data.describe().transpose()
นี่จะให้ตารางจากตำแหน่งที่เราสามารถอ่านการแจกแจงค่าอื่น ๆ ของชุดข้อมูลของเรา:
count mean std min 25% 50% 75% max
CustomerID 200.0 100.50 57.879185 1.0 50.75 100.5 150.25 200.0
Age 200.0 38.85 13.969007 18.0 28.75 36.0 49.00 70.0
Annual Income (k$) 200.0 60.56 26.264721 15.0 41.50 61.5 78.00 137.0
Spending Score (1-100) 200.0 50.20 25.823522 1.0 34.75 50.0 73.00 99.0
สมมติฐานของเราได้รับการยืนยันแล้ว ดิ min
มูลค่าของ Spending Score
is 1
และสูงสุดคือ 99
. เราเลยไม่มี 0
or 100
ผู้ใช้จ่ายคะแนน ลองดูที่คอลัมน์อื่นๆ ของทรานสโพส describe
โต๊ะ. เมื่อมองดู mean
และ std
คอลัมน์ เราจะเห็นได้ว่าสำหรับ Age
mean
is 38.85
และ std
จะอยู่ที่ประมาณ 13.97
. สิ่งเดียวกันนี้เกิดขึ้นสำหรับ Annual Income
ด้วย mean
of 60.56
และ std
26.26
และสำหรับ Spending Score
กับ mean
of 50
และ std
of 25.82
. สำหรับคุณสมบัติทั้งหมด mean
อยู่ไกลจากค่าเบี่ยงเบนมาตรฐานซึ่งบ่งชี้ว่า ข้อมูลของเรามีความแปรปรวนสูง.
เพื่อให้เข้าใจได้ดีขึ้นว่าข้อมูลของเราแตกต่างกันอย่างไร เรามาพล็อต Annual Income
การกระจาย:
customer_data['Annual Income (k$)'].hist()
ซึ่งจะให้เรา:
สังเกตในฮิสโตแกรมว่าข้อมูลส่วนใหญ่ของเราซึ่งมีลูกค้ามากกว่า 35 รายนั้นกระจุกตัวอยู่ใกล้ตัวเลข 60
, บนของเรา mean
ในแกนนอน แต่จะเกิดอะไรขึ้นเมื่อเราก้าวไปสู่จุดสิ้นสุดของการกระจาย? เมื่อไปทางซ้าย จากค่าเฉลี่ย $60.560 ค่าต่อไปที่เราจะเจอคือ $34.300 – ค่าเฉลี่ย ($60.560) ลบรูปแบบมาตรฐาน ($26.260) หากเราออกไปทางซ้ายของการกระจายข้อมูลของเรามากขึ้น กฎที่คล้ายกันจะมีผล เราจะลบรูปแบบมาตรฐาน ($26.260) ออกจากค่าปัจจุบัน ($34.300) ดังนั้น เราจะพบมูลค่า $8.040 สังเกตว่าข้อมูลของเราเปลี่ยนจาก 60 ดอลลาร์เป็น 8 ดอลลาร์อย่างรวดเร็ว มัน “กระโดด” $26.260 ทุกครั้ง – แตกต่างกันมาก และนั่นคือสาเหตุที่เรามีความแปรปรวนสูงเช่นนี้
ความแปรปรวนและขนาดของข้อมูลมีความสำคัญในการวิเคราะห์การจัดกลุ่ม เนื่องจากการวัดระยะทางของอัลกอริธึมการจัดกลุ่มส่วนใหญ่มีความไวต่อขนาดข้อมูล ความแตกต่างของขนาดสามารถเปลี่ยนผลลัพธ์การจัดกลุ่มโดยทำให้จุดหนึ่งดูเหมือนใกล้หรือไกลกว่าที่เป็นจริง ทำให้การจัดกลุ่มข้อมูลผิดเพี้ยนไป
จนถึงตอนนี้ เราได้เห็นรูปร่างของข้อมูลของเรา การแจกแจงบางส่วน และสถิติเชิงพรรณนา ด้วย Pandas เรายังสามารถแสดงรายการประเภทข้อมูลของเราและดูว่าแถวทั้งหมด 200 แถวของเราเต็มหรือมีบางส่วนหรือไม่ null
ค่า:
customer_data.info()
ผลลัพธ์นี้ใน:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 200 entries, 0 to 199
Data columns (total 5 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 CustomerID 200 non-null int64
1 Genre 200 non-null object
2 Age 200 non-null int64
3 Annual Income (k$) 200 non-null int64
4 Spending Score (1-100) 200 non-null int64
dtypes: int64(4), object(1)
memory usage: 7.9+ KB
ที่นี่เราจะเห็นว่าไม่มี null
ค่าในข้อมูลและที่เรามีคอลัมน์หมวดหมู่เดียวเท่านั้น – Genre
. ในขั้นตอนนี้ สิ่งสำคัญคือเราต้องคำนึงถึงคุณลักษณะที่น่าสนใจที่จะเพิ่มลงในโมเดลคลัสเตอร์ หากเราต้องการเพิ่มคอลัมน์ประเภทลงในโมเดลของเรา เราจะต้องแปลงค่าจาก เด็ดขาด ไปยัง เชิงตัวเลข.
เรามาดูกันว่า Genre
เต็มไปด้วยการดู 5 ค่าแรกของข้อมูลของเราอย่างรวดเร็ว:
customer_data.head()
ผลลัพธ์นี้ใน:
CustomerID Genre Age Annual Income (k$) Spending Score (1-100)
0 1 Male 19 15 39
1 2 Male 21 15 81
2 3 Female 20 16 6
3 4 Female 23 16 77
4 5 Female 31 17 40
เหมือนจะมีแต่ Female
และ Male
หมวดหมู่ เรามั่นใจได้โดยพิจารณาจากค่านิยมอันเป็นเอกลักษณ์ด้วย unique
:
customer_data['Genre'].unique()
นี่เป็นการยืนยันสมมติฐานของเรา:
array(['Male', 'Female'], dtype=object)
จนถึงตอนนี้ เรารู้ว่าเรามีเพียงสองประเภท หากเราวางแผนที่จะใช้คุณลักษณะนี้กับโมเดลของเรา Male
สามารถแปลงเป็น 0
และ Female
ไปยัง 1
. สิ่งสำคัญคือต้องตรวจสอบสัดส่วนระหว่างแนวเพลง เพื่อดูว่ามีความสมดุลหรือไม่ เราสามารถทำได้ด้วย value_counts()
วิธีการและข้อโต้แย้งของมัน normalize=True
เพื่อแสดงเปอร์เซ็นต์ระหว่าง Male
และ Female
:
customer_data['Genre'].value_counts(normalize=True)
ผลลัพธ์นี้:
Female 0.56
Male 0.44
Name: Genre, dtype: float64
เรามีผู้หญิง 56% ในชุดข้อมูลและ 44% ของผู้ชาย ความแตกต่างระหว่างพวกเขาเป็นเพียง 16% และข้อมูลของเราไม่ใช่ 50/50 แต่เป็น สมดุลพอ เพื่อไม่ให้เกิดปัญหา หากผลลัพธ์เป็น 70/30, 60/40 อาจจำเป็นต้องรวบรวมข้อมูลเพิ่มเติมหรือใช้เทคนิคการเสริมข้อมูลบางอย่างเพื่อทำให้อัตราส่วนนั้นสมดุลมากขึ้น
จนถึงตอนนี้คุณสมบัติทั้งหมด แต่ Age
, ได้รับการสำรวจโดยสังเขป ในสิ่งที่กังวล Age
มักจะน่าสนใจที่จะแบ่งมันออกเป็นถังขยะเพื่อให้สามารถแบ่งกลุ่มลูกค้าตามกลุ่มอายุของพวกเขาได้ หากเราทำเช่นนั้น เราจะต้องแปลงหมวดหมู่อายุเป็นตัวเลขเดียวก่อนที่จะเพิ่มลงในแบบจำลองของเรา ด้วยวิธีนี้ แทนที่จะใช้หมวดหมู่ 15-20 ปี เราจะนับจำนวนลูกค้าใน 15-20
หมวดหมู่และนั่นจะเป็นตัวเลขในคอลัมน์ใหม่ที่เรียกว่า 15-20
.
คำแนะนำ: ในคู่มือนี้ เรานำเสนอการวิเคราะห์ข้อมูลเชิงสำรวจสั้นๆ เท่านั้น แต่คุณไปต่อได้และคุณควรไปต่อ คุณสามารถดูว่ามีความแตกต่างของรายได้และการให้คะแนนที่แตกต่างกันตามประเภทและอายุหรือไม่ สิ่งนี้ไม่เพียงทำให้การวิเคราะห์สมบูรณ์ยิ่งขึ้น แต่ยังนำไปสู่ผลลัพธ์ของแบบจำลองที่ดีขึ้นด้วย หากต้องการเจาะลึกลงไปในการวิเคราะห์ข้อมูลเชิงสำรวจ โปรดดูที่ บท EDA ใน “การทำนายราคาบ้านแบบลงมือปฏิบัติ – การเรียนรู้ของเครื่องใน Python" โครงการแนะนำ.
หลังจากคาดคะเนสิ่งที่สามารถทำได้ทั้งแบบจัดหมวดหมู่ – หรือจัดหมวดหมู่เป็น – Genre
และ Age
คอลัมน์ มาประยุกต์ใช้สิ่งที่ได้พูดคุยกัน
การเข้ารหัสตัวแปรและวิศวกรรมคุณลักษณะ
มาเริ่มด้วยการหาร Age
ออกเป็นกลุ่มๆ ละ 10 แบบ เพื่อให้เรามี 20-30, 30-40, 40-50 เป็นต้น เนื่องจากลูกค้าที่อายุน้อยที่สุดของเราคือ 15 เราสามารถเริ่มต้นที่ 15 และสิ้นสุดที่ 70 ซึ่งเป็นอายุของลูกค้าที่เก่าแก่ที่สุดในข้อมูล เริ่มต้นที่ 15 และสิ้นสุดที่ 70 เราจะมีช่วงเวลา 15-20, 20-30, 30-40, 40-50, 50-60 และ 60-70
เพื่อจัดกลุ่มหรือ ถัง Age
ค่าในช่วงเวลาเหล่านี้ เราสามารถใช้ Pandas cut()
วิธีการตัดให้เป็นถังขยะแล้วกำหนดถังขยะให้ใหม่ Age Groups
คอลัมน์:
intervals = [15, 20, 30, 40, 50, 60, 70]
col = customer_data['Age']
customer_data['Age Groups'] = pd.cut(x=col, bins=intervals)
customer_data['Age Groups']
ผลลัพธ์นี้ใน:
0 (15, 20]
1 (20, 30]
2 (15, 20]
3 (20, 30]
4 (30, 40]
...
195 (30, 40]
196 (40, 50]
197 (30, 40]
198 (30, 40]
199 (20, 30]
Name: Age Groups, Length: 200, dtype: category
Categories (6, interval[int64, right]): [(15, 20] < (20, 30] < (30, 40] < (40, 50] < (50, 60] < (60, 70]]
โปรดสังเกตว่าเมื่อดูค่าของคอลัมน์ ยังมีบรรทัดที่ระบุว่าเรามี 6 หมวดหมู่และแสดงช่วงข้อมูลที่รวมไว้ทั้งหมด ด้วยวิธีนี้ เราได้จัดหมวดหมู่ข้อมูลตัวเลขก่อนหน้านี้ของเราและสร้างใหม่ Age Groups
ลักษณะ
แล้วแต่ละหมวดเรามีลูกค้ากี่คน? เราสามารถรู้ได้อย่างรวดเร็วว่าโดยการจัดกลุ่มคอลัมน์และนับค่าด้วย groupby()
และ count()
:
customer_data.groupby('Age Groups')['Age Groups'].count()
ผลลัพธ์นี้ใน:
Age Groups
(15, 20] 17
(20, 30] 45
(30, 40] 60
(40, 50] 38
(50, 60] 23
(60, 70] 17
Name: Age Groups, dtype: int64
สังเกตได้ง่ายว่าลูกค้าส่วนใหญ่มีอายุระหว่าง 30 ถึง 40 ปี รองลงมาคือลูกค้าระหว่าง 20 ถึง 30 ปี และลูกค้าที่มีอายุระหว่าง 40 ถึง 50 ปี นี่เป็นข้อมูลที่ดีสำหรับฝ่ายการตลาดด้วย
ในขณะนี้ เรามีตัวแปรหมวดหมู่สองแบบคือ Age
และ Genre
ซึ่งเราต้องแปลงเป็นตัวเลขเพื่อนำไปใช้ในแบบจำลองของเรา มีหลายวิธีในการเปลี่ยนแปลงนั้น – เราจะใช้แพนด้า get_dummies()
เมธอดที่สร้างคอลัมน์ใหม่สำหรับแต่ละช่วงเวลาและประเภทแล้วเติมค่าด้วย 0s และ 1s- การดำเนินการประเภทนี้เรียกว่า การเข้ารหัสแบบร้อนครั้งเดียว. มาดูกันว่ามันมีลักษณะอย่างไร:
customer_data_oh = pd.get_dummies(customer_data)
customer_data_oh
สิ่งนี้จะให้ตัวอย่างตารางผลลัพธ์แก่เรา:
ด้วยผลลัพธ์จะง่ายที่จะเห็นว่าคอลัมน์ Genre
ถูกแบ่งออกเป็นคอลัมน์ - Genre_Female
และ Genre_Male
. เมื่อลูกค้าเป็นผู้หญิง Genre_Female
เท่ากับ 1
และเมื่อลูกค้าเป็นผู้ชายก็เท่ากับ 0
.
นอกจากนี้ Age Groups
คอลัมน์ถูกแบ่งออกเป็น 6 คอลัมน์ หนึ่งคอลัมน์สำหรับแต่ละช่วงเวลา เช่น Age Groups_(15, 20]
, Age Groups_(20, 30]
และอื่นๆ ในทำนองเดียวกันกับ Genre
, เมื่อลูกค้าอายุ 18 ปี Age Groups_(15, 20]
มูลค่าคือ 1
และค่าของคอลัมน์อื่นทั้งหมดคือ 0
.
พื้นที่ ความได้เปรียบ ของการเข้ารหัสแบบ one-hot คือความเรียบง่ายในการแสดงค่าของคอลัมน์ มันง่ายที่จะเข้าใจสิ่งที่เกิดขึ้น – ในขณะที่ ข้อเสียเปรียบ คือตอนนี้เราได้สร้างคอลัมน์เพิ่มเติม 8 คอลัมน์ เพื่อสรุปกับคอลัมน์ที่เรามีอยู่แล้ว
การเตือน: หากคุณมีชุดข้อมูลที่จำนวนคอลัมน์ที่เข้ารหัสแบบ hot เดียวเกินจำนวนแถว วิธีที่ดีที่สุดคือใช้วิธีการเข้ารหัสอื่นเพื่อหลีกเลี่ยงปัญหามิติข้อมูล
การเข้ารหัสแบบร้อนครั้งเดียวยังเพิ่ม 0s ให้กับข้อมูลของเรา ทำให้กระจัดกระจายมากขึ้น ซึ่งอาจเป็นปัญหาสำหรับอัลกอริธึมบางตัวที่มีความอ่อนไหวต่อข้อมูลที่กระจัดกระจาย
สำหรับความต้องการการจัดกลุ่มของเรา ดูเหมือนว่าการเข้ารหัสแบบใช้ครั้งเดียวจะได้ผล แต่เราสามารถพล็อตข้อมูลเพื่อดูว่ามีกลุ่มที่แตกต่างกันจริงๆ สำหรับเราในการจัดกลุ่มหรือไม่
การพล็อตพื้นฐานและการลดมิติ
ชุดข้อมูลของเรามี 11 คอลัมน์ และมีบางวิธีที่เราสามารถแสดงภาพข้อมูลนั้นได้ อย่างแรกคือการพล็อตเป็น 10 มิติ (โชคดีนะ) สิบเพราะ Customer_ID
คอลัมน์ไม่ได้รับการพิจารณา อันที่สองคือโดยพล็อตคุณสมบัติตัวเลขเริ่มต้นของเรา และอันที่สามคือโดยการเปลี่ยนฟีเจอร์ 10 อย่างของเราเป็น 2 อัน - ดังนั้นจึงลดขนาดลง
การพล็อตข้อมูลแต่ละคู่
เนื่องจากการพล็อต 10 มิตินั้นค่อนข้างเป็นไปไม่ได้ เราจะเลือกใช้แนวทางที่สอง – เราจะพล็อตคุณสมบัติเริ่มต้นของเรา เราสามารถเลือกได้สองแบบสำหรับการวิเคราะห์คลัสเตอร์ของเรา วิธีหนึ่งที่เราสามารถดูคู่ข้อมูลทั้งหมดของเรารวมกับ Seaborn pairplot()
:
import seaborn as sns
customer_data = customer_data.drop('CustomerID', axis=1)
sns.pairplot(customer_data)
ซึ่งแสดง:
โดยคร่าว ๆ เราสามารถมองเห็น scatterplot ที่ดูเหมือนจะมีกลุ่มข้อมูลอยู่ สิ่งที่ดูน่าสนใจคือ scatterplot ที่รวมเข้าด้วยกัน Annual Income
และ Spending Score
. สังเกตว่าไม่มีการแบ่งแยกที่ชัดเจนระหว่าง scatterplot ตัวแปรอื่น อย่างมากที่สุด เราอาจบอกได้ว่าจุดความเข้มข้นต่างกันสองจุดใน Spending Score
vs Age
พล็อตกระจาย
ทั้งสอง scatterplot ประกอบด้วย Annual Income
และ Spending Score
โดยพื้นฐานแล้วจะเหมือนกัน เราเห็นมันสองครั้งเพราะแกน x และ y ถูกแลกเปลี่ยนกัน เมื่อพิจารณาจากกลุ่มใดกลุ่มหนึ่ง เราจะเห็นกลุ่มต่างๆ ห้ากลุ่มที่แตกต่างกัน ลองพล็อตแค่สองคุณสมบัตินั้นด้วย Seaborn scatterplot()
เพื่อดูอย่างใกล้ชิด:
sns.scatterplot(x=customer_data['Annual Income (k$)'],
y=customer_data['Spending Score (1-100)'])
เมื่อมองให้ใกล้ขึ้น เราสามารถแยกความแตกต่างของข้อมูล 5 กลุ่มได้อย่างแน่นอน ดูเหมือนว่าลูกค้าของเราสามารถจัดกลุ่มตามรายได้ที่พวกเขาทำในหนึ่งปีและจำนวนเงินที่พวกเขาใช้จ่าย นี่เป็นอีกประเด็นที่เกี่ยวข้องในการวิเคราะห์ของเรา เป็นสิ่งสำคัญที่เราจะพิจารณาเพียงสองคุณสมบัติเพื่อจัดกลุ่มลูกค้าของเรา ข้อมูลอื่น ๆ ที่เรามีเกี่ยวกับสิ่งเหล่านี้จะไม่เข้าสู่สมการ สิ่งนี้ให้ความหมายในการวิเคราะห์ – หากเรารู้ว่าลูกค้ามีรายได้และใช้จ่ายเท่าใด เราสามารถค้นหาความคล้ายคลึงที่เราต้องการได้อย่างง่ายดาย
ดีมาก! จนถึงตอนนี้ เรามีสองตัวแปรอยู่แล้วในการสร้างแบบจำลองของเรา นอกจากสิ่งนี้จะแสดงให้เห็นแล้ว ยังทำให้โมเดลดูเรียบง่าย เป็นกันเอง และอธิบายได้ชัดเจนยิ่งขึ้น
ดูคู่มือเชิงปฏิบัติสำหรับการเรียนรู้ Git ที่มีแนวทางปฏิบัติที่ดีที่สุด มาตรฐานที่ยอมรับในอุตสาหกรรม และเอกสารสรุปรวม หยุดคำสั่ง Googling Git และจริงๆ แล้ว เรียน มัน!
หมายเหตุ Data Science มักจะชอบวิธีการที่เรียบง่ายที่สุด ไม่เพียงเพราะอธิบายได้ง่ายกว่าสำหรับธุรกิจเท่านั้น แต่ยังเพราะมันตรงไปตรงมามากกว่า ด้วยคุณสมบัติ 2 ประการและรูปแบบที่อธิบายได้ จึงเป็นที่ชัดเจนว่าโมเดลกำลังทำอะไรและทำงานอย่างไร
พล็อตข้อมูลหลังจากใช้PCA
ดูเหมือนว่าแนวทางที่สองของเราน่าจะดีที่สุด แต่ลองดูแนวทางที่สามของเราด้วย อาจมีประโยชน์เมื่อเราไม่สามารถพล็อตข้อมูลได้เนื่องจากมีมิติข้อมูลมากเกินไป หรือเมื่อไม่มีความเข้มข้นของข้อมูลหรือการแยกกลุ่มที่ชัดเจน เมื่อเกิดสถานการณ์ดังกล่าวขึ้น ขอแนะนำให้ลองลดขนาดข้อมูลด้วยวิธีที่เรียกว่า การวิเคราะห์องค์ประกอบหลัก (PCA).
หมายเหตุ คนส่วนใหญ่ใช้ PCA ในการลดขนาดก่อนสร้างภาพ มีวิธีการอื่นที่ช่วยในการสร้างภาพข้อมูลก่อนการจัดกลุ่ม เช่น การจัดคลัสเตอร์เชิงพื้นที่ตามความหนาแน่นของแอปพลิเคชันที่มีสัญญาณรบกวน (DBSCAN) และ แผนที่จัดระเบียบตนเอง (SOM) การจัดกลุ่ม ทั้งสองเป็นอัลกอริธึมการจัดกลุ่ม แต่ยังสามารถใช้สำหรับการแสดงข้อมูลด้วย เนื่องจากการวิเคราะห์คลัสเตอร์ไม่มีมาตรฐานทองคำ การเปรียบเทียบการสร้างภาพข้อมูลและอัลกอริธึมที่แตกต่างกันจึงเป็นสิ่งสำคัญ
PCA จะลดขนาดของข้อมูลของเราในขณะที่พยายามรักษาข้อมูลให้ได้มากที่สุด มาทำความเข้าใจวิธีการทำงานของ PCA กันก่อน แล้วจึงสามารถเลือกขนาดข้อมูลที่เราจะลดข้อมูลลงได้
สำหรับคุณลักษณะแต่ละคู่ PCA จะพิจารณาว่าค่าที่มากกว่าของตัวแปรหนึ่งสอดคล้องกับค่าที่มากกว่าของตัวแปรอื่นหรือไม่ และค่าที่น้อยกว่าจะทำเช่นเดียวกันกับค่าที่น้อยกว่า ดังนั้น โดยพื้นฐานแล้วจะคำนวณว่าค่าคุณสมบัติแตกต่างกันมากน้อยเพียงใด เราเรียกมันว่า ความแปรปรวนร่วม. ผลลัพธ์เหล่านั้นจะถูกจัดเป็นเมทริกซ์ จะได้ a เมทริกซ์ความแปรปรวนร่วม.
หลังจากได้เมทริกซ์ความแปรปรวนร่วมแล้ว PCA พยายามหาชุดค่าผสมเชิงเส้นของคุณสมบัติที่อธิบายได้ดีที่สุด ซึ่งเหมาะกับตัวแบบเชิงเส้นจนกว่าจะระบุตัวที่อธิบาย สูงสุด ปริมาณความแปรปรวน.
หมายเหตุ: PCA คือการแปลงเชิงเส้น และความเป็นเชิงเส้นนั้นไวต่อมาตราส่วนของข้อมูล ดังนั้น PCA จึงทำงานได้ดีที่สุดเมื่อค่าข้อมูลทั้งหมดอยู่ในระดับเดียวกัน สามารถทำได้โดยการลบคอลัมน์ หมายความ จากค่าและหารผลลัพธ์ด้วยค่าเบี่ยงเบนมาตรฐาน ที่เรียกว่า การกำหนดมาตรฐานข้อมูล. ก่อนใช้ PCA ตรวจสอบให้แน่ใจว่าได้ปรับขนาดข้อมูลแล้ว! หากคุณไม่แน่ใจว่าเป็นอย่างไร อ่านของเรา “คุณสมบัติการปรับขนาดข้อมูลด้วย Scikit-Learn สำหรับการเรียนรู้ของเครื่องใน Python”!
ด้วยเส้นที่ดีที่สุด (ชุดค่าผสมเชิงเส้น) พบ PCA รับทิศทางของแกนที่เรียกว่า เวกเตอร์ไอเกน, และสัมประสิทธิ์เชิงเส้นของมัน, the ค่าลักษณะเฉพาะ. การรวมกันของเวกเตอร์ลักษณะเฉพาะและค่าลักษณะเฉพาะ - หรือทิศทางและสัมประสิทธิ์ของแกน - คือ ส่วนประกอบหลัก ของสคบ. และนั่นคือเวลาที่เราสามารถเลือกจำนวนมิติของเราตามความแปรปรวนที่อธิบายไว้ของแต่ละคุณลักษณะ โดยทำความเข้าใจว่าองค์ประกอบหลักใดที่เราต้องการเก็บหรือละทิ้งตามความแปรปรวนที่อธิบายไว้
หลังจากได้รับส่วนประกอบหลัก PCA จะใช้เวกเตอร์ลักษณะเฉพาะเพื่อสร้างเวกเตอร์ของคุณลักษณะที่ปรับทิศทางข้อมูลจากแกนดั้งเดิมไปยังแกนที่แสดงโดยส่วนประกอบหลัก นั่นคือวิธีที่มิติข้อมูลจะลดลง
หมายเหตุ รายละเอียดสำคัญประการหนึ่งที่ต้องพิจารณาในที่นี้คือ เนื่องจากลักษณะเชิงเส้นของมัน PCA จะเน้นความแปรปรวนที่อธิบายไว้ส่วนใหญ่ในองค์ประกอบหลักแรก ดังนั้น เมื่อดูที่ความแปรปรวนที่อธิบาย โดยปกติสององค์ประกอบแรกของเราจะเพียงพอ แต่นั่นอาจทำให้เข้าใจผิดได้ในบางกรณี ดังนั้นให้พยายามเปรียบเทียบพล็อตและอัลกอริธึมที่แตกต่างกันเมื่อทำคลัสเตอร์เพื่อดูว่ามีผลลัพธ์ที่คล้ายคลึงกันหรือไม่
ก่อนสมัคร PCA เราต้องเลือกระหว่าง Age
คอลัมน์หรือ Age Groups
คอลัมน์ในข้อมูลที่เข้ารหัสแบบ one-hot ก่อนหน้านี้ของเรา เนื่องจากทั้งสองคอลัมน์แสดงข้อมูลเดียวกัน การแนะนำสองครั้งจึงส่งผลต่อความแปรปรวนของข้อมูลของเรา ถ้า Age Groups
เลือกคอลัมน์แล้ว เพียงลบ Age
คอลัมน์โดยใช้ Pandas drop()
วิธีการและกำหนดใหม่ให้กับ customer_data_oh
ตัวแปร:
customer_data_oh = customer_data_oh.drop(['Age'], axis=1)
customer_data_oh.shape
ตอนนี้ข้อมูลของเรามี 10 คอลัมน์ ซึ่งหมายความว่าเราสามารถรับองค์ประกอบหลักหนึ่งองค์ประกอบต่อคอลัมน์ และเลือกว่าเราจะใช้กี่คอลัมน์โดยการวัดว่าการแนะนำมิติข้อมูลใหม่หนึ่งรายการอธิบายความแปรปรวนข้อมูลของเราได้มากขึ้นเพียงใด
มาทำสิ่งนั้นกับ Scikit-Learn PCA
. เราจะคำนวณความแปรปรวนที่อธิบายของแต่ละมิติโดย explained_variance_ratio_
แล้วดูผลรวมที่สะสมด้วย cumsum()
:
from sklearn.decomposition import PCA
pca = PCA(n_components=10)
pca.fit_transform(customer_data_oh)
pca.explained_variance_ratio_.cumsum()
ความแปรปรวนที่อธิบายสะสมของเราคือ:
array([0.509337 , 0.99909504, 0.99946364, 0.99965506, 0.99977937,
0.99986848, 0.99993716, 1. , 1. , 1. ])
เราจะเห็นว่ามิติข้อมูลแรกอธิบายข้อมูล 50% และเมื่อรวมกับมิติข้อมูลที่สองจะอธิบาย 99% เปอร์เซ็นต์ ซึ่งหมายความว่า 2 มิติข้อมูลแรกอธิบายข้อมูลของเรา 99% แล้ว ดังนั้นเราจึงสามารถใช้ PCA ที่มี 2 องค์ประกอบ รับส่วนประกอบหลักของเราและวางแผนได้:
from sklearn.decomposition import PCA
pca = PCA(n_components=2)
pcs = pca.fit_transform(customer_data_oh)
pc1_values = pcs[:,0]
pc2_values = pcs[:,1]
sns.scatterplot(x=pc1_values, y=pc2_values)
แผนภาพข้อมูลหลัง PCA จะคล้ายกับแผนภาพที่ใช้ข้อมูลเพียงสองคอลัมน์โดยไม่มี PCA สังเกตว่าจุดที่ก่อตัวเป็นกลุ่มอยู่ใกล้กว่าและมีความเข้มข้นมากขึ้นหลัง PCA มากกว่าเดิมเล็กน้อย
การแสดงภาพโครงสร้างแบบลำดับชั้นด้วย Dendrograms
จนถึงตอนนี้ เราได้สำรวจข้อมูล ซึ่งเป็นคอลัมน์ที่จัดหมวดหมู่แบบ one-hot encoded ตัดสินใจว่าคอลัมน์ใดเหมาะสมสำหรับการจัดกลุ่ม และลดมิติข้อมูล แผนภาพระบุว่าเรามี 5 กลุ่มในข้อมูลของเรา แต่ยังมีวิธีอื่นในการแสดงภาพความสัมพันธ์ระหว่างจุดของเราและช่วยกำหนดจำนวนคลัสเตอร์ - โดยการสร้าง เดนโดรแกรม (มักสะกดผิดว่า dendogram) เดนโดร วิธี ต้นไม้ ในภาษาละติน
พื้นที่ เดนโดรแกรม เป็นผลมาจากการเชื่อมโยงจุดในชุดข้อมูล เป็นการแสดงภาพของกระบวนการจัดกลุ่มตามลำดับชั้น และกระบวนการจัดกลุ่มแบบลำดับชั้นทำงานอย่างไร ก็… ขึ้นอยู่กับ – อาจเป็นคำตอบที่คุณเคยได้ยินมามากใน Data Science
การทำความเข้าใจการจัดกลุ่มแบบลำดับชั้น
เมื่อราคาของ อัลกอริธึมการจัดกลุ่มแบบลำดับชั้น (HCA) เริ่มเชื่อมโยงจุดและค้นหากลุ่ม โดยแรกสามารถแบ่งจุดออกเป็น 2 กลุ่มใหญ่ แล้วแยกแต่ละกลุ่มออกเป็น 2 กลุ่มเล็ก ๆ มีทั้งหมด 4 กลุ่ม คือ แตกแยก และ จากบนลงล่าง เข้าใกล้
หรือจะทำตรงกันข้ามก็ได้ คือ ดูจุดข้อมูลทั้งหมด หาจุดใกล้กัน 2 จุด โยงกัน แล้วหาจุดอื่นๆ ที่ใกล้เคียงจุดที่โยงกันมากที่สุด และสร้าง 2 กลุ่มต่อไป จาก จากล่างขึ้นบน. ซึ่งเป็น รวมตัวกัน แนวทางที่เราจะพัฒนา
ขั้นตอนในการดำเนินการคลัสเตอร์แบบลำดับชั้นแบบรวมกลุ่ม
เพื่อให้แนวทางการรวมกลุ่มชัดเจนยิ่งขึ้น มีขั้นตอนของ การจัดกลุ่มลำดับชั้นแบบรวมกลุ่ม (AHC) อัลกอริทึม:
- ในตอนเริ่มต้น ให้ถือว่าแต่ละจุดข้อมูลเป็นคลัสเตอร์เดียว ดังนั้นจำนวนคลัสเตอร์ที่จุดเริ่มต้นจะเป็น K ในขณะที่ K เป็นจำนวนเต็มที่แสดงถึงจำนวนจุดข้อมูล
- สร้างคลัสเตอร์โดยเชื่อมจุดข้อมูลที่ใกล้เคียงที่สุดสองจุดซึ่งส่งผลให้เกิดคลัสเตอร์ K-1
- สร้างคลัสเตอร์มากขึ้นโดยการรวมกลุ่มที่ใกล้เคียงที่สุดสองกลุ่มที่ส่งผลให้เกิดคลัสเตอร์ K-2
- ทำซ้ำสามขั้นตอนข้างต้นจนเกิดคลัสเตอร์ขนาดใหญ่หนึ่งกลุ่ม
หมายเหตุ: เพื่อให้เข้าใจง่ายขึ้น เรากำลังพูดถึงจุดข้อมูล "สองจุดที่ใกล้เคียงที่สุด" ในขั้นตอนที่ 2 และ 3 แต่มีวิธีการเชื่อมโยงจุดอื่นๆ เพิ่มเติม ตามที่เราจะเห็นในอีกสักครู่
หากคุณกลับขั้นตอนของอัลกอริทึม ACH ไปจาก 4 เป็น 1 - นั่นจะเป็นขั้นตอนในการ *การแบ่งกลุ่มแบบลำดับชั้น (DHC)*.
ขอให้สังเกตว่า HCA สามารถเป็นได้ทั้งแบบแบ่งและแบบบนลงล่าง หรือแบบรวมตัวและแบบล่างขึ้นบน วิธี DHC จากบนลงล่างจะได้ผลดีที่สุดเมื่อคุณมีคลัสเตอร์น้อยกว่าแต่มีขนาดใหญ่กว่า ดังนั้นจึงมีราคาแพงกว่าในการคำนวณ ในทางกลับกัน วิธีการ AHC จากล่างขึ้นบนนั้นเหมาะสมเมื่อคุณมีคลัสเตอร์ขนาดเล็กจำนวนมาก มันง่ายกว่าในการคำนวณ ใช้มากขึ้นและพร้อมใช้งานมากขึ้น
หมายเหตุ ไม่ว่าจะจากบนลงล่างหรือล่างขึ้นบน การแสดงภาพเดนโดรแกรมของกระบวนการจัดกลุ่มจะเริ่มต้นด้วยการหารเป็นสองส่วน และจบลงด้วยการเลือกปฏิบัติแต่ละจุด เมื่อโครงสร้างพื้นฐานของกระบวนการจัดกลุ่มเป็นไบนารีทรี
เรามาพลอตแผนภาพข้อมูลลูกค้าของเราเพื่อให้เห็นภาพความสัมพันธ์แบบลำดับชั้นของข้อมูลกัน คราวนี้เราจะใช้ scipy
ห้องสมุดเพื่อสร้าง dendrogram สำหรับชุดข้อมูลของเรา:
import scipy.cluster.hierarchy as shc
import matplotlib.pyplot as plt
plt.figure(figsize=(10, 7))
plt.title("Customers Dendrogram")
selected_data = customer_data_oh.iloc[:, 1:3]
clusters = shc.linkage(selected_data,
method='ward',
metric="euclidean")
shc.dendrogram(Z=clusters)
plt.show()
ผลลัพธ์ของสคริปต์มีลักษณะดังนี้:
ในสคริปต์ด้านบน เราได้สร้างคลัสเตอร์และคลัสเตอร์ย่อยด้วยคะแนนของเรา กำหนดวิธีที่จุดของเราจะเชื่อมโยง (โดยใช้ ward
วิธี) และวิธีวัดระยะห่างระหว่างจุดต่างๆ (โดยใช้ปุ่ม euclidean
เมตริก)
ด้วยโครงเรื่องของ dendrogram กระบวนการที่อธิบายไว้ของ DHC และ AHC สามารถมองเห็นได้ เมื่อต้องการเห็นภาพวิธีการจากบนลงล่าง ให้เริ่มจากด้านบนสุดของ dendrogram แล้วลงไป และทำตรงกันข้าม โดยเริ่มจากลงและเลื่อนขึ้นด้านบนเพื่อให้เห็นภาพวิธีการจากล่างขึ้นบน
วิธีการเชื่อมโยง
มีวิธีการเชื่อมโยงอื่น ๆ อีกมากมาย เมื่อเข้าใจวิธีการทำงานมากขึ้น คุณจะสามารถเลือกวิธีที่เหมาะสมกับความต้องการของคุณได้ นอกจากนั้นแต่ละอย่างจะให้ผลลัพธ์ที่แตกต่างกันเมื่อใช้ ไม่มีกฎตายตัวในการวิเคราะห์การจัดกลุ่ม หากเป็นไปได้ ให้ศึกษาลักษณะของปัญหาเพื่อดูว่าข้อใดเหมาะสมที่สุด ทดสอบวิธีการต่างๆ และตรวจสอบผลลัพธ์
วิธีการเชื่อมโยงบางส่วน ได้แก่ :
- การเชื่อมโยงเดียว: เรียกอีกอย่างว่า เพื่อนบ้านที่ใกล้ที่สุด (NN). ระยะห่างระหว่างคลัสเตอร์ถูกกำหนดโดยระยะห่างระหว่างสมาชิกที่ใกล้ที่สุด
- เชื่อมโยงให้สมบูรณ์: เรียกอีกอย่างว่า เพื่อนบ้านที่อยู่ไกลที่สุด (FN), อัลกอริธึมจุดที่ไกลที่สุด,หรือ อัลกอริทึมของ Voor Hees. ระยะห่างระหว่างกระจุกถูกกำหนดโดยระยะห่างระหว่างสมาชิกที่ไกลที่สุด วิธีนี้มีราคาแพงในการคำนวณ
- ความเชื่อมโยงเฉลี่ย: หรือที่เรียกว่า อัพจีเอ็มเอ (วิธีกลุ่มคู่ไม่ถ่วงน้ำหนักพร้อมค่าเฉลี่ยเลขคณิต). เปอร์เซ็นต์ของจำนวนคะแนนของแต่ละคลัสเตอร์จะคำนวณตามจำนวนคะแนนของสองคลัสเตอร์หากรวมเข้าด้วยกัน
- การเชื่อมโยงแบบถ่วงน้ำหนัก: หรือที่เรียกว่า WPMA (วิธีกลุ่มถ่วงน้ำหนักด้วยค่าเฉลี่ยเลขคณิต). จุดแต่ละจุดของกระจุกทั้งสองกลุ่มมีส่วนทำให้ระยะห่างรวมระหว่างกระจุกที่เล็กกว่ากับกระจุกที่ใหญ่กว่า
- การเชื่อมโยงเซนทรอยด์: เรียกอีกอย่างว่า อัพจีเอ็มซี (วิธีกลุ่มคู่ไม่ถ่วงน้ำหนักโดยใช้ Centroids). จุดที่กำหนดโดยค่าเฉลี่ยของจุดทั้งหมด (เซนทรอยด์) จะถูกคำนวณสำหรับแต่ละคลัสเตอร์ และระยะห่างระหว่างคลัสเตอร์คือระยะห่างระหว่างเซนทรอยด์ตามลำดับ
- การเชื่อมโยงวอร์ด: หรือที่เรียกว่า มิสคิว (เพิ่มขึ้นน้อยที่สุดของผลรวมของสี่เหลี่ยมจัตุรัส). ระบุระยะห่างระหว่างสองคลัสเตอร์ คำนวณผลรวมของข้อผิดพลาดกำลังสอง (ESS) และเลือกคลัสเตอร์ถัดไปตามลำดับโดยพิจารณาจาก ESS ที่เล็กกว่า Ward's Method พยายามลดการเพิ่มขึ้นของ ESS ในแต่ละขั้นตอน ดังนั้นการลดข้อผิดพลาด
ตัวชี้วัดระยะทาง
นอกจากการเชื่อมโยงแล้ว เรายังสามารถระบุตัวชี้วัดระยะทางที่ใช้มากที่สุดได้:
- ยุคลิด: เรียกอีกอย่างว่า พีทาโกรัสหรือเส้นตรง ระยะทาง. มันคำนวณระยะห่างระหว่างจุดสองจุดในอวกาศ โดยการวัดความยาวของส่วนของเส้นตรงที่ผ่านระหว่างจุดทั้งสอง มันใช้ทฤษฎีบทพีทาโกรัสและค่าระยะทางเป็นผล (ค) ของสมการ:
$$
ค^2 = ก^2 + ข^2
$$
- แมนฮัตตัน: เรียกอีกอย่างว่า บล็อกเมือง แท็กซี่ ระยะทาง. เป็นผลรวมของความแตกต่างสัมบูรณ์ระหว่างการวัดในทุกมิติของสองจุด หากมิติเหล่านั้นเป็นสอง ก็เปรียบได้กับการทำขวาและซ้ายเมื่อเดินหนึ่งช่วงตึก
- มินโคว์สกี้: เป็นลักษณะทั่วไปของระยะทางทั้งแบบยุคลิดและแมนฮัตตัน เป็นวิธีคำนวณระยะทางตามผลต่างสัมบูรณ์ตามลำดับของตัวชี้วัด Minkowski p. แม้ว่าจะถูกกำหนดไว้สำหรับ any p> 0มักใช้กับค่าอื่นที่ไม่ใช่ 1, 2 และ ∞ (อนันต์) ระยะทาง Minkowski เท่ากับระยะทางแมนฮัตตันเมื่อ p = 1และเท่ากับระยะทางแบบยุคลิดเมื่อ p = 2.
$$
Dleft(X,Yright) = ซ้าย(sum_{i=1}^n |x_i-y_i|^pright)^{frac{1}{p}}
$$
- เซฟ: หรือที่เรียกว่า กระดานหมากรุก ระยะทาง. มันเป็นกรณีที่รุนแรงของระยะทาง Minkowski เมื่อเราใช้อินฟินิตี้เป็นค่าของพารามิเตอร์ พี (p = ∞)เราลงเอยด้วยเมตริกที่กำหนดระยะทางเป็นความแตกต่างสัมบูรณ์สูงสุดระหว่างพิกัด
- โคไซน์: คือระยะห่างโคไซน์เชิงมุมระหว่างลำดับจุดสองจุดหรือเวกเตอร์ ความคล้ายคลึงของโคไซน์เป็นผลคูณดอทของเวกเตอร์หารด้วยผลคูณของความยาว
- แจ็คการ์ด: วัดความคล้ายคลึงกันระหว่างชุดจุดจำกัด มันถูกกำหนดให้เป็นจำนวนคะแนนทั้งหมด (คาร์ดินาลลิตี้) ในจุดร่วมในแต่ละเซ็ต (ทางแยก) หารด้วยจำนวนคะแนนทั้งหมด (คาร์ดินาลลิตี้) ของคะแนนรวมของทั้งสองชุด (ยูเนียน)
- เจนเซ่น-แชนนอน: ขึ้นอยู่กับความแตกต่างของ Kullback-Leibler จะพิจารณาการแจกแจงความน่าจะเป็นของคะแนนและวัดความคล้ายคลึงกันระหว่างการแจกแจงเหล่านั้น เป็นวิธีการยอดนิยมของทฤษฎีความน่าจะเป็นและสถิติ
เราเลือกแล้ว ท้องที่ และ ยุคลิด สำหรับ dendrogram เนื่องจากเป็นวิธีและเมตริกที่ใช้กันมากที่สุด พวกเขามักจะให้ผลลัพธ์ที่ดีเนื่องจาก Ward links ชี้ตามการลดข้อผิดพลาดให้น้อยที่สุด และ Euclidean ทำงานได้ดีในมิติที่ต่ำกว่า
ในตัวอย่างนี้ เรากำลังทำงานกับสองคุณลักษณะ (คอลัมน์) ของข้อมูลการตลาด และการสังเกตหรือแถว 200 รายการ เนื่องจากจำนวนการสังเกตมากกว่าจำนวนจุดสนใจ (200 > 2) เรากำลังทำงานในพื้นที่มิติต่ำ
เมื่อจำนวนคุณสมบัติ (F) มากกว่าจำนวนการสังเกต (N) – ส่วนใหญ่เขียนเป็น ฉ >> นู๋ก็หมายความว่าเรามีไฟล์ พื้นที่มิติสูง.
หากเราต้องรวมคุณลักษณะเพิ่มเติม ดังนั้นเราจึงมีคุณสมบัติมากกว่า 200 อย่าง ระยะทางแบบยุคลิดอาจทำงานได้ไม่ดีนัก เนื่องจากจะมีปัญหาในการวัดระยะทางเล็ก ๆ ทั้งหมดในพื้นที่ขนาดใหญ่มากที่ใหญ่ขึ้นเท่านั้น กล่าวอีกนัยหนึ่งวิธีระยะทางแบบยุคลิดมีปัญหาในการทำงานกับข้อมูล ความเบาบาง. เรื่องนี้เรียกว่า คำสาปแห่งมิติ. ค่าระยะทางจะเล็กมาก ราวกับว่าพวกมัน "เจือจาง" ในพื้นที่ขนาดใหญ่ บิดเบี้ยวจนกลายเป็น 0
หมายเหตุ หากคุณเคยเจอชุดข้อมูลที่มี ฉ >> pคุณอาจจะใช้ตัววัดระยะทางอื่นๆ เช่น มหาลาโนบี ระยะทาง. คุณยังสามารถลดขนาดชุดข้อมูลได้โดยใช้ การวิเคราะห์องค์ประกอบหลัก (PCA). ปัญหานี้เกิดขึ้นบ่อยโดยเฉพาะเมื่อจัดกลุ่มข้อมูลการจัดลำดับทางชีวภาพ
เราได้พูดถึงเมตริก การเชื่อมโยง และวิธีที่แต่ละรายการจะส่งผลต่อผลลัพธ์ของเรา ตอนนี้ เรามาทำการวิเคราะห์ dendrogram กันต่อ และดูว่าจะสามารถระบุจำนวนคลัสเตอร์ในชุดข้อมูลของเราได้อย่างไร
การหาจำนวนกลุ่มที่น่าสนใจใน dendrogram ก็เหมือนกับการหาพื้นที่แนวนอนที่ใหญ่ที่สุดที่ไม่มีเส้นแนวตั้ง (ช่องว่างที่มีเส้นแนวตั้งที่ยาวที่สุด) ซึ่งหมายความว่ามีการแยกระหว่างคลัสเตอร์มากขึ้น
เราสามารถวาดเส้นแนวนอนที่ลากผ่านระยะทางที่ยาวที่สุดนั้นได้:
plt.figure(figsize=(10, 7))
plt.title("Customers Dendogram with line")
clusters = shc.linkage(selected_data,
method='ward',
metric="euclidean")
shc.dendrogram(clusters)
plt.axhline(y = 125, color = 'r', linestyle = '-')
หลังจากระบุตำแหน่งเส้นแนวนอนแล้ว เราจะนับจำนวนครั้งที่เส้นแนวตั้งของเราตัดกับเส้นแนวตั้ง ในตัวอย่างนี้ 5 ครั้ง ดังนั้น 5 จึงเป็นตัวบ่งชี้ที่ดีของจำนวนกระจุกที่มีระยะห่างระหว่างกันมากที่สุด
หมายเหตุ: dendrogram ควรถือเป็นข้อมูลอ้างอิงเท่านั้นเมื่อใช้เพื่อเลือกจำนวนคลัสเตอร์ มันสามารถกำจัดตัวเลขนั้นได้อย่างง่ายดายและได้รับอิทธิพลจากประเภทของตัวชี้วัดการเชื่อมโยงและระยะทางอย่างสมบูรณ์ เมื่อทำการวิเคราะห์คลัสเตอร์ในเชิงลึก ขอแนะนำให้ดูที่ dendrograms ที่มีการเชื่อมโยงและตัวชี้วัดที่แตกต่างกัน และดูผลลัพธ์ที่สร้างขึ้นด้วยสามบรรทัดแรกที่กลุ่มมีระยะห่างมากที่สุดระหว่างพวกเขา
การใช้คลัสเตอร์แบบลำดับชั้นแบบรวมกลุ่ม
การใช้ข้อมูลเดิม
จนถึงตอนนี้ เราได้คำนวณจำนวนคลัสเตอร์ที่แนะนำสำหรับชุดข้อมูลของเราที่สอดคล้องกับการวิเคราะห์เริ่มต้นและการวิเคราะห์ PCA ของเรา ตอนนี้เราสามารถสร้างโมเดลการจัดกลุ่มแบบลำดับชั้นแบบรวมกลุ่มโดยใช้ Scikit-Learn AgglomerativeClustering
และค้นหาฉลากของจุดการตลาดด้วย labels_
:
from sklearn.cluster import AgglomerativeClustering
clustering_model = AgglomerativeClustering(n_clusters=5, affinity='euclidean', linkage='ward')
clustering_model.fit(selected_data)
clustering_model.labels_
ผลลัพธ์นี้ใน:
array([4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3,
4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 1,
4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 0, 2, 0, 2,
1, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 2, 1, 2, 0, 2, 0, 2, 0, 2,
0, 2, 0, 2, 0, 2, 1, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2,
0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2,
0, 2])
เราได้ตรวจสอบมากมายเพื่อไปยังจุดนี้ และฉลากเหล่านี้หมายความว่าอย่างไร ที่นี่ เรามีข้อมูลแต่ละจุดที่มีป้ายกำกับเป็นกลุ่มตั้งแต่ 0 ถึง 4:
data_labels = clustering_model.labels_
sns.scatterplot(x='Annual Income (k$)',
y='Spending Score (1-100)',
data=selected_data,
hue=data_labels,
pallete="rainbow").set_title('Labeled Customer Data')
นี่คือข้อมูลคลัสเตอร์สุดท้ายของเรา คุณสามารถดูจุดข้อมูลที่มีรหัสสีในรูปแบบของห้าคลัสเตอร์
จุดข้อมูลที่ด้านล่างขวา (ป้ายกำกับ: 0
, จุดข้อมูลสีม่วง) เป็นของลูกค้าที่มีเงินเดือนสูงแต่รายจ่ายต่ำ ลูกค้าเหล่านี้เป็นลูกค้าที่ใช้จ่ายเงินอย่างระมัดระวัง
ในทำนองเดียวกัน ลูกค้าที่มุมขวาบน (ป้ายกำกับ: 2
, Green data points) คือลูกค้าที่มีเงินเดือนสูงและมีรายจ่ายสูง เหล่านี้เป็นลูกค้าประเภทที่บริษัทกำหนดเป้าหมาย
ลูกค้าที่อยู่ตรงกลาง (ฉลาก: 1
, จุดข้อมูลสีน้ำเงิน) คือกลุ่มที่มีรายได้เฉลี่ยและรายจ่ายเฉลี่ย จำนวนลูกค้าสูงสุดอยู่ในหมวดหมู่นี้ บริษัทยังสามารถกำหนดเป้าหมายลูกค้าเหล่านี้ได้เนื่องจากมีจำนวนมาก
ลูกค้าที่ด้านล่างซ้าย (ป้ายกำกับ: 4
, สีแดง) คือลูกค้าที่มีเงินเดือนน้อยและมีรายจ่ายน้อย อาจถูกดึงดูดโดยเสนอโปรโมชั่น
และสุดท้าย ลูกค้าที่ด้านซ้ายบน (ป้ายกำกับ: 3
, จุดข้อมูลสีส้ม) คือกลุ่มที่มีรายได้สูงและรายจ่ายต่ำ ซึ่งมีเป้าหมายทางการตลาดในอุดมคติ
การใช้ผลลัพธ์จาก PCA
หากเราอยู่ในสถานการณ์ที่แตกต่างกัน ซึ่งเราต้องลดมิติข้อมูลลง นอกจากนี้เรายังสามารถพล็อตผลลัพธ์ PCA แบบคลัสเตอร์ได้อย่างง่ายดาย ซึ่งสามารถทำได้โดยการสร้างโมเดลการจัดกลุ่มแบบรวมกลุ่มและรับป้ายกำกับข้อมูลสำหรับแต่ละองค์ประกอบหลัก:
clustering_model_pca = AgglomerativeClustering(n_clusters=5, affinity='euclidean', linkage='ward')
clustering_model_pca.fit(pcs)
data_labels_pca = clustering_model_pca.labels_
sns.scatterplot(x=pc1_values,
y=pc2_values,
hue=data_labels_pca,
palette="rainbow").set_title('Labeled Customer Data Reduced with PCA')
สังเกตว่าผลลัพธ์ทั้งสองมีความคล้ายคลึงกันมาก ความแตกต่างที่สำคัญคือผลลัพธ์แรกกับข้อมูลดั้งเดิมนั้นอธิบายได้ง่ายกว่ามาก เห็นได้ชัดว่าลูกค้าสามารถแบ่งออกเป็น XNUMX กลุ่มตามรายได้ประจำปีและคะแนนการใช้จ่าย ในขณะที่ในแนวทาง PCA เรากำลังพิจารณาคุณลักษณะทั้งหมดของเรา เท่าที่เราสามารถดูความแปรปรวนที่อธิบายโดยแต่ละคุณลักษณะได้ นี่เป็นแนวคิดที่เข้าใจยากขึ้น โดยเฉพาะอย่างยิ่งเมื่อรายงานไปยังแผนกการตลาด
อย่างน้อยเราต้องแปลงข้อมูลของเราให้ดีขึ้น
หากคุณมีชุดข้อมูลขนาดใหญ่และซับซ้อนซึ่งคุณต้องดำเนินการลดขนาดก่อนที่จะทำคลัสเตอร์ - ให้ลองวิเคราะห์ความสัมพันธ์เชิงเส้นระหว่างคุณลักษณะแต่ละอย่างกับส่วนที่เหลือเพื่อสำรองการใช้ PCA และปรับปรุงความชัดเจนของกระบวนการ ด้วยการสร้างแบบจำลองเชิงเส้นต่อคู่คุณลักษณะ คุณจะสามารถเข้าใจได้ว่าคุณลักษณะโต้ตอบกันอย่างไร
หากปริมาณข้อมูลมีขนาดใหญ่มาก จะไม่สามารถพล็อตคู่ของคุณสมบัติ เลือกตัวอย่างข้อมูลของคุณ ให้สมดุลและใกล้เคียงกับการแจกแจงแบบปกติมากที่สุด และทำการวิเคราะห์กับตัวอย่างก่อน ทำความเข้าใจกับมัน ปรับแต่ง มัน – และนำไปใช้กับชุดข้อมูลทั้งหมดในภายหลัง
คุณสามารถเลือกเทคนิคการสร้างภาพคลัสเตอร์ที่แตกต่างกันได้ตามลักษณะของข้อมูลของคุณ (เชิงเส้น ไม่ใช่เชิงเส้น) และรวมหรือทดสอบทั้งหมดหากจำเป็น
สรุป
เทคนิคการจัดกลุ่มจะมีประโยชน์มากเมื่อพูดถึงข้อมูลที่ไม่มีป้ายกำกับ เนื่องจากข้อมูลส่วนใหญ่ในโลกแห่งความเป็นจริงไม่มีป้ายกำกับ และการทำหมายเหตุประกอบข้อมูลมีค่าใช้จ่ายสูงกว่า เทคนิคการจัดกลุ่มจึงสามารถนำมาใช้เพื่อติดป้ายกำกับข้อมูลที่ไม่มีป้ายกำกับได้
ในคู่มือนี้ เราได้นำเสนอปัญหาด้านวิทยาศาสตร์ข้อมูลที่แท้จริง เนื่องจากเทคนิคการจัดกลุ่มส่วนใหญ่จะใช้ในการวิเคราะห์การตลาด (และในการวิเคราะห์ทางชีววิทยาด้วย) เรายังได้อธิบายขั้นตอนการตรวจสอบหลายๆ ขั้นตอนเพื่อให้ได้โมเดลการจัดกลุ่มแบบลำดับชั้นที่ดีและวิธีอ่าน dendrograms และตั้งคำถามว่า PCA เป็นขั้นตอนที่จำเป็นหรือไม่ วัตถุประสงค์หลักของเราคือครอบคลุมหลุมพรางและสถานการณ์ต่างๆ ที่เราพบการจัดกลุ่มตามลำดับชั้น
การรวมกลุ่มมีความสุข!
- blockchain
- C + +
- การจัดกลุ่ม
- รหัส
- เหรียญอัจฉริยะ
- วิทยาศาสตร์ข้อมูล
- การสร้างภาพข้อมูล
- ชวา
- matplotlib
- โทเค็นที่ไม่สามารถทำซ้ำได้
- ทะเลเปิด
- หมีแพนด้า
- PHP
- เพลโต
- เพลโตไอ
- เพลโตดาต้าอินเทลลิเจนซ์
- เกมเพลโต
- Platoblockchain
- เพลโตดาต้า
- เพลโตเกม
- รูปหลายเหลี่ยม
- หลาม
- เกิดปฏิกิริยา
- scikit เรียนรู้
- ทะเลบอร์น
- สัญญาสมาร์ท
- โซลานา
- สแต็ค
- Vyper
- Web3
- ลมทะเล