11 | 數(shù)據(jù)科學(xué)家80%時間都花費在了這些清洗任務(wù)上?
在數(shù)據(jù)挖掘中,數(shù)據(jù)清洗就是這樣的前期準(zhǔn)備工作欢峰。對于數(shù)據(jù)科學(xué)家來說,我們會遇到各種各樣的數(shù)據(jù)涨共,在分析前纽帖,要投入大量的時間和精力把數(shù)據(jù)“整理裁剪”成自己想要或需要的樣子。
數(shù)據(jù)清洗規(guī)則總結(jié)為以下 4 個關(guān)鍵點举反,統(tǒng)一起來叫“完全合一”懊直。
- 完整性:單條數(shù)據(jù)是否存在空值,統(tǒng)計的字段是否完善照筑。
- 全面性:觀察某一列的全部數(shù)值吹截,比如在 Excel 表中,我們選中一列凝危,可以看到該列的平均值波俄、最大值、最小值蛾默。我們可以通過常識來判斷該列是否有問題懦铺,比如:數(shù)據(jù)定義、單位標(biāo)識支鸡、數(shù)值本身冬念。
- 合法性:數(shù)據(jù)的類型、內(nèi)容牧挣、大小的合法性急前。比如數(shù)據(jù)中存在非 ASCII 字符,性別存在了未知瀑构,年齡超過了 150 歲等裆针。
- 唯一性:數(shù)據(jù)是否存在重復(fù)記錄,因為數(shù)據(jù)通常來自不同渠道的匯總,重復(fù)的情況是常見的世吨。行數(shù)據(jù)澡刹、列數(shù)據(jù)都需要是唯一的,比如一個人不能重復(fù)記錄多次耘婚,且一個人的體重也不能在列指標(biāo)中重復(fù)記錄多次罢浇。
解決問題
使用Pandas工具
1.完整性°宓唬可以采用以下三種方法:刪除:刪除數(shù)據(jù)缺失的記錄嚷闭;均值:使用當(dāng)前列的均值;高頻:使用當(dāng)前列出現(xiàn)頻率最高的數(shù)據(jù)戈轿;使用 dropna() 進行處理凌受,刪除空行。
df['Age'].fillna(df['Age'].mean(), inplace=True)
age_maxf = train_features['Age'].value_counts().index[0] #取頻率最高的數(shù)據(jù)
train_features['Age'].fillna(age_maxf, inplace=True)
- 全面性問題:列數(shù)據(jù)的單位不統(tǒng)一觀察 weight 列的數(shù)值思杯,我們能發(fā)現(xiàn) weight 列的單位不統(tǒng)一胜蛉。有的單位是千克(kgs),有的單位是磅(lbs)色乾。這里我使用千克作為統(tǒng)一的度量單位誊册,將磅(lbs)轉(zhuǎn)化為千克(kgs):
# 獲取 weight 數(shù)據(jù)列中單位為 lbs 的數(shù)據(jù)
rows_with_lbs = df['weight'].str.contains('lbs').fillna(False)
print df[rows_with_lbs]
# 將 lbs轉(zhuǎn)換為 kgs, 2.2lbs=1kgs
for i,lbs_row in df[rows_with_lbs].iterrows():
# 截取從頭開始到倒數(shù)第三個字符之前,即去掉lbs暖璧。
weight = int(float(lbs_row['weight'][:-3])/2.2)
df.at[i,'weight'] = '{}kgs'.format(weight)
- 合理性問題:非 ASCII 字符我們可以看到在數(shù)據(jù)集中 Fristname 和 Lastname 有一些非 ASCII 的字符案怯。我們可以采用刪除或者替換的方式來解決非 ASCII 問題,這里我們使用刪除方法:
# 刪除非 ASCII 字符
df['first_name'].replace({r'[^\x00-\x7F]+':''}, regex=True, inplace=True)
df['last_name'].replace({r'[^\x00-\x7F]+':''}, regex=True, inplace=True)
- 唯一性問題 1:一列有多個參數(shù)在數(shù)據(jù)中不難發(fā)現(xiàn)澎办,姓名列(Name)包含了兩個參數(shù) Firtname 和 Lastname嘲碱。為了達(dá)到數(shù)據(jù)整潔目的,我們將 Name 列拆分成 Firstname 和 Lastname 兩個字段局蚀。我們使用 Python 的 split 方法麦锯,str.split(expand=True),將列表拆成新的列琅绅,再將原來的 Name 列刪除扶欣。
# 切分名字,刪除源數(shù)據(jù)列
df[['first_name','last_name']] = df['name'].str.split(expand=True)
df.drop('name', axis=1, inplace=True)
問題 2:重復(fù)數(shù)據(jù)我們校驗一下數(shù)據(jù)中是否存在重復(fù)記錄千扶。如果存在重復(fù)記錄料祠,就使用 Pandas 提供的 drop_duplicates() 來刪除重復(fù)數(shù)據(jù)。
# 刪除重復(fù)數(shù)據(jù)行
df.drop_duplicates(['first_name','last_name'],inplace=True)
12 | 數(shù)據(jù)集成:這些大號一共20億粉絲澎羞?
數(shù)據(jù)挖掘前髓绽,需要的數(shù)據(jù)往往分布在不同的數(shù)據(jù)源中,需要考慮字段表達(dá)是否一樣妆绞,以及屬性是否冗余顺呕。
數(shù)據(jù)集成的兩種架構(gòu):ELT 和 ETL
ETL 是英文 Extract接谨、Transform 和 Load 的縮寫,包括了數(shù)據(jù)抽取塘匣、轉(zhuǎn)換、加載三個過程巷帝。
ETL 的過程為提取 (Extract)——轉(zhuǎn)換 (Transform)——加載 (Load)忌卤,在數(shù)據(jù)源抽取后首先進行轉(zhuǎn)換,然后將轉(zhuǎn)換的結(jié)果寫入目的地楞泼。當(dāng)前的主流驰徊。
ELT 的過程則是提取 (Extract)——加載 (Load)——變換 (Transform),在抽取后將結(jié)果先寫入目的地堕阔,然后利用數(shù)據(jù)庫的聚合分析能力或者外部計算框架棍厂,如 Spark 來完成轉(zhuǎn)換的步驟。以后應(yīng)用會越來越多超陆。
ETL工具的使用
- Kettle
- 阿里開源軟件:DataX
- Apache 開源軟件:Sqoop
13 | 數(shù)據(jù)變換:考試成績要求正態(tài)分布合理么牺弹?
數(shù)據(jù)變換:讓不同渠道的數(shù)據(jù)統(tǒng)一到一個目標(biāo)數(shù)據(jù)庫里。作用:讓數(shù)據(jù)滿足一定的規(guī)律时呀,達(dá)到規(guī)范性的要求张漂,便于進行挖掘。在數(shù)據(jù)變換前谨娜,先對字段進行篩選航攒,然后對數(shù)據(jù)進行探索和相關(guān)性分析,接著是選擇算法模型(這里暫時不需要進行模型計算)趴梢,然后針對算法模型對數(shù)據(jù)的需求進行數(shù)據(jù)變換漠畜,從而完成數(shù)據(jù)挖掘前的準(zhǔn)備工作。
常見的變換方法:
- 數(shù)據(jù)平滑:去除數(shù)據(jù)中的噪聲坞靶,將連續(xù)數(shù)據(jù)離散化憔狞。這里可以采用分箱、聚類和回歸的方式進行數(shù)據(jù)平滑滩愁,我會在后面給你講解聚類和回歸這兩個算法躯喇;
- 數(shù)據(jù)聚集:對數(shù)據(jù)進行匯總,在 SQL 中有一些聚集函數(shù)可以供我們操作硝枉,比如 Max() 反饋某個字段的數(shù)值最大值廉丽,Sum() 返回某個字段的數(shù)值總和;
- 數(shù)據(jù)概化:將數(shù)據(jù)由較低的概念抽象成為較高的概念妻味,減少數(shù)據(jù)復(fù)雜度正压,即用更高的概念替代更低的概念。比如說上海责球、杭州焦履、深圳拓劝、北京可以概化為中國。
- 數(shù)據(jù)規(guī)范化:使屬性數(shù)據(jù)按比例縮放嘉裤,這樣就將原來的數(shù)值映射到一個新的特定區(qū)域中郑临。常用的方法有最小—最大規(guī)范化、Z—score 規(guī)范化屑宠、按小數(shù)定標(biāo)規(guī)范化等厢洞,我會在后面給你講到這些方法的使用;
- 屬性構(gòu)造:構(gòu)造出新的屬性并添加到屬性集中典奉。這里會用到特征工程的知識躺翻,因為通過屬性與屬性的連接構(gòu)造新的屬性,其實就是特征工程卫玖。比如說公你,數(shù)據(jù)表中統(tǒng)計每個人的英語、語文和數(shù)學(xué)成績假瞬,你可以構(gòu)造一個“總和”這個屬性陕靠,來作為新屬性。這樣“總和”這個屬性就可以用到后續(xù)的數(shù)據(jù)挖掘計算中脱茉。
在這些變換方法中懦傍,最簡單易用的就是對數(shù)據(jù)進行規(guī)范化處理。下面我來給你講下如何對數(shù)據(jù)進行規(guī)范化處理芦劣。
數(shù)據(jù)規(guī)范化的幾種方法
1. Min-max 規(guī)范化
Min-max 規(guī)范化方法是將原始數(shù)據(jù)變換到 [0,1] 的空間中粗俱。用公式表示就是:新數(shù)值 =(原數(shù)值 - 極小值)/(極大值 - 極小值)。
2. Z-Score 規(guī)范化
假設(shè) A 與 B 的考試成績都為 80 分虚吟,A 的考卷滿分是 100 分(及格 60 分)寸认,B 的考卷滿分是 500 分(及格 300 分)。雖然兩個人都考了 80 分串慰,但是 A 的 80 分與 B 的 80 分代表完全不同的含義偏塞。那么如何用相同的標(biāo)準(zhǔn)來比較 A 與 B 的成績呢?Z-Score 就是用來可以解決這一問題的邦鲫。我們定義:新數(shù)值 =(原數(shù)值 - 均值)/ 標(biāo)準(zhǔn)差灸叼。假設(shè) A 所在的班級平均分為 80,標(biāo)準(zhǔn)差為 10庆捺。B 所在的班級平均分為 400古今,標(biāo)準(zhǔn)差為 100。那么 A 的新數(shù)值 =(80-80)/10=0滔以,B 的新數(shù)值 =(80-400)/100=-3.2捉腥。那么在 Z-Score 標(biāo)準(zhǔn)下,A 的成績會比 B 的成績好你画。我們能看到 Z-Score 的優(yōu)點是算法簡單抵碟,不受數(shù)據(jù)量級影響桃漾,結(jié)果易于比較。不足在于拟逮,它需要數(shù)據(jù)整體的平均值和方差撬统,而且結(jié)果沒有實際意義,只是用于比較敦迄。
3. 小數(shù)定標(biāo)規(guī)范化
小數(shù)定標(biāo)規(guī)范化就是通過移動小數(shù)點的位置來進行規(guī)范化宪摧。小數(shù)點移動多少位取決于屬性 A 的取值中的最大絕對值。舉個例子颅崩,比如屬性 A 的取值范圍是 -999 到 88,那么最大絕對值為 999蕊苗,小數(shù)點就會移動 3 位沿后,即新數(shù)值 = 原數(shù)值 /1000。那么 A 的取值范圍就被規(guī)范化為 -0.999 到 0.088朽砰。
工具:Python 的 sklearn 庫
SciKit-Learn 不僅可以用于數(shù)據(jù)變換尖滚,它還提供了分類、聚類瞧柔、預(yù)測等數(shù)據(jù)挖掘算法的 API 封裝漆弄。后面我會詳細(xì)給你講解這些算法,也會教你如何使用 SciKit-Learn 工具來完成數(shù)據(jù)挖掘算法的工作造锅。