用Python玩转统计数据:取样、计算相关性、拆分训练模型和测试
導(dǎo)讀:本文會(huì)介紹一些技術(shù),幫你更好地理解數(shù)據(jù),以及探索特征之間的關(guān)系。
本文使用Python建立對(duì)數(shù)據(jù)的理解。我們會(huì)分析變量的分布,捋清特征之間的關(guān)系。最后,你會(huì)學(xué)習(xí)給樣本分層,并將數(shù)據(jù)集拆分成測(cè)試集與訓(xùn)練集。
作者:托馬茲·卓巴斯(Tomasz Drabas)
如需轉(zhuǎn)載請(qǐng)聯(lián)系大數(shù)據(jù)(ID:hzdashuju)
01 生成描述性的統(tǒng)計(jì)數(shù)據(jù)
要完全理解任何隨機(jī)變量的分布,我們需要知道其平均數(shù)與標(biāo)準(zhǔn)差、最小值與最大值、中位數(shù)、四分位數(shù)、偏度和峰度。
1. 準(zhǔn)備
要實(shí)踐本技巧,你只需裝好pandas模塊。此外沒有要求了。
2. 怎么做
下面的代碼可以快速達(dá)成對(duì)數(shù)據(jù)的初步理解。假設(shè)數(shù)據(jù)已從CSV文件讀出,并存于csv_read變量(data_describe.py文件)中:
[
'beds',?'baths',?'sq_tf',?'price',?'s_price',
'n_price',?'s_sq__ft',?'n_sq__ft',?'b_price',
'p_price',?'d_Condo',?'d_Multi-Family',
'd_Residential',?'d_Unkown'
]
].describe().transpose()
#?加上偏度,眾數(shù)與峰度
csv_desc['skew']?=?csv_read.skew(numeric_only=True)
csv_desc['mode']?=?csv_read.mode(numeric_only=True).transpose()
csv_desc['kurtosis']?=?csv_read.kurt(numeric_only=True)
3. 原理
pandas有個(gè)很管用的.describe()方法,它替我們做了大部分的工作。這個(gè)方法能生成我們想要的大部分描述變量;輸出看起來是這樣的(為清晰做了相應(yīng)簡化):
count?981.000000
mean?2.914373
std?1.306502
min?0.000000
25%?2.000000
50%?3.000000
75%?4.000000
max?8.000000
DataFrame對(duì)象的索引標(biāo)明了描述性統(tǒng)計(jì)數(shù)據(jù)的名字,每一列代表我們數(shù)據(jù)集中一個(gè)特定的變量。不過,我們還缺偏度、峰度和眾數(shù)。為了更方便地加入csv_desc變量,我們使用.transpose()移項(xiàng)了.describe()方法的輸出結(jié)果,使得變量放在索引里,每一列代表描述性的變量。
你也可以手動(dòng)計(jì)算平均數(shù)、標(biāo)準(zhǔn)差及其他描述性的統(tǒng)計(jì)數(shù)據(jù)。可用的方法列表見:
http://pandas.pydata.org/pandas-docs/stable/api.html#api-dataframe-stats
有了基礎(chǔ)的統(tǒng)計(jì)數(shù)據(jù),我們可以補(bǔ)上其他的。要留意的是,.skew(...)和.kurt(...)方法以類似的格式返回?cái)?shù)據(jù),而.mode(...)不然;.mode(...)方法返回的數(shù)據(jù)要進(jìn)行調(diào)整,以便和.describe()方法的輸出格式保持一致。
4. 更多
描述性的統(tǒng)計(jì)數(shù)據(jù)也可用SciPy和NumPy計(jì)算得到。當(dāng)然,比起pandas來不那么直觀(data_describe_alternative.py文件)。
首先加載兩個(gè)模塊。
import?bumpy?as?np
然后從CSV文件讀取數(shù)據(jù):
csv_read?=?np.genfromtxt(
r_filenameCSV,
delimiter=',',
names=True,
#?只有數(shù)字列
usecols=[4,5,6,8,11,12,13,14,15,16,17,18,19,20]
)
.genfromtxt(...)方法以文件名作為第一個(gè)(也是唯一必需的)參數(shù)。指定分隔符是一個(gè)好做法;本例中分隔符是',',也可以是\t。names參數(shù)指定為True,意味著變量名存于第一行。最后,usecols參數(shù)指定文件中哪些列要存進(jìn)csv_read對(duì)象。
最終可以計(jì)算出要求的數(shù)據(jù):
.genfromtxt(...)方法創(chuàng)建的數(shù)據(jù)是一系列元組。.describe(...)方法只接受列表形式的數(shù)據(jù),所以得先(使用列表表達(dá)式)將每個(gè)元組轉(zhuǎn)換成列表。
這個(gè)方法的輸出可以說對(duì)用戶不太友好:
5. 參考
查閱SciPy中的文檔,了解所有統(tǒng)計(jì)函數(shù):
http://docs.scipy.org/doc/scipy/reference/stats.html#statistical-functions
02 探索特征之間的相關(guān)性
兩個(gè)變量之間的相關(guān)系數(shù)用來衡量它們之間的關(guān)系。系數(shù)為1,我們可以說這兩個(gè)變量完全相關(guān);系數(shù)為-1,我們可以說第二個(gè)變量與第一個(gè)變量完全負(fù)相關(guān);系數(shù)0意味著兩者之間不存在可度量的關(guān)系。
這里要強(qiáng)調(diào)一個(gè)基礎(chǔ)事實(shí):不能因?yàn)閮蓚€(gè)變量是相關(guān)的,就說兩者之間存在因果關(guān)系。
要了解更多,可訪問:
https://web.cn.edu/kwheeler/logic_causation.html
1. 準(zhǔn)備
要實(shí)踐本技巧,你要先裝好pandas模塊。此外沒有要求了。
2. 怎么做
我們將測(cè)算公寓的臥室數(shù)目、浴室數(shù)目、樓板面積與價(jià)格之間的相關(guān)性。再一次,我們假設(shè)數(shù)據(jù)已經(jīng)在csv_read對(duì)象中了。下面是代碼(data_correlations.py文件):
coefficients?=?['pearson',?'kendall',?'spearman']
csv_corr?=?{}
for?coefficient?in?coefficients:
csv_corr[coefficient]?=?csv_read.corr(method=coefficient).transpose()
3. 原理
pandas可用于計(jì)算三種相關(guān)度:皮爾遜積矩相關(guān)系數(shù)、肯達(dá)爾等級(jí)相關(guān)系數(shù)和斯皮爾曼等級(jí)相關(guān)系數(shù)。后兩者對(duì)于非正態(tài)分布的隨機(jī)變量并不是很敏感。
我們計(jì)算這三種相關(guān)系數(shù),并且將結(jié)果存在csv_corr變量中。DataFrame對(duì)象csv_read調(diào)用了.corr(...)方法,唯一要指定的參數(shù)是要使用的計(jì)算方法。結(jié)果如下所示:
4. 參考
你也可以使用NumPy計(jì)算皮爾遜相關(guān)系數(shù):
http://docs.scipy.org/doc/numpy/reference/generated/numpy.corrcoef.html
03 數(shù)據(jù)取樣
有時(shí)候數(shù)據(jù)集過大,不方便建立模型。出于實(shí)用的考慮(不要讓模型的估計(jì)沒有個(gè)盡頭),最好從完整的數(shù)據(jù)集中取出一些分層樣本。
本文從MongoDB讀取數(shù)據(jù),用Python取樣。
1. 準(zhǔn)備
要實(shí)踐本技巧,你需要PyMongo、pandas和NumPy。其他沒有什么要準(zhǔn)備的。
2. 怎么做
有兩種做法:確定一個(gè)抽樣的比例(比如說,20%),或者確定要取出的記錄條數(shù)。下面的代碼展示了如何提取一定比例的數(shù)據(jù)(data_sampling.py文件):
client?=?pymongo.MongoClient()
db?=?client['packt']
real_estate?=?db['real_estate']
#?讀取數(shù)據(jù)
sales?=?pd.DataFrame.from_dict(
list(?real_estate.find(
{'beds':?{'$in':?[2,?3,?4]}?},
{'_id':?0,?'zip':?1,?'city':?1,?'price':?1,?'beds':?1,?'sq__ft':?1}
)
)
)
#?取樣
sample?=?pd.DataFrame()
for?bed?in?[2,?3,?4]:
sample?=?sample.append(
sales[sales.beds?==?bed].sample(frac=strata_frac),
ignore_index=True
)
3. 原理
首先確定取樣的比例,即strata_frac變量。從MongoDB取出數(shù)據(jù)。MongoDB返回的是一個(gè)字典。pandas的.from_dict(...)方法生成一個(gè)DataFrame對(duì)象,這樣處理起來更方便。
要獲取數(shù)據(jù)集中的一個(gè)子集,pandas的.sample(...)方法是一個(gè)很方便的途徑。不過這里還是有一個(gè)陷阱:所有的觀測(cè)值被選出的概率相同,可能我們得到的樣本中,變量的分布并不能代表整個(gè)數(shù)據(jù)集。
在這個(gè)簡單的例子中,為了避免前面的陷阱,我們遍歷臥室數(shù)目的取值,用.sample(...)方法從這個(gè)子集中取出一個(gè)樣本。我們可以指定frac參數(shù),以返回?cái)?shù)據(jù)集子集(臥室數(shù)目)的一部分。
我們還使用了DataFrame的.append(...)方法:有一個(gè)DataFrame對(duì)象(例子中的sample),將另一個(gè)DataFrame附加到這一個(gè)已有的記錄后面。ignore_index參數(shù)設(shè)為True時(shí),會(huì)忽略附加DataFrame的索引值,并沿用原有DataFrame的索引值。
4. 更多
有時(shí),你會(huì)希望指定抽樣的數(shù)目,而不是占原數(shù)據(jù)集的比例。之前說過,pandas的 .sample(...)方法也能很好地處理這種場(chǎng)景(data_sampling_alternative.py文件)。
首先,我們指定要從原數(shù)據(jù)集中抽樣的記錄數(shù)目:
要保持不同臥室數(shù)目的取值比例與原數(shù)據(jù)集一致,我們首先計(jì)算每個(gè)桶中該放的記錄數(shù):
strata_expected_counts?=?sales['beds'].value_counts()?/?ttl_cnt?*?strata_cnt
DataFrame的.count()方法會(huì)計(jì)算整個(gè)數(shù)據(jù)集中的總數(shù)目。然后,我們可以分別計(jì)算出各臥室數(shù)目下的比例,乘上strata_cnt變量,就得到了各自的記錄條數(shù)。.value_counts()方法返回的是指定列(例子中的beds)中,每個(gè)值的數(shù)目。然后將數(shù)據(jù)集中每條記錄除以ttl_cnt再乘以想要的樣本大小。
抽樣可以使用.sample(...)方法。不過,我們這次不指定frac參數(shù)了,而是指定要提取的記錄數(shù)n:
sample?=?sample.append(
sales[sales.beds?==?bed]?\
.sample(n=np.round(strata_expected_counts[bed])),
ignore_index=True
)
04 將數(shù)據(jù)集拆分成訓(xùn)練集、交叉驗(yàn)證集和測(cè)試集
要建立一個(gè)可信的統(tǒng)計(jì)模型,我們需要確信它精確地抽象出了我們要處理的現(xiàn)象。要獲得這個(gè)保證,我們需要測(cè)試模型。要保證精確度,我們訓(xùn)練和測(cè)試不能用同樣的數(shù)據(jù)集。
本技法中,你會(huì)學(xué)到如何將你的數(shù)據(jù)集快速分成兩個(gè)子集:一個(gè)用來訓(xùn)練模型,另一個(gè)用來測(cè)試。
1. 準(zhǔn)備
要實(shí)踐本技巧,你需要pandas、SQLAlchemy和NumPy。其他沒有什么要準(zhǔn)備的。
2. 怎么做
我們從PostgreSQL數(shù)據(jù)庫讀出數(shù)據(jù),存到DataFrame里。通常我們劃出20%~40%的數(shù)據(jù)用于測(cè)試。本例中,我們選出1/3的數(shù)據(jù)(data_split.py文件):
test_size?=?0.33
#?輸出樣本的文件名
w_filenameTrain?=?'../../Data/Chapter02/realEstate_train.csv'
w_filenameTest?=?'../../Data/Chapter02/realEstate_test.csv'
#?用一個(gè)變量標(biāo)記訓(xùn)練樣本
data['train']?=?np.random.rand(len(data))?<?(1?-?test_size)
#?區(qū)分訓(xùn)練集和測(cè)試集
train?=?data[data.train]
test?=?data[~data.train]
3. 原理
我們從指定劃分?jǐn)?shù)據(jù)的比例與存儲(chǔ)數(shù)據(jù)的位置開始:兩個(gè)存放訓(xùn)練集和測(cè)試集的文件。
我們希望隨機(jī)選擇測(cè)試數(shù)據(jù)。這里,我們使用NumPy的偽隨機(jī)數(shù)生成器。.rand(...)方法生成指定長度(len(data))的隨機(jī)數(shù)的列表。生成的隨機(jī)數(shù)在0和1之間。
接著我們將這些數(shù)字與要?dú)w到訓(xùn)練集的比例(1-test_size)進(jìn)行比較:如果數(shù)字小于比例,我們就將記錄放在訓(xùn)練集(train屬性的值為True)中;否則就放到測(cè)試集中(train屬性的值為False)。
最后兩行將數(shù)據(jù)集拆成訓(xùn)練集和測(cè)試集。~是邏輯運(yùn)算“否”的運(yùn)算符;這樣,如果train屬性為False,那么“否”一下就成了True。
4. 更多
SciKit-learn提供了另一種拆分?jǐn)?shù)據(jù)集的方法。我們先將原始的數(shù)據(jù)集分成兩塊,一塊是因變量y,一塊是自變量x:
x?=?data[['zip',?'beds',?'sq__ft']]
y?=?data['price']
然后就可以拆了:
x_train,?x_test,?y_train,?y_test?=?sk.train_test_split(
x,?y,?test_size=0.33,?random_state=42)
.train_test_split(...)方法幫我們將數(shù)據(jù)集拆成互補(bǔ)的子集:一個(gè)是訓(xùn)練集,另一個(gè)是測(cè)試集。在每個(gè)種類中,我們有兩個(gè)數(shù)據(jù)集:一個(gè)包含因變量,另一個(gè)包含自變量。
延伸閱讀《數(shù)據(jù)分析實(shí)戰(zhàn)》
點(diǎn)擊上圖了解及購買
轉(zhuǎn)載請(qǐng)聯(lián)系微信:togo-maruko
推薦語:通過大量的現(xiàn)實(shí)案例,詳細(xì)講解數(shù)據(jù)分析相關(guān)的各種方法。
據(jù)統(tǒng)計(jì),99%的大咖都完成了這個(gè)神操作
▼
更多精彩
在公眾號(hào)后臺(tái)對(duì)話框輸入以下關(guān)鍵詞
查看更多優(yōu)質(zhì)內(nèi)容!
PPT?|?報(bào)告?|?讀書?|?書單
大數(shù)據(jù)?|?揭秘?|?人工智能?|?AI
Python?|?機(jī)器學(xué)習(xí)?|?深度學(xué)習(xí)?|?神經(jīng)網(wǎng)絡(luò)
可視化?|?區(qū)塊鏈?|?干貨?|?數(shù)學(xué)
猜你想看
最全攻略:數(shù)據(jù)分析師必備Python編程基礎(chǔ)知識(shí)
王興:上天、入地、全球化,是互聯(lián)網(wǎng)下半場(chǎng)的三條路
輸在學(xué)歷的起跑線上?沒關(guān)系,10本書助你技能爆表升職加薪
2019升職加薪必備:你一定要修煉的產(chǎn)品思維
Q:?你還知道哪些處理數(shù)據(jù)的技巧?
歡迎留言與大家分享
覺得不錯(cuò),請(qǐng)把這篇文章分享給你的朋友
轉(zhuǎn)載 / 投稿請(qǐng)聯(lián)系:baiyu@hzbook.com
更多精彩,請(qǐng)?jiān)诤笈_(tái)點(diǎn)擊“歷史文章”查看
點(diǎn)擊閱讀原文,了解更多
總結(jié)
以上是生活随笔為你收集整理的用Python玩转统计数据:取样、计算相关性、拆分训练模型和测试的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何成为一名合格的数据科学家?这5个要点
- 下一篇: 写给中学生的算法入门:学代码之前看这篇就