数据分析之路week05

探索泰坦尼克号登船港口价格之谜

Posted by BY xiaobao(微信:Bao1697047283) on September 8, 2019

目录

  1. 数据的描述性统计
  2. python基础学习
  3. 数据的分布形态描述
  4. 用python验证数据集中的体温是否服从正态分布
  5. 探索泰坦尼克号登船港口价格之谜
  6. 彩票预测,选号分析
  7. 数据分析可视化superset安装

本文按照数据咆哮大师文章参考学习

原文:https://mp.weixin.qq.com/s/f-ay2fNR3VeQzFYGsHF-cQ

探索泰坦尼克号登船港口价格之谜

数据预处理

数据源https://pan.baidu.com/s/1AKsYpjZgtG8FNhk6Pxs9VA#list/path=%2F

readme:

数据集的原始数据是泰坦尼克号的数据,本次截取了其中的一部分数据进行学习.

  • Age:年龄,指登船者的年龄
  • Fare:价格,指船票价格
  • Embark:登船的港口
import requests
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
doc = "/Users/lianxiaobao/Desktop/blog/作业/data.xlsx";
df = pd.read_excel(doc)
df.head()
# Age:年龄,指登船者的年龄
# Fare:价格,指船票价格
# Embark:登船的港口
ID Age Fare Embarked
0 1 22.0 7.2500 S
1 2 38.0 71.2833 C
2 3 26.0 7.9250 S
3 4 35.0 53.1000 S
4 5 35.0 8.0500 S

按照港口分类,使用python求出各类数据年龄、车票价格的统计量


print(df.groupby('Embarked').describe())

            Age                                                        Fare  \
          count       mean        std   min    25%   50%   75%   max  count   
Embarked                                                                      
C         130.0  30.814769  15.434860  0.42  21.25  29.0  40.0  71.0  130.0   
Q          28.0  28.089286  16.915396  2.00  17.50  27.0  34.5  70.5   28.0   
S         554.0  29.445397  14.143192  0.67  21.00  28.0  38.0  80.0  554.0   

                     ...                           ID                          \
               mean  ...         75%       max  count        mean         std   
Embarked             ...                                                        
C         68.296767  ...    81.42810  512.3292  130.0  360.023077  202.395364   
Q         18.265775  ...    18.90625   90.0000   28.0  329.392857  217.155404   
S         27.476284  ...    27.86250  263.0000  554.0  357.043321  206.138619   

                                              
           min     25%    50%     75%    max  
Embarked                                      
C          2.0  206.50  364.5  521.50  711.0  
Q         16.0  146.00  295.0  516.50  712.0  
S          1.0  179.25  355.5  535.75  710.0  

[3 rows x 24 columns]
  • 由于展示列数太多不全所以选取特定列去group by

按照Embarked:age 的统计量

# 按照Embarked:age 的统计量
df1 = pd.read_excel(doc, usecols='B,D')
df1.groupby('Embarked').describe()
Age
count mean std min 25% 50% 75% max
Embarked
C 130.0 30.814769 15.434860 0.42 21.25 29.0 40.0 71.0
Q 28.0 28.089286 16.915396 2.00 17.50 27.0 34.5 70.5
S 554.0 29.445397 14.143192 0.67 21.00 28.0 38.0 80.0

按照Embarked:fare 的统计量

# 按照Embarked:fare 的统计量
df2 = pd.read_excel(doc, usecols='C,D')
df2.groupby('Embarked').describe()
Fare
count mean std min 25% 50% 75% max
Embarked
C 130.0 68.296767 90.557822 4.0125 14.4542 36.2521 81.42810 512.3292
Q 28.0 18.265775 21.843582 6.7500 7.7500 7.7500 18.90625 90.0000
S 554.0 27.476284 36.546362 0.0000 8.0500 13.0000 27.86250 263.0000
  • 此时可以看出 c 港口 均价和标准差都比较大 所以大多是高级仓
  • S港口上船人数最多,并且票价均衡,那很有可能是泰坦尼克号的始发站。那我们看看历史资料是不是这样。

1912年4月10日,泰坦尼克号从英国南安普敦(Southampton)港出发,途经法国 瑟堡-奥克特维尔(Cherbourg-Octeville)以及爱尔兰 昆士敦(Queenstown),计划中的目的地为美国纽约(New York),开始了这艘“梦幻客轮”的处女航。

画出价格的分布图像,验证数据服从哪种分布

# plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
# plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
df = pd.read_excel(doc)
fig=plt.figure(figsize=(16, 5))
plt.scatter(df['ID'], df['Fare'], c='b', marker='o', alpha=0.7)
plt.title('price')
plt.xlabel('people')
plt.ylabel('price')
plt.grid(True)
plt.show()

df['Fare'].hist(bins=20,alpha=0.5)
df['Fare'].plot(kind='kde',secondary_y=True)

# p值大于0.05,说明服从正态分布
import scipy.stats as stats

s = 0.954
fare = df[df['Embarked'] == 'S']['Fare'].copy().values
dfa, loc, scale = stats.chi2.fit(fare)
print(len(fare),dfa, loc, scale)
x2 = stats.chi2.rvs(dfa, loc=loc, scale=scale, size=100)
D, p = stats.ks_2samp(fare, x2)
print("卡方 D=%.4f, p=%.4f" % (D, p))
dfa, loc, scale = stats.lognorm.fit(fare)
# print(len(fare), dfa, loc, scale)
x2 = stats.lognorm.rvs(dfa, loc=loc, scale=scale, size=100)
D, p = stats.ks_2samp(fare, x2)
print("对数正态 D=%.4f, p=%.4f" % (D, p))
dfa, loc, scale = stats.t.fit(fare)
x2 = stats.t.rvs(dfa, loc=loc, scale=scale, size=100)
D, p = stats.ks_2samp(fare, x2)
print("学生t D=%.4f, p=%.4f" % (D, p))
loc, scale = stats.norm.fit(fare)
# print(len(fare), dfa, loc, scale)
x2 = stats.norm.rvs(loc=loc, scale=scale, size=100)
D, p = stats.ks_2samp(fare, x2)
print("正态 D=%.4f, p=%.4f" % (D, p))
554 2.2619992080297675 -0.052371794787308884 12.170033788711386
卡方 D=0.1783, p=0.0078
对数正态 D=0.2038, p=0.0014
学生t D=0.3047, p=0.0000
正态 D=0.2756, p=0.0000
  • pvalue都特别小,抽样不符合任何分布!但是相比来说对数正态还算是最相近的形态。一般在分析金融类数据的时候因为t分布比正态分布更加厚尾,所以更加适合分析金融变量。但是目前是哪个分布都不是。

  • 换个港口试试,C港口是明显的贵族港口,所以票价很有可能是以拍卖的形式出售,导致票价无上限,但是恰恰是这个特点有可能让这个港口符合对数正态分布

s = 0.954
fare = df[df['Embarked'] == 'C']['Fare'].copy().values
dfa, loc, scale = stats.chi2.fit(fare)
print(len(fare),dfa, loc, scale)
x2 = stats.chi2.rvs(dfa, loc=loc, scale=scale, size=100)
D, p = stats.ks_2samp(fare, x2)
print("卡方 D=%.4f, p=%.4f" % (D, p))
dfa, loc, scale = stats.lognorm.fit(fare)
# print(len(fare), dfa, loc, scale)
x2 = stats.lognorm.rvs(dfa, loc=loc, scale=scale, size=100)
D, p = stats.ks_2samp(fare, x2)
print("对数正态 D=%.4f, p=%.4f" % (D, p))
dfa, loc, scale = stats.t.fit(fare)
x2 = stats.t.rvs(dfa, loc=loc, scale=scale, size=100)
D, p = stats.ks_2samp(fare, x2)
print("学生t D=%.4f, p=%.4f" % (D, p))
loc, scale = stats.norm.fit(fare)
# print(len(fare), dfa, loc, scale)
x2 = stats.norm.rvs(loc=loc, scale=scale, size=100)
D, p = stats.ks_2samp(fare, x2)
print("正态 D=%.4f, p=%.4f" % (D, p))
130 1.3711812200909383 4.012499999999999 1.7908494988001724
卡方 D=0.7785, p=0.0000
对数正态 D=0.1654, p=0.0812
学生t D=0.2023, p=0.0166
正态 D=0.2469, p=0.0016
  • pvalue大于0.05 接受假设C港口票价是对数正态分布,所以价格可能是拍卖导致的

根据港口分类,验证S与Q两个港口价格之差是否服从某种分布

根据中心极限定理

总体不服从正态分布,当需要当n比较大时(一般要求n>=30)两个样本均值之差的抽样分布可近似为正态分布

Q港口的总体容量为28,其样本容量不可能超过30,故其S港和Q港两个样本均值之差的抽样分布不服从正态分布

C港口的总体容量为130,故其S港和C港两个样本均值之差的抽样分布近似服从正态分布,其分布图如下:

s_fare = df[df['Embarked'] == 'S']['Fare'].copy().values
q_fare = df[df['Embarked'] == 'Q']['Fare'].copy().values
c_fare = df[df['Embarked'] == 'C']['Fare'].copy().values
mu = np.mean(s_fare) - np.mean(c_fare)
sigma = np.sqrt(np.var(s_fare, ddof=1) / len(s_fare) + np.var(c_fare, ddof=1) / len(c_fare))

x = np.arange(- 100, 20)
y = stats.norm.pdf(x, mu, sigma)
plt.plot(x, y)
plt.xlabel("S_Fare - C_Fare")
plt.ylabel("Density")
plt.title('Fare difference between S and C\n$\mu=%.2f,\quad \sigma=%.2f$' % (mu, sigma))
plt.show()

  1. E(X1)是独立的抽取自S港的价格总体的一个容量为n1的样本的均值,n1<=554
  2. E(X2)是独立的抽取自Q港的价格总体的一个容量为n2的样本的均值,n1<=28
  3. E(X3)是独立的抽取自C港的价格总体的一个容量为n3的样本的均值,n1<=130
    • 因为总体不服从正态分布,所以需要当n比较大时,一般要求n>=30,两个样本均值之差的抽样分布可近似为正态分布
    • 因为X2的总体容量为28,其样本容量不可能超过30,故其S港和Q港两个样本均值之差(E(X1)-E(X2))的抽样分布不服从正态分布
    • 因为X3的总体容量为130,故其S港和C港两个样本均值之差(E(X1)-E(X3))的抽样分布近似服从正态分布,其均值和方差分别为 * E(E(X1) - E(X3)) = E(E(X1)) - E(E(X3)) = μ1 - μ3
    • D(E(X1) + E(X3)) = D(E(X1)) + D(E(X3)) = σ1²/n1 + σ3²/n3