如何使用特征哈希器将非数值离散数据转换为可供SVM使用的格式?

我正在尝试使用UCI机器学习库中的CRX数据集。这个特定的数据集包含一些非连续变量的特征。因此,我需要在将它们传递给SVM之前将它们转换为数值。

我最初考虑使用独热编码器,它可以将整数值转换为矩阵(例如,如果一个特征有三种可能的值,’red’ ‘blue’ 和 ‘green’,这将被转换为三个二进制特征:’red’ 为 1,0,0,’blue’ 为 0,1,0,’green’ 为 0,0,1)。这对于我的需求来说是理想的,除了它只能处理整数特征这一事实之外。

def get_crx_data(debug=False):    with open("/Volumes/LocalDataHD/jt306/crx.data", "rU") as infile:        features_array = []        reader = csv.reader(infile,dialect=csv.excel_tab)        for row in reader:            features_array.append(str(row).translate(None,"[]'").split(","))        features_array = np.array(features_array)        print features_array.shape        print features_array[0]        labels_array = features_array[:,15]        features_array = features_array[:,:15]        print features_array.shape        print labels_array.shape        print("FeatureHasher on frequency dicts")        hasher = FeatureHasher(n_features=44)        X = hasher.fit_transform(line for line in features_array)        print X.shapeget_crx_data()

这返回了

Reading CRX data from diskTraceback (most recent call last):  File"/Volumes/LocalDataHD/PycharmProjects/FeatureSelectionPython278/Crx2.py", line 38, in <module>get_crx_data()  File "/Volumes/LocalDataHD/PycharmProjects/FeatureSelectionPython278/Crx2.py", line 32, in get_crx_dataX = hasher.fit_transform(line for line in features_array)File "/Volumes/LocalDataHD/anaconda/lib/python2.7/site-packages/sklearn/base.py", line 426, in fit_transform    return self.fit(X, **fit_params).transform(X)File "/Volumes/LocalDataHD/anaconda/lib/python2.7/site-packages/sklearn/feature_extraction/hashing.py", line 129, in transform    _hashing.transform(raw_X, self.n_features, self.dtype)File "_hashing.pyx", line 44, in sklearn.feature_extraction._hashing.transform (sklearn/feature_extraction/_hashing.c:1649)File "/Volumes/LocalDataHD/anaconda/lib/python2.7/site-packages/sklearn/feature_extraction/hashing.py", line 125, in <genexpr>    raw_X = (_iteritems(d) for d in raw_X)File "/Volumes/LocalDataHD/anaconda/lib/python2.7/site-packages/sklearn/feature_extraction/hashing.py", line 15, in _iteritems    return d.iteritems() if hasattr(d, "iteritems") else d.items()AttributeError: 'numpy.ndarray' object has no attribute 'items'(690, 16)['0' ' 30.83' ' 0' ' u' ' g' ' w' ' v' ' 1.25' ' 1' ' 1' ' 1' ' 0' ' g' ' 202' ' 0' ' +'](690, 15)(690,)FeatureHasher on frequency dictsProcess finished with exit code 1如何使用特征哈希(或其他方法)将这些数据从类别(其中一些是字符串,其他的是离散数值)转换为SVM可以处理的数据?我也考虑过使用独热编码,但它只能接受整数作为输入。

回答:

问题在于FeatureHasher对象期望每行输入具有特定的结构——或者更准确地说,是三种不同的可能的结构之一。第一种可能性是feature_name:value对的字典。第二种是(feature_name, value)元组的列表。第三种是feature_name的平面列表。在前两种情况下,特征名称被映射到矩阵中的列,并在每行中存储给定的值。在最后一种情况下,列表中特征的存在或不存在被隐式理解为TrueFalse值。以下是一些简单具体的例子:

>>> hasher = sklearn.feature_extraction.FeatureHasher(n_features=10,...                                                   non_negative=True,...                                                   input_type='dict')>>> X_new = hasher.fit_transform([{'a':1, 'b':2}, {'a':0, 'c':5}])>>> X_new.toarray()array([[ 1.,  2.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  5.,  0.,  0.]])

这展示了默认模式——如果您没有传递input_type,如您原始代码中那样,FeatureHasher将期望的输入是每个输入样本或数据行的字典列表。每个字典包含任意数量的特征名称,映射到该行的值。

输出X_new包含数组的稀疏表示;调用toarray()返回一个新的普通numpy数组副本。

如果您想传递元组对,请传递input_type='pairs'。然后您可以这样做:

>>> hasher = sklearn.feature_extraction.FeatureHasher(n_features=10,...                                                   non_negative=True,...                                                   input_type='pair')>>> X_new = hasher.fit_transform([[('a', 1), ('b', 2)], [('a', 0), ('c', 5)]])>>> X_new.toarray()array([[ 1.,  2.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  5.,  0.,  0.]])

最后,如果您只有布尔值,您根本不需要显式传递值——FeatureHasher将简单地假设如果特征名称存在,则其值为True(这里表示为浮点值1.0)。

>>> hasher = sklearn.feature_extraction.FeatureHasher(n_features=10,...                                                   non_negative=True,...                                                   input_type='string')>>> X_new = hasher.fit_transform([['a', 'b'], ['a', 'c']])>>> X_new.toarray()array([[ 1.,  1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],       [ 1.,  0.,  0.,  0.,  0.,  0.,  0.,  1.,  0.,  0.]])

不幸的是,您的数据似乎并不一致地符合这些格式中的任何一种。然而,将您现有的数据修改为适应'dict''pair'格式应该不会太难。如果您需要帮助,请告诉我;在这种情况下,请详细说明您尝试转换的数据格式。

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注