一、數(shù)據(jù)離散化
1、所謂離散化,就是把無限空間中的有限個體映射到一個有限的空間中。
2、數(shù)據(jù)離散化大多針對連續(xù)數(shù)據(jù)進行,處理后數(shù)據(jù)值域分布將從連續(xù)屬性變?yōu)殡x散屬性。
3、數(shù)據(jù)離散化在很多情況下也有針對已經(jīng)離散化的數(shù)據(jù),大多是因為這些離散化數(shù)據(jù)本身劃分過于復(fù)制和瑣碎,甚至不符合業(yè)務(wù)邏輯。
二、數(shù)據(jù)離散化的方法
2.1針對時間數(shù)據(jù)離散化
1、在帶時間的數(shù)據(jù)集中,時間可作為行記錄序列,也可作為列記錄的數(shù)據(jù)特征。
2、時間數(shù)據(jù)離散化操作2類:
- 1天中的時間離散,時間戳轉(zhuǎn)為秒,分鐘,小時或上午
- 日顆粒以上的,日期轉(zhuǎn)化為周數(shù),周幾,月,工作日或休息日,季度,年等
3、常使用方法:利用dt訪問器對時間數(shù)據(jù)進行操作
# 設(shè)置cell多行輸出
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = 'all' #默認為'last'
# 導(dǎo)入相關(guān)庫
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import os
import warnings
warnings.filterwarnings('ignore')
os.chdir(r'E:\python_learn\data\python_book_v2\chapter3')
# 導(dǎo)入數(shù)據(jù)
file_name = 'data7.txt'
df = pd.read_table(file_name,names=['id','amount','income','datetime','age'])
print(df.head())
id amount income datetime age
0 15093 1390 10.40 2017-04-30 19:24:13 0-10
1 15062 4024 4.68 2017-04-27 22:44:59 70-80
2 15028 6359 3.84 2017-04-27 10:07:55 40-50
3 15012 7759 3.70 2017-04-04 07:28:18 30-40
4 15021 331 4.25 2017-04-08 11:14:00 70-80
# 缺失查看
df.isna().sum().sum()
0
# 數(shù)據(jù)結(jié)構(gòu)查看
df['datetime'].dtypes
df['datetime'] = pd.to_datetime(df['datetime'])
dtype('O')
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 100 entries, 0 to 99
Data columns (total 5 columns):
id 100 non-null int64
amount 100 non-null int64
income 100 non-null float64
datetime 100 non-null datetime64[ns]
age 100 non-null object
dtypes: datetime64[ns](1), float64(1), int64(2), object(1)
memory usage: 4.0+ KB
# 時間數(shù)據(jù)離散化 → 轉(zhuǎn)為周幾
df['weekday'] = df['datetime'].dt.weekday
print(df.head())
# 0 → 周一
# 6 → 周日
id amount income datetime age weekday
0 15093 1390 10.40 2017-04-30 19:24:13 0-10 6
1 15062 4024 4.68 2017-04-27 22:44:59 70-80 3
2 15028 6359 3.84 2017-04-27 10:07:55 40-50 3
3 15012 7759 3.70 2017-04-04 07:28:18 30-40 1
4 15021 331 4.25 2017-04-08 11:14:00 70-80 5
2.2針對多值離散數(shù)據(jù)的離散化
1、對多值離散化是指要進行離散化的數(shù)據(jù)本身不是數(shù)值型數(shù)據(jù),而是分類或定序數(shù)據(jù)。如本次使用的數(shù)據(jù)集的age字段。
2、例如,用戶收入變量的值原為10個區(qū)間,后因新需求,需要將其劃分為4個區(qū)間,這時就需對原10個區(qū)間進行重新劃分。
3、對多值離散化除了因需而變,還可能因為業(yè)務(wù)邏輯不符合或變更需要重新劃分。
df['age'].unique()
len(df['age'].unique()) # 查看age字段的唯一值個數(shù) →10個
array(['0-10', '70-80', '40-50', '30-40', '10-20', '20-30', '>90',
'50-60', '60-70', '80-90'], dtype=object)
10
# 將原來10個區(qū)間轉(zhuǎn)換為3個區(qū)間 → 0-40,40-80,>80
dic = {'age':['0-10','10-20','20-30','30-40','40-50','50-60','60-70','70-80','80-90','>90'],
'age_new':['0-40','0-40','0-40','0-40','40-80','40-80','40-80','40-80','>80','>80']
}
age_new = pd.DataFrame(dic)
data = pd.merge(df,age_new,on='age')
data.head(10)

2.3針對連續(xù)數(shù)據(jù)離散化
1、針對連續(xù)數(shù)據(jù)離散化是離散化的主要應(yīng)用操作。
2、連續(xù)數(shù)據(jù)離散化結(jié)果分為兩類:
- 將連續(xù)數(shù)據(jù)劃分為特定區(qū)間集合 → {0-10,10-20,20-30……}
- 將連續(xù)數(shù)據(jù)劃分為特定類 → 1類、2類、3類
2.3.1連續(xù)數(shù)據(jù)離散化常用方法:
(1)等寬法(距離區(qū)間法)
等寬法(距離區(qū)間法) → pandas的cut方法
使用等距或自定義區(qū)間的方式進行離散化。即系將連續(xù)型變量的取值范圍均勻劃分成n等份,每份的間距相等。
如,年齡字段,將其劃分為0-10歲為一組,10-20歲為一組……以此類推,其組距都為10;
特點:靈活且能滿足自定義需求并能保持數(shù)據(jù)原有分布。
# pandas的cut方法對字段amount實現(xiàn)等寬劃分
bins = [0,200,1000,5000,10000] # 自定義區(qū)間邊界
data['amount_cut'] = pd.cut(data['amount'],bins) # 沒設(shè)置labels參數(shù)
data['amount_cutLabel'] = pd.cut(data['amount'],bins,labels=['bad','medium','good','awesome']) # 設(shè)置labels參數(shù)
data.head()
# labels參數(shù)設(shè)置了就用標(biāo)簽代替上述區(qū)間

(2)等頻法(頻率區(qū)間法)
- 等頻法(頻率區(qū)間法): → pandas的qcut方法
以相同數(shù)量的記錄放進每個區(qū)間,即系把觀察點均勻分成n等份,每份包含的觀察點數(shù)相同。
如,某雜志訂戶共有5萬人,等頻分段需要先把訂戶按訂閱時間按順序排列,排列好后可以按5000人一組,把全部訂戶均勻分為十段。
特點:數(shù)據(jù)會被均勻分布,各個區(qū)間的觀察值相同,改變數(shù)據(jù)原有的分布狀態(tài)。
data['amount_qcut'] = pd.qcut(data['amount'],q=4) # 按4份劃分,每份數(shù)量相同
# 參數(shù)q表示,整數(shù)或分位數(shù)組成的數(shù)組,即要將數(shù)據(jù)分成幾組
data.groupby(data['amount_qcut']).count()['amount_qcut'] # 查看每組的數(shù)量

(3)聚類法(基于聚類分析的方法)
- 聚類法(基于聚類分析的方法): → sklearn.cluster的K-Means方法
2個步驟:① 將連續(xù)屬性的值用聚類算法(如K-Means算法)進行聚類;
② 將聚類得到的簇進行處理,合并到一個簇的連續(xù)屬性值做同一標(biāo)記。
但是,聚類分析的離散化方法也需要事先指定簇的個數(shù),從而決定產(chǎn)生的區(qū)間數(shù)(類數(shù))
→ sklearn.cluster的K-Means算法實現(xiàn):
① 獲得建模數(shù)據(jù)列
② 作為輸入變量需要做形狀轉(zhuǎn)換,否則算法會認為輸入數(shù)據(jù)只有1行
③ 創(chuàng)建KMwans模型并指定聚類數(shù)量,設(shè)置初始化隨機種子固定值為0,否則每次聚類的結(jié)果很可能不一樣
④ 使用fit_predict方法直接建模輸出結(jié)果
# sklearn.cluster的K-Means方法實現(xiàn)
from sklearn.cluster import KMeans
amount = data['amount']
amount.shape # amount列原形狀為1行數(shù)據(jù)
amount_shape = amount.values.reshape((amount.shape[0],1)) # reshape轉(zhuǎn)換形狀
amount_shape.shape # 轉(zhuǎn)換形狀后為(100,1) 100行*1列
model_kmeans = KMeans(n_clusters=4,random_state=0) # 創(chuàng)建Kmeans模型
# n_clusters=4,指定聚類數(shù)量
# random_state=0,設(shè)置初始化隨機種子固定值為0
kmeans_result = model_kmeans.fit_predict(amount_shape) # 建立聚類
data['amount_kmeans'] = kmeans_result
data.head()

2.4針對連續(xù)數(shù)據(jù)的二值化
1、連續(xù)數(shù)據(jù)二值化是指將連續(xù)的變量特征進行二值的操作。
2、將每個數(shù)據(jù)點跟某個設(shè)定的閾值比較,大于閾值設(shè)置為某一固定值(例如1),小于閾值設(shè)置為某一固定值(例如0),最后得到一個只擁有兩個值域的二值化數(shù)據(jù)集
3、需要注意的是二值化應(yīng)用的前提:
- 數(shù)據(jù)集中所有的屬性值所代表的含義相同或類似。如某圖像數(shù)據(jù)集的顏色字段的數(shù)據(jù)集,其讀取圖像時的模式設(shè)置有灰度,RGB等,但都表示為顏色,此時該列特征含有相同,可對該列數(shù)據(jù)集進行二值化。
4、二值化方法:
→ sklearn.preprocessing的Binarizer方法
# 將income字段二值化,閾值設(shè)置為該列的均值
from sklearn import preprocessing
binarizer = preprocessing.Binarizer(threshold=data['income'].mean()) # 建立Binarizer模型對象
income = binarizer.fit_transform(data[['income']]) # 使用模型對象進行二值化
income.shape
income.resize(data['income'].shape) # 將列數(shù)據(jù)形狀還原為(100,)
income.shape
data['income_binarizer'] = income
data.head()

如下圖所示,是數(shù)據(jù)離散前后的對比:

三、優(yōu)化離散
- 數(shù)據(jù)離散化的關(guān)鍵是,如何根據(jù)不同的數(shù)據(jù)特征和建模需求選擇離散的方式。 → 離散化方式是否合理直接影響后續(xù)的數(shù)據(jù)建模和應(yīng)用效果
- 如何優(yōu)化離散? → 需要把自變量和目標(biāo)變量聯(lián)系起來考察。切分點是導(dǎo)致目標(biāo)變量出現(xiàn)明顯變化的折點。