數據預處理的主要內容包括數據清洗、數據集成、數據變換和數據規約,在數據挖掘的過程中,數據預處理工作量占到了整個過程的60%。數據清洗在上一篇博客中寫過,這里主要寫后面三部分。
數據集成
數據挖掘需要的數據往往分布在不同的數據源中,數據集成就是將多個數據源合並存放在一個一致的數據存儲(如數據倉庫)中的過程。
在數據集成時,來自多個數據源的現實世界實體的表達形式是不一樣的,有可能不匹配,要考慮實體識別問題和屬性冗余問題,從而將源數據在最低層上加以轉換、提煉和集成。
1、實體識別
同名異義、異名同義、單位不統一
2、冗余項識別
數據集成往往導致數據冗余,如:
①同一屬性多次出現。
②同一屬性命名不一致導致重復。
有些冗余屬性可以用相關分析檢測。給定兩個數值型的屬性A和B,根據其屬性值,用相關系數度量一個屬性在多大程度上蘊含另一個屬性。
數據變換
數據變換主要是對數據進行規范化處理,將數據轉換成適當的形式,以適用於挖掘任務及算法的需要。
簡單的函數變換
常見的函數變換有平方、開方、取對數、差分等。$$\begin{array}{*{20}{l}}
{{x^\prime } = {x^2}}\\
{{x^\prime } = \sqrt x }\\
{{x^\prime } = \log (x)}\\
{\nabla f\left( {{x_k}} \right) = f\left( {{x_{k + 1}}} \right) - f\left( {{x_k}} \right)}
\end{array}$$
簡單的函數變換常用來將不具有正態分布的數據變換成具有正態分布的數據;在時間序列分析中,有時簡單的對數變換或者差分運算就可以將非平穩序列轉換成平穩序列。
規范化
數據標准化(歸一化)處理是數據挖掘的一項基礎工作。不同評價指標往往具有不同的量綱,數值間的差別可能很大,不進行處理可能會影響到數據分析的結果。為了消除指標之間的量綱和取值范圍差異的影響,需要進行規范化處理,將數據按照比例進行縮放,使之落入一個特定的區域,便於進行綜合分析。
①最小-最大規范化
也稱為離差標准化,是對原始數據的線性變換,將數值映射到[0,1]區間。
公式如下:$$x^{*}=\frac{x-\min }{\max -\min }$$
其中,max為樣本數據的最大值,min為樣本數據的最小值,max-min為極差。
離差標准化保留了原來數據中存在的關系,是消除量綱和數據取值范圍影響的最簡單的方法。
這種處理方法的缺點是若數值集中或某個數值很大,則規范化后各值會接近於0,並且將會相差不大。若將來遇到超過目前屬性[min,max]取值范圍的時候,會引起系統出錯,需要重新確定min和max。
②零-均值規范化
也叫標准差標准化,經過處理的數據的均值為0,標准差為1。
公式如下:$$x^{*}=\frac{x-\overline{x}}{\sigma}$$
其中$\overline x $為原始數據的均值;$\sigma $為原始數據的標准差。這種方法是當前用得最多的數據標准化方法,但是均值和標准差受離群點的影響很大,因此通常需要修改上述變換。
首先,用中位數M取代均值,其次用絕對標准差取代標准差$\sigma^{*}=\sum_{i=1}^{i=n}\left|x_{i}-W\right|$,W是平均數或者中位數。
③小數定標規范化
通過移動屬性值的小數位數,將屬性值映射到[-1,1]之間,移動的小數位數取決於屬性值絕對值的最大值。
公式如下:$$x^{*}=\frac{x}{10^{k}}$$
對於一個含有n個記錄、p個屬性的數據集,就分別對每一個屬性的取值進行最小-最大規范化、零-均值規范化、小數定標規范化進行規范化。
%% 數據規范化 clear; % 參數初始化: data = '../data/normalization_data.xls'; %% 讀取數據 [data,~] = xlsread(data); %% 最小-最大規范化 data_scatter = mapminmax(data',0,1); % 數據需要轉置 data_scatter = data_scatter'; %% 零-均值規范化 data_zscore = zscore(data); %% 小數定標規范化 max_ = max(abs(data)); max_ = power(10,ceil(log10(max_))); cols = size(max_,2); data_dot = data; for i=1:cols data_dot(:,i)=data(:,i)/max_(1,i); end %% 打印結果 disp('原始數據為:'); disp(data); disp('最小-最大規范化后的數據為:'); disp(data_scatter); disp('零-均值規范化后的數據為:'); disp(data_zscore); disp('小數定標規范化后的數據為:'); disp(data_dot);

連續屬性離散化
一些數據挖掘算法,特別是某些分類算法如ID3算法、Apriori算法等,要求數據是分類屬性形式。這樣,常常需要將連續屬性變換成分類屬性,即連續屬性離散化。
1、離散化的過程
連續屬性的離散化就是在數據的取值范圍內設定若干個離散的划分點,將取值范圍划分為一些離散化的區間,最后用不同的符號或整數值代表落在每個子區間中的數據值。
所以,離散化涉及兩個子任務:確定分類數以及如何將連續屬性值映射到這些分類值中。
2、常用的離散化方法
常用的離散化方法有等寬法、等頻法和聚類分析法。
①等寬法
將屬性的值域分成具有相同寬度的區間,區間的個數由數據本身的特點決定或者用戶指定,類似於制作頻率分布表。
②等頻法
將相同數量的記錄放進每個區間。
這兩種方法簡單、易於操作,但都需要人為地規定划分區間的個數。
缺點:
等寬法的缺點在於它對離群點比較敏感,傾向於不均勻地把屬性值分布到各個區間。有些區間包含許多數據,而另外一些區間的數據極少,這樣會嚴重損壞所建立的決策模型。
等頻法雖然避免了上述問題的產生,卻可能將相同的數據值分到不同的區間以滿足每個區間中固定的數據個數。
③聚類分析
聚類分析法包括兩個步驟,首先將連續屬性的值用聚類算法進行聚類,然后再將聚類得到的簇進行處理,合並到一個簇的連續屬性值做同一標記。
聚類分析的離散化方法也需要用戶指定簇的個數,從而決定產生的區間數。
%% 數據離散化 clear; % 參數初始化: data = '../data/discretization_data.xls'; k = 4; %% 讀取數據 [data,~] = xlsread(data); rows = size(data,1); %% 等寬離散化 % 規則需要自定義 rules = [0,0.179,0.258,0.35,0.504]; width_data = zeros(rows,2); width_data(:,1) = data; width_data(:,2)= arrayfun(@find_type,data); %% 等頻離散化 frequent_data = zeros(rows,2); frequent_data(:,1) = data; end_ =-1; for i=1:k-1 start_ = floor((i-1)*rows/k)+1; end_ = floor(i*rows/k); frequent_data(start_:end_,2) = i; end frequent_data(end_+1:end,2) = k; %% 聚類離散化 [idx,~] = kmeans(data,k); cluster_data = zeros(rows,2); cluster_data(:,1) = data; cluster_data(:,2) = idx; %% 作圖展示結果 figure cust_subplot(width_data,3,1,1,k,'等寬離散化'); cust_subplot(frequent_data,3,1,2,k,'等頻離散化'); cust_subplot(cluster_data,3,1,3,k,'聚類離散化'); disp('數據離散化完成!');

分別用等寬法、等頻法和聚類分析法對數據進行離散化,將數據分成四類,然后將每一類記為同一個標識,再進行建模。
屬性構造
在數據挖掘的過程中,為了幫助提取更有用的信息、挖掘更深層次的模式,提高挖掘結果的精度,需要利用已有的屬性集構造出新的屬性,並加到現有的屬性集合中。
比如進行防竊漏電診斷建模時,已有的屬性包括供入電量、供出電量(線路上各大用戶用電量之和)。理論上供入電量和供出電量應該是相等的,但是由於在傳輸過程中存在電能損耗,使得供入電量略大於供出電量,如果該條線路上的一個或多個大用戶存在竊漏電行為,會使得供入電量明顯大於供出電量。反過來,為了判斷是否有大用戶存在竊漏電行為,可以構造出一個新的指標—線損率,該過程就是構造屬性。
新構造的屬性線損率按以下公式計算:

線損率的正常范圍一般在3%~15%,如果遠遠超過該范圍,就可以認為該條線路的用戶很可能存在竊漏電等用電異常的行為。
%% 線損率屬性構造 clear; %初始化參數 inputfile= '../data/electricity_data.xls'; % 供入供出電量數據 outputfile = '../tmp/electricity_data.xls'; % 屬性構造后數據文件 %% 讀取數據 [num,txt,raw]=xlsread(inputfile); % 數據第一列為供入電量,第二列為供出電量 [rows,cols] = size(num); %% 構造屬性 loss = (num(:,1)-num(:,2))./num(:,1); %% 保存結果 result = cell(rows+1,cols+1); result(:,1:cols) =raw; result{1,cols+1} = '線損率'; result(2:end,cols+1) = num2cell(loss); xlswrite(outputfile,result); disp('線損率屬性構造完畢!');

小波變換
傅里葉變換與小波變換強烈安利:http://cda.pinggu.org/view/18623.html,慢慢看。
基於小波變換的特征提取方法主要有:①基於小波變換的多尺度空間能量分布特征的提取、②基於小波變換的多尺度空間中模極大值特征的提取、③基於小波包變換特征的提取、④基於適應性小波神經網絡特征的提取。
小波基函數:
小波基函數是一種具有局部支集的函數,並且平均值為0,小波基函數滿足:$\psi(0)=\int \psi(t) \mathrm{d} t=0$。常用的小波基有Haar小波基、db系列小波基等。
小波變換:
對小波基函數進行伸縮和平移變換:$\psi_{a, b}(t)=\frac{1}{\sqrt{|a|}} \psi\left(\frac{t-b}{a}\right)$
其中,a為伸縮因子;b為平移因子。
任意函數$f(t)$的連續小波變換(CWT)為:$$W_{f}(a, b)=|a|^{-1 / 2} \int f(t) \psi\left(\frac{t-b}{a}\right) \mathrm{d} t$$
可知,連續小波變換為$f(t) \rightarrow W_{f}(a, b)$的映射,對小波基函數$\psi(t)$增加約束條件$C_{\psi}=\int \frac{|\hat{\psi}(t)|^{2}}{t} \mathrm{d} t<\infty$就可以由$W_{f}(a, b)$逆變換得到$f(t)$。其中$\hat{\psi}(t)$為$\psi(t)$的傅里葉變換。其逆變換為:$$f(t) = \frac{1}{{{C_\psi }}}{W_f}(a,b)\psi \left( {\frac{{t - b}}{a}} \right){\rm{d}}a \cdot {\rm{d}}b$$
利用小波函數對聲波信號數據進行分解,得到5個層次的小波系數。利用這些小波系數求得各個能量值,這些能量值即可作為聲波信號的特征數據。
%% 利用小波分析 進行特征分析 clear; % 參數初始化 level =5; load leleccum; signal = leleccum(1:3920); %% 進行 level層小波分解 [C,S] = wavedec2(signal,level,'bior3.7'); %% 提取第i層小波系數,並計算各層能量值 E=zeros(1,level); for i=1:level [H_i,~,~] = detcoef2('all',C,S,i); E(1,i)=norm(H_i,'fro'); end %% 打印各層能量值,即提取的特征值 disp('聲音信號小波分析完成,提取的特征向量為:'); disp(E);
得到聲音信號的特征向量如下所示:

數據規約
在大數據集上進行復雜的數據分析和挖掘將需要很長的時間,數據規約產生更小的但保持原數據完整性的新數據集。在規約后的數據集上進行分析和挖掘將更有效率。
數據規約的意義在於:
①降低無效、錯誤數據對建模的影響,提高建模的准確性。口少量且具代表性的數據將大幅縮減數據挖掘所需的時間。
②降低儲存數據的成本。
屬性規約
屬性規約通過屬性合並創建新屬性維數,或者直接通過刪除不相關的屬性維數來減少數據維數,從而提高數據挖掘的效率、降低計算成本。屬性規約的目標是尋找出最小的屬性子集並確保新數據子集的概率分布,並盡可能地接近原來數據集的概率分布。
屬性規約常用方法:(限於篇幅,這里淺顯的寫一點點,其實這樣效果並不好,建議看一些機器學習和數據挖掘的教材)
①合並屬性
將一些舊屬性合並為新屬性。
②逐步向前選擇
從一個空屬性集開始;每次從原來屬性集合中選擇一個當前最優的屬性添加到當前屬性子集中。直到無法選擇出最優屬性或滿足一定閥值約束為止。
③逐步向后刪除
從一個全屬性集開始,每次從當前屬性子集中選擇一個當前最差的屬性並將其從當前屬性子集中消去,直到無法選擇出最差屬性為止或滿足一定閥值約束為止。
⑤決策樹歸納
利用決策樹的歸納方法對初始數據進行分類歸納學習,獲得一個初始決策樹,所有沒有出現在這個決策樹上的屬性均可認為是無關屬性,因此將這些屬性從初始集合中刪除,就可以獲得一個較優的屬性子集。
⑥主成分分析
用較少的變量去解釋原始數據中的大部分變量,將許多相關性很高的變量轉化成彼此相互獨立或不相關的變量。
下面以主成分分析為例。
逐步向前選擇、逐步向后刪除和決策樹歸納是屬於直接刪除不相關屬性維數的方法。
而主成分分析是一種用於連續屬性的數據降維方法,它構造了原始數據的一個正交變換,新空間的基底去除了原始空間基底數據的相關性,只需使用少數新變量就能夠解釋原始數據中的大部分變異。
在應用中,通常是選出比原始變量個數少,能解釋大部分數據中的變量的幾個新變量,即所謂的主成分,來代替原始變量進行建模。
步驟:
①設原始變量$X_{1}, X_{2}, \cdots, X_{p}$的n次觀測數據矩陣為: $$X=\left[\begin{array}{ccc}{x_{11}} & {x_{12}} & {\cdots} & {x_{1 p}} \\ {x_{21}} & {x_{22}} & {\cdots} & {x_{2 p}} \\ {\vdots} & {\vdots} & {} & {\vdots} \\ {x_{n 1}} & {x_{n 2}} & {\cdots} & {x_{n p}}\end{array}\right] A\left(X_{1}, X_{2}, \cdots, X_{P}\right)$$
②將數據矩陣按列進行中心標准化。為了方便,將標准化后的數據矩陣仍然記為X。
③求相關系數矩陣$R, R=\left(r_{i j}\right)_{p \cdot p}, \quad r_{i j}$定義為
$$r_{i j}=\sum_{k=1}^{n}\left(x_{k i}-\overline{x}_{i}\right)\left(x_{k j}-\overline{x}_{j}\right) / \sqrt{\sum_{k=1}^{n}\left(x_{k i}-\overline{x}_{i}\right)^{2} \sum_{k=1}^{n}\left(x_{k j}-\overline{x}_{j}\right)^{2}}$$
其中,$r_{j}=r_{j, i}, r_{i i}=1$
④求R的特征方程$\operatorname{det}(R-\lambda E)=0$的特征根$\lambda_{1} \geqslant \lambda_{2} \geqslant \cdots \geqslant \lambda_{p}>0$
⑤確定主成分個數m:$\frac{\sum_{i=1}^{m} \lambda_{i}}{\sum_{i=1}^{p} \lambda_{i}} \geqslant \alpha$。a根據實際問題確定,一般取80%。
⑥計算m個相應的單位特征向量:$$\beta_{1}=\left[\begin{array}{c}{\beta_{11}} \\ {\beta_{21}} \\ {\vdots} \\ {\beta_{p 1}}\end{array}\right], \beta_{2}=\left[\begin{array}{c}{\beta_{12}} \\ {\beta_{22}} \\ {\vdots} \\ {\beta_{p 2}}\end{array}\right], \ldots, \beta_{m}=\left[\begin{array}{c}{\beta_{m 2}} \\ {\beta_{x 2}} \\ {\vdots} \\ {\beta_{m 2}}\end{array}\right]$$
⑦計算主成分:$$Z_{i}=\beta_{1 i} X_{1}+\beta_{2 i} X_{2}+\dots+\beta_{p i} X_{p}(i=1,2, \cdots, m)$$
%% 主成分分析 降維 clear; % 參數初始化 inputfile = '../data/principal_component.xls'; outputfile = '../tmp/dimention_reducted.xls'; % 降維后的數據 proportion = 0.95 ; % 主成分的比例 %% 數據讀取 [num,~] = xlsread(inputfile); %% 主成分分析 [coeff,~,latent] = pca(num); %% 計算累計貢獻率,確認維度 sum_latent = cumsum(latent/sum(latent)); % 累計貢獻率 dimension = find(sum_latent>proportion); dimension= dimension(1); %% 降維 data = num * coeff(:,1:dimension); xlswrite(outputfile,data); disp('主成分特征根:'); disp(latent'); disp('主成分單位特征向量'); disp(coeff); disp('累計貢獻率'); disp(sum_latent'); disp(['主成分分析完成,降維后的數據在' outputfile]);
從結果可以得到特征方程有7個特征根、對應的7個單位特征向量以及累計貢獻率。

原始數據從8維被降維到了3維,同時這3維數據占了原始數據95%以上的信息。

數值規約
數值規約通過選擇替代的、較小的數據來減少數據量,包括有參數方法和無參數方法兩類。
有參數方法是使用一個模型來評估數據,只需存放參數,而不需要存放實際數據。例如,回歸(線性回歸和多元回歸)和對數線性模型(近似離散屬性集中的多維概率分布)。
無參數方法就需要存放實際數據,例如,直方圖、聚類、抽樣(采樣)、參數回歸。
1.直方圖
直方圖使用分箱來近似數據分布,是一種流行的數據規約形式。屬性A的直方圖將A的數據分布划分為不相交的子集或桶。如果每個桶只代表單個屬性值/頻率對,則該桶稱為單桶。通常,桶表示給定屬性的一個連續區間。
2.聚類
聚類技術是將數據元組(即記錄,數據表中的一行)視為對象。它將對象划分為簇,使一個簇中的對象相互“相似”,而與其他簇中的對象“相異”。在數據規約中,用數據的簇替換實際數據。該技術的有效性依賴於簇的定義是否符合數據的分布性質。
3.抽樣
抽樣也是一種數據規約技術,它用比原始數據小得多的隨機樣本(子集)表示原始數據集。假定原始數據集D包含N個元組,可以采用抽樣方法對D進行抽樣。下面介紹常用的抽樣方法。
①s個樣本無放回簡單隨機抽樣:從D的N個元組中抽取s個樣本(s<N),其中D中任意元組被抽取的概率均為1/N,即所有元組的抽取是可能相等的。
②s個樣本有放回簡單隨機抽樣:該方法類似於無放回簡單隨機抽樣,其不同在於每次一個元組從D中抽取后,記錄它,然后放回原處。
③聚類抽樣:如果D中的元組分組放人M個互不相交的“簇”,則可以得到s個簇的簡單隨機抽樣,其中s<M。例如,數據庫中元組通常一次檢索一頁,這樣每頁就可以視為一個簇。
④分層抽樣:如果D划分成互不相交的部分,稱做層,則通過對每一層的簡單隨機抽樣就可以得到D的分層樣本。
用於數據規約時,抽樣最常用來估計聚集查詢的結果。在指定的誤差范圍內,可以確定(使用中心極限定理)估計一個給定的函數所需的樣本大小。通常樣本的大小s相對於N非常小。而通過簡單地增加樣本大小,這樣的集合可以進一步求精。
4.參數回歸
簡單線性模型和對數線性模型可以用來近似給定的數據。用簡單線性模型對數據建模,使之擬合為一條直線。
把點對(2,5)、(3,7)、(4,9)、(5,12)、(6,11)、(7,15)、(8,18)、(9,19)、(11,22)、(12,25)、(13,24)、(15,30)、(17,35)規約成線性函數$y = wx + b$,即擬合函數 $y = 2x + 1.3$ 線上所對應的點可以近似地看做是已知點,如圖4-9所示。
clc clear x=[2,3,4,5,6,7,8,9,11,12,13,15,17]; y=[5,7,9,12,11,15,18,19,22,25,24,30,35]; % 繪制散點圖,判斷是否具有線性關系 figure plot(x,y,'r*') %作散點圖 set(gca,'linewidth',2); % 采用最小二乘擬合 Lxx=sum((x-mean(x)).^2); Lxy=sum((x-mean(x)).*(y-mean(y))); b1=Lxy/Lxx; b0=mean(y)-b1*mean(x); y1=b1*x+b0; hold on plot(x, y1,'linewidth',2);

其中,y的方差是常量13.44。在數據挖掘中,x和y是數值屬性。系數2和1.3(稱做回歸系數)分別為直線的斜率和y軸截距。系數可以用最小二乘方法求解,它使數據的實際直線與估計直線之間的誤差最小化。多元線性回歸是(簡單)線性回歸的擴充,允許響應變量y建模為兩個或多個預測變量的線性函數。
MATLAB主要的數據預處理函數
①interp1()
功能:一維數據插值。
使用格式:yi=interp1(x,Y,xi,method),進行一維數據的線性插值。
參數X和Y表示已知數據,其中,X為向量,Y為與X同維向量或行數等於x長度的矩陣。xi為向量,表示待插入點,如果Y為向量,則xi中元素通過向量X與Y的內插值得到yi;如果Y為一矩陣,則xi中的元素通過對向量X與矩陣Y的每列分別進行內插值得到yi。
②unique()
功能:去除數據中的重復元素,得到單值元素列表。
使用格式:[b,i,jl=unique(x),將數據矩陣X中的元素去重復后,返回到b中,並返回索引向量i、j。其中,i表示元素在原向量或矩陣中的最大索引位置;j表示原向量中單值元素在b中的索引位置。
A=[8,7,3,9,2,4,11,3,8,4,4]; [b,i,j]=unique(A)

③find()
功能:找到矩陣數據中相應標識所在的位置。
使用格式:[i,j]=find(X=-mark),找到樣本矩陣X中和mark值一樣的元素,返回它所在的位置,i記錄行坐標,j記錄列坐標。
④isnan()
功能:判斷矩陣數據中的元素是否為數值。
使用格式:Y=isnan(X),對樣本矩陣X中的每個元素進行判斷,如果元素為數值則返回0,不是數值則返回1,返回的結果存儲到矩陣Y中,矩陣Y由0、1組成。
⑤mapminmax()
功能:對數據矩陣進行最大值、最小值的規范化。
使用格式:Z=mapminmax(X,ymin,ymax),輸入樣本數據X,規范化后的最小值為ymin,最大值為ymax,Z為進行規范化后的數據。
eg:將一個10維行向量進行最大值、最小值的規范化到[0,1]之間。
X=1:1:10; Z=mapminmax(X,0,1)

⑥zscore()
功能:對數據矩陣進行標准差的規范化。
使用格式:Z=zscore(x),對樣本矩陣X進行標准差的標准化,返回標准化后的結果到z矩陣中。
⑦pca()
功能:對指標變量矩陣進行主成分分析。
使用格式:[coeff,score,latent,tsquared]=pca(X)
X為要進行主成分分析的數據矩陣,X矩陣一列的值代表一個變量指標的一列觀測值。
latent為主成分分析得到的特征根;
coeff為各特征根對應的系數矩陣;
score為得分,由coeff與X得到;
tsquared為X中每個觀測值的Hotelling's T-squared值
eg:使用pca()函數對一個10×4維的隨機矩陣進行主成分分析的結果如下。
X=rand(10,4); [coeff,score,latent]=pca(X)

⑧rand()
功能:生成服從均勻分布的隨機矩陣,元素分布在區間(0,1)上,抽樣時可使用。
使用格式:Y=rand(n),生成一個n·n隨機矩陣,其元素均勻分布在區間(0,1)上;
Y=rand(m,n),生成一個m·n隨機矩陣,其元素均勻分布在區間(0,1)上。
eg:使用rand函數對一個10維的向量放回采集一個3維樣本的代碼如下。
a=1:1:10; m=length(a); n=3; idx=ceil(m*rand(1,n)); b=a(idx)

⑨randsample()
功能:進行不放回隨機抽樣。
使用格式:a=randsample(n,k),1~n的數字序列里隨機返回k個數。
其中,這k個數之間彼此不相同,以實現不放回隨機抽樣。
