自制數據挖掘工具分析北京房價 (二) 數據清洗


 

         上一節我們通過爬蟲工具爬取了近七萬條二手房數據,那么這一節就對這些數據進行預處理,也就是所謂的ETL(Extract-Transform-Load)

 

    一.ETL工具的必要性

          數據分析的前提是數據清洗。不論如何高大上的算法,遇到錯誤數據,一個異常拋出來,絕對屍橫遍野。而你不能指望核心算法為你處理錯誤或者短缺的數據。所以,數據清洗(ETL)就變得必不可少了。 如果數據分析是炒菜階段,那么清洗就是洗菜,絕對是非常重要的一環。  

          而實際上,ETL工具可以很簡單,也可以很復雜。簡單到只需要把字符串轉換為數字或者提供正則表達式。而復雜的ETL需要建立完整的錯誤日志機制,智能處理,自動匯總,還要做成工作流,腳本等復雜的形式。我決定做一個折中,提供最需要和差不多夠用的功能。如果真有對ETL特別強烈而復雜的需求,那就只能借助專業的ETL工具了。

    二.ETL插件

在本系統中,ETL以插件的形式存在,可供系統進行調用。這些ETL工具包括了常見的場景:

  • 正則表達式提取
  • 數據類型轉換,包括時間格式等
  • 隨機數和范圍數生成
  • 數據分割,排序和篩選
  • 噪聲生成
  • 字符串轉數字編號
  • 腳本數據
  • 高級的模塊 如 分詞,文本情感分析等

同時所有的模塊都可以支持二次擴展。可為了新的場景增加新的模塊。 模塊分為兩類:

  • 無監督工具:不需要之前的數據,直接生成新數據,如噪聲產生器
  • 有監督工具:需根據之前的數據生成,如正則提取

這些ETL插件可以形成一個處理隊列,以隊列的形式依次處理數據,形成職責鏈。這樣就能應對絕大多數的ETL需求。

    三. 使用介紹

下面,我們就以北京房價樣例數據為例,進行ETL清洗。這些數據爬蟲來自於網絡,具體的爬取過程可參考前一節內容。

1. 數據導入和觀察

首先在數據管理器上點擊“導入”按鈕,導入XML數據文件,如下圖所示:

image

之后可以普通列表的形式,查看這些數據:

image

會發現這些數據非常有規律。我們可制定如下方案:

  1.   篩選出正常的數據,因為有些數據是殘缺的,比如“面積”一欄是空的。
  2.   其價格是XXXXX元/平米,為了進行統計,需要通過正則進行提取
  3.   “屬性3” 樓層數,可通過/ ,進行分割,取第二個項就好,最后一項是板樓或塔樓
  4.   在“屬性3”中,可通過正則匹配提取年份
  5.   可在“坐標”一項中,通過分割,方便地提取編號,地理位置,所在小區和其他信息。
  6.    其他…

           2.編寫數據篩選腳本

             首先進行數據篩選,將“數據篩選”插件拖入算法框中:

image

        同時進行配置,為了方便,我們僅提取前1000條數據作為分析目標。

  image

         最重要的是,編寫篩選的自定義函數腳本。與C#的語法相同:

       image

        點擊開始處理,即可篩選出滿足條件的前1000條數據。

     3.進行ETL配置:

          與上一步類似,將“數據生成與預處理”模塊拖到算法管理器中。

         將該模塊的數據源,選為“全部”:

         image

         點擊命令列,可對ETL所需的插件進行配置:

image

      集合編輯器中,列舉了系統加載的所有ETL插件,我們首先將價格提取出來:

     image

     選擇原始列名,填入新列名,如果不勾選“添加到新列”,則原始數據就會被覆蓋。同時填寫正則表達式 \d+ ,用於提取價格中的房價。同時,將目標類型選擇為INT,轉換完成后,數據的類型就會變為INT

     類似的,可提取建設年份。

image

      由於轉換后,建設年份為STRING類型,可再添加一個字符串轉時間的工具,方便轉換為DateTime,直接將原有的數據覆蓋就好。

     image

     接下來提取地理坐標: 觀察這些坐標,同樣可以使用正則匹配,此處從略。

     接下來是所在的片區,它位於“坐標”這一屬性中。使用正則匹配並不方便,因此采用數列分割的方法,即通過字符對該屬性進行分割,提取出固定位置的項。通過觀察, 可通過符號,進行分割,正好位於第4項

   image

   類似的,可以提取小區名稱,與所在行政區的唯一區別在於匹配編號,要填2

   最終完成的ETL流程如下圖所示:

image

    這些ETL插件會順次執行。如果一個插件的結果依賴於前一個插件,則一定要排在依賴插件的后邊

    之后點擊開始處理,ETL流程即可啟動,所有的錯誤日志都會保存到一個專門的數據集中,用於再次分析和處理。這次處理沒有錯誤,系統提示ETL流程成功結束,下面就是經過ETL后得到的新列

image

 

   為了保險起見,我們將這次加載的所有設置保存為一個任務,名字為”ETL清洗任務”,如果遇到同樣的數據,可以進行相同的任務,而無需進行再次配置。

image

    可以在生成的系統配置文件中,看到此次任務所保存的XML文件:

<Doc Name="ETL數據清洗任務" Description="任務描述" Group=""> 
  <Nodes> 
    <Children X="-2.01" Y="0" Z="0" Group="0" Key="數據篩選_1" Weight="1"> 
      <Data Collection="全部" Name="數據篩選" NewDataSetName="" ScriptCode="return String.IsNullOrEmpty(item['價格']) ;  // 1表示篩選該數據,否則表示不篩選" CanRemove="True" Start="0" End="1000" Layer="0" /> 
    </Children> 
    <Children X="3" Y="0" Z="0" Group="1" Key="數據生成和預處理_2" Weight="1"> 
      <Data Collection="全部" Name="數據生成和預處理" Size="1001" Layer="0"> 
        <Children Type="正則過濾器" CollumName="價格" NewCollumName="新價格" IsAddNewCollum="True" TargetDataType="INT" ScriptCode="\d+" Index="0" /> 
        <Children Type="正則過濾器" CollumName="屬性3" NewCollumName="年份" IsAddNewCollum="True" TargetDataType="STRING" ScriptCode="\d{4}" Index="0" /> 
        <Children Type="字符串轉時間" CollumName="年份" NewCollumName="" IsAddNewCollum="False" TargetDataType="DATETIME" Format="yyyy" /> 
        <Children Type="數列分割" CollumName="坐標" NewCollumName="片區" IsAddNewCollum="True" TargetDataType="STRING" SplitChar="," Index="3" SplitPause="SplitPause" /> 
        <Children Type="數列分割" CollumName="坐標" NewCollumName="小區名" IsAddNewCollum="True" TargetDataType="STRING" SplitChar="," Index="2" SplitPause="SplitPause" /> 
        <Children Type="正則過濾器" CollumName="坐標" NewCollumName="lag" IsAddNewCollum="True" TargetDataType="DOUBLE" ScriptCode="\d{2}.\d+" Index="0" /> 
        <Children Type="正則過濾器" CollumName="坐標" NewCollumName="Lng" IsAddNewCollum="True" TargetDataType="DOUBLE" ScriptCode="\d{3}.\d+" Index="0" /> 
      </Data> 
    </Children> 
  </Nodes> 
  <Paths /> 
</Doc> 

     

 

        三.總結

          本節主要介紹了如何使用該工具進行ETL清洗,下一節我們將正式進入數據分析的流程。敬請期待。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM