1

我有這樣一個類似的列表:類別中的一個熱編碼

list = ['Opinion, Journal, Editorial', 
     'Opinion, Magazine, Evidence-based', 
     'Evidence-based'] 

其中逗號類別例如之間分割。意見和期刊是兩個不同的類別。真正的名單要大得多,並且有更多可能的類別。我想使用單熱編碼來轉換列表,以便它可以用於機器學習。例如,從該列表中我想以產生含有像數據的稀疏矩陣:

list = [[1, 1, 1, 0, 0], 
     [1, 0, 0, 0, 1], 
     [0, 0, 0, 0, 1]] 

理想情況下,我想用scikit-learn's one hot encoder作爲我相信這將是最有效的。

響應於@nbrayns評論:

的想法是從文本轉換類別的列表給矢量wherby如果它屬於該類別將被分配1,否則爲0。對於上面的例子,該標題將是:

headings = ['Opinion', 'Journal', 'Editorial', 'Magazine', 'Evidence-based'] 
+0

什麼值應該是1,什麼應該是0? – nbryans

+0

@nbryans編輯了這個問題。 – user7347576

回答

0

這可能不是最有效的方法,但可能很容易掌握。
如果您還沒有所有可能的單詞列表,則需要創建該列表。在下面的代碼中,它被稱爲unique。輸出矩陣s的列將對應於那些唯一字;這些行將成爲列表中的項目。

import numpy as np 

lis = ['Opinion, Journal, Editorial','Opinion, Magazine, Evidence-based','Evidence-based'] 

unique=list(set(", ".join(lis).split(", "))) 
print unique 
# prints ['Opinion', 'Journal', 'Magazine', 'Editorial', 'Evidence-based'] 

s = np.zeros((len(lis), len(unique))) 
for i, item in enumerate(lis): 
    for j, notion in enumerate(unique): 
     if notion in item: 
      s[i,j] = 1 

print s 
# prints [[ 1. 1. 0. 1. 0.] 
#   [ 1. 0. 1. 0. 1.] 
#   [ 0. 0. 0. 0. 1.]] 
-1
pandas

非常簡單:

import pandas as pd 
s = pd.Series(['a','b','c']) 
pd.get_dummies(s) 

輸出:

a b c 
0 1 0 0 
1 0 1 0 
2 0 0 1 
0

另一種方式:

l = ['Opinion, Journal, Editorial', 'Opinion, Magazine, Evidence-based', 'Evidence-based'] 

# Get list of unique classes 
classes = list(set([j for i in l for j in i.split(', ')])) 
=> ['Journal', 'Opinion', 'Editorial', 'Evidence-based', 'Magazine'] 

# Get indices in the matrix 
indices = np.array([[k, classes.index(j)] for k, i in enumerate(l) for j in i.split(', ')]) 
=> array([[0, 1], 
      [0, 0], 
      [0, 2], 
      [1, 1], 
      [1, 4], 
      [1, 3], 
      [2, 3]]) 

# Generate output 
output = np.zeros((len(l), len(classes)), dtype=int) 
output[indices[:, 0], indices[:, 1]]=1 
=> array([[ 1, 1, 1, 0, 0], 
      [ 0, 1, 0, 1, 1], 
      [ 0, 0, 0, 1, 0]]) 
3

如果你能夠使用熊貓,這個功能是基本上內置在那裏:

import pandas as pd 

l = ['Opinion, Journal, Editorial', 'Opinion, Magazine, Evidence-based', 'Evidence-based'] 
pd.Series(l).str.get_dummies(', ') 
Editorial Evidence-based Journal Magazine Opinion 
0   1    0  1   0  1 
1   0    1  0   1  1 
2   0    1  0   0  0 

如果你想堅持與sklearn生態系統,您正在尋找MultiLabelBinarizer,而不是OneHotEncoder。顧名思義,OneHotEncoder僅支持每個類別的每個樣本一個級別,而您的數據集則有多個。

from sklearn.preprocessing import MultiLabelBinarizer 

mlb = MultiLabelBinarizer() # pass sparse_output=True if you'd like 
mlb.fit_transform(s.split(', ') for s in l) 
[[1 0 1 0 1] 
[0 1 0 1 1] 
[0 1 0 0 0]] 

要列映射回分類級別,您可以訪問mlb.classes_。對於上面的例子,這給出['Editorial' 'Evidence-based' 'Journal' 'Magazine' 'Opinion']

+0

無論類別的順序如何,這項工作是否會進行? – user7347576

+1

@ user7347576是的,如果您問「意見,日記」或「日記,意見」是否有所作爲,那麼它不會。 –