我的数据包含连续和分类功能的混合。下面是我的数据在csv格式中的一小部分(将其视为由在不同城市运营商店的超级商店链收集的数据)
city,avg_income_in_city,population,square_feet_of_store_area, store_type ,avg_revenue
NY ,54504 , 3506908 ,3006 ,INDOOR , 8000091
CH ,44504 , 2505901 ,4098 ,INDOOR , 4000091
HS ,50134 , 3206911 ,1800 ,KIOSK , 7004567
NY ,54504 , 3506908 ,1000 ,KIOSK , 2000091
她可以看到avg_income_in_city,square_feet_of_store_area和avg_revenue是连续值,其中city,store_type等是分类类(还有一些我没有在这里展示以保持数据的简洁性)。
我希望对数据建模以预测收入。问题是如何使用sklearn“离散”连续值? sklearn是否为连续值的离散化提供了任何“现成的”类/方法? (就像我们在Orange中一样,例如Orange.Preprocessor_discretize(data,method = orange.EntropyDiscretization())
谢谢!
答案 0 :(得分:8)
答案是否定的。 scikit-learn中没有binning。正如eickenberg所说,你可能想要使用np.histogram。假设scikit-learn中的特征是连续的,而不是离散的。没有装箱的主要原因可能是大部分sklearn是基于文本,图像特征或来自科学界的数据集开发的。在这些设置中,分箱很少有用。你知道一个免费提供的数据集,其中binning真的有用吗?
答案 1 :(得分:4)
您也可以考虑将分类变量数字化,例如通过指标变量,一个程序也称为一个热编码
尝试
from sklearn.preprocessing import OneHotEncoder
并使其适合您的分类数据,然后使用数值估算方法,如线性回归。只要没有太多类别(城市可能有点太多),这可以很好地运作。
对于连续变量的离散化,您可以考虑使用适应的bin大小进行分级,或者等效地,在直方图归一化之后进行均匀分级。 numpy.histogram
在这里可能会有所帮助。此外,虽然Fayyad-Irani群集未在sklearn
中实施,但请随时查看sklearn.cluster
您的数据的自适应离散化(即使它只是1D),例如通过KMeans。
答案 2 :(得分:2)
更新(2018年9月):从0.20.0
版开始,有一个函数sklearn.preprocessing.KBinsDiscretizer,它使用几种不同的策略离散化了连续特征:
不幸的是,目前,该函数不接受自定义间隔(这对我来说真是令人讨厌,因为这正是我想要的,也是我最终来到这里的原因)。如果要达到相同的目的,可以使用Pandas函数cut:
import numpy as np
import pandas as pd
n_samples = 10
a = np.random.randint(0, 10, n_samples)
# say you want to split at 1 and 3
boundaries = [1, 3]
# add min and max values of your data
boundaries = sorted({a.min(), a.max() + 1} | set(boundaries))
a_discretized_1 = pd.cut(a, bins=boundaries, right=False)
a_discretized_2 = pd.cut(a, bins=boundaries, labels=range(len(boundaries) - 1), right=False)
a_discretized_3 = pd.cut(a, bins=boundaries, labels=range(len(boundaries) - 1), right=False).astype(float)
print(a, '\n')
print(a_discretized_1, '\n', a_discretized_1.dtype, '\n')
print(a_discretized_2, '\n', a_discretized_2.dtype, '\n')
print(a_discretized_3, '\n', a_discretized_3.dtype, '\n')
产生:
[2 2 9 7 2 9 3 0 4 0]
[[1, 3), [1, 3), [3, 10), [3, 10), [1, 3), [3, 10), [3, 10), [0, 1), [3, 10), [0, 1)]
Categories (3, interval[int64]): [[0, 1) < [1, 3) < [3, 10)]
category
[1, 1, 2, 2, 1, 2, 2, 0, 2, 0]
Categories (3, int64): [0 < 1 < 2]
category
[1. 1. 2. 2. 1. 2. 2. 0. 2. 0.]
float64
请注意,默认情况下,pd.cut
返回类型为Category
的dtype为interval[int64]
的pd.Series对象。如果您指定自己的labels
,则输出的dtype仍为Category
,但元素的类型为int64
。如果希望系列具有数字dtype,则可以使用.astype(np.int64)
。
我的示例使用整数数据,但它与浮点数一样适用。
答案 3 :(得分:1)
您可以使用pandas.cut方法,如下所示:
bins = [0, 4, 10, 30, 45, 99999]
labels = ['Very_Low_Fare', 'Low_Fare', 'Med_Fare', 'High_Fare','Very_High_Fare']
train_orig.Fare[:10]
Out[0]:
0 7.2500
1 71.2833
2 7.9250
3 53.1000
4 8.0500
5 8.4583
6 51.8625
7 21.0750
8 11.1333
9 30.0708
Name: Fare, dtype: float64
pd.cut(train_orig.Fare, bins=bins, labels=labels)[:10]
Out[50]:
0 Low_Fare
1 Very_High_Fare
2 Low_Fare
3 Very_High_Fare
4 Low_Fare
5 Low_Fare
6 Very_High_Fare
7 Med_Fare
8 Med_Fare
9 High_Fare
Name: Fare, dtype: category
Categories (5, object): [High_Fare < Low_Fare < Med_Fare < Very_High_Fare < Very_Low_Fare]
答案 4 :(得分:0)
感谢上述想法;
要离散化连续值,可以使用:
或
sklearn的KBinsDiscretizer函数(参数encode
设置为“普通”)
strategy
= uniform
将以与pd.cut相同的方式离散化。strategy
= quantile
将以与pd.qcut函数相同的方式离散化由于先前的答案中提供了cut / qcut的示例,因此让我们继续使用KBinsDiscretizer上的干净示例:
import numpy as np
from sklearn.preprocessing import KBinsDiscretizer
A = np.array([[24,0.2],[35,0.3],[74,0.4], [96,0.5],[2,0.6],[39,0.8]])
print(A)
# [[24. 0.2]
# [35. 0.3]
# [74. 0.4]
# [96. 0.5]
# [ 2. 0.6]
# [39. 0.8]]
enc = KBinsDiscretizer(n_bins=3, encode='ordinal', strategy='uniform')
enc.fit(A)
print(enc.transform(A))
# [[0. 0.]
# [1. 0.]
# [2. 1.]
# [2. 1.]
# [0. 2.]
# [1. 2.]]
如输出所示,每个特征已离散为3个bin。 希望这对您有所帮助:)
最后的笔记:
cut versus qcut
,请参见此post KBinsDiscretizer(encode='onehot')
对该功能执行一键热编码