คู่มือขั้นสุดท้ายสำหรับการจัดคลัสเตอร์ตามลำดับชั้นด้วย Python และ Scikit-Learn PlatoBlockchain Data Intelligence ค้นหาแนวตั้ง AI.

คู่มือขั้นสุดท้ายสำหรับการจัดคลัสเตอร์แบบลำดับชั้นด้วย Python และ Scikit-Learn

บทนำ

ในคู่มือนี้ เราจะมุ่งเน้นไปที่การนำ อัลกอริธึมการจัดกลุ่มแบบลำดับชั้นด้วย 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()

img

เมื่อดูจากฮิสโตแกรมแล้ว เราจะพบว่าลูกค้ามากกว่า 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()

ซึ่งจะให้เรา:

img

สังเกตในฮิสโตแกรมว่าข้อมูลส่วนใหญ่ของเราซึ่งมีลูกค้ามากกว่า 35 รายนั้นกระจุกตัวอยู่ใกล้ตัวเลข 60, บนของเรา meanในแกนนอน แต่จะเกิดอะไรขึ้นเมื่อเราก้าวไปสู่จุดสิ้นสุดของการกระจาย? เมื่อไปทางซ้าย จากค่าเฉลี่ย $60.560 ค่าต่อไปที่เราจะเจอคือ $34.300 – ค่าเฉลี่ย ($60.560) ลบรูปแบบมาตรฐาน ($26.260) หากเราออกไปทางซ้ายของการกระจายข้อมูลของเรามากขึ้น กฎที่คล้ายกันจะมีผล เราจะลบรูปแบบมาตรฐาน ($26.260) ออกจากค่าปัจจุบัน ($34.300) ดังนั้น เราจะพบมูลค่า $8.040 สังเกตว่าข้อมูลของเราเปลี่ยนจาก 60 ดอลลาร์เป็น 8 ดอลลาร์อย่างรวดเร็ว มัน “กระโดด” $26.260 ทุกครั้ง – แตกต่างกันมาก และนั่นคือสาเหตุที่เรามีความแปรปรวนสูงเช่นนี้

img

ความแปรปรวนและขนาดของข้อมูลมีความสำคัญในการวิเคราะห์การจัดกลุ่ม เนื่องจากการวัดระยะทางของอัลกอริธึมการจัดกลุ่มส่วนใหญ่มีความไวต่อขนาดข้อมูล ความแตกต่างของขนาดสามารถเปลี่ยนผลลัพธ์การจัดกลุ่มโดยทำให้จุดหนึ่งดูเหมือนใกล้หรือไกลกว่าที่เป็นจริง ทำให้การจัดกลุ่มข้อมูลผิดเพี้ยนไป

จนถึงตอนนี้ เราได้เห็นรูปร่างของข้อมูลของเรา การแจกแจงบางส่วน และสถิติเชิงพรรณนา ด้วย 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 

สิ่งนี้จะให้ตัวอย่างตารางผลลัพธ์แก่เรา:

img

ด้วยผลลัพธ์จะง่ายที่จะเห็นว่าคอลัมน์ 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)

ซึ่งแสดง:

img

โดยคร่าว ๆ เราสามารถมองเห็น 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)'])

img

เมื่อมองให้ใกล้ขึ้น เราสามารถแยกความแตกต่างของข้อมูล 5 กลุ่มได้อย่างแน่นอน ดูเหมือนว่าลูกค้าของเราสามารถจัดกลุ่มตามรายได้ที่พวกเขาทำในหนึ่งปีและจำนวนเงินที่พวกเขาใช้จ่าย นี่เป็นอีกประเด็นที่เกี่ยวข้องในการวิเคราะห์ของเรา เป็นสิ่งสำคัญที่เราจะพิจารณาเพียงสองคุณสมบัติเพื่อจัดกลุ่มลูกค้าของเรา ข้อมูลอื่น ๆ ที่เรามีเกี่ยวกับสิ่งเหล่านี้จะไม่เข้าสู่สมการ สิ่งนี้ให้ความหมายในการวิเคราะห์ – หากเรารู้ว่าลูกค้ามีรายได้และใช้จ่ายเท่าใด เราสามารถค้นหาความคล้ายคลึงที่เราต้องการได้อย่างง่ายดาย

img

ดีมาก! จนถึงตอนนี้ เรามีสองตัวแปรอยู่แล้วในการสร้างแบบจำลองของเรา นอกจากสิ่งนี้จะแสดงให้เห็นแล้ว ยังทำให้โมเดลดูเรียบง่าย เป็นกันเอง และอธิบายได้ชัดเจนยิ่งขึ้น

ดูคู่มือเชิงปฏิบัติสำหรับการเรียนรู้ 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)

img

แผนภาพข้อมูลหลัง PCA จะคล้ายกับแผนภาพที่ใช้ข้อมูลเพียงสองคอลัมน์โดยไม่มี PCA สังเกตว่าจุดที่ก่อตัวเป็นกลุ่มอยู่ใกล้กว่าและมีความเข้มข้นมากขึ้นหลัง PCA มากกว่าเดิมเล็กน้อย

img

การแสดงภาพโครงสร้างแบบลำดับชั้นด้วย Dendrograms

จนถึงตอนนี้ เราได้สำรวจข้อมูล ซึ่งเป็นคอลัมน์ที่จัดหมวดหมู่แบบ one-hot encoded ตัดสินใจว่าคอลัมน์ใดเหมาะสมสำหรับการจัดกลุ่ม และลดมิติข้อมูล แผนภาพระบุว่าเรามี 5 กลุ่มในข้อมูลของเรา แต่ยังมีวิธีอื่นในการแสดงภาพความสัมพันธ์ระหว่างจุดของเราและช่วยกำหนดจำนวนคลัสเตอร์ - โดยการสร้าง เดนโดรแกรม (มักสะกดผิดว่า dendogram) เดนโดร วิธี ต้นไม้ ในภาษาละติน

พื้นที่ เดนโดรแกรม เป็นผลมาจากการเชื่อมโยงจุดในชุดข้อมูล เป็นการแสดงภาพของกระบวนการจัดกลุ่มตามลำดับชั้น และกระบวนการจัดกลุ่มแบบลำดับชั้นทำงานอย่างไร ก็… ขึ้นอยู่กับ – อาจเป็นคำตอบที่คุณเคยได้ยินมามากใน Data Science

การทำความเข้าใจการจัดกลุ่มแบบลำดับชั้น

เมื่อราคาของ อัลกอริธึมการจัดกลุ่มแบบลำดับชั้น (HCA) เริ่มเชื่อมโยงจุดและค้นหากลุ่ม โดยแรกสามารถแบ่งจุดออกเป็น 2 กลุ่มใหญ่ แล้วแยกแต่ละกลุ่มออกเป็น 2 กลุ่มเล็ก ๆ มีทั้งหมด 4 กลุ่ม คือ แตกแยก และ จากบนลงล่าง เข้าใกล้

หรือจะทำตรงกันข้ามก็ได้ คือ ดูจุดข้อมูลทั้งหมด หาจุดใกล้กัน 2 จุด โยงกัน แล้วหาจุดอื่นๆ ที่ใกล้เคียงจุดที่โยงกันมากที่สุด และสร้าง 2 กลุ่มต่อไป จาก จากล่างขึ้นบน. ซึ่งเป็น รวมตัวกัน แนวทางที่เราจะพัฒนา

ขั้นตอนในการดำเนินการคลัสเตอร์แบบลำดับชั้นแบบรวมกลุ่ม

เพื่อให้แนวทางการรวมกลุ่มชัดเจนยิ่งขึ้น มีขั้นตอนของ การจัดกลุ่มลำดับชั้นแบบรวมกลุ่ม (AHC) อัลกอริทึม:

  1. ในตอนเริ่มต้น ให้ถือว่าแต่ละจุดข้อมูลเป็นคลัสเตอร์เดียว ดังนั้นจำนวนคลัสเตอร์ที่จุดเริ่มต้นจะเป็น K ในขณะที่ K เป็นจำนวนเต็มที่แสดงถึงจำนวนจุดข้อมูล
  2. สร้างคลัสเตอร์โดยเชื่อมจุดข้อมูลที่ใกล้เคียงที่สุดสองจุดซึ่งส่งผลให้เกิดคลัสเตอร์ K-1
  3. สร้างคลัสเตอร์มากขึ้นโดยการรวมกลุ่มที่ใกล้เคียงที่สุดสองกลุ่มที่ส่งผลให้เกิดคลัสเตอร์ K-2
  4. ทำซ้ำสามขั้นตอนข้างต้นจนเกิดคลัสเตอร์ขนาดใหญ่หนึ่งกลุ่ม

หมายเหตุ: เพื่อให้เข้าใจง่ายขึ้น เรากำลังพูดถึงจุดข้อมูล "สองจุดที่ใกล้เคียงที่สุด" ในขั้นตอนที่ 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()

ผลลัพธ์ของสคริปต์มีลักษณะดังนี้:

img

ในสคริปต์ด้านบน เราได้สร้างคลัสเตอร์และคลัสเตอร์ย่อยด้วยคะแนนของเรา กำหนดวิธีที่จุดของเราจะเชื่อมโยง (โดยใช้ ward วิธี) และวิธีวัดระยะห่างระหว่างจุดต่างๆ (โดยใช้ปุ่ม euclidean เมตริก)

ด้วยโครงเรื่องของ dendrogram กระบวนการที่อธิบายไว้ของ DHC และ AHC สามารถมองเห็นได้ เมื่อต้องการเห็นภาพวิธีการจากบนลงล่าง ให้เริ่มจากด้านบนสุดของ dendrogram แล้วลงไป และทำตรงกันข้าม โดยเริ่มจากลงและเลื่อนขึ้นด้านบนเพื่อให้เห็นภาพวิธีการจากล่างขึ้นบน

วิธีการเชื่อมโยง

มีวิธีการเชื่อมโยงอื่น ๆ อีกมากมาย เมื่อเข้าใจวิธีการทำงานมากขึ้น คุณจะสามารถเลือกวิธีที่เหมาะสมกับความต้องการของคุณได้ นอกจากนั้นแต่ละอย่างจะให้ผลลัพธ์ที่แตกต่างกันเมื่อใช้ ไม่มีกฎตายตัวในการวิเคราะห์การจัดกลุ่ม หากเป็นไปได้ ให้ศึกษาลักษณะของปัญหาเพื่อดูว่าข้อใดเหมาะสมที่สุด ทดสอบวิธีการต่างๆ และตรวจสอบผลลัพธ์

วิธีการเชื่อมโยงบางส่วน ได้แก่ :

  • การเชื่อมโยงเดียว: เรียกอีกอย่างว่า เพื่อนบ้านที่ใกล้ที่สุด (NN). ระยะห่างระหว่างคลัสเตอร์ถูกกำหนดโดยระยะห่างระหว่างสมาชิกที่ใกล้ที่สุด

img

  • เชื่อมโยงให้สมบูรณ์: เรียกอีกอย่างว่า เพื่อนบ้านที่อยู่ไกลที่สุด (FN), อัลกอริธึมจุดที่ไกลที่สุด,หรือ อัลกอริทึมของ Voor Hees. ระยะห่างระหว่างกระจุกถูกกำหนดโดยระยะห่างระหว่างสมาชิกที่ไกลที่สุด วิธีนี้มีราคาแพงในการคำนวณ

img

  • ความเชื่อมโยงเฉลี่ย: หรือที่เรียกว่า อัพจีเอ็มเอ (วิธีกลุ่มคู่ไม่ถ่วงน้ำหนักพร้อมค่าเฉลี่ยเลขคณิต). เปอร์เซ็นต์ของจำนวนคะแนนของแต่ละคลัสเตอร์จะคำนวณตามจำนวนคะแนนของสองคลัสเตอร์หากรวมเข้าด้วยกัน

img

  • การเชื่อมโยงแบบถ่วงน้ำหนัก: หรือที่เรียกว่า WPMA (วิธีกลุ่มถ่วงน้ำหนักด้วยค่าเฉลี่ยเลขคณิต). จุดแต่ละจุดของกระจุกทั้งสองกลุ่มมีส่วนทำให้ระยะห่างรวมระหว่างกระจุกที่เล็กกว่ากับกระจุกที่ใหญ่กว่า
  • การเชื่อมโยงเซนทรอยด์: เรียกอีกอย่างว่า อัพจีเอ็มซี (วิธีกลุ่มคู่ไม่ถ่วงน้ำหนักโดยใช้ Centroids). จุดที่กำหนดโดยค่าเฉลี่ยของจุดทั้งหมด (เซนทรอยด์) จะถูกคำนวณสำหรับแต่ละคลัสเตอร์ และระยะห่างระหว่างคลัสเตอร์คือระยะห่างระหว่างเซนทรอยด์ตามลำดับ

img

  • การเชื่อมโยงวอร์ด: หรือที่เรียกว่า มิสคิว (เพิ่มขึ้นน้อยที่สุดของผลรวมของสี่เหลี่ยมจัตุรัส). ระบุระยะห่างระหว่างสองคลัสเตอร์ คำนวณผลรวมของข้อผิดพลาดกำลังสอง (ESS) และเลือกคลัสเตอร์ถัดไปตามลำดับโดยพิจารณาจาก ESS ที่เล็กกว่า Ward's Method พยายามลดการเพิ่มขึ้นของ ESS ในแต่ละขั้นตอน ดังนั้นการลดข้อผิดพลาด

img

ตัวชี้วัดระยะทาง

นอกจากการเชื่อมโยงแล้ว เรายังสามารถระบุตัวชี้วัดระยะทางที่ใช้มากที่สุดได้:

  • ยุคลิด: เรียกอีกอย่างว่า พีทาโกรัสหรือเส้นตรง ระยะทาง. มันคำนวณระยะห่างระหว่างจุดสองจุดในอวกาศ โดยการวัดความยาวของส่วนของเส้นตรงที่ผ่านระหว่างจุดทั้งสอง มันใช้ทฤษฎีบทพีทาโกรัสและค่าระยะทางเป็นผล (ค) ของสมการ:

$$
ค^2 = ก^2 + ข^2
$$

  • แมนฮัตตัน: เรียกอีกอย่างว่า บล็อกเมือง แท็กซี่ ระยะทาง. เป็นผลรวมของความแตกต่างสัมบูรณ์ระหว่างการวัดในทุกมิติของสองจุด หากมิติเหล่านั้นเป็นสอง ก็เปรียบได้กับการทำขวาและซ้ายเมื่อเดินหนึ่งช่วงตึก

img

  • มินโคว์สกี้: เป็นลักษณะทั่วไปของระยะทางทั้งแบบยุคลิดและแมนฮัตตัน เป็นวิธีคำนวณระยะทางตามผลต่างสัมบูรณ์ตามลำดับของตัวชี้วัด 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}}
$$

img

  • เซฟ: หรือที่เรียกว่า กระดานหมากรุก ระยะทาง. มันเป็นกรณีที่รุนแรงของระยะทาง 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 = '-')

img

หลังจากระบุตำแหน่งเส้นแนวนอนแล้ว เราจะนับจำนวนครั้งที่เส้นแนวตั้งของเราตัดกับเส้นแนวตั้ง ในตัวอย่างนี้ 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')

img

นี่คือข้อมูลคลัสเตอร์สุดท้ายของเรา คุณสามารถดูจุดข้อมูลที่มีรหัสสีในรูปแบบของห้าคลัสเตอร์

จุดข้อมูลที่ด้านล่างขวา (ป้ายกำกับ: 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')

img

สังเกตว่าผลลัพธ์ทั้งสองมีความคล้ายคลึงกันมาก ความแตกต่างที่สำคัญคือผลลัพธ์แรกกับข้อมูลดั้งเดิมนั้นอธิบายได้ง่ายกว่ามาก เห็นได้ชัดว่าลูกค้าสามารถแบ่งออกเป็น XNUMX กลุ่มตามรายได้ประจำปีและคะแนนการใช้จ่าย ในขณะที่ในแนวทาง PCA เรากำลังพิจารณาคุณลักษณะทั้งหมดของเรา เท่าที่เราสามารถดูความแปรปรวนที่อธิบายโดยแต่ละคุณลักษณะได้ นี่เป็นแนวคิดที่เข้าใจยากขึ้น โดยเฉพาะอย่างยิ่งเมื่อรายงานไปยังแผนกการตลาด

อย่างน้อยเราต้องแปลงข้อมูลของเราให้ดีขึ้น

หากคุณมีชุดข้อมูลขนาดใหญ่และซับซ้อนซึ่งคุณต้องดำเนินการลดขนาดก่อนที่จะทำคลัสเตอร์ - ให้ลองวิเคราะห์ความสัมพันธ์เชิงเส้นระหว่างคุณลักษณะแต่ละอย่างกับส่วนที่เหลือเพื่อสำรองการใช้ PCA และปรับปรุงความชัดเจนของกระบวนการ ด้วยการสร้างแบบจำลองเชิงเส้นต่อคู่คุณลักษณะ คุณจะสามารถเข้าใจได้ว่าคุณลักษณะโต้ตอบกันอย่างไร

หากปริมาณข้อมูลมีขนาดใหญ่มาก จะไม่สามารถพล็อตคู่ของคุณสมบัติ เลือกตัวอย่างข้อมูลของคุณ ให้สมดุลและใกล้เคียงกับการแจกแจงแบบปกติมากที่สุด และทำการวิเคราะห์กับตัวอย่างก่อน ทำความเข้าใจกับมัน ปรับแต่ง มัน – และนำไปใช้กับชุดข้อมูลทั้งหมดในภายหลัง

คุณสามารถเลือกเทคนิคการสร้างภาพคลัสเตอร์ที่แตกต่างกันได้ตามลักษณะของข้อมูลของคุณ (เชิงเส้น ไม่ใช่เชิงเส้น) และรวมหรือทดสอบทั้งหมดหากจำเป็น

สรุป

เทคนิคการจัดกลุ่มจะมีประโยชน์มากเมื่อพูดถึงข้อมูลที่ไม่มีป้ายกำกับ เนื่องจากข้อมูลส่วนใหญ่ในโลกแห่งความเป็นจริงไม่มีป้ายกำกับ และการทำหมายเหตุประกอบข้อมูลมีค่าใช้จ่ายสูงกว่า เทคนิคการจัดกลุ่มจึงสามารถนำมาใช้เพื่อติดป้ายกำกับข้อมูลที่ไม่มีป้ายกำกับได้

ในคู่มือนี้ เราได้นำเสนอปัญหาด้านวิทยาศาสตร์ข้อมูลที่แท้จริง เนื่องจากเทคนิคการจัดกลุ่มส่วนใหญ่จะใช้ในการวิเคราะห์การตลาด (และในการวิเคราะห์ทางชีววิทยาด้วย) เรายังได้อธิบายขั้นตอนการตรวจสอบหลายๆ ขั้นตอนเพื่อให้ได้โมเดลการจัดกลุ่มแบบลำดับชั้นที่ดีและวิธีอ่าน dendrograms และตั้งคำถามว่า PCA เป็นขั้นตอนที่จำเป็นหรือไม่ วัตถุประสงค์หลักของเราคือครอบคลุมหลุมพรางและสถานการณ์ต่างๆ ที่เราพบการจัดกลุ่มตามลำดับชั้น

การรวมกลุ่มมีความสุข!

ประทับเวลา:

เพิ่มเติมจาก สแต็ค