㈠ 怎麼用python算p值和t檢驗
引入相關模塊,這次我們使用stats的
產生兩列隨機變數,用到了stats。norm.rvs,參數loc表示平均數,scale表示標准差,size是樣本量這是產生的兩個變數的數據的一部分
ttest_rel的用法:輸出t和p值從p值可以看出,這兩列數據是沒有差異的。
當然,ttest_rel還可以接受pandas.DataFrame數據,先從excel中讀取數據我們可以看一下數據的基本內容:
我們可以選擇scoreA和ScoreB這兩列數據進行T檢驗輸出的結果可見兩列變數均值無差異
我們還可以同時對多個變數進行檢驗,比如:這是產生的結果可見:第一個array表示t值,兩個表示p值,因此我們可以知道p(scoreA)=0.126>0.05
㈡ python隨機森林分類模型,測試集和訓練集的樣本數沒有準確按照70%和30%分配
進行比例劃分的時候 從 int 型 轉化為了 float 型, float型總是會有微小的誤差的,這個不是大問題。
比如你輸入 1- 0.9 , 可能返回 0.1, 也可能返回0.09999999 或者 0.100000000001 , 這是計算機存儲機制導致的。
㈢ 如何用python寫 數據分析工具
數據導入
導入本地的或者web端的CSV文件;
數據變換;
數據統計描述;
假設檢驗
單樣本t檢驗;
可視化;
創建自定義函數。
數據導入
這是很關鍵的一步,為了後續的分析我們首先需要導入數據。通常來說,數據是CSV格式,就算不是,至少也可以轉換成CSV格式。在Python中,我們的操作如下:
Python
1
2
3
4
5
6
7
8
import pandas as pd
# Reading data locally
df = pd.read_csv('/Users/al-ahmadgaidasaad/Documents/d.csv')
# Reading data from web
data_url = "t/Analysis-with-Programming/master/2014/Python/Numerical-Descriptions-of-the-Data/data.csv"
df = pd.read_csv(data_url)
為了讀取本地CSV文件,我們需要pandas這個數據分析庫中的相應模塊。其中的read_csv函數能夠讀取本地和web數據。
數據變換
既然在工作空間有了數據,接下來就是數據變換。統計學家和科學家們通常會在這一步移除分析中的非必要數據。我們先看看數據:
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Head of the data
print df.head()
# OUTPUT
0 12432934148330010553
1 41589235 4287806335257
2 17871922 19551074 4544
317152 14501 3536 1960731687
4 12662385 25303315 8520
# Tail of the data
print df.tail()
# OUTPUT
74 2505 20878 3519 1973716513
7560303 40065 7062 1942261808
76 63116756 3561 1591023349
7713345 38902 2583 1109668663
78 2623 18264 3745 1678716900
對R語言程序員來說,上述操作等價於通過print(head(df))來列印數據的前6行,以及通過print(tail(df))來列印數據的後6行。當然Python中,默認列印是5行,而R則是6行。因此R的代碼head(df, n = 10),在Python中就是df.head(n = 10),列印數據尾部也是同樣道理。
在R語言中,數據列和行的名字通過colnames和rownames來分別進行提取。在Python中,我們則使用columns和index屬性來提取,如下:
Python
1
2
3
4
5
6
7
8
9
10
11
# Extracting column names
print df.columns
# OUTPUT
Index([u'Abra', u'Apayao', u'Benguet', u'Ifugao', u'Kalinga'], dtype='object')
# Extracting row names or the index
print df.index
# OUTPUT
Int64Index([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78], dtype='int64')
數據轉置使用T方法,
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# Transpose data
print df.T
# OUTPUT
01 23 45 67 89
Abra1243 41581787171521266 5576 927215401039 5424
Apayao2934 92351922145012385 7452109917038138210588
Benguet148 42871955 353625307712796 24632592 1064
Ifugao3300
... 69 70 71 72 73 74 75 76 77
Abra ...12763 247059094 620913316 250560303 631113345
Apayao ...376251953235126 6335386132087840065 675638902
Benguet... 2354 4045 5987 3530 2585 3519 7062 3561 2583
Ifugao ... 9838171251894015560 774619737194221591011096
Kalinga...
78
Abra2623
Apayao 18264
Benguet 3745
Ifugao 16787
Kalinga16900
Other transformations such as sort can be done using<code>sort</code>attribute. Now let's extract a specific column. In Python, we do it using either<code>iloc</code>or<code>ix</code>attributes, but<code>ix</code>is more robust and thus I prefer it. Assuming we want the head of the first column of the data, we have
其他變換,例如排序就是用sort屬性。現在我們提取特定的某列數據。Python中,可以使用iloc或者ix屬性。但是我更喜歡用ix,因為它更穩定一些。假設我們需數據第一列的前5行,我們有:
Python
1
2
3
4
5
6
7
8
9
print df.ix[:, 0].head()
# OUTPUT
0 1243
1 4158
2 1787
317152
4 1266
Name: Abra, dtype: int64
順便提一下,Python的索引是從0開始而非1。為了取出從11到20行的前3列數據,我們有:
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
print df.ix[10:20, 0:3]
# OUTPUT
AbraApayaoBenguet
109811311 2560
1127366 15093 3039
12 11001701 2382
13 7212 11001 1088
14 10481427 2847
1525679 15661 2942
16 10552191 2119
17 54376461734
18 10291183 2302
1923710 12222 2598
20 10912343 2654
上述命令相當於df.ix[10:20, ['Abra', 'Apayao', 'Benguet']]。
為了舍棄數據中的列,這里是列1(Apayao)和列2(Benguet),我們使用drop屬性,如下:
Python
1
2
3
4
5
6
7
8
9
print df.drop(df.columns[[1, 2]], axis = 1).head()
# OUTPUT
AbraIfugaoKalinga
0 1243330010553
1 4158806335257
2 17871074 4544
317152 1960731687
4 12663315 8520
axis參數告訴函數到底舍棄列還是行。如果axis等於0,那麼就舍棄行。
統計描述
下一步就是通過describe屬性,對數據的統計特性進行描述:
Python
1
2
3
4
5
6
7
8
9
10
11
12
print df.describe()
# OUTPUT
AbraApayaoBenguetIfugao Kalinga
count 79.000000 79.00000079.000000 79.000000 79.000000
mean 12874.37974716860.6455703237.39240512414.62025330446.417722
std16746.46694515448.1537941588.536429 5034.28201922245.707692
min927.000000401.000000 148.000000 1074.000000 2346.000000
25% 1524.000000 3435.5000002328.000000 8205.000000 8601.500000
50% 5790.00000010588.0000003202.00000013044.00000024494.000000
75%13330.50000033289.0000003918.50000016099.50000052510.500000
max60303.00000054625.0000008813.00000021031.00000068663.000000
假設檢驗
Python有一個很好的統計推斷包。那就是scipy裡面的stats。ttest_1samp實現了單樣本t檢驗。因此,如果我們想檢驗數據Abra列的稻穀產量均值,通過零假設,這里我們假定總體稻穀產量均值為15000,我們有:
Python
1
2
3
4
5
6
7
from scipy import stats as ss
# Perform one sample t-test using 1500 as the true mean
print ss.ttest_1samp(a = df.ix[:, 'Abra'], popmean = 15000)
# OUTPUT
(-1.1281738488299586, 0.26270472069109496)
返回下述值組成的元祖:
t : 浮點或數組類型
t統計量
prob : 浮點或數組類型
two-tailed p-value 雙側概率值
通過上面的輸出,看到p值是0.267遠大於α等於0.05,因此沒有充分的證據說平均稻穀產量不是150000。將這個檢驗應用到所有的變數,同樣假設均值為15000,我們有:
Python
1
2
3
4
5
6
print ss.ttest_1samp(a = df, popmean = 15000)
# OUTPUT
(array([ -1.12817385, 1.07053437, -65.81425599,-4.564575, 6.17156198]),
array([2.62704721e-01, 2.87680340e-01, 4.15643528e-70,
1.83764399e-05, 2.82461897e-08]))
第一個數組是t統計量,第二個數組則是相應的p值。
可視化
Python中有許多可視化模塊,最流行的當屬matpalotlib庫。稍加提及,我們也可選擇bokeh和seaborn模塊。之前的博文中,我已經說明了matplotlib庫中的盒須圖模塊功能。
;
重復100次; 然後
計算出置信區間包含真實均值的百分比
Python中,程序如下:
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import numpy as np
import scipy.stats as ss
def case(n = 10, mu = 3, sigma = np.sqrt(5), p = 0.025, rep = 100):
m = np.zeros((rep, 4))
for i in range(rep):
norm = np.random.normal(loc = mu, scale = sigma, size = n)
xbar = np.mean(norm)
low = xbar - ss.norm.ppf(q = 1 - p) * (sigma / np.sqrt(n))
up = xbar + ss.norm.ppf(q = 1 - p) * (sigma / np.sqrt(n))
if (mu > low) & (mu < up):
rem = 1
else:
rem = 0
m[i, :] = [xbar, low, up, rem]
inside = np.sum(m[:, 3])
per = inside / rep
desc = "There are " + str(inside) + " confidence intervals that contain "
"the true mean (" + str(mu) + "), that is " + str(per) + " percent of the total CIs"
return {"Matrix": m, "Decision": desc}
上述代碼讀起來很簡單,但是循環的時候就很慢了。下面針對上述代碼進行了改進,這多虧了Python專家,看我上篇博文的15條意見吧。
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import numpy as np
import scipy.stats as ss
def case2(n = 10, mu = 3, sigma = np.sqrt(5), p = 0.025, rep = 100):
scaled_crit = ss.norm.ppf(q = 1 - p) * (sigma / np.sqrt(n))
norm = np.random.normal(loc = mu, scale = sigma, size = (rep, n))
xbar = norm.mean(1)
low = xbar - scaled_crit
up = xbar + scaled_crit
rem = (mu > low) & (mu < up)
m = np.c_[xbar, low, up, rem]
inside = np.sum(m[:, 3])
per = inside / rep
desc = "There are " + str(inside) + " confidence intervals that contain "
"the true mean (" + str(mu) + "), that is " + str(per) + " percent of the total CIs"
return {"Matrix": m, "Decision": desc}
更新
那些對於本文ipython notebook版本感興趣的,請點擊這里。這篇文章由Nuttens Claude負責轉換成ipython notebook 。
㈣ 相關比例檢驗
網站投放廣告的時候,一開始給大家看到的落地頁是訪問課程資料,現在又推出了開始免費試學這個落地頁,網站的兩個不同的落地頁(老版本,新版本),想知道哪個版本的落地頁能帶來更多的轉化率,這時候就要檢測兩個落地頁的轉化效果,下面是測試的24天數據
#讀取數據
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
df = pd.read_csv('C:/Users/mxl/Desktop/小鳥計劃/ab_data.csv')
df.head()
user_id-用戶,timestamp-用戶訪問頁面的時間,group-舊方案control和新方案trement分組, landing_page-落地頁是舊頁(訪問課程資料)或新頁(開始免費試學),converted-1表示已轉化
#查看每一列的數據類型
df.dtypes
#描述統計信息
df.describe()
#數據集中有treament和new_page不一致的數據,要對數據集中的這些數據進行剔除,觀察treatment有寫成treament
df.loc[(df["group"] == "treatment")!=(df["landing_page"] == "new_page")].count()
#剔除錯誤記錄,剩下的作為測試數據
df_test = df.loc[~((df["group"] == "treatment")!=(df["landing_page"] == "new_page"))]
#查看有沒有重復用戶,若有就去重
df_test.user_id.nunique()
#對重復的數據用plicate進行刪除,對象是User_id,保留第一個
df_test = df_test.drop_plicates(subset=["user_id"],keep='first')
#樣本均值
a_mean=df_test.loc[df_test['landing_page']=='new_page']['converted'].mean()
b_mean=df_test.loc[df_test['landing_page']=='old_page']['converted'].mean()
#樣本數量
n_a=df_test.loc[df_test['group']=='treatment'].shape[0]
n_b=df_test.loc[df_test['group']=='control'].shape[0]
print('A版本平均值=',a_mean,'轉化量')
print('B版本平均值=',b_mean,'轉化量')
自變數是指原因。因變數是指結果,也就是自變數發生變化導致改變的值就是因變數。
自變數:我們有兩組實驗數據,第一組是落地頁是新網頁。第二組落地頁是舊網頁。所以自變數是落地頁的類型
因變數:落地頁帶來的轉化量
所以,我們要考察的是自變數(落地頁)兩種情況下對因變數(網頁成交轉化量)的影響。
測試用戶分為兩部分,一部分用新頁面A,一部分用舊頁面B,經過一定時間後,收集到兩方案的觀測數據,要研究的問題是A和B方案的轉化率的差異性。由於我們期望是A方案頁面的成交轉化率高於B方案頁面的成交轉化率,所以提出下面兩個互為相反的假設:
零假設:u_a-u_b= 0
零假設總是表述為研究沒有改變,沒有效果,不起作用等。
備選假設:u_a-u_b>0
A版本和B版本有差別,也就是A版本平均值大於B版本平均值。
由於兩種數據是相關樣本,採用的是相關比例檢驗
相關比例檢驗只關注每組數據相關比例的差值
備選假設是A版本和B版本有差別,也就是A版本轉化率平均值大於B版本轉化率平均值,所以我們使用右尾檢驗。
在零假設成立前提下,得到樣本平均值的概率p是多少?
'''用python統計包statsmodels.stats.proportion.proportions_ztest自動計算
'''
#導入統計模塊
import statsmodels.stats.proportion as sm
#計算轉化在新網頁和舊網頁的樣本比例
convert_new = df_test.query('group == "treatment" & converted == 1').shape[0]
convert_old = df_test.query('group == "control" & converted == 1').shape[0]
z_score,p_value = sm.proportions_ztest([convert_new,convert_old],[n_a,n_b],alternative='smaller')
這里alternative表示備擇假設可以是雙側檢驗two-sided,也可以是單側檢驗之一,smaller表示備擇假設為prop < value,較大的表示prop >value。在兩個樣本檢驗中,smaller表示備擇假設為p1 < p2,較大的表示p1 > p2,其中p1為第一個樣本比例,p2第二個樣本的比例。
z_score,p_value
顯著水平 alpha=0.05
#右尾判斷條件:p_value<alpha時,拒絕原假設
if(p_value<alpha):
print('拒絕零假設,有統計顯著,也就是接受備選假設')
print('備選假設:A版本和B版本有差異')
else:
print('接受零假設,沒有統計顯著')
print('零假設:A版本和B版本沒有差異')
#1)置信水平對於的z值
#2)計算上下限
#置信區間上限=樣本平均值-z_score*標准誤差
#置信區間下限=樣本平均值+z_score*標准誤差
a=(a_mean-b_mean)-z_score*np.sqrt(a_mean*(1-a_mean)/n_a + b_mean*(1-b_mean)/n_b)
b=(a_mean-b_mean)+z_score*np.sqrt(a_mean*(1-a_mean)/n_a + b_mean*(1-b_mean)/n_b)
#總體比例差平均值差值對應的值是0
pop_mean=0
#樣本比例差平均值差值對應的值是0
sample_mean=a_mean-b_mean
#總體比例差平均值差值的標准差
sample_std=np.sqrt(a_mean*(1-a_mean)/n_a + b_mean*(1-b_mean)/n_b)
d=(sample_mean - pop_mean) / sample_std
print('d=',d)
A版本平均值= 0.11880806551510564 轉化量
B版本平均值= 0.1203863045004612 轉化量
1)假設檢驗
本次假設檢驗是基於正態(z)檢驗的比例檢驗 z_score=-1.3109241984234394,p_value=0.094941687240975514,單側檢驗(右側) 統計上不存在顯著差異,接受零假設
2)置信區間
總體比例差的95%的置信區間 CI=[-3.5520257269348876e-09,-0.0031564744186853865]
3)效應量
d= -1.31092714883,效果顯著
參考鏈接:
1、數據集
2、數據分析AB測試實戰項目
㈤ 數據分析員用python做數據分析是怎麼回事,需要用到python中的那些內容,具體是怎麼操作的
大數據!大數據!其實是離不開數據二字,但是總體來講,自己之前對數據的認知是不太夠的,更多是在關注技術的提升上。換句話講,自己是在做技術,這些技術處理的是數據,而不能算是自己是在做數據的。大規模數據的處理是一個非常大的課題,但是這一點更偏向於是搞技術的。
與數據分析相關的Python庫很多,比如Numpy、pandas、matplotlib、scipy等,數據分析的操作包括數據的導入和導出、數據篩選、數據描述、數據處理、統計分析、可視化等等。接下來我們看一下如何利用Python完成數據的分析。
生成數據表
常見的生成方法有兩種,第一種是導入外部數據,第二種是直接寫入數據,Python支持從多種類型的數據導入。在開始使用Python進行數據導入前需要先導入pandas庫,為了方便起見,我們也同時導入Numpy庫。代碼是最簡模式,裡面有很多可選參數設置,例如列名稱、索引列、數據格式等等。
檢查數據表
Python中使用shape函數來查看數據表的維度,也就是行數和列數。你可以使用info函數查看數據表的整體信息,使用dtypes函數來返回數據格式。Isnull是Python中檢驗空值的函數,你可以對整個數據表進行檢查,也可以單獨對某一列進行空值檢查,返回的結果是邏輯值,包含空值返回True,不包含則返回False。使用unique函數查看唯一值,使用Values函數用來查看數據表中的數值。
數據表清洗
Python中處理空值的方法比較靈活,可以使用Dropna函數用來刪除數據表中包含空值的數據,也可以使用fillna函數對空值進行填充。Python中dtype是查看數據格式的函數,與之對應的是astype函數,用來更改數據格式,Rename是更改列名稱的函數,drop_plicates函數刪除重復值,replace函數實現數據替換。
數據預處理
數據預處理是對清洗完的數據進行整理以便後期的統計和分析工作,主要包括數據表的合並、排序、數值分列、數據分組及標記等工作。在Python中可以使用merge函數對兩個數據表進行合並,合並的方式為inner,此外還有left、right和outer方式。使用ort_values函數和sort_index函數完成排序,使用where函數完成數據分組,使用split函數實現分列。
數據提取
主要是使用三個函數:loc、iloc和ix,其中loc函數按標簽值進行提取,iloc按位置進行提取,ix可以同時按標簽和位置進行提取。除了按標簽和位置提起數據以外,還可以按具體的條件進行數據,比如使用loc和isin兩個函數配合使用,按指定條件對數據進行提取。
數據篩選匯總
Python中使用loc函數配合篩選條件來完成篩選功能,配合sum和 count函數還能實現excel中sumif和countif函數的功能。Python中使用的主要函數是groupby和pivot_table。groupby是進行分類匯總的函數,使用方法很簡單,制定要分組的列名稱就可以,也可以同時制定多個列名稱,groupby 按列名稱出現的順序進行分組。
㈥ 如何用Python進行線性回歸以及誤差分析
數據挖掘中的預測問題通常分為2類:回歸與分類。
簡單的說回歸就是預測數值,而分類是給數據打上標簽歸類。
本文講述如何用Python進行基本的數據擬合,以及如何對擬合結果的誤差進行分析。
本例中使用一個2次函數加上隨機的擾動來生成500個點,然後嘗試用1、2、100次方的多項式對該數據進行擬合。
擬合的目的是使得根據訓練數據能夠擬合出一個多項式函數,這個函數能夠很好的擬合現有數據,並且能對未知的數據進行預測。
代碼如下:
importmatplotlib.pyplot as plt
importnumpy as np
importscipy as sp
fromscipy.statsimportnorm
fromsklearn.pipelineimportPipeline
fromsklearn.linear_modelimportLinearRegression
fromsklearn.
fromsklearnimportlinear_model
''''' 數據生成 '''
x = np.arange(0,1,0.002)
y = norm.rvs(0, size=500, scale=0.1)
y = y + x**2
''''' 均方誤差根 '''
defrmse(y_test, y):
returnsp.sqrt(sp.mean((y_test - y) **2))
''''' 與均值相比的優秀程度,介於[0~1]。0表示不如均值。1表示完美預測.這個版本的實現是參考scikit-learn官網文檔 '''
defR2(y_test, y_true):
return1- ((y_test - y_true)**2).sum() / ((y_true - y_true.mean())**2).sum()
''''' 這是Conway&White《機器學習使用案例解析》里的版本 '''
defR22(y_test, y_true):
y_mean = np.array(y_true)
y_mean[:] = y_mean.mean()
return1- rmse(y_test, y_true) / rmse(y_mean, y_true)
plt.scatter(x, y, s=5)
degree = [1,2,100]
y_test = []
y_test = np.array(y_test)
fordindegree:
clf = Pipeline([('poly', PolynomialFeatures(degree=d)),
('linear', LinearRegression(fit_intercept=False))])
clf.fit(x[:, np.newaxis], y)
y_test = clf.predict(x[:, np.newaxis])
print(clf.named_steps['linear'].coef_)
print('rmse=%.2f, R2=%.2f, R22=%.2f, clf.score=%.2f'%
(rmse(y_test, y),
R2(y_test, y),
R22(y_test, y),
clf.score(x[:, np.newaxis], y)))
plt.plot(x, y_test, linewidth=2)
plt.grid()
plt.legend(['1','2','100'], loc='upper left')
plt.show()
該程序運行的顯示結果如下:
[ 0. 0.75873781]
rmse=0.15, R2=0.78, R22=0.53, clf.score=0.78
[ 0. 0.35936882 0.52392172]
rmse=0.11, R2=0.87, R22=0.64, clf.score=0.87
[ 0.00000000e+00 2.63903249e-01 3.14973328e-01 2.43389461e-01
1.67075328e-01 1.10674280e-01 7.30672237e-02 4.88605804e-02
......
3.70018540e-11 2.93631291e-11 2.32992690e-11 1.84860002e-11
1.46657377e-11]
rmse=0.10, R2=0.90, R22=0.68, clf.score=0.90
㈦ python pandas的describe的25%是什麼意思
25%, 50%和75%是對應的四分位數。
四分位數(Quartile)是指在統計學中把所有數值由小到大排列並分成四等份,處於三個分割點位置的數值。
第一四分位數 (Q1),又稱「較小四分位數」,等於該樣本中所有數值由小到大排列後第25%的數字。
第二四分位數 (Q2),又稱「中位數」,等於該樣本中所有數值由小到大排列後第50%的數字。
第三四分位數 (Q3),又稱「較大四分位數」,等於該樣本中所有數值由小到大排列後第75%的數字。
第三四分位數與第一四分位數的差距又稱四分位距(InterQuartile Range,IQR)。
㈧ Python中的加權隨機樣本問題,怎麼解決
我們平時比較多會遇到的一種情景是從一堆的數據中隨機選擇一個, 大多數我們使用random就夠了, 但是假如我們要選取的這堆數據分別有自己的權重, 也就是他們被選擇的概率是不一樣的, 在這種情況下, 就需要使用加權隨機來處理這些數據
1. 簡單線性方法
下面是一種簡單的方案, 傳入權重的列表(weights), 然後會返回隨機結果的索引值(index), 比如我們傳入[2, 3, 5], 那麼就會隨機的返回0(概率0.2), 1(概率0.3), 2(概率0.5)
簡單的思路就是把所有的權重加和, 然後隨機一個數, 看看落在哪個區間
import random
def weighted_choice(weights):
totals = []
running_total = 0
for w in weights:
running_total += w
totals.append(running_total)
rnd = random.random() * running_total
for i, total in enumerate(totals):
if rnd < total:
return i
2. 加速搜索
上面這個方法看起來非常簡單, 已經可以完成我們所要的加權隨機, 然是最後的這個for循環貌似有些啰嗦, Python有個內置方法bisect可以幫我們加速這一步
import random
import bisect
def weighted_choice(weights):
totals = []
running_total = 0
for w in weights:
running_total += w
totals.append(running_total)
rnd = random.random() * running_total
return bisect.bisect_right(totals, rnd)
bisect方法可以幫我們查找rnd在totals裡面應該插入的位置, 兩個方法看起來差不多, 但是第二個會更快一些, 取決於weights這個數組的長度, 如果長度大於1000, 大約會快30%左右
3. 去掉臨時變數
其實在這個方法裡面totals這個數組並不是必要的, 我們調整下策略, 就可以判斷出weights中的位置
def weighted_choice(weights):
rnd = random.random() * sum(weights)
for i, w in enumerate(weights):
rnd -= w
if rnd < 0:
return i
這個方法比第二種方法竟然快了一倍, 當然, 從演算法角度角度, 復雜度是一樣的, 只不過我們把賦值臨時變數的功夫省下來了, 其實如果傳進來的weights是已經按照從大到小排序好的話, 速度會更快, 因為rnd遞減的速度最快(先減去最大的數)
4. 更多的隨機數
如果我們使用同一個權重數組weights, 但是要多次得到隨機結果, 多次的調用weighted_choice方法, totals變數還是有必要的, 提前計算好它, 每次獲取隨機數的消耗會變得小很多
class WeightedRandomGenerator(object):
def __init__(self, weights):
self.totals = []
running_total = 0
for w in weights:
running_total += w
self.totals.append(running_total)
def next(self):
rnd = random.random() * self.totals[-1]
return bisect.bisect_right(self.totals, rnd)
def __call__(self):
return self.next()
在調用次數超過1000次的時候, WeightedRandomGenerator的速度是weighted_choice的100倍
所以我們在對同一組權重列表進行多次計算的時候選擇方法4, 如果少於100次, 則使用方法3
5. 使用accumulate
在python3.2之後, 提供了一個itertools.accumulate方法, 可以快速的給weights求累積和
>>>> from itertools import accumulate
>>>> data = [2, 3, 5, 10]
>>>> list(accumulate(data))
[2, 5, 10, 20]
㈨ Python中如何實現分層抽樣
分層抽樣也叫按比例抽樣,根本樣本在總體中所佔的比例進行抽樣
㈩ 初學python,怎樣用python做pearson相關系數的檢驗呢,求指導啊
scipy.stats.pearsonr(x, y)
x和y為相同長度的兩組數據
返回值 r, p-value
r是相關系數,取值-1~1. 表示線性相關程度
p-value越小,表示相關程度越顯著。按照文檔的說法「The p-values are not entirely reliable but are probably reasonable for datasets larger than 500 or so.」,p-value在500個樣本值以上有較高的可靠性