python資料預處理 :資料離散化
阿新 • • 發佈:2018-11-27
何為離散化:
一些資料探勘演算法中,要求資料是分類屬性形式。因此常常需要將連續屬性的資料通過斷點進行劃分最後歸屬到不同的分類,即離散化。
為什麼要離散化:
- 調高計算效率
- 分類模型計算需要
- 給予距離計算模型(k均值、協同過濾)中降低異常資料對模型的影響
- 影象處理中的二值化處理
ps:離散化也可以用於已經離散化的資料,就是值域的重新劃分,一切都是看業務需要
連續資料離散化方法:
- 分位數法:使用四分位、五分位、十分位等進行離散
- 距離區間法:等距區間或自定義區間進行離散,有點是靈活,保持原有資料分佈
- 頻率區間法:根據資料的頻率分佈進行排序,然後按照頻率進行離散,好處是資料變為均勻分佈,但是會更改原有的資料結構
- 聚類法:使用k-means將樣本進行離散處理
- 卡方:通過使用基於卡方的離散方法,找出資料的最佳臨近區間併合並,形成較大的區間
- 二值化:資料跟閾值比較,大於閾值設定為某一固定值(例如1),小於設定為另一值(例如0),然後得到一個只擁有兩個值域的二值化資料集。
ps:卡方檢驗就是統計樣本的實際觀測值與理論推斷值之間的偏離程度,實際觀測值與理論推斷值之間的偏離程度就決定卡方值的大小,卡方值越大,越不符合;卡方值越小,偏差越小,越趨於符合,若兩個值完全相等時,卡方值就為0,表明理論值完全符合。
python實現
import pandas as pd
from sklearn. cluster import KMeans
from sklearn import preprocessing
#######時間序列離散#######
# 創造時間資料
date = pd.date_range('5/1/2018','11/26/2018')
df_t = pd.DataFrame(date, columns=['date'])
# 轉化為周
df_t['week'] = df_t['date'].apply(lambda x:x.weekday())
df_t.head()
# 匯入資料
df = pd.read_csv('https://raw.githubusercontent.com/ffzs/dataset/master/Mall_Customers.csv' , usecols=['Age', 'Annual Income (k$)', 'Spending Score (1-100)'])
# 更改列名
df.columns = ['Age', 'Income', 'Spend']
#######等距離散#######
df['Age_discretized'] = pd.cut(df.Age, 4, labels=range(4))
df.groupby('Age_discretized').count()
#####使用聚類實現離散化#######
# 資料準備
data = df['Income']
# 改變資料形狀
data_re = data.reshape((data.index.size, 1))
# 建立k-means模型並指定聚類數量
km_model = KMeans(n_clusters=4, random_state=2018)
# 模型匯入資料
result = km_model.fit_predict(data_re)
# 離散資料併入原資料
df['Income_discretized'] = result
df.groupby('Income_discretized').count()
#####使用4分位離散資料#######
df['Spend_discretized'] = pd.qcut(df.Spend, 4, labels=['C', 'B', 'A', 'S'])
df.groupby('Spend_discretized').count()
#####等頻率離散#######
# 設定離散區間數
k =4
# 獲取資料
data = df.Age
# 設定頻率範圍
w = [1.0*i/k for i in range(k+1)]
# 使用describe獲取頻率區域的分界點
w = data.describe(percentiles = w)[4:4+k+1]
w[0] = w[0]*(1-1e-10)
# 根據分界點進行資料離散處理
df['Age2'] = pd.cut(data, w, labels = range(k))
df.groupby('Age2').count()
#####資料二值化######
# 建立模型 根據平均值作為閾值
data = df['Income']
binarizer_scaler = preprocessing.Binarizer(threshold=data.mean())
# 二值化處理
result = binarizer_scaler.fit_transform(data.reshape(-1, 1))
# 資料合併
df['Income2'] = result
df.groupby('Income2').count()