可供参考的三种特征离散化方法
在数据分析中,我们认为在某个范围内取值过于密集的特征认为是取值”连续“的特征。出于某些需求经常需要将这些”连续特征进行离散化“。本文介绍三种比较实用的数据离散化方法。
李俊才的个人博客
方法1:尺度缩小法
这种方法是对于数值元素的一种简单粗暴的方法。离散化的目的不就是减少取值数目吗。那么好,只要把数据除以某个值,大数就变小数,抹掉小数位,自然取值个数就少了很多。很显然,这种离散化方法的特点在于对越小的数整合归并能力越强。
经常我们将数据读取为一个二维DataFrame结构的表,而需要离散化的是该DataFrame对象中的一列。以下该方法离散化的源代码。
defscaling(DF, feature, scale, submit=True): """ 数据尺度缩小法离散化 Parameters ------- - DF: DataFrame,假设我们需要离散化的是DF种索引为feature的那一列 - feature: str,特征名,将用作从DF中索引该列特征的有序所有取值 - scale: 该列特征数值的放缩尺度。 - submit: bool,离散化后直接提交更改到DF中的该特征 """dis_feature=DF[feature].copy() dis_feature=np.array(np.floor(np.array(DF[feature]/scale))) ifsubmit: DF[feature] =dis_featurereturndis_feature
方法2:按数值区间分割数据法(使用pandas.cut())
经常我们将数据读取为一个二维DataFrame结构的表,而需要离散化的是该DataFrame对象中的一列。以下该方法离散化的源代码。
defpd_cut(DF,feature,bins,submit=True): """ 离散化备选方法2: 按数值区间分割数据离散化——先按照数据取值将数据分割成n组。 Parameters ---------- - DF: DataFrame,假设我们需要离散化的是DF种索引为feature的那一列 - feature: str,特征名,将用作从DF中索引该列特征的有序所有取值 - bins: 若为Series,则序列中数据元素各为分割点; 若为int,则特征值定义范围内的等宽bin数。x的范围在每一侧 都扩展了0.1%,以包括x的最小值和最大值。 - submit: bool,离散化后直接提交更改到self.DF中的该特征 """dis_feature=DF[feature].copy() dis_feature=pd.cut(Feature,bins) ifsubmit: self.DF[feature] =dis_featurereturndis_feature
方法3:等元素个数分割法(使用pandas.qcut())
经常我们将数据读取为一个二维DataFrame结构的表,而需要离散化的是该DataFrame对象中的一列。以下该方法离散化的源代码。
defpd_qcut(self,feature,q,submit=True,**kw): """ 离散化备选方法3: 等元素个数分割数据——分割后每个存储组有相同元素个数。 Parameters ------- - feature: str,特征名,将用作从DF中索引该列特征的有序所有取值 - q: 频数,int,也就是分割后的组数 - q_label: serial,分割后,必须用新的标签代表旧的数据,标签数目必 须和分割的频数对应一致 - submit: bool,离散化后直接提交更改到self.DF中的该特征 """ifkw.get('q_label') !=None: q_label=kw.get('q_label') else: q_label=list(range(q)) dis_feature=self.DF[feature].copy() dis_feature=pd.qcut(dis_feature,q,q_label,duplicates="drop") # duplicates="drop"表示如果bin边缘(每组的分位点处)不是唯一则丢弃非唯一变量ifsubmit: self.DF[feature] =dis_featurereturndis_feature
使用作图法以对比DF中所有feature列离散前后的效果
直接上代码:
defbarchart_ax(discrete_df, title='各个特征取值数量统计', xlabel='特征名称', ylabel='特征的不同取值量', background_color="#EAEAF2", Batch1_color="#25AFF3"): feature_values= [] x_text= [] forcindiscrete_df.columns[1:]: x_text.append(c) ct=discrete_df[c].duplicated(keep='first') feature_values.append(len(ct[ct==False])) batch1=feature_valuespylab.rcParams['figure.figsize'] = (19.0, 10.0) plt.rcParams['font.sans-serif'] = ['KaiTi'] matplotlib.rcParams['axes.unicode_minus'] =Falsex=np.arange(len(x_text)) width=0.66fig, ax=plt.subplots() rects=ax.bar(x-width/2, batch1, width, color=Batch1_color) ax.patch.set_facecolor(background_color) ax.set_title(title, fontsize=26) ax.set_xlabel(xlabel, fontsize=22) ax.set_ylabel(ylabel, fontsize=22) ax.set_xticks(x) ax.set_xticklabels(x_text, fontsize=22) forrectinrects: height=rect.get_height() ax.annotate('{}'.format(height), xy=(rect.get_x() +rect.get_width() /2, height), xytext=(0,3), textcoords="offset points", ha='center', va='bottom') plt.grid(linestyle="dotted",color="g") plt.xticks(rotation=89) fig.tight_layout() plt.show()
案例:等待编写。
小结
importpandasaspdimportnumpyasnpclassdiscretization(object): """ 离散化类:提供几种可供选择的离散化方法。 离散化就是将特征中多个不同的特征值用相对少的取值表示。 每种离散化方法一次工作中对特定的列(特征)进行离散化操作,返回被离散的列的离散化结果 如果最终需要获取完成所有特征离散化的DataFrame,则使用该类实例的DF属性(discretization.DF)即可 """def__init__(self,DataF): """ 初始化:拷贝一份传入的DataFrame。 仅当各备选的离散化方法中,submit = True 时,将改变 self.DF 中该列特征的数据。 """self.DF=DataF.copy() defscaling(self,feature,scale,submit=True): """ 离散化备选方法1: 数据尺度缩小法离散化——该方法法通过将数值除以特定的数来进行离散化。 Parameters ------- - feature: str,特征名,将用作从DF中索引该列特征的有序所有取值 - scale: 该列特征数值的放缩尺度。 - submit: bool,离散化后直接提交更改到self.DF中的该特征 """dis_feature=self.DF[feature].copy() dis_feature=np.array(np.floor(np.array(self.DF[feature]/scale))) ifsubmit: self.DF[feature] =dis_featurereturndis_featuredefpd_cut(self,feature,bins,submit=True): """ 离散化备选方法2: 按数值区间分割数据离散化——先按照数据取值将数据分割成n组。 Parameters ------- - feature: str,特征名,将用作从DF中索引该列特征的有序所有取值 - bins: 若为Series,则序列中数据元素各为分割点; 若为int,则特征值定义范围内的等宽bin数。x的范围在每一侧 都扩展了0.1%,以包括x的最小值和最大值。 - submit: bool,离散化后直接提交更改到self.DF中的该特征 """dis_feature=self.DF[feature].copy() dis_feature=pd.cut(dis_feature ,bins) ifsubmit: self.DF[feature] =dis_featurereturndis_featuredefpd_qcut(self,feature,q,submit=True,**kw): """ 离散化备选方法3: 等元素个数分割数据离散化——分割后每个存储组有相同元素个数。 Parameters ------- - feature: str,特征名,将用作从DF中索引该列特征的有序所有取值 - q: 频数,int,也就是分割后的组数 - q_label: serial,分割后,必须用新的标签代表旧的数据,标签数目必 须和分割的频数对应一致 - submit: bool,离散化后直接提交更改到self.DF中的该特征 """ifkw.get('q_label') !=None: q_label=kw.get('q_label') else: q_label=list(range(q)) dis_feature=self.DF[feature].copy() dis_feature=pd.qcut(dis_feature,q,q_label,duplicates="drop") # duplicates="drop"表示如果bin边缘(每组的分位点处)不是唯一则丢弃非唯一变量ifsubmit: self.DF[feature] =dis_featurereturndis_feature