超干!Gain 算法實現缺失值預測
出品 | AI科技大本營(ID:rgznai100)
隨著計算機和信息技術的快速發展,大數據和人工智能技術表現出越來越好的發展前景。數據在互聯網、物聯網、醫療、金融等諸多領域迅速累積,形成大規模數據時代。大數據和人工智能技術相輔相成,一方面數據是人工智能算法做出決策的基礎,另一方面數據也需要人工智能算法實現其價值。高質量的數據是實現人工智能、數據挖掘等技術最原始的驅動力,但是在現實世界中,許多數據集存在數據質量問題。數據集來源于人工或機器的收集,即使是關系型數據庫中存儲的數據,也很容易存在數據缺失、數據冗余、數據不一致等問題。低質量的數據不僅增加了算法設計的難度,還降低了算法分析結果的準確性。因此,擁有高質量的數據才是實現人工智能等算法的前提。在大數據等領域,數據預處理就是實現高質量數據的過程,其包括數據清洗、數據集成、數據轉換、數據規約。不同的任務其數據集成、數據轉換和數據規約方式不同,但都離不開數據清洗。由此可見處理原始數據,實現高質量數據起著重要作用。
然而在數據處理過程中,經常面臨數據缺失問題。例如,在問卷調查中,被調查人員由于遺漏或者涉及隱私而沒有填寫完整信息造成的數據缺失;在醫療系統中,由于患者沒有相關疾病或未經過檢測而造成的部分數據缺失;一些傳感器設備的故障造成的信息缺失,等等。這些在實際生活中面臨的切實問題不可避免,并且已經成為亟待解決的數據質量題。
故為了解決數據缺失值預測的問題,今天我們嘗試使用Gain算法訓練深度學習模型,對其缺少的數據進行匹配性的預測,得到的訓練均方根誤差如下圖可見,代碼放置文末:
常用缺失值處理方法
1.1 基于傳統統計學的方法
數據填補問題最早可歸類于統計學領域,其方法又可分為單一填補法和多重填補法。常用的單一填補法如均值填補法、眾數填補法、熱卡填補法、冷卡填補法、回歸填補法等。
均值填補是利用缺失值所在屬性列中存在值的均值填補,在該屬性列中填補的缺失值都相等。均值填補法是針對數值型數據,而眾數填補是針對離散型數據,使用不完整屬性列中存在值的眾數填補該列中的缺失值。均值填補和眾數填補雖然簡便,但是使填補值缺少了隨機性,損失了大量數據信息。
1.2 基于模型的方法
高斯混合模型是基于模型的填補方法的代表性方法,其求解通常采用 EM 算法,因此也被稱為 EM 填補法。EM 填補法假設數據集服從多元正態分布,且數據缺失為任意缺失模式,通過迭代模型和填補值的方式填補。
1.3 基于機器學習的方法
機器學習學科內有已經有多種方法被拓展在數據填補上,常見的包括 K 近鄰填補法、基于聚類的填補法、基于決策樹的填補法、基于神經網絡的填補法等。KNN 算法在機器學習內比較適用于數據的分類,算法從帶有標簽的數據庫內選取離待測試樣本最近鄰的 K 個樣本,通過統計 K 個最近鄰樣本的標簽來標識測試樣本的類別。樣本之間的距離通常選取歐式距離、曼哈頓距離、閔可夫斯基距離等距離公式。KNN 算法用于填補數據,通常會改進樣本之間距離的計算公式,使其可以表示不完整樣本和完整樣本之間的距離。KNN 填補法通過選取和不完整樣本最近鄰的 K 個完整樣本,通過加權平均完整樣本的屬性值填補相應的缺失值。
基于神經網絡的填補法更是多種多樣,其常用的網絡結構包括多層感知機、廣義回歸神經網絡、自組織映射神經網絡、多任務學習網絡等,每一種網絡都可以用來填補缺失值。
而本文使用的Gain算法就歸屬于神經網絡中的一種,是基于GAN網絡的框架生成缺失數據。
其中系統流程圖如下:
項目搭建
Gain算法是由GAN網絡推廣而來,其中生成器用來準確估算缺失數據,判別器為判別預測值和真實值之間的誤差,從而更新生成器和判別器的參數。同樣按照GAN網絡基本原則,其基本目標為尋找納什平衡點,使其生成器和判別器loss相同得到最佳結果。項目整體過程分為數據集準備、數據處理、以及網絡結構搭建和模型訓練,具體介紹如下:
2.1 訓練數據集
這里使用的數據集為開源的UCI Spam數據和UCI Letter數據集,數據集內容如下:
2.2 數據處理
按照數據集的不同,讀取對應數據集,然后將其中為0的值填充為nan,為后續預測和模型訓練做基本處理,對應data_loader函數。然后對數據做基本的標準化處理,核心代碼如下:
def normalization (data, parameters=None): _, dim = data.shape norm_data = data.copy() if parameters is None: min_val = np.zeros(dim) max_val = np.zeros(dim) for i in range(dim): min_val[i] = np.nanmin(norm_data[:,i]) norm_data[:,i] = norm_data[:,i] - np.nanmin(norm_data[:,i]) max_val[i] = np.nanmax(norm_data[:,i]) norm_data[:,i] = norm_data[:,i] / (np.nanmax(norm_data[:,i]) + 1e-6) norm_parameters = {'min_val': min_val, 'max_val': max_val} else: min_val = parameters['min_val'] max_val = parameters['max_val'] for i in range(dim): norm_data[:,i] = norm_data[:,i] - min_val[i] norm_data[:,i] = norm_data[:,i] / (max_val[i] + 1e-6) norm_parameters = parameters return norm_data, norm_parameters
2.3 模型搭建
按照Gain算法基本架構,分別構建生成器generator和判別器discriminator,然后按照偽代碼過程搭建架構。
其中偽代碼如下:
def generator(x,m): inputs = tf.concat(values = [x, m], axis = 1) G_h1 = tf.nn.relu(tf.matmul(inputs, G_W1) + G_b1) G_h2 = tf.nn.relu(tf.matmul(G_h1, G_W2) + G_b2) G_prob = tf.nn.sigmoid(tf.matmul(G_h2, G_W3) + G_b3) return G_probdef discriminator(x, h): inputs = tf.concat(values = [x, h], axis = 1) D_h1 = tf.nn.relu(tf.matmul(inputs, D_W1) + D_b1) D_h2 = tf.nn.relu(tf.matmul(D_h1, D_W2) + D_b2) D_logit = tf.matmul(D_h2, D_W3) + D_b3 D_prob = tf.nn.sigmoid(D_logit) return D_probX = tf.placeholder(tf.float32, shape = [None, dim])M = tf.placeholder(tf.float32, shape = [None, dim])H = tf.placeholder(tf.float32, shape = [None, dim])D_W1 = tf.Variable(xavier_init([dim*2, h_dim])) D_b1 = tf.Variable(tf.zeros(shape = [h_dim]))D_W2 = tf.Variable(xavier_init([h_dim, h_dim]))D_b2 = tf.Variable(tf.zeros(shape = [h_dim]))D_W3 = tf.Variable(xavier_init([h_dim, dim]))D_b3 = tf.Variable(tf.zeros(shape = [dim])) theta_D = [D_W1, D_W2, D_W3, D_b1, D_b2, D_b3]G_W1 = tf.Variable(xavier_init([dim*2, h_dim])) G_b1 = tf.Variable(tf.zeros(shape = [h_dim]))G_W2 = tf.Variable(xavier_init([h_dim, h_dim]))G_b2 = tf.Variable(tf.zeros(shape = [h_dim]))G_W3 = tf.Variable(xavier_init([h_dim, dim]))G_b3 = tf.Variable(tf.zeros(shape = [dim]))theta_G = [G_W1, G_W2, G_W3, G_b1, G_b2, G_b3]
完整代碼:
鏈接:https://pan.baidu.com/s/1EdlmEx7lXsGKMm8DQR4lZA
提取碼:yeyz
李秋鍵,CSDN博客專家,CSDN達人課作者。碩士在讀于中國礦業大學,開發有taptap競賽獲獎等。
*博客內容為網友個人發布,僅代表博主個人觀點,如有侵權請聯系工作人員刪除。