2013-02-22 29 views
12

मैं यूसीआई भंडार से कार मूल्यांकन डेटासेट का उपयोग करने की कोशिश कर रहा हूं और मुझे आश्चर्य है कि sklearn में स्पष्ट चर को बिनराइज़ करने का एक सुविधाजनक तरीका है या नहीं। एक दृष्टिकोण लेबलबिनाइज़र के डिक्टिवेटोरिज़र का उपयोग करना होगा, लेकिन यहां मुझे के विभिन्न विशेषताएं मिल रही हैं जबकि कॉललाइनराइजेशन से बचने के लिए आपके पास केवल के -1 होना चाहिए। मुझे लगता है कि मैं अपना खुद का फ़ंक्शन लिख सकता हूं और एक कॉलम छोड़ सकता हूं लेकिन यह बहीखाता थकाऊ है, क्या ऐसे परिवर्तनों को करने का एक आसान तरीका है और परिणामस्वरूप एक स्पैर मैट्रिक्स है?sklearn में एक स्पष्ट चर को एन्कोड कैसे करें?

+0

क्या कोई विशेष कारण है कि आप के -1 पर विशेषताओं को क्यों पसंद करते हैं? के गुणों के साथ गुणांक की व्याख्या (एक रैखिक मॉडल में कहें) बहुत आसान है और दुर्लभ विशेषताओं को बढ़ावा दे सकती है। –

+1

मैं गुणांक की प्रासंगिकता खोजने की कोशिश कर रहा था और कॉललाइनरिटी समस्याओं में भाग गया http://en.wikipedia.org/wiki/Multicollinearity – tonicebrian

+0

मुझे लगता है कि मैं चीजों के आंकड़ों के पक्ष में पर्याप्त नहीं हूं यह देखने के लिए कि यह समस्या क्यों होगी । मैं किसी अन्य कोडिंग विधि की तुलना में फीचर प्रासंगिकता के संदर्भ में अधिक सार्थक परिणाम देने के लिए के फीचर कोडिंग की कल्पना करूंगा। –

उत्तर

15

डिक्टिवेटोरिज़र स्पष्ट चर के एक-गर्म एन्कोडिंग को उत्पन्न करने का अनुशंसित तरीका है; आप एक घने numpy सरणी के बजाय एक स्पैस सीएसआर मैट्रिक्स बनाने के लिए sparse तर्क का उपयोग कर सकते हैं। मुझे आमतौर पर बहुविकल्पीयता की परवाह नहीं है और मैंने उन दृष्टिकोणों के साथ कोई समस्या नहीं देखी है जो मैं उपयोग करता हूं (यानी लीनियरएसवीसी, एसजीडी क्लासिफायर, ट्री-आधारित विधियों)।

यह डिक्टिवेटोरिज़र को प्रति स्तंभ एक कॉलम ड्रॉप करने के लिए पैच करने में कोई समस्या नहीं होनी चाहिए - fit विधि के अंत में आपको DictVectorizer.vocabulary से एक शब्द निकालने की सरल आवश्यकता है। (पुल अनुरोध हमेशा स्वागत है!)

+5

क्या कोई विशेष कारण है कि आप OneHotEncoder क्लास पर DictVectorizer की अनुशंसा करते हैं? – Dexter

+5

डिक्टिवेटोरिज़र अधिक सामान्य है - OneHotEncoder इनपुट श्रेणियों का प्रतिनिधित्व करने वाले पूर्णांक के कॉलम तक ही सीमित है। डिक्टिवेटोरिज़र भी टेक्स्टिक विशिष्ट मूल्यों से संबंधित है। दूसरी तरफ, यदि आपके पास पहले स्थान पर पूर्णांक श्रेणियां हैं, तो OneHotEncoder सबसे सरल विकल्प की तरह लगता है। –

+1

लेकिन डिक्टिवेटोरिज़र का उपयोग करने के लिए, मुझे सरणी में पंक्ति में संबंधित प्रत्येक सूची के साथ सरणी को प्रत्येक शब्दकोश के साथ शब्दकोशों की सूची में परिवर्तित करने की आवश्यकता होगी। यह एक हैक की तरह लगता है। मैं सिर्फ डिक्टिवेटोरिज़र में सरणी क्यों नहीं पारित कर सकता हूं? – Ben

16

बुनियादी विधि

import numpy as np 
import pandas as pd, os 
from sklearn.feature_extraction import DictVectorizer 

def one_hot_dataframe(data, cols, replace=False): 
    vec = DictVectorizer() 
    mkdict = lambda row: dict((col, row[col]) for col in cols) 
    vecData = pd.DataFrame(vec.fit_transform(data[cols].apply(mkdict, axis=1)).toarray()) 
    vecData.columns = vec.get_feature_names() 
    vecData.index = data.index 
    if replace is True: 
     data = data.drop(cols, axis=1) 
     data = data.join(vecData) 
    return (data, vecData, vec) 

data = {'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada'], 
     'year': [2000, 2001, 2002, 2001, 2002], 
     'pop': [1.5, 1.7, 3.6, 2.4, 2.9]} 

df = pd.DataFrame(data) 

df2, _, _ = one_hot_dataframe(df, ['state'], replace=True) 
print df2 

है यहाँ विरल प्रारूप

import numpy as np 
import pandas as pd, os 
import scipy.sparse as sps 
import itertools 

def one_hot_column(df, cols, vocabs): 
    mats = []; df2 = df.drop(cols,axis=1) 
    mats.append(sps.lil_matrix(np.array(df2))) 
    for i,col in enumerate(cols): 
     mat = sps.lil_matrix((len(df), len(vocabs[i]))) 
     for j,val in enumerate(np.array(df[col])): 
      mat[j,vocabs[i][val]] = 1. 
     mats.append(mat) 

    res = sps.hstack(mats) 
    return res 

data = {'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada'], 
     'year': ['2000', '2001', '2002', '2001', '2002'], 
     'pop': [1.5, 1.7, 3.6, 2.4, 2.9]} 

df = pd.DataFrame(data) 
print df 

vocabs = [] 
vals = ['Ohio','Nevada'] 
vocabs.append(dict(itertools.izip(vals,range(len(vals))))) 
vals = ['2000','2001','2002'] 
vocabs.append(dict(itertools.izip(vals,range(len(vals))))) 

print vocabs 

print one_hot_column(df, ['state','year'], vocabs).todense() 
+2

इस दृष्टिकोण के साथ नए डेटा में अदृश्य मानों को आप कैसे प्रबंधित करते हैं? – marbel

31

में कैसे करना है तो आपको अपने डेटा एक पांडा DataFrame है, तो आप बस कर सकते हैं है get_dummies कॉल करें। मान लें कि आपका डेटा फ्रेम डीएफ है, और आप वैरिएबल 'कुंजी' के प्रति स्तर पर एक बाइनरी चर होना चाहते हैं। आप बस कॉल कर सकते हैं:

pd.get_dummies(df['key']) 

और फिर बहु-कॉलिनेरिटी समस्या से बचने के लिए, डमी चरों में से एक को हटा दें। मुझे उम्मीद है कि यह मदद करता है ...

+5

व्यक्तिगत रूप से, मैं पांडस 'get_dummies को OneHotEncoder या skictarn से DictVectorizer को पसंद करता हूं। पांडों में get_dummies का उपयोग अक्सर अधिक सुव्यवस्थित प्रक्रिया और कम कोड में होता है। पांडस डेटा विश्लेषण और प्रीप्रोकैसिंग के बारे में अधिक है और जहां तक ​​मेरा संबंध है, भारी उठाने वाली 'सीखने' प्रक्रियाओं के बारे में स्केलर अधिक है। – luanjunyi

+19

get_dummies की कमी यह है कि यह एक स्कोरिंग डेटासेट पर एक ही डमी कॉलम का उत्पादन नहीं करेगा (आपको मॉडल स्कोर करने की कोशिश करते समय जटिलता के एक टन के साथ छोड़कर) – Chris

+1

ऐसा करने का एक तरीका सबसे पहले प्रशिक्षण प्रशिक्षण और परीक्षण डेटाफ्रेम है, फिर get_dummies लागू करें, और अंत में प्रशिक्षण और परीक्षण डेटाफ्रेम अलग करें। इस तरह, प्रशिक्षण और परीक्षण डेटा में लगातार एक-गर्म एन्कोडिंग होगी। – weidongxu