karar ağacı / rastgele ormandaki özellikler olarak karakter dizileri


64

Karar ağacı / rastgele orman uygulamasında bazı problemler yaşıyorum. Sayı gibi karakter dizileri (ülke adı gibi) özellikli bir soruna uymaya çalışıyorum. Şimdi, kütüphane, scikit-learn sadece sayı olarak parametre alır, fakat önemli miktarda bilgi taşıdıkları gibi dizeleri de enjekte etmek istiyorum.

Böyle bir senaryoyu nasıl idare ederim?

Python'da karma gibi bazı mekanizmalarla bir dizeyi sayılara dönüştürebilirim. Ancak karar ağacı problemlerinde iplerin nasıl ele alındığına dair en iyi uygulamayı bilmek istiyorum.


Sckitlearn durumunda, kategorik değişkenleri kodlamamız gerektiğini gördüm, aksi halde fit yöntemi, ValueError: string'i float'a çeviremediğini söyleyerek bir hata verirdi
Kar

Yanıtlar:


56

İyi bilinen makine öğrenim sistemlerinin çoğunda, kategorik değişkenler doğal olarak ele alınmaktadır. Örneğin, R'de faktörleri, WEKA'da ise nominal değişkenleri kullanırsınız. Scikit-learn'da durum böyle değil. Scikit-learn'de uygulanan karar ağaçları yalnızca sayısal özellikleri kullanır ve bu özellikler her zaman sürekli sayısal değişkenler olarak yorumlanır .

Bu nedenle, basitçe dizeleri bir karma kodla değiştirmekten kaçınılmalıdır, çünkü sürekli bir sayısal özellik olarak kabul edileceğinden, kullanacağınız herhangi bir kodlama, verilerinizde basitçe bulunmayan bir sıraya neden olacaktır.

Bunun bir örneği [1,2,3] ile ['kırmızı', 'yeşil', 'mavi'] kodunun 'kırmızı' gibi tuhaf şeyleri 'mavi' değerinden daha düşük olacağını ve 'kırmızı' olarak adlandırıldığını gösterir. ve bir 'mavi', 'yeşil' olacak. [1,2,3] ile ['low', 'medium', 'high' olarak kodladığınızda daha ince bir örnek daha olabilir. İkinci durumda, mantıklı bir sıralamaya sahip olabilir, ancak “orta”, “düşük” ve “yüksek” ortasında değilken, bazı ince tutarsızlıklar olabilir.

Son olarak, sorunuzun cevabı, kategorik özelliği çoklu ikili özelliklere kodlamaktan geçiyor . Örneğin, ['kırmızı', 'yeşil', 'mavi'] kodunu, her kategoride bir tane olmak üzere, kategori eşleştiğinde 1 ve diğerinde 0 olan 3 sütunla kodlayabilirsiniz. Buna sıcak kodlama , ikili kodlama, k kodlarından biri veya her neyse denir . Kategorik özellikleri kodlamak ve özellik çıkarma - karma ve dikte etmek için belgeleri burada kontrol edebilirsiniz . Açıkçası bir sıcak kodlama, alan gereksinimlerinizi artıracak ve bazen performansı da olumsuz etkileyecektir.


2
Kategorik değişkenleri doğru bir şekilde işlememesi, bu, scikit uygulamasıdır. Bu cevabın önerdiği gibi kayıt yapmak muhtemelen yapabileceğiniz en iyisidir. Daha ciddi bir kullanıcı alternatif paket arayabilir.
SmallChess

3
Bir kategorik değişkenin tek bir sıcak kodlaması için sklearn.preprocessing.LabelBinarizer kullanabilirsiniz.
GuSuku

@rapaio İkili kodlamanın sıcak kodlamanın aynı olmadığını düşünüyorum. İkili kodlama, 3 sütunlu 8 kategoriyi veya 4 sütunlu vb. 9 - 16 kategoriyi temsil ettiğiniz zamandır. Yanlış mıyım?
Alok Nayak

patsy python paketi kategorik değişkenlerin tek bir sıcak kodlamasıyla ilgilenecek. patsy.readthedocs.io/en/latest/quickstart.html
zhespelt

5
LabelBinarizer'ı kullanmayın, sklearn.preprocessing.OneHotEncoder kullanın . Verilerinizi almak ve işlemek için pandalar kullanıyorsanız, bunu doğrudan pandas.get_dummies kullanarak da yapabilirsiniz . Scikit-learn'ın kategorik değişkenleri desteklemediğini berbat ediyor.
Ricardo Cruz

11

Dizelerinizi, bilim-kitinin ML algoritmaları için kullanabileceği sayısal özellikler olarak kodlamanız gerekir. Bu işlev ön işleme modülünde ele alınır (örneğin, örneğin sklearn.preprocessing.LabelEncoder ).


3
rapaio cevabında neden yanlış bir sonuç aldığını açıklıyor
Keith

7

Rasgele orman dahil olmak üzere, scikit-learning modelleri için genellikle bir sıcak kodlama kategorik değişkenleri gerekir . Rastgele orman genellikle bir sıcak kodlama olmadan tamam çalışır, ancak bir sıcak kodlama yaparsanız genellikle daha iyi performans gösterir. Tek sıcak kodlama ve "sahte" değişkenler bu bağlamda aynı anlama gelir. Scikit-learn, sklearn.preprocessing'e sahiptir.OneHotEncoder ve Pandalar'da bunu gerçekleştirmek için pandas.get_dummies vardır .

Ancak, alternatifler var. Makale KDNuggets kısmındaki "Tek Sıcak Ötesinde" Eğer tek sıcak kodlama kategorik değişkenler ve alternatifler kodlamak için neden ihtiyaç anlatan harika bir iş yok.

R veya H20 gibi bir sıcak kodlama gerektirmeyen rastgele orman alternatif uygulamaları vardır. R'deki uygulama hesaplama açısından pahalıdır ve özellikleriniz çok fazla kategoriye sahipse işe yaramaz . H2O çok sayıda kategori ile çalışacaktır. Continuum, H2O'yu Anaconda Python'da kullanıma sunmuştur.

Bilimsel-öğrenmenin kategorik özellikleri doğrudan ele alması için süregelen bir çaba var .

Bu makalede H20'da kullanılan algoritma açıklanmaktadır. Akademik makaleye A Streaming Parallel Karar Ağacı Algoritması ile aynı makalenin daha uzun bir versiyonunu gösterir.


5

2018 Güncellemesi!

Kategorik değişkenleriniz için bir gömme (yoğun vektör) alanı oluşturabilirsiniz. Birçoğunuz, kelimeleri anlamlı bir yoğun vektör uzayına yerleştiren word2vec ve fastext ile tanışıyorsunuz. Burada da aynı fikir - kategorik değişkenleriniz bir anlamı olan bir vektör ile eşleşecek.

Gönderen Guo / Berkhahn kağıdı :

Varlık gömme işlemi yalnızca bellek kullanımını azaltmakla kalmaz, tek-sıcak kodlamaya kıyasla sinir ağlarını hızlandırır, ancak daha önemlisi gömülü alanda birbirine yakın olan benzer değerleri eşleyerek kategorik değişkenlerin kendine özgü özelliklerini ortaya çıkarır. Son Kaggle yarışmasında başarılı bir şekilde uyguladık ve göreceli basit özelliklerle üçüncü pozisyona ulaştık.

Yazarlar, kategorik değişkenleri bu şekilde temsil etmenin, rastgele orman dahil olmak üzere, test edilen tüm makine öğrenme algoritmalarının etkinliğini arttırdığını buldular.

En iyi örnek, Pinterest'in ilgili Pinleri gruba tekniğine uygulaması olabilir :

görüntü tanımını buraya girin

Fastai millet kategorik katıştırmalarını uygulanacak ve çok güzel yarattık blog yazısı arkadaşı ile demo notebook .

Ek Detaylar ve Açıklama

Gömütleri oluşturmak için bir sinir ağı kullanılır, yani her kategorik değere bir vektör atar. Vektörlere sahip olduktan sonra, bunları sayısal değerleri kabul eden herhangi bir modelde kullanabilirsiniz. Vektörün her bir bileşeni bir giriş değişkeni olur. Örneğin, kategorik renk listenizi yerleştirmek için 3-B vektörleri kullandıysanız, şöyle bir şey elde edebilirsiniz: kırmızı = (0, 1.5, -2.3), mavi = (1, 1, 0) vb. rastgele ormanınızdaki üç değişkene karşılık gelen değişkenleri girin. Kırmızı şeyler için, c1 = 0, c2 = 1.5 ve c3 = -2.3'tür. Mavi şeyler için, c1 = 1, c2 = 1 ve c3 = 0'dır.

Gerçekten de gömüler oluşturmak için bir sinir ağı kullanmanıza gerek yok (teknikten uzak durmanızı önermememe rağmen). Mümkün olduğunda, kendi gömülerinizi elle veya başka yollarla yaratmakta özgürsünüz. Bazı örnekler:

  1. Renkleri RGB vektörlerine eşleyin.
  2. Konumları enlem / boylam vektörlerine eşleyin.
  3. ABD siyasi modelinde, şehirleri sol / sağ uyumu, vergi yükü vb. Gibi bazı vektör bileşenlerine eşleyin.

Tamam serin ama bir şeyi kaçırmadığım sürece bu, ağların bitmesi için. Bir gömme oluşturma ve bu gömme işlemini Forrest'e nasıl geçirebiliriz? Tüm özelliklerle bir ağın tamamını eğitmeniz ve ardından ilk birkaç katmanı almanız ve bunu Forrest'ınıza giriş özelliği olarak kullanmanız gerektiğini düşünüyorum. Bunun nasıl yapılacağı belli değil.
Keith

@ Bir sinir ağı yerleştirmek için kullanılır, yani her kategorik değere bir vektör atar. Vektörlere sahip olduktan sonra, bunları sayısal değerleri kabul eden herhangi bir modelde kullanabilirsiniz. Vektörün her bir bileşeni bir giriş değişkeni olur. Örneğin, kategorik renk listenizi yerleştirmek için 3 boyutlu vektörler kullandıysanız, şöyle bir şey elde edebilirsiniz: kırmızı = (0, 1.5, -2.3), mavi = (1, 1, 0)vb. Rasgele ormanınızda üç bileşene karşılık gelen üç giriş değişkeni kullanırsınız. Kırmızı şeyler için, c1 = 0, c2 = 1.5 ve c3 = -2.3'tür. Mavi şeyler için, c1 = 1, c2 = 1 ve c3 = 0'dır
Pete

Konsepti çok basit olduğu için anladım. Yani, bu uygulamada nasıl yapılır? Bağladığınız fast.ai demo not defterinde sonunda bir RandomForestRegressor ile biraz var ama bunun gömülmelere nasıl eklendiğini gerçekten göremiyorum.
Keith


3

Sahte değişkenleri bu gibi senaryolarda kullanabilirsiniz. Panda ile panda.get_dummieskarar ağacı veya rastgele orman koymak istediğiniz dizeleri için kukla değişkenler oluşturabilirsiniz.

Örnek:

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

Bunları sayılara çevirin, örneğin benzersiz bir sayı atayan her ülke için (1,2,3 ve ... gibi)

Ayrıca etmeyin kullanmak gerekir Tek Sıcak Kodlama rasgele orman ile çalışırken (diğer adıyla kukla değişkenler) ağaçları diğer algoritma gibi işe yaramaz, çünkü (örneğin lineer / lojistik regresyon gibi) ve bunlar (uzak tarafından çalışmaz onlar iyi sizin özellikler için bölünmüş) böylece bulmakla işe Gerek Tek Sıcak Kodlama için


1
Aslında ağacı eğiten belirli bir algoritmaya bağlı. Özellikle, scikit kategorik değişkenleri desteklemiyor.
Şubat'ta
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.