1. 程式人生 > >資料預處理-資料變換-連續屬性離散化實現:pandas(0.23)+sklearn(0.19.1)+matplotlib(2.2.2)

資料預處理-資料變換-連續屬性離散化實現:pandas(0.23)+sklearn(0.19.1)+matplotlib(2.2.2)

程式碼來源:Python資料分析與挖掘實戰

原始碼有如下錯誤:

line22: 原: data.reshape      修改後:  data.values.reshape
line23: 原: sort(0)                  修改後: sort_values(0)
line24: 原: pd.rolling_mean(c, 2).iloc[1:]            修改後: pd.DataFrame.rolling(c, 2).mean().iloc[1:]
line31: 原: [j for i in d[d==j]]     修改後: [i for i in d[d==j]]

import pandas as pd
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

datafile = '../data/discretization_data.xls'
data = pd.read_excel(datafile)
data = data[u'肝氣鬱結證型係數'].copy()
k = 4

d1 = pd.cut(data, k, labels=range(k))    #等寬離散化,各個類比依次命名為0,1,2,3

#等頻率離散化
w = [1.0*i/k for i in range(k+1)]
w = data.describe(percentiles=w)[4:4+k+1]    #使用describe函式自動計算分位數;w = [0.0, 0.25, 0.5, 0.75, 1.0]
w[0] = w[0]*(1-1e-10)    #1e-10表示1*10的-10次方
d2 = pd.cut(data, w, labels=range(k))    #w表示等頻

kmodel = KMeans(n_clusters=k, n_jobs=4)    #建立模型,n_jobs是並行數,一般等於cpu數較好
kmodel.fit(data.values.reshape((len(data), 1)))    #訓練模型;data.values.reshape((len(data), 1))返回值是包含於一個大陣列的n個小陣列,型別為ndarray
c = pd.DataFrame(kmodel.cluster_centers_).sort_values(0)    #輸出聚類中心,並且排序(預設是隨機排序的);kmodel.cluster_centers_表示聚類中心座標
w = pd.DataFrame.rolling(c, 2).mean().iloc[1:]    #相鄰兩項求中點,作為邊界點
w = [0] + list(w[0]) + [data.max()]    #把首末邊界點加上
d3 = pd.cut(data, w, labels=range(k))

def cluster_plot(d, k):    #自定義做圖函式來顯示聚類結果
    plt.figure(figsize=(8, 3))    #由於這部分程式碼比較難理解,所以以d=d1與j=0為例說明
    for j in range(0, k):
        plt.plot(data[d==j], [i for i in d[d==j]], 'o')    #data[d1==0]表示的是data中被類比為0的資料,是x軸的資料;d1[d1==0]的取值均為0,表示y軸的值,與data[d1==0]中的值對應,一起組成下圖中的線段

    plt.ylim(-0.5, k-0.5)    #設定當前y軸區間
    return plt

cluster_plot(d1,k).show()
cluster_plot(d2,k).show()
cluster_plot(d3,k).show()