# 巨匠Python - 數統基礎
###### tags: `資料分析`
# 第一章、方程式操作 & 微分與極值
**前導:程式與數值計算關係**
1.統計分析 vs. 機器學習
統計:找出真相、因果推理
機器:解決問題、預測結果
2.數學:解決問題的方法
<線性>
(1)如何解決問題-方程式
(2)固定&變動資訊-截距&斜率
(3)瞬間變化量-微分
(4)趨近值-極限
<非線性>
(5)敘述統計:聚集、離散程度
(6)推論統計:資料無法探索
(7)機率、分配
(8)母體、抽樣、檢定、標準差
-------
**Google Colab**
1. 環境:Ubuntu + Python3.7
2. 套件:每次執行都得重新安裝
3. 檔案:執行完就會刪除
4. 免費版本不能於背景執行
-----
## 一、線性方程式:求斜率&截距
[matplotlib.pyplot - Documentation](https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.html)
[numpy - Documentation](https://numpy.org/doc/stable/reference/generated/numpy.polyfit.htm)
-----
**01. Set (in Google Colab)**
```
# !pip install matplotlib
# !pip install numpy
# ! 表示轉移至Linux環境下達指令 (離開python環境)
import matplotlib.pyplot as plt
import numpy as np
x = [1,2,3,4,5,6,7]
y = [1,3,3,12,5,7,9]
plt.plot(x,y,'--') # x軸、y軸、虛線表示
plt.grid() # 增加格線
plt.show() # 顯示圖形
```

-----
**02. 轉換成線性方程式(斜率、截距)**
```
# 令有一次方程式: y = slope * x + intercept
# np.polyfit(x,y,N): 可將現資料(x,y)調整找出N次方程式, 回傳list
slope, intercept = np.polyfit(x,y,1)
print(slope)
print(intercept)
# 若拆解成二次方程式 (y = a * x ** 2 + b * x + c)
# 等號左邊可以得幾個值,視等號右邊會拆成幾個變數
a, b, c = np.polyfit(x,y,2)
print(data)
# 以一次方程式為例,列出每一個x值所對應y值(list)
y1 = [slope * i + intercept for i in x]
plt.plot(x,y,'--')
plt.plot(x,y1,'r') #red
plt.grid()
plt.show()
```

-----
**練習一、經濟部1994-2004年經濟成長率**
```
x = np.arange(1994,2005,1) # 1994-2005,1年1格
y = [7.11,6.42,6.10,6.37,4.33,5.32,5.78,-2.22,3.94,3.33,5.71]
# 以 polyfit 求一次方程式,以進行預測
slope, intercept = np.polyfit(x,y,1)
print(f"斜率: {slope}")
print(f"截距: {intercept}")
# 產生list: 每一個x所對應的y值
y1 = [slope * i + intercept for i in x]
plt.plot(x,y,'--')
plt.plot(x,y1,'r') #red
plt.grid()
plt.show()
# 試求二次方程式 (y = a * x ** 2 + b * x + c)
a, b, c = np.polyfit(x,y,2)
y1 = [a * i ** 2 + b * i + c for i in x]
plt.plot(x,y,'--')
plt.plot(x,y1,'r') #red
plt.grid()
plt.show()
```


-----
**練習二、銷售業績計算(CSV)**
* 若數值凌亂不一定可以推出線性方程式 => 以最近鄰概念進行推估
* 建議最高至三元(三欄位)即可,可以3D圖表呈現
* 連結google drive內檔案
```
from google.colab import drive
drive.mount('/content/drive', force_remount=True)
# force_remount=True 強制安裝驅動器,避免中斷情形
```
```
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
df = pd.read_csv("/content/drive/MyDrive/colab/Advertising.csv")
x = df['Newspaper']
y = df['Sales']
plt.scatter(x,y) # 使用散佈圖
# plt.plot(x,y) # 使用曲線圖
plt.show()
# 加入polyfit找出資料中的線性關係
a,b,c = np.polyfit(x,y,2)
y1 = [a * i ** 2 + b * i + c for i in x]
plt.scatter(x, y)
plt.plot(x, y1, "r")
plt.show()
```

**資料過於零散,無法得出有效表示關係之方程式**
-----
## 二、方程式求解
1. 需先以`物件 = sympy.Symbol('符號')`定義函式內物件
2. **f(x) = 0** 或 **聯立方程式** => 求變數解
* 以`sympy.solve([input],[output])` 求解(回傳dictionary)
3. **線性方程式 f(x) = ax+by+c** => 求每一變數對應值
* 以`sympy.lambdify((x, y), function)`或`sympy.Lambda((x, y), funciton)`建立物件計算
4. **二次函數**極值與圖形
* 以`numpy.arange`限定範圍求`var.argmin()`或`var.argmax()`
* 以`matplotlib.pyplot.scatter(x,y)`散佈圖點出極值位置
* 亦可微分(`.diff`)求解(`.solve`)並帶回原式(`.lambdify`)
-----
### (一) 二元一次聯立方程式
```
# eg 1.
import sympy as sp
import numpy as np
x = sp.Symbol('x')
y = sp.Symbol('y')
f1 = 2 * x + 3 * y - 23
f2 = x + 4 * y - 24
print(sp.solve([f1, f2], [x, y]))
> {x: 4, y: 5}
```
```
# eg 2.
# 有草莓(50元)、巧克力(30元)兩種冰淇淋
s = sp.Symbol('s')
c = sp.Symbol('c')
# 總數量 = 20個
f1 = s + c - 20
# 總金額 = 800元
f2 = 50 * s + 30 * c - 800
# f1, f2 表示兩個答案為零的方程式
answer = sp.solve([f1, f2], [s, c])
print(answer)
print(answer.__class__) # 回傳資料的屬性
print(type(answer)) # 回傳資料的型態
print("草莓冰淇淋份數: ", answer[s])
print("巧克力冰淇淋份數: ", answer[c])
> {s: 10, c: 10}
> <class 'dict'>
> <class 'dict'>
> 草莓冰淇淋份數: 10
> 巧克力冰淇淋份數: 10
```
-----
### (二) 線性方程式求解 lambdify vs. Lambda
```
from sympy import lambdify, Symbol, Lambda
import numpy as np
'''
lambdify vs. Lambda
ddx = lambdify(自變數, 方程式)
answer = ddx(自變數代入數值)
func = Lambda(自變數, 方程式)
answer = func(自變數代入數值)
'''
print("\n\n----- 若x = -1,求一階導數的結果 -----")
x = sp.Symbol('x')
y1 = 2 * np.power(x,4) - 3 * np.power(x,2) + 2 * x - 20
print("\n原方程式: ", y1)
y2 = y1.diff(x)
print("一階函式: ", y2)
y3 = 8 * (-1) ** 3 - 6 * (-1) + 2
print("\n【法1】直接代入: ",y3)
ddx = lambdify(x, y2)
print("\n【法2】使用lambdify: ",ddx(-1))
func = sp.Lambda(x, y2)
print("\n【法3】使用Lambda: ",func(-1))
print("\n\n----- 使 x = -5 ~ 5,判斷函式圖形 -----")
ddx = lambdify(x, y1)
print("\n【法1】使用lambdify:", ddx(np.arange(-5, 5, 1)))
func = Lambda(x, y1)
# print(func(np.arange(-5, 5, 1))) => error
print("\n【法2】使用Lambda: errer - 無法代入list")
print("\n\n----- 若x = 3, y = 7,二元方程式求解 -----")
x = sp.Symbol('x')
y = sp.Symbol('y')
f = x ** 2 - 2 * y + 4 * x -3
print("\n令二元方程式: ", f)
ddx = lambdify((x, y), f)
print("\n【法1】使用lambdify: ", ddx(3, 7))
func = Lambda((x, y), f)
print("\n【法2】使用Lambda: ", func(3, 7))
print("\n**lambdify物件: ", ddx.__class__)
print("**Lambda物件: ", func.__class__)
```

-----
## 三、微分與極限求解
1. 一次函數 `f'(x) = f.diff(x)`
2. 極限函式 `sympy.limit(函式, 自變數,趨近值)`
3. 以 `sp.oo` 表示無限大
```
# ---------- 微分 ---------- #
# 意義:求瞬間變化量
x = sp.Symbol('x')
y = np.power(x,5)+ 2*np.power(x,4)+ 3*np.power(x,3)+ 4*np.power(x,2)+ 5*x+ 6
y2 = y.diff(x) # 對y做x的微分
print(y2)
> 5*x**4 + 8*x**3 + 9*x**2 + 8*x + 5
# ---------- 極限 ---------- #
# 意義:求 x = ? 會使 函式 趨近於 趨近值
x = sp.Symbol('x')
f3 = sp.limit((x**2+2*x-3)/(x-1),x,sp.oo)
print(f3)
> oo
```
# 第二章、二次函數與矩陣
## 一、二次函數-極值與圖形
```
import sympy as sp
print("\n---- 令x為正負10以內整數,求極值 ----")
x = np.arange(-10, 11, 1)
y = -3 * x ** 2 + 20 * x + 3
y_max = np.max(y)
x_max = x[y.argmax()]
print("\n求圖形最高點: ", x_max, ",", y_max)
print("\n---- 繪製二次函數圖形 (放大、並標示最大值) ----")
# 放大圖表
plt.figure(figsize=(8, 5))
plt.plot(x, y)
# 以散佈圖方式點出最大值
plt.scatter(x_max, y_max, c='r')
plt.grid()
plt.show()
print("\n---- 以微分求極值 ----")
x = sp.Symbol("x")
y = -3 * x ** 2 + 20 * x + 3
y_diff = y.diff(x)
x_max = sp.solve([y_diff],[x])[x]
ddf = sp.lambdify(x, y)
y_max = ddf(x_max)
print("\n求圖形最高點: ", x_max, ",", y_max)
```

## 二、矩陣與運算
### (一) 矩陣運算
```
# 2x2 矩陣運算
import numpy as np
a = np.array(
[
[6,3],
[8,10]
])
b = np.array(
[
[1,2],
[0,1]
])
print("a")
print(a)
print("b")
print(b)
print("-"*20)
print("a*b => 點對點相乘")
print(a*b)
print("-"*20)
print("np.dot(a,b) => 二維矩陣內積相乘(row對應column)/前方矩陣轉置")
print(np.dot(a,b))
print("-"*20)
print("np.inner(a,b) => 一維矩陣方式相乘(row對應row)/後方矩陣轉置")
print(np.inner(a,b))
print("-"*20)
print("np.outer(a,b) => 二維矩陣外積相乘")
print(np.outer(a,b))
```

---
**練習一、矩陣應用**
```
gamer = np.array([
[15, 14, 15], # A校排球、游泳、田徑隊人數
[12, 13, 17] # B校排球、游泳、田徑隊人數
]) # 2x3 矩陣
cost = np.array([
[10, 14], # 排球隊訓練 & 場地成本
[5, 18], # 游泳隊訓練 & 場地成本
[8, 10] # 田徑隊訓練 & 場地成本
]) # 3x2 矩陣
total_cost = gamer.dot(cost)
print(total_cost)
print(total_cost.sum(axis=1))
'''
[[340 612]
[321 572]]
[952 893]
'''
```
**練習二、3x3矩陣內積計算**
```
import numpy as np
a=[
[50,40,15],
[20,32,47]
]
b=[
[10,14],
[5,8],
[8,10]
]
print(np.dot(a,b))
'''
[[ 820 1170]
[ 736 1006]]
'''
```
### (二) 特殊矩陣
1. 單位矩陣: `np.eye(3)`
2. 轉置矩陣: `square.T`
3. 反矩陣: `np.linalg.inv(square)`
* row & column數量要相同才可算出反矩陣
* 矩陣與單位矩陣內積相乘 = 單位矩陣
* 並非每個矩陣有反矩陣 => 不可逆矩陣
---
# 第三章、敘述統計
## 一、統計學分類與介紹
**敘述統計 & 推論統計**
1. 敘述統計
* 資料整理
* 圖表
* 變異數
* 標準差
* 離散程度
2. 推論統計
* 機率分配
* 檢定方式
* 多變量分析
* 獨立性檢定
* 迴歸分析
**統計資料型態**
1. 以資料發生時間區分 => 橫斷面資料 & 時間序列資料
2. 以資料屬性區分 =>
* 質性
* 名目Nominal: ex. 1是男生, 2是女生
* 順序Ordinal: ex. 1-5 代表喜歡的程度
* 量化
* 離散Discrete: ex. 學生的成績
* 連續Continuous: ex. 學生的身高 & 體重
**範例一、名目資料統計**
```
import collections as ct
lang=['Python','Java','C#','C++','python','VB','Python']
count = ct.Counter(lang)
# 各筆名目資料的數量
print(count)
# 特定資料的數量
print(count['Python'])
'''
> Counter({'Python': 2, 'Java': 1, 'C#': 1, 'C++': 1, 'python': 1, 'VB': 1})
> 2
'''
```
---
## 二、敘述統計-數據分析
**使用工具安裝**
```
import numpy as np
import stats as sts
import matplotlib.pyplot
```
**常見統計指標與函式**
1. 平均數計算: `np.meam()`
* 圖形標示: `plt.axvline(np.mean(datas),0,1,c='r')`
2. 中位數計算: `np.median()`
* 圖形標示: `plt.axvline(np.median(datas),0,1,linestyle='--')`
3. 全距計算: `np.ptp()`
4. 四分位數: eg. Q1 `np.percentile(datas, 25)`
* 圖形標示: `plt.axvline(np.percentile(money, 25),0,1,c='g')`
5. 四分位距 = Q3-Q1: `np.percentile(datas, 75)-np.percentile(datas, 25)`
6. 變異數 = 平均差值平方: `np.var()`
7. 標準差 = 標準差開根號: `np.std()`
8. 變異係數 = 平均數/標準差: `np.mean() / np.std()`
* 用途: 不同單位、不同標準差資料之比較
9. 標準分數 = (數值-平均值)/標準差 `(value-mean)/std`
* 用途: 相同單位、不同標準差資料之比較
10. 共變異數 = `np.cov(b,a)`
* 用途: 求得兩數字的相對波動程度(和共變異數作比較)
* 矩陣左上值: b值相對變異數
* 矩陣右下值: a值相對變異數
* 矩陣反向對角線: 共變異數
11. 相關係數 = `np.corrcoef(a,b)`
* 用途: 求得兩數字互相影響的程度(介於-1到1之間)
* -1~0 => 負相關
* 0 => 無相關
* 0~1 => 正相關
* 絕對值 > 0.75 => 強烈正/負相關
12. 偏態係數 = `sts.skewness(data)`
* 用途: 了解圖形的對稱程度
* SK=0,圖形對稱
* SK>0,右偏、正偏,少數資料大,平均值>中位數
* SK<0,左偏、負偏,少數資料小,平均值<中位數
13. 峰度係數 = `sts.kurtosis(data)+3`
* 用途: 了解圖形的陡峭程度(統計上以3為基準,和3做比較)
* 修正: 因程式以0為基準,故須+3
* Kurtosis=3,常態峰,與常態分配圖形相同
* Kurtosis>3,高峻峰,較常態分配陡峭
* Kurtosis<3,低闊峰,較常態分配平緩
:::info
:label: **變異係數與標準分數判斷法**
變異數越低
=> 可靠性越高
=> 標準差越低
=> 算出變異係數越高 (mean/std)
=> 算出標準分數越高 ((score-mean)/std)
=> 表現越好
:::
---
## 三、敘述統計-圖表繪製
**使用工具安裝**
```
import matplotlib.pyplot
```
**圖表適用性與函式**
1. 折線圖Plot: 適用連續型函數
* `plt.plot(x, y)`
2. 長條圖Bar: 適用離散型函數
* `plt.bar(x, y)`
3. 散佈圖Scatter: 了解x軸與y軸屬性關係
* `plt.scatter(x,y)`
4. 直方圖Hist: 了解資料分組後數量
* `plt.hist(datas, bins=%組別數量%)`
5. 圓餅圖Pie: 了解資料於百分比內比例
6. 箱型圖Box: 了解資料分布的離散程度
* `plt.boxplot(datas)`
---
## 四、實作練習
**練習一、學生成績分析**
```
# ----- 數據分析 ----- #
np1=np.array([15,10,30,30,30,25,25,55,57,54,80,75,77,84,91,92,88,90,95,86])
# 要是numpy物件型態才可使用函式
print("中位數:",np.median(np1))
print("平均值:",np.mean(np1))
print("筆數:",len(np1))
# ----- 圖表繪製 ----- #
import matplotlib.pyplot as plt
## 設定橫軸: 總筆數
x = np.arange(0,len(np1))
# 依照實際數據呈現
plt.bar(x,np1) # 長條圖
# plt.plot(x,np1,c="r") # 曲線圖
plt.show()
```


---
**練習二、2017勞動部公布各行業初到職薪資**
```
# ----- 數據分析 ----- #
money=np.array([27583,27555,26492,29441,24973,27499,
26421,29686,27156,26771,25499,26571,28029,27624,
30176,31058,29404,27492,27092,26941,27507,27519,
26029,28207,28825,27307,27502,26676,26621,24789,
26759,29928,29517,32492,28628,28467,32777,26276,
25981,28537,26853,27702,29885,29653,27005,26066,
27628,26758,27682,25679,28294,31711,27439,25416,
26491,32800,33325,35821,28181,27548,38151,27932,
26304,25269,27024,26765,28832,27956,25540,26941,
28626,29984,29440,32044,36354,25470,28820,32522,
30741,29201,36384,29176,28092,29266,27383,29052,32467,
28191,28852,29854,28025,28838,26941,26243,28168,25263,
25426,25607,26804,26062,26374,26392,27739,26006,
27635,25896,24614,24701,23187,25841])
print(f"總筆數: {len(money)}")
print(f"平均數: {np.round_(np.mean(money), decimals=2)}")
print(f"中位數: {np.median(money)}")
print(f"最高薪: {np.max(money)}")
print(f"最低薪: {np.min(money)}")
print(f"全距: {np.ptp(money)}")
print(f"25%位置上的薪資{np.percentile(money, 25)}")
print(f"75%位置上的薪資{np.percentile(money, 75)}")
print(f"變異數: {np.var(money)}")
print(f"標準差: {np.std(money)} (變異數開根號)")
print('偏態係數:',sts.skewness(money))
print('峰度係數:',sts.kurtosis(money)+3)
print("-"*20)
# ----- 圖表繪製 ----- #
import matplotlib.pyplot as plt
plt.hist(money, bins=5)
# 第25%, 50%, 75%筆資料位置
plt.axvline(np.percentile(money, 25),0,1,c='g')
plt.axvline(np.mean(money),0,1,c='y')
plt.axvline(np.percentile(money, 75),0,1,c='r')
# 平均數位置
plt.axvline(np.median(money),0,1,linestyle='--',c='purple')
plt.show()
# 箱型圖: 可知離散程度
plt.boxplot(money)
plt.show()
```


---
**練習三、數學最高分及國文最高分-程度比較**
```
import numpy as np
math = np.array([40,25,80,50,44,64,90,85,60,65])
chinese = np.array([61,71,55,70,78,68,60,66,90,80])
math.sort() # 預設由小到大
chinese.sort()
print("math_mean =",math.mean())
print("chinese_mean =",chinese.mean())
print("math_std =", round(math.std(),2))
print("chinese_std =", round(chinese.std(),2))
print("\n","-"*10,"\n")
print("(一) 單位不同時:可以變異係數作比較,數值高表示離散程度高,誤差值大\n")
print("數學變異係數 =",round(math.mean()/math.std(),2))
print("國文變異係數 =",round(chinese.mean()/chinese.std(),2))
print("\n","-"*10,"\n")
print("(二) 單位相同時:可以先轉成標準化值(z-score)再作比較\n")
math_standardized=[]
chinese_standardized=[]
for score in math:
score = round((score - math.mean())/ math.std(),2)
math_standardized.append(score)
for score in chinese:
score = round((score - chinese.mean()) / chinese.std(),2)
chinese_standardized.append(score)
print(math_standardized)
print(chinese_standardized)
```

---
**練習四、共變異數與相關係數**
```
a=np.array([5.4,-4.2,10.4,11.2,-7.8,-2])
b=np.array([3.4,-1.2,7.5,5.2,3,-5])
print('共變異數的推算,計算波動的程度')
print(np.cov(b,a))
# 左上: 前者(b)相對變異數
# 右下: 後者(a)相對變異數
# 反對角線: 共變異數
# 可得結果: b很穩定, a變動性大
print('\n相關係數的推算,計算兩者的相關性')
print(np.corrcoef(a,b))
```

---
# 第四章、機率分配
:::success
* 間斷型資料中的二項分配、超幾何分配、Poisson分配。
* 當資料量龐大(例如十萬筆),資料分配就會落於平均值附近。
* 連續型資料中常態分配,資料分配具有落於平均值附近的特性。
* 基於上述的資料分配我們就可以知道,各種資料的分布:
1.平均值=中位數 (資料量必須夠大)
2.在正負一個標準差範圍內的資料數約佔68%比例。
3.在正負兩個標準差範圍內的資料數約佔95%比例。
4.在正負三個標準差範圍內的資料數約佔99%比例。
* 上述四點也是中央極限定理、假設檢定、Z檢定、T檢定等的基本原理。
:::
## 一、基本機率分配概念

**00. 隨機變數** *=> 試驗結果*
1. 離散型變數 => 結果有限
ex.丟硬幣結果(正/反)、整數的結果
主要計算:平均值、變異數、期望值
2. 連續型變數 => 結果無限
ex.銷售金額(無限大)、身高(無窮小數)
主要計算:機率密度函數
**01. 機率分配** *=> 資料於統計中的分布,包括對位置、散佈、形狀的描述*
[特定分布的資料] + [機率分配] = [找出資料分布的機率與形狀]
1. 主要描述:離散型變數
(1) 二項分配 => 結果只有兩種
(2) 超幾何分配
(3) 波瓦松分配
2. 主要描述:連續型變數
(1) 均勻分配/矩形機率分配
(2) 常態分配
**random函式操作**
1. 隨機生成 整數
* 不包含結束值: ==`numpy.random.randint()`==
* ra1.randint(4,5,(2,2))
* 包含結束值: `random.randint()`
* ra2.randint(4,5)
2. 隨機生成 0~1 小數
* 最多只能產生一個數值: `random.random()`
* ra2.random()
* 最多只能產生一維矩陣: ==`numpy.random.random()`==
* ra1.random(5)
* 可以產生多維矩陣: ==`numpy.random.rand()`==
* ra1.rand(2,2,2)*10
3. 隨機生成 1~10 小數
* 最多只能產生一個數值: `random.random()`
* ra2.random() * 9 + 1
* 最多只能產生一維矩陣: ==`numpy.random.random()`==
* ra1.random(5) * 9 + 1
* 可以產生多維矩陣: ==`numpy.random.rand()`==
* ra1.rand(2,2) * 9 + 1
4. 針對list的隨機套件
* 在list中隨機挑選一個值: `random.choice()`
* ra2.choice(list)
* 將list內資料順序打亂: `random.shuffle()`
* ra2.shuffle(list)
* 從list中隨機獲取5個元素返回: `random.sample()`
* ra2.sample(list, 5)
* 從list中隨機挑選多個值: ==`numpy.random.choice()`==
* args1: `list`
* args2: `取出的數目`
* kwargs: `p=[0.3, 0.3, 0.2, 0.1, 0.1]` (被抽出機率)
* kwargs: `replace=False` (重複值的可能)
5. 兩矩陣是否相同
* 不可直接用 if `a == b`
* if `(a==b).all()`: 兩矩陣是否完全相同
* if `(a==b).any()`: 兩矩陣是否有位置相同的數值
**案例一、尾牙抽獎**
```
# 設定不同獎金中獎機率
# 設定每桌獎項不重複
money = [100,200,500,1000,5000,10000]
for table in range(5):
np1 = ra1.choice(
money, # 選擇的list
3, # 抽出的數目
p=[0.3,0.3,0.2,0.1,0.1,0], # 各項目被抽出機率
replace=False) # 重複值的可能
print(np1, end=" ")
```
---
## 二、離散型變數機率分配
### (一) 二項分配
* 結果只有 0 與 1
* 各項結果互相獨立
* 公式: `numpy.random.binomial(n,p,size)`
* n: 操作次數(ex.每輪丟100次硬幣)
* p: 成功機率(介於0與1之間)
* size: 實驗數量(ex.實驗100輪)
**案例一、骰硬幣**
```
import numpy as np
import matplotlib.pyplot as plt
ps = []
for _ in range(0,1000):
# 得20局,每局丟100次硬幣,各局正面朝上的次數
a = np.random.binomial(100, 0.5, 20)
# 平均每局正面朝上的次數
ps.append(np.mean(a))
# 得1000輪後的平均次數,操作次數越多,結果越接近估計值
print(np.mean(ps))
plt.hist(ps)
plt.show()
```

**案例二、消費者喜好調查,恰兩人喜歡的機率**
```
import numpy as np
import matplotlib.pyplot as plt
round = 10000 # 總共訪問輪數
times = 10 # 每輪訪問次數
customers = 4 # 每次訪問人數
percent = 0.25 # 每人喜歡的機率
total = round * times
count = 0
list = []
for i in range(round):
a = sum(
# 得訪問10次,每次訪問4人中,表示喜歡的人數
np.random.binomial(customers, percent, times)
==2) # 等於2的次數 => 進行加總
list.append(a/10)
count += a
print(count / total)
plt.hist(list)
plt.axvline(count / total,0,1,c="red")
plt.show()
```

---
### (二) 超幾何分配
* 結果只有 0 與 1
* 各項結果"不"互相獨立
* 公式: `numpy.random.hypergeometric(ngood, nbad, nsample, size=None)`
* ngood:目標資料總數
* nbad:非目標資料總數
* nsample:每次抽出數量
* size: 試驗次數
* 需要前三筆資料:因為連續抽取情況下,會影響抽取結果
* 若(樣本/母體 < 0.05),可使用二項分配取代(影響不大)
:::info
:spiral_note_pad: **二項分配 vs. 超幾何分配**
**二項分配:每次結果獨立**
連續抽取多人:
(1) 抽幾次?
(2) 抽中機率多少?
=> 抽完會放回,故母體不減少、機率不改變
**超幾何分配:每次結果非獨立**
連續抽取多人:
(1) 兩群各有多少人?
(2) 抽幾次?
=> 抽完不放回,故母體會減少,機率會改變
:::
**案例三、班上同學5男15女,求抽查到男生作業的機率**
```
import numpy.random as nr
import matplotlib.pyplot as plt
# 二項分配
a = nr.binomial(
3, # 總共抽3人
0.25, # 抽到男生的的機率 ## 二項分配只要機率就好
20 # 抽20次
)
print(a)
# 超幾何分配
s = nr.hypergeometric(
5, # 男生群5人 ## 超幾何分配需要兩群體大小
15, # 女生群15人 ## 超幾何分配需要兩群體大小
3, # 總共抽3人
20 # 抽20次
) # 得到回傳值: 20次中,抽到目標的次數
print(s)
```
---
### (三) Poisson分配 (卜瓦松分配)
* 相同的時間區間內(ex.一年內)
* 不連續發生的事件
* 各項結果互相獨立
* 公式: `numpy.random.poisson(lam,size)`
* lam: 事件發生次數
* size: 試驗次數
* 適合描述單位時間內隨機事件發生次數的機率分布
* 若不符合"獨立"或"隨機",則使用常態分配
* 實務上使用機會少
**案例四、去年發生3次地震,今年發生少於3次的機率**
```
import numpy as np
import numpy.random as nr
x=nr.poisson(lam=3,size=100)
print(np.mean(x<3))
```
---
## 三、連續型變數機率分配
### (一) 均勻分配
* 連續型分布
* 公式: `numpy.random.uniform(low, high, size)`
* ex. 高雄捷運發車時間
```
import numpy as np
import matplotlib.pyplot as plt
s = np.random.uniform(5,10,1000)
plt.hist(s,15)
plt.show()
```

---
### (二) 常態分配
* 連續型分布
* 公式: `numpy.random.normal(loc, scale, size)`
* loc: 平均值
* scale: 標準差
* ex. 班上女同學的身高
```
import numpy.random as nr
import matplotlib.pyplot as plt
x=nr.normal(loc=5, scale=1, size=100)
y=nr.normal(loc=5, scale=2, size=100)
z=nr.normal(loc=5, scale=3, size=100)
plt.hist(z,color='b')
plt.hist(y,color='g')
plt.hist(x,color='r')
plt.show()
```

---
# 第五章、推論統計-抽樣估計
[樣本變異數 & 自由度補充資料](https://blog.udn.com/nilnimest/92412101)
## 一、推論統計基本概念
* 估計(Estimation):從樣本資料推論母體特徵(平均數與標準差)
* 假設檢定(Hypothesis Testing):先針對母體提出假設,再從樣本驗證其是否有效
* 虛無假設
* 對立假設
* 信賴區間
## 二、母體與抽樣
1. 抽樣與普查
* 考量: 必要性、可行性、偽陰或偽陽的可能
2. 準確度與精確度
* 準確度: 與實際資料接近的程度
* 精確度: 抽查樣本相似的程度
3. 抽樣的四個方法
* 簡單隨機抽樣(simple random sampling)
* 又稱純隨機抽樣
* 每個樣本抽取機率均等
* 優點: 容易執行
* 缺點: 需有母體清單、易產生較大誤差

* 系統抽樣(systematic sampling)
* 又稱等距抽樣
* 先隨機抽取地初始樣本,再等距離抽取其他樣本

* 分層抽樣(stratified sampling)
* 將母體按某種特徵或規則劃分不同的層,再從不同層中獨立抽樣
* 優點: 控制樣本規模,誤差小
* 缺點: 成本高
* 適用於層與層間差異性大,而層內個體差異性小

* 整群抽樣(cluster sampling)
* 將母體中若干個單位合併為組,抽樣時直接抽取群,再抽樣
* 優點: 成本低,沒有母體清冊亦可執行
* 缺點: 小群組同性質高時,易造成資料辨識度差
* 適用於群體與群體差異性小;而群體內個體差異性大
## 三、樣本與估計
1. 點估計與區間估計
* 點估計(Point Estimation):估計出單一值
* ex. 男性平均身高170公分
* 區間估計(Interval Estimation):估計出範圍值,又可稱==信賴區間==
* ex. 男性平均身高是161~179公分
2. 抽樣誤差與非抽樣誤差
* 抽樣誤差: 來自樣本與母體的差異
* 可藉由增加樣本數修正
* 非抽樣誤差: 來自於實驗方法的錯誤
* 需透過妥善規劃與嚴格審查修正
## 四、母體與樣本的計算
:::info
**結論:**
1. 母體特性:
* 母數越多,越接近常態分配
3. 樣本特性
* 大數法則:樣本數越多,樣本平均越接近母體平均
* 中央極限定理:樣本數越多,樣本平均數的分配越接近常態分配
* 無論母體是否為常態分配
:::
```
# ----- 產生母體 ------ #
dice=[1,2,3,4,5,6]
population=[]
# 為產生連續性資料
for x in range(10000):
sample=np.random.choice(dice,100)
population.append(sample.mean())
print('母體平均數: ',np.mean(population))
print('母體標準差: ',np.std(population))
print('母體資料總數: ',len(population))
# 依母體平均與標準差 => 常態分佈圖
mu=np.mean(population)
sigma=np.std(population)
x=np.random.normal(mu,sigma,10000)
plt.hist(x,color='red',label='normal distribution')
# 真實的母體資料
plt.hist(population,color='blue',label='population')
plt.legend(fontsize=10)
plt.show()
```

```
# ----- 抽樣 ------ #
mean_diff=[] #平均數差異值
mean_list=[] #儲存樣本的平均數
std_list=[] #儲存樣本的標準差
samples=[] #儲存樣本資料
samples_sizes = [10,100,1000,5000]
for sample_size in samples_sizes:
# 在母體中抽取sample size的樣本
sample = np.random.choice(a=population,size=sample_size)
samples.append(sample)
print('抽樣的樣本數:',sample_size)
print('樣本的平均數:',np.mean(sample))
print('樣本的標準差:',np.std(sample))
mean_different = np.mean(sample) - np.mean(population)
mean_diff.append(mean_different)
mean_list.append(np.mean(sample))
std_list.append(np.std(sample))
print('-'*70)
print(mean_diff)
b=np.array(mean_diff)
print(f"母體平均與樣本平均-差異值最小大約是: {np.min(np.abs(mean_diff)): .5f}")
plt.hist(population,color='blue') #隨機產生的母體資料
plt.hist(sample,color='green') #最後一個sample的資料最接近母體
plt.show()
```

```
# 以散佈圖了解抽樣數目不同時,樣本間的關係
plt.scatter(np.mean(population),np.std(population),c='red',label='population')
plt.scatter(mean_list[0],std_list[0],c='black',label='10sample')
plt.scatter(mean_list[1],std_list[1],c='green',label='100sample')
plt.scatter(mean_list[2],std_list[2],c='blue',label='1000sample')
plt.scatter(mean_list[3],std_list[3],c='yellow',label='5000sample')
plt.legend()
plt.xlabel('mean')
plt.ylabel('std')
plt.show()
# 故樣本數越大,越接近母體真實資料
```

```
# 以直方圖了解抽樣數目不同時,樣本間的關係
fig,ax=plt.subplots(4)
ax[0].hist(samples[0])
ax[1].hist(samples[1])
ax[2].hist(samples[2])
ax[3].hist(samples[3])
plt.show()
# 故樣本數越大,樣本分布越接近常態分配
```

---
# 第六章、推論統計-信賴區間與假設檢定

## 一、基本名詞解釋
1. 預期正確的機率
* 信賴係數(confidence level)
* 信賴水準(confidence coefficient)
2. 預期錯誤的機率
* 顯著水準(significant level)
* α(alpha)
3. 此預期的區間
* 信賴區間(confidence interval)
4. 此預期的邊界
* 信賴界限(confidence limit)
5. 利用z-score標準化分數
* z-score
6. 轉換語法
```
import scipy.stats as st
# 信賴水準 => z分數
st.norm.ppf(.95)
# z分數 => 信賴水準
st.norm.cdf(1.64)
```
## 二、假設檢定流程
### (一)提出虛無假設和對立假設
#### 虛無假設和對立假設
1. 設定希望推翻的目標為虛無假設(H0)
* ex. 一般情形、無罪、可信任客戶
2. 期望證實的結果為對立假設(H1)
* ex. 想證明的特殊觀點、有罪、不可信任
* 要有足夠證據才能證錯
3. 依據H0訂定範圍,將檢定形式分為單尾或雙尾檢定
#### 型 I 錯誤 & 型 II 錯誤
實際是H0(positive),正確接受 => TP
實際是H1(negative),正確推翻 => TN
實際是H0(positive),錯誤推翻 => FP => 型I錯誤
實際是H1(negative),錯誤接受 => TN => 型II錯誤
:::success
**型一錯誤:False Positive 錯誤拒絕(棄真錯誤、α錯誤、偽陽性)**
1. 實際是有信用的,錯誤拒絕 (後果嚴重,盡量避免)
2. 影響信賴區間,可透過增加樣本數修正
**型二錯誤:False Negative 錯誤接受(存偽錯誤、β錯誤、偽陰性)**
1. 實際是無信用的,錯誤接受
2. 偏向外部或其他因素造成
:::
### (二)選擇檢定統計量 (test statistic)
1. 母體已知:無論樣本數大小,皆使用 z 分配 (常態分配)
2. 母體未知:
* 當樣本數 n > 30,可以使用 z 分配 (常態分配)
* 當樣本數 n < 30,使用 t 分配
### (三)決定決策法則 (臨界值 or P-value)
#### 1. 臨界值法 (Critical value method)
使用臨界值法時,我們一般會給定拒絕域 (拒絕H0的區域)以及接受域 (不拒絕H0的區域),當檢定統計量落入拒絕域時,則表示我們的樣本有足夠的證據來拒絕H0;反之,當檢定統計量落入接受域的時候,就表示我們的樣本資訊沒有足夠的證據來拒絕H0。
#### 2.P值法 (P-value method)
1. p-value是在假設虛無假設為真的前提下,觀察到檢定統計量比取樣得到的值更極端的機率
2. p-value越小,表示檢定的結果越顯著,越可以拒絕假設檢定中的虛無假設。
3. 若P值小於 α ,則拒絕虛無假設 (H0),否則便無法拒絕H0。
### (四)比較結果,產生結論
## 三、混淆矩陣(Confusion Matrix)

### 準確率(Accuracy)= (tp+tn)/(tp+fp+fn+tn)
正確判斷有信用或無信用客戶的機率
### 精確率(Precision)= tp/(tp+fp)
**<假設positive,正確的機率>
1. 以預測為主
2. 預測有信用,正確預測的機率
### 召回率(Recall)= tp/(tp+fn)
**<真實為positive,正確的機率>
1. 以實際為主
2. 有信用的客戶,正確預測的機率