Background

在建立machine learning的model中, 再處理numerical data基本上一定都不會遇到什麼問題, 但在處理categorical data時往往都要再多花一個步驟把categorical的資料轉成numerical的方式. 以便做矩陣的運算. 那我自己也遇到了類似的問題. 所以查了一下如何用scikit-learn來解決這類的問題.

我查的的解決方式有下列兩種:

  • DictVectorizer
  • LabelEncoder

之後再慢慢細講這兩種方法有什麼不同.

DictVectorizer

def translate_non_numeric_features(df):
    """The classifier just only deal with numeric features
    so we need to translate our features into that format using DictVectorizer.

    Args
    ----
    df -- data frame with non numeric features
    """

    # translate dataframe to list of dicts
    list_dicts_of_df = df.T.to_dict().values()
    vec = DictVectorizer()
    new_features_list_dicts = vec.fit_transform(list_dicts_of_df).toarray()
    new_df = pd.DataFrame(new_features_list_dicts,
                          columns=vec.get_feature_names())

    return new_df

DictVectorizer的code如上. 這個code的基本想法, 就是把categorical data轉成0 1這種Binary sparse matrix. 舉個例子來說有一個Feature欄位叫做性別, 有男女兩種情況. 那DictVectorizer會把這個Feature轉成兩個Feature欄位. 一個是is_male, 另一個是 is_female. 所以今天如果你是男生的話. 你的feature list會是[1, 0], 女生的話則是[0, 1]這樣.

LabelEncoder

那另外一種方法就是利用LabelEncoder把Categorical的值變成數字, ex: [女生, 男生] => [0, 1]這樣. 下面是官網的範例:

>>> le = preprocessing.LabelEncoder()
>>> le.fit(["paris", "paris", "tokyo", "amsterdam"]) # 需要Traning data來定義整個數值的範圍
LabelEncoder()
>>> list(le.classes_)
['amsterdam', 'paris', 'tokyo']
>>> le.transform(["tokyo", "tokyo", "paris"])
array([2, 2, 1])

Reference