สตริงเป็นคุณลักษณะในต้นไม้ตัดสินใจ / ฟอเรสต์แบบสุ่ม


64

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

ฉันจะจัดการสถานการณ์ดังกล่าวได้อย่างไร

ฉันสามารถแปลงสตริงเป็นตัวเลขโดยกลไกบางอย่างเช่น hashing ใน Python แต่ฉันต้องการทราบวิธีปฏิบัติที่ดีที่สุดเกี่ยวกับวิธีการจัดการสตริงในปัญหาต้นไม้การตัดสินใจ


ในกรณีของ sckitlearn ฉันได้เห็นว่าเราจำเป็นต้องเข้ารหัสตัวแปรเด็ดขาดวิธีอื่นที่เหมาะสมจะทำให้เกิดข้อผิดพลาดที่บอกว่า ValueError: ไม่สามารถแปลงสตริงให้ลอยได้
Kar

คำตอบ:


56

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

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

ตัวอย่างหนึ่งคือการใช้รหัส ['red', 'green', 'blue'] ด้วย [1,2,3] จะสร้างสิ่งแปลก ๆ เช่น 'red' ต่ำกว่า 'blue' และถ้าคุณเฉลี่ย 'red' และ 'สีน้ำเงิน' คุณจะได้รับ 'สีเขียว' ตัวอย่างที่ละเอียดอ่อนอีกตัวอย่างหนึ่งอาจเกิดขึ้นเมื่อคุณโค้ด ['ต่ำ', 'ปานกลาง', 'สูง'] ด้วย [1,2,3] ในกรณีหลังมันอาจจะมีคำสั่งที่เหมาะสม แต่ความไม่แน่นอนบางอย่างอาจเกิดขึ้นเมื่อ 'สื่อ' ไม่อยู่ในกลาง 'ต่ำ' และ 'สูง'

สุดท้ายคำตอบสำหรับคำถามของคุณที่อยู่ในการเข้ารหัสคุณลักษณะเด็ดขาดลงไปคุณสมบัติไบนารีหลาย ตัวอย่างเช่นคุณอาจใช้รหัส ['red', 'green', 'blue'] ที่มี 3 คอลัมน์หนึ่งคอลัมน์สำหรับแต่ละหมวดหมู่โดยมี 1 เมื่อหมวดหมู่ตรงกันและ 0 เป็นอย่างอื่น สิ่งนี้เรียกว่าการเข้ารหัสแบบหนึ่งร้อนการเข้ารหัสแบบไบนารีการเข้ารหัสแบบหนึ่งใน k หรืออะไรก็ตาม คุณสามารถตรวจสอบเอกสารที่นี่เพื่อเข้ารหัสคุณสมบัติที่เป็นหมวดหมู่และการแยกฟีเจอร์ - การแฮชและการกำหนด เห็นได้ชัดว่าการเข้ารหัสแบบร้อนแรงจะขยายความต้องการพื้นที่ของคุณและบางครั้งก็ส่งผลเสียต่อประสิทธิภาพการทำงานเช่นกัน


2
มันเป็นการนำ scikit มาใช้ซึ่งไม่สามารถจัดการตัวแปรเด็ดขาดได้อย่างถูกต้อง การเข้ารหัสเช่นเดียวกับที่คำตอบนี้แนะนำน่าจะเป็นสิ่งที่ดีที่สุดที่คุณสามารถทำได้ ผู้ใช้ที่จริงจังกว่านี้อาจมองหาแพ็คเกจอื่น
SmallChess

3
หนึ่งสามารถใช้ sklearn.preprocessing.LabelBinarizer สำหรับการเข้ารหัสตัวแปรเด็ดขาด
GuSuku

@rapaio ฉันคิดว่าการเข้ารหัสแบบไบนารีนั้นไม่เหมือนการเข้ารหัสแบบร้อน การเข้ารหัสแบบไบนารีคือเมื่อคุณแสดงถึง 8 หมวดหมู่ด้วย 3 คอลัมน์หรือระหว่าง 9 ถึง 16 หมวดหมู่ที่มี 4 คอลัมน์เป็นต้น ฉันผิดหรือเปล่า?
Alok Nayak

แพคเกจ patsy หลามจะจัดการกับการเข้ารหัสตัวแปรเด็ดขาดหนึ่งร้อน patsy.readthedocs.io/en/latest/quickstart.html
zhespelt

5
อย่าใช้ LabelBinarizer ใช้sklearn.preprocessing.OneHotEncoder หากคุณกำลังใช้หมีแพนด้าที่จะนำเข้าและกระบวนการก่อนข้อมูลของคุณคุณยังสามารถทำเช่นนั้นได้โดยตรงโดยใช้pandas.get_dummies มันแย่มากที่ scikit-Learn ไม่สนับสนุนตัวแปรเด็ดขาด
Ricardo Cruz

11

คุณต้องเข้ารหัสสตริงของคุณเนื่องจากคุณลักษณะตัวเลขที่ sci-kit สามารถใช้สำหรับอัลกอริทึม ML ฟังก์ชั่นนี้ได้รับการจัดการในโมดูลการประมวลผลล่วงหน้า (เช่นดูsklearn.preprocessing.LabelEncoderสำหรับตัวอย่าง)


3
rapaio อธิบายในคำตอบของเขาว่าทำไมสิ่งนี้ถึงได้ผลลัพธ์ที่ไม่ถูกต้อง
Keith

7

โดยทั่วไปคุณควรเข้ารหัสตัวแปรเด็ดขาดแบบเข้ารหัสเดียวสำหรับโมเดลการเรียนรู้ Scikit รวมถึงฟอเรสต์แบบสุ่ม ฟอเรสต์แบบสุ่มมักจะใช้ได้ดีโดยไม่มีการเข้ารหัสแบบร้อนแรง แต่มักจะทำงานได้ดีขึ้นหากคุณเข้ารหัสแบบร้อนแรง การเข้ารหัสแบบร้อนแรงและตัวแปร "แบบจำลอง" หมายถึงสิ่งเดียวกันในบริบทนี้ Scikit-learn มีsklearn.preprocessing.OneHotEncoderและ Pandas มีpandas.get_dummiesเพื่อทำสิ่งนี้

อย่างไรก็ตามมีทางเลือกอื่น บทความ"Beyond One-Hot" ที่ KDnuggetsทำงานได้ดีเยี่ยมในการอธิบายว่าทำไมคุณต้องเข้ารหัสตัวแปรเด็ดขาดและทางเลือกอื่นในการเข้ารหัสแบบร้อนแรง

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

มีเป็นความพยายามอย่างต่อเนื่องที่จะทำให้ scikit เรียนรู้การจัดการคุณสมบัติเด็ดขาดโดยตรง

บทความนี้มีคำอธิบายของอัลกอริทึมที่ใช้ใน H2O มันอ้างอิงเอกสารทางวิชาการขั้นตอนวิธีการตัดสินใจแบบขนาน Parallel Decisionและรุ่นที่ยาวกว่าของกระดาษเดียวกัน


5

อัปเดตในปี 2018!

คุณสามารถสร้างพื้นที่ฝัง (เวกเตอร์หนาแน่น) สำหรับตัวแปรเด็ดขาดของคุณ พวกคุณหลายคนคุ้นเคยกับ word2vec และ fastext ซึ่งฝังคำในพื้นที่เวกเตอร์ที่มีความหนาแน่นสูงซึ่งมีความหมาย แนวคิดเดียวกันที่นี่ - ตัวแปรหมวดหมู่ของคุณจะจับคู่กับเวกเตอร์ที่มีความหมายบางอย่าง

จากกระดาษ Guo / Berkhahn :

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

ผู้เขียนพบว่าเป็นตัวแทนของตัวแปรเชิงหมวดหมู่ด้วยวิธีนี้ปรับปรุงประสิทธิภาพของอัลกอริทึมการเรียนรู้ของเครื่องทั้งหมดที่ทดสอบรวมถึงฟอเรสต์แบบสุ่ม

ตัวอย่างที่ดีที่สุดอาจเป็นการประยุกต์ใช้เทคนิคของ Pinterest ในการจัดกลุ่มพินที่เกี่ยวข้อง:

ป้อนคำอธิบายรูปภาพที่นี่

folks ที่ fastai ได้ดำเนินการ embeddings เด็ดขาดและสร้างดีมากโพสต์บล็อกกับสหายโน้ตบุ๊คสาธิต

รายละเอียดเพิ่มเติมและคำอธิบาย

โครงข่ายประสาทใช้ในการสร้างงานแต่งงานเช่นกำหนดเวกเตอร์ให้กับแต่ละค่านิยม เมื่อคุณมีเวกเตอร์คุณสามารถใช้มันในโมเดลใดก็ได้ที่ยอมรับค่าตัวเลข ส่วนประกอบของเวกเตอร์แต่ละตัวจะกลายเป็นตัวแปรอินพุต ตัวอย่างเช่นถ้าคุณใช้เวกเตอร์ 3 มิติเพื่อฝังรายการหมวดหมู่สีของคุณคุณอาจได้รับ: red = (0, 1.5, -2.3), blue = (1, 1, 0) เป็นต้นคุณจะใช้สาม ตัวแปรอินพุตในฟอเรสต์สุ่มของคุณที่สอดคล้องกับสามองค์ประกอบ สำหรับสิ่งสีแดง c1 = 0, c2 = 1.5 และ c3 = -2.3 สำหรับสิ่งสีฟ้า c1 = 1, c2 = 1 และ c3 = 0

คุณไม่จำเป็นต้องใช้เครือข่ายประสาทเทียมในการสร้างงานแต่งงาน (แม้ว่าฉันจะไม่แนะนำให้แยกจากเทคนิค) คุณสามารถสร้างงานแต่งงานของคุณเองด้วยมือหรือวิธีการอื่น ๆ หากเป็นไปได้ ตัวอย่างบางส่วน:

  1. แมปสีกับเวกเตอร์ RGB
  2. แผนที่ที่ตั้งเพื่อเวกเตอร์ lat / long
  3. ในแบบจำลองทางการเมืองของสหรัฐอเมริกาแผนที่เมืองไปยังส่วนประกอบเวกเตอร์บางส่วนที่แสดงถึงการจัดแนวซ้าย / ขวาภาระภาษี ฯลฯ

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

@Keith ใช้โครงข่ายประสาทเพื่อสร้างงานแต่งงานเช่นกำหนดเวกเตอร์ให้กับแต่ละค่านิยม เมื่อคุณมีเวกเตอร์คุณสามารถใช้มันในโมเดลใดก็ได้ที่ยอมรับค่าตัวเลข ส่วนประกอบของเวกเตอร์แต่ละตัวจะกลายเป็นตัวแปรอินพุต ตัวอย่างเช่นหากคุณใช้เวกเตอร์ 3 มิติเพื่อฝังรายการหมวดหมู่สีของคุณคุณอาจได้รับ: red = (0, 1.5, -2.3), blue = (1, 1, 0)ฯลฯ คุณจะใช้ตัวแปรอินพุตสามตัวในฟอเรสต์แบบสุ่มที่สอดคล้องกับองค์ประกอบทั้งสาม สำหรับสิ่งสีแดง c1 = 0, c2 = 1.5 และ c3 = -2.3 สำหรับสิ่งสีฟ้า c1 = 1, c2 = 1 และ c3 = 0
Pete

ฉันได้รับแนวคิดทั้งหมดเพราะมันค่อนข้างง่าย ฉันหมายถึงจะทำอย่างไรในการนำไปใช้ สมุดบันทึกสาธิต fast.ai ที่คุณลิงค์มีบิตกับ RandomForestRegressor ในตอนท้าย แต่ฉันไม่เห็นว่าสิ่งนี้จะเพิ่มในงานแต่งงานได้อย่างไร
Keith

ฉันคิดว่านี่อาจเป็นตัวอย่างที่ดีของรหัสใน Keras github.com/entron/entity-embedding-rossmann
Keith

3

คุณสามารถใช้ตัวแปรจำลองในสถานการณ์ดังกล่าว ด้วยแพนด้าpanda.get_dummiesคุณสามารถสร้างตัวแปรจำลองสำหรับสตริงที่คุณต้องการใส่ใน Decision Tree หรือ Random Forest

ตัวอย่าง:

import pandas as pd
d = {'one' : pd.Series([1., 2., 3.,4.], index=['a', 'b', 'c','d']),'two' :pd.Series(['Paul', 'John', 'Micheal','George'], index=['a', 'b', 'c', 'd'])}
df = pd.DataFrame(d)

df_with_dummies= pd.get_dummies(df,columns=["two"],drop_first=False)
df_with_dummies

2

เปลี่ยนเป็นตัวเลขตัวอย่างเช่นสำหรับแต่ละประเทศที่ไม่ซ้ำกันจะใช้หมายเลขเฉพาะ (เช่น 1,2,3 และ ... )

นอกจากนี้คุณไม่จำเป็นต้องใช้การเข้ารหัสแบบ One-Hot (ตัวแปรดัมมี่) เมื่อทำงานกับฟอเรสต์แบบสุ่มเพราะต้นไม้ไม่ทำงานเหมือนอัลกอริทึมอื่น ๆ (เช่นการถดถอยเชิงเส้น / ลอจิสติก) และพวกมันไม่ทำงานไกล ทำงานกับการหาตัวแบ่งที่ดีสำหรับคุณสมบัติของคุณ) ดังนั้นไม่จำเป็นสำหรับการเข้ารหัสแบบ One-Hot


1
จริง ๆ แล้วมันขึ้นอยู่กับอัลกอริทึมเฉพาะที่ฝึกต้นไม้ โดยเฉพาะ scikit ไม่สนับสนุนตัวแปรเด็ดขาด
chuse
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.