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