数据离散化 - 等宽等频聚类离散 - Python代码
目錄
等寬離散
等頻離散
聚類離散
附錄:
rolling_mean函數(shù)解釋
cut函數(shù)解釋
其他數(shù)據(jù)預(yù)處理方法
一些數(shù)據(jù)挖掘算法中,特別是某些分類算法(eg:ID3算法、Aprioroi算法等),要求數(shù)據(jù)是分類屬性形式。因此常常需要將連續(xù)屬性變換成分類屬性,即離散化。
離散化就是在數(shù)據(jù)的取值范圍內(nèi)設(shè)定若干個(gè)離散的花粉店,將取值范圍劃分為一些離散化的區(qū)間,最后用不同的符號(hào)護(hù)著整數(shù)值代表落在每個(gè)區(qū)間中的數(shù)據(jù)值。所以離散化涉及兩個(gè)過程:確定分類數(shù)&將連續(xù)屬性值映射到n個(gè)分類值。
常用的離散化方法:等寬離散、等頻離散和聚類離散(一維)。
?
等寬離散
將屬性的值域從最小值到最大值分成具有相同寬度的n個(gè)區(qū)間,n由數(shù)據(jù)特點(diǎn)決定,往往是需要有業(yè)務(wù)經(jīng)驗(yàn)的人進(jìn)行評(píng)估。
代碼實(shí)現(xiàn):
#-*- coding:utf-8 -*- #數(shù)據(jù)離散化-等寬離散 import pandas as pddatafile = u'E:\\pythondata\\hk04.xlsx' data = pd.read_excel(datafile) data = data[u'回款金額'].copy() k = 5 #設(shè)置離散之后的數(shù)據(jù)段為5#等寬離散 d1 = pd.cut(data,k,labels = range(k))#將回款金額等寬分成k類,命名為0,1,2,3,4,5,data經(jīng)過cut之后生成了第一列為索引,第二列為當(dāng)前行的回款金額被劃分為0-5的哪一類,屬于3這一類的第二列就顯示為3def cluster_plot(d,k):import matplotlib.pyplot as pltplt.rcParams['font.sans-serif'] = ['SimHei']plt.rcParams['axes.unicode_minus'] = Falseplt.figure(figsize = (12,4))for j in range(0,k):plt.plot(data[d==j], [j for i in d[d==j]],'o')plt.ylim(-0.5, k-0.5)return pltcluster_plot(d1, k).show()離散結(jié)果:
由這個(gè)離散結(jié)果我們可以直觀的看出等寬離散的缺點(diǎn),其缺點(diǎn)在于對(duì)噪點(diǎn)過于敏感,傾向于不均勻的把屬性值分布到各個(gè)區(qū)間,導(dǎo)致有些區(qū)間的數(shù)值極多,而有些區(qū)間極少,嚴(yán)重?fù)p壞離散化之后建立的數(shù)據(jù)模型。
?
等頻離散
將相同數(shù)量的記錄放在每個(gè)區(qū)間,保證每個(gè)區(qū)間的數(shù)量基本一致。
代碼實(shí)現(xiàn):
#-*- coding:utf-8 -*- #數(shù)據(jù)離散化-等頻離散 import pandas as pddatafile = u'E:\\pythondata\\hk04.xlsx' data = pd.read_excel(datafile) data = data[u'回款金額'].copy() k = 5 #設(shè)置離散之后的數(shù)據(jù)段為5#等頻率離散化 w = [1.0*i/k for i in range(k+1)] w = data.describe(percentiles = w)[4:4+k+1] w[0] = w[0]*(1-1e-10) d2 = pd.cut(data, w, labels = range(k))def cluster_plot(d,k):import matplotlib.pyplot as pltplt.rcParams['font.sans-serif'] = ['SimHei']plt.rcParams['axes.unicode_minus'] = Falseplt.figure(figsize = (12,4))for j in range(0,k):plt.plot(data[d==j], [j for i in d[d==j]],'o')plt.ylim(-0.5, k-0.5)return pltcluster_plot(d2, k).show()離散結(jié)果:
由離散結(jié)果看出,等頻離散不會(huì)像等寬離散一樣,出現(xiàn)某些區(qū)間極多或者極少的情況。但是根據(jù)等頻離散的原理,為了保證每個(gè)區(qū)間的數(shù)據(jù)一致,很有可能將原本是相同的兩個(gè)數(shù)值卻被分進(jìn)了不同的區(qū)間,這對(duì)最終模型的損壞程度一點(diǎn)都不亞于等寬離散。
?
聚類離散
一維聚類離散包括兩個(gè)過程:通過聚類算法(K-Means算法)將連續(xù)屬性值進(jìn)行聚類,處理聚類之后的到的k個(gè)簇,得到每個(gè)簇對(duì)應(yīng)的分類值(類似這個(gè)簇的標(biāo)記)。
代碼實(shí)現(xiàn):
#-*- coding:utf-8 -*- #數(shù)據(jù)離散化-聚類離散 import pandas as pddatafile = u'E:\\pythondata\\hk04.xlsx' data = pd.read_excel(datafile) data = data[u'回款金額'].copy() k = 5 #設(shè)置離散之后的數(shù)據(jù)段為5#聚類離散 from sklearn.cluster import KMeanskmodel = KMeans(n_clusters = k, n_jobs = 4)#n_jobs是并行數(shù),一般等于CPU數(shù) kmodel.fit(data.reshape((len(data), 1))) c = pd.DataFrame(kmodel.cluster_centers_, columns=list('a')).sort_values(by='a') #rolling_mean表示移動(dòng)平均,即用當(dāng)前值和前2個(gè)數(shù)值取平均數(shù), #由于通過移動(dòng)平均,會(huì)使得第一個(gè)數(shù)變?yōu)榭罩?#xff0c;因此需要使用.iloc[1:]過濾掉空值。 w = pd.rolling_mean(c, 2).iloc[1:]#此處w=[2174.1003996693553, 8547.46386803177, 22710.538501243103, 48516.861774600904] w = [0] + list(w[0]) + [data.max()]#把首末邊界點(diǎn)加上,首邊界為0,末邊界為data的最大值120000,此處w=[0, 2174.1003996693553, 8547.46386803177, 22710.538501243103, 48516.861774600904, 120000.0] d3 = pd.cut(data, w, labels = range(k))#cut函數(shù)實(shí)現(xiàn)將data中的數(shù)據(jù)按照w的邊界分類。def cluster_plot(d,k):import matplotlib.pyplot as pltplt.rcParams['font.sans-serif'] = ['SimHei']plt.rcParams['axes.unicode_minus'] = Falseplt.figure(figsize = (12,4))for j in range(0,k):plt.plot(data[d==j], [j for i in d[d==j]],'o')plt.ylim(-0.5, k-0.5)return pltcluster_plot(d3, k).show()離散結(jié)果:
三種離散化方法中,最得本宮心意的便是最后這個(gè)聚類離散,但是即便是這般如花似玉,也有她的弊端:無法自己學(xué)習(xí)得知離散后簇的個(gè)數(shù),依然需要內(nèi)閣大學(xué)士來決定。
?
附錄:
rolling_mean函數(shù)解釋
pandas.rolling_mean(arg, window, min_periods=None, freq=None, center=False, how=None, **kwargs)
rolling_mean函數(shù)表示通過移動(dòng)窗口求平均值,即用當(dāng)前值和前[window]個(gè)數(shù)值取平均數(shù),得到新的數(shù)值。
import pandas as pddata = [3, 60, 83, 100, 52, 36]#源數(shù)據(jù) data = pd.DataFrame(data).sort_values(0) w2 = pd.rolling_mean(data, 2)#設(shè)置移動(dòng)窗口為2,即用當(dāng)前值和前2個(gè)數(shù)值取平均數(shù) w3 = pd.rolling_mean(data, 3)#用當(dāng)前值和前3個(gè)數(shù)值取平均數(shù) print("源數(shù)據(jù):\n", data) print("移動(dòng)窗口數(shù)為2:\n", w2) print("移動(dòng)窗口數(shù)為3:\n", w3)運(yùn)行結(jié)果:
源數(shù)據(jù):0 0 3 5 36 4 52 1 60 2 83 3 100 移動(dòng)窗口數(shù)為2:0 0 NaN 5 19.5 4 44.0 1 56.0 2 71.5 3 91.5 移動(dòng)窗口數(shù)為3:0 0 NaN 5 NaN 4 30.333333 1 49.333333 2 65.000000 3 81.000000rolling的一系列函數(shù)中,除了rolling_mean(移動(dòng)窗口的均值),還有rolling_median(移動(dòng)窗口的中位數(shù))、rolling_var (移動(dòng)窗口的方差)、rolling_std (移動(dòng)窗口的標(biāo)準(zhǔn)差)、rolling_cov (移動(dòng)窗口的協(xié)方差)、rolling_sum (移動(dòng)窗口的和)、rolling_min (移動(dòng)窗口的最小值)、rolling_max (移動(dòng)窗口的最大值)、rolling_corr (移動(dòng)窗口的相關(guān)系數(shù))、rolling_count (計(jì)算各個(gè)窗口中非NA觀測值的數(shù)量)。最常用的還是rolling_mean了,作用類似時(shí)間序列中提到的移動(dòng)平滑。
?
cut函數(shù)解釋
cut()函數(shù)可以將一個(gè)數(shù)組中的數(shù)據(jù)切分成幾個(gè)部分。兩種用法:可以設(shè)置分類的邊界,也可以僅規(guī)定分類后的個(gè)數(shù)。 cut([被分割的數(shù)據(jù)],[將數(shù)據(jù)分為幾個(gè)部分])
import pandas as pddata = [3, 60, 83, 100, 52, 36]#源數(shù)據(jù) w = [0, 25, 50, 75, 100]#規(guī)定了分類的邊界 v = 4 #僅規(guī)定分類的個(gè)數(shù),不規(guī)定邊界值 data_cut1 = pd.cut(data, w) data_cut2 = pd.cut(data, v) print("規(guī)定了分類的邊界:\n", data_cut1) print("\n規(guī)定了分類的個(gè)數(shù):\n", data_cut2)運(yùn)行結(jié)果:
規(guī)定了分類的邊界:[(0, 25], (50, 75], (75, 100], (75, 100], (50, 75], (25, 50]] Categories (4, interval[int64]): [(0, 25] < (25, 50] < (50, 75] < (75, 100]]規(guī)定了分類的個(gè)數(shù):[(2.903, 27.25], (51.5, 75.75], (75.75, 100.0], (75.75, 100.0], (51.5, 75.75], (27.25, 51.5]] Categories (4, interval[float64]): [(2.903, 27.25] < (27.25, 51.5] < (51.5, 75.75] < (75.75, 100.0]]?
其他數(shù)據(jù)預(yù)處理方法
拉格朗日插值法補(bǔ)充缺失值
清洗重復(fù)數(shù)據(jù)
數(shù)據(jù)預(yù)處理 - 歸一化與標(biāo)準(zhǔn)化
?
總結(jié)
以上是生活随笔為你收集整理的数据离散化 - 等宽等频聚类离散 - Python代码的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Matplotlib - 折线图 plo
- 下一篇: jdbctemplate 开启事务_Sp