模型假設檢測、嶺回歸、Lasso回歸、Lodistic回歸模型、決策樹與隨機森林、K近鄰模型
- 模型假設檢驗(F與T)
- 嶺回歸模型、Lasso回歸模型和交叉模型
- 決策樹和決策森林
- K近鄰模型
模型假設檢驗(F與T)
F檢驗概念
提出問題的原假設和備擇假設,在原假設的條件下,構造統計量F,根據樣本信息,計算統計量的值,對⽐統計量的值和理論F分布的值,當統計量值超過理論值時,拒絕原假設,否則接受原假設
代碼執行
調用模塊
# 調用模塊 import numpy as np import pandas as pd import matplotlib.pyplot as plt import statsmodels.api as sm
建立多元回歸模型
# ⽣成由State變量衍⽣的啞變量 dump = pd.get_dummies(Profit.State) # 將啞變量與原始數據集⽔平合並 new_date = pd.concat([Profit,dump], axis = 1) # 刪除State變量和California變量(因為State變量已被分解為啞變量,New York變量需要作為參照組) new_date.drop(labels = ['State','New York'], axis = 1, inplace = True) # 拆分數據集Profit_New train, test = model_selection.train_test_split(new_date, test_size = 0.2, random_state=1234) # 建模 model2 = sm.formula.ols('Profit~RD_Spend+Administration+Marketing_Spend+Florida+California',data = train).fit()
模型F檢測地原假設
# 獲取均值 ybar=train.Profit.mean() # 統計變量個數和觀測個數 p=model2.df_model n=train.shape[0] # 計算回歸平方和 RSS=np.sum((model2.fittedvalues-ybar)**2) # 計算誤差平⽅和 ESS=np.sum(model2.resid**2) # 計算F統計量的值 F=(RSS/p)/(ESS/(n-p-1)) F
計算理論值
# 導⼊模塊 from scipy.stats import f # 計算F分布的理論值 F_Theroy = f.ppf(q=0.95, dfn = p,dfd = n-p-1) F_Theroy
結論
F統計量值174.64⼤於F分布的理論值2.50,原假設是錯的
T假設
T檢驗更加側重於檢驗模型的各個參數是否合理
代碼
# 有關模型的概覽信息 model2.summary()
主要看P>|t|列,其余變量都沒有通過系數的顯著性檢驗,在模型中變量不影響利潤的重要因素
嶺回歸模型、Lasso回歸模型和交叉模型
線性回歸模型的短板
- 自變量的個數大於樣本量
- 自變量之間存在多重共線性
為了解決這些短板就誕生了:嶺回歸和Lasso模型
嶺回歸模型
在線性回歸模型的基礎之上添加一個l2懲罰項(平方項、正則項)
'''該模型最終轉變成求解圓柱體與橢圓拋物線的焦點問題'''
嶺回歸函數
RidgeCV(alphas=(0.1, 1.0, 10.0), fit_intercept=True, normalize=False,
scoring=None, cv=None)
alphas:⽤於指定多個lambda值的元組或數組對象,默認該參數包含0.1、1和10三種值。
fit_intercept:bool類型參數,是否需要擬合截距項,默認為True。
normalize:bool類型參數,建模時是否需要對數據集做標准化處理,默認為False。
scoring:指定⽤於評估模型的度量⽅法。 cv:指定交叉驗證的重數。
代碼案例
調用模塊
import numpy as np import pandas as pd import matplotlib.pyplot as plt from sklearn.linear_model import Ridge,RidgeCV from sklearn import model_selection
獲取數據
# 讀取糖尿病數據集 diabetes = pd.read_excel(r'diabetes.xlsx') # 構造自變量(剔除患者性別、年齡和因變量) predictors = diabetes.columns[2:-1] # 將數據集拆分為訓練集和測試集 X_train, X_test, y_train, y_test = model_selection.train_test_split(diabetes[predictors], diabetes['Y'], test_size = 0.2, random_state = 1234 ) diabetes
# 構造不同的Lambda值 Lambdas = np.logspace(-5, 2, 200) # 嶺回歸模型的交叉驗證 # 設置交叉驗證的參數,對於每一個Lambda值,都執行10重交叉驗證 ridge_cv = RidgeCV(alphas = Lambdas, normalize=True, scoring='neg_mean_squared_error', cv = 10) # 模型擬合 ridge_cv.fit(X_train, y_train) # 返回最佳的lambda值 ridge_best_Lambda = ridge_cv.alpha_ ridge_best_Lambda
獲得系數
# 導入第三方包中的函數 from sklearn.metrics import mean_squared_error # 基於最佳的Lambda值建模 ridge = Ridge(alpha = ridge_best_Lambda, normalize=True) ridge.fit(X_train, y_train) # 返回嶺回歸系數 what_num=pd.Series(index = ['Intercept'] + X_train.columns.tolist(),data = [ridge.intercept_] + ridge.coef_.tolist()) what_num
預測值
# 預測 ridge_predict = ridge.predict(X_test) # 預測效果驗證 RMSE = np.sqrt(mean_squared_error(y_test,ridge_predict)) RMSE
Lasso回歸模型
在線性回歸模型的基礎之上添加一個l1懲罰項(絕對值項、正則項)
相較於嶺回歸降低了模型的復雜度
'''該模型最終轉變成求解正方體與橢圓拋物線的焦點問題'''
Lasso函數
LassoCV(alphas=None, fit_intercept=True,
normalize=False,max_iter=1000, tol=0.0001)
alphas:指定具體的Lambda值列表⽤於模型的運算
fit_intercept:bool類型參數,是否需要擬合截距項,默認為True
normalize:bool類型參數,建模時是否需要對數據集做標准化處理,默認為False
max_iter:指定模型最⼤的迭代次數,默認為1000次
代碼執行
# 導入第三方模塊中的函數
from sklearn.linear_model import Lasso,LassoCV
# LASSO回歸模型的交叉驗證
lasso_cv = LassoCV(alphas = Lambdas, normalize=True, cv = 10, max_iter=10000)
lasso_cv.fit(X_train, y_train)
# 輸出最佳的lambda值
lasso_best_alpha = lasso_cv.alpha_
lasso_best_alpha
獲得系數
# 基於最佳的lambda值建模 lasso = Lasso(alpha = lasso_best_alpha, normalize=True, max_iter=10000) lasso.fit(X_train, y_train) # 返回LASSO回歸的系數 pd.Series(index = ['Intercept'] + X_train.columns.tolist(),data = [lasso.intercept_] + lasso.coef_.tolist())
# Y=-279+6BMI+0.7BP-0.1S2-0.4S3+0.0S4+44S5+0.3S6
預測值
# 預測 lasso_predict = lasso.predict(X_test) # 預測效果驗證 RMSE = np.sqrt(mean_squared_error(y_test,lasso_predict)) RMSE
''' 在運用這些模型時,需要使用到交叉驗證 '''
交叉驗證
將所有數據都參與到模型的構建和測試中 最后生成多個模型
再從多個模型中篩選出得分最高(准確度)的模型
將線性回歸模型的公式做Logit變換即為Logistic回歸模型
將預測問題變成了0到1之間的概率問題
事件發生比為:e的β1次方
混淆矩陣
A:表示正確預測負例的樣本個數,⽤TN表示。
B:表示預測為負例但實際為正例的個數,⽤FN表示。
C:表示預測為正例但實際為負例的個數,⽤FP表示。
D:表示正確預測正例的樣本個數,⽤TP表示。
准確率:表示正確預測的正負例樣本數與所有樣本數量的⽐值,即(A+D)/(A+B+C+D)。
正例覆蓋率:表示正確預測的正例數在實際正例數中的⽐例,即D/(B+D)。
負例覆蓋率:表示正確預測的負例數在實際負例數中的⽐例,即A/(A+C)。
正例命中率:表示正確預測的正例數在預測正例數中的⽐例,即D/(C+D),
模型評估方法
1.ROC曲線
主要計算折線下的⾯積,這個⾯積稱為AUC。AUC的值越⼤越好,通常情況下, 當AUC在0.8以上時,模型就基本可以接受了。
2.KS曲線
通過兩條曲線很難對模型的好壞做評估,選⽤最⼤的KS值作為衡量指標。KS的計算公式為: KS= Sensitivity-(1- Specificity)= Sensitivity+ Specificity-1。對於KS值⽽⾔,也是希望越⼤越好,通常 情況下,當KS值⼤於0.4時,模型可以接受。
Logistic回歸模型函數
LogisticRegression(tol=0.0001, fit_intercept=True,class_weight=None, max_iter=100)
tol:⽤於指定模型跌倒收斂的閾值
fit_intercept:bool類型參數,是否擬合模型的截距項,默認為True
class_weight:⽤於指定因變量類別的權重,如果為字典,則通過字典的形式{class_label:weight}傳 遞每個類別的權重;如果為字符串'balanced',則每個分類的權重與實際樣本中的⽐例成反⽐,當各分 類存在嚴重不平衡時,設置為'balanced'會⽐較好;如果為None,則表示每個分類的權重相等
max_iter:指定模型求解過程中的最⼤迭代次數, 默認為100
代碼案例
獲取數據
# 導入第三方模塊
import pandas as pd
import numpy as np
from sklearn import model_selection
from sklearn import linear_model
構造訓練、測試集
# 讀取數據
sports = pd.read_csv(r'Run or Walk.csv')
sports.head()
# 提取出所有自變量名稱
predictors = sports.columns[4:]
#構建自變量矩陣
X = sports.loc[:,predictors]
# 提取y變量值
y = sports.activity
# 將數據集拆分為訓練集和測試集
X_train, X_test, y_train, y_test = model_selection.train_test_split(X, y, test_size = 0.25, random_state = 1234)
# 利用訓練集建模
sklearn_logistic = linear_model.LogisticRegression()
sklearn_logistic.fit(X_train, y_train)
# 返回模型的各個參數
print(sklearn_logistic.intercept_, sklearn_logistic.coef_)
模型預測
# 模型預測 sklearn_predict = sklearn_logistic.predict(X_test) # 預測結果統計 pd.Series(sklearn_predict).value_counts()
# 導入第三方模塊 from sklearn import metrics # 混淆矩陣 cm = metrics.confusion_matrix(y_test, sklearn_predict, labels = [0,1]) cm
Accuracy = metrics.scorer.accuracy_score(y_test, sklearn_predict) Sensitivity = metrics.scorer.recall_score(y_test, sklearn_predict) Specificity = metrics.scorer.recall_score(y_test, sklearn_predict, pos_label=0) print('模型准確率為%.2f%%:' %(Accuracy*100)) print('正例覆蓋率為%.2f%%' %(Sensitivity*100)) print('負例覆蓋率為%.2f%%' %(Specificity*100))
混淆矩陣
# 混淆矩陣的可視化 # 導入第三方模塊 import seaborn as sns import matplotlib.pyplot as plt %matplotlib # 繪制熱力圖 sns.heatmap(cm, annot = True, fmt = '.2e',cmap = 'GnBu') # 圖形顯示 plt.show()
決策樹和決策森林
概念
""" 決策樹與隨機森林的功能 默認情況下解決分類問題(買與不買、帶與不帶、走與不走) 也可以切換算法解決預測問題(具體數值多少) """
樹其實是一種計算機底層的數據結構,計算機里面的樹都是自上而下的生長
決策樹則是算法模型中的一種概念 有三個主要部分:
根節點、枝節點、葉子節點
# 根節點與枝節點用於存放條件 葉子節點存放真正的數據結果
1.信息熵
⽤來表示信息量的⼤⼩。 信息量越⼤(分類越不“純凈”),對應的熵值就越⼤,反之亦然。
eg:信息熵小相當過馬路時為紅燈情況,信息熵大相當於買彩票中獎情況
2.條件熵
條件熵其實就是由信息熵再次細分而來
eg:比如有九個用戶購買了商品五個沒有購買 那么條件熵就是繼續從購買不購買的用戶中再選擇一個條件(比如按照性別計算男和女的熵)
3.信息增益
信息增益可以反映出某個條件是否對最終的分類有決定性的影響
在構建決策樹時根節點與枝節點所放的條件按照信息增益由大到小排
4.信息增益率
決策樹中的ID3算法使⽤信息增益指標實現根節點或中間節點的字段選擇,但是該指標存在⼀個⾮常明顯的缺
點,即信息增益會偏向於取值較多的字段。
為了克服信息增益指標的缺點,提出了信息增益率的概念,它的思想很簡單,就是在信息增益的基礎上進⾏相
應的懲罰。
5.基尼指數
可以讓模型解決預測問題
6.基尼指數增益
與信息增益類似,還需要考慮⾃變量對因變量的影響程度,即因變量的基尼指數下降速度的快慢,下降得越快,⾃變量對因變量的影響就越強
決策樹函數
DecisionTreeClassifier(criterion='gini', splitter='best', max_depth=None,min_samples_split=2, min_samples_leaf=1,max_leaf_nodes=None, class_weight=None)
參數說明:
criterion:⽤於指定選擇節點字段的評價指標,對於分類決策樹,默認為'gini',表示采⽤基尼指數選 擇節點的
最佳分割字段;對於回歸決策樹,默認為'mse',表示使⽤均⽅誤差選擇節點的最佳分割字段
splitter:⽤於指定節點中的分割點選擇⽅法,默認為'best',表示從所有的分割點中選擇最佳分割點; 如果指
定為'random',則表示隨機選擇分割點
max_depth:⽤於指定決策樹的最⼤深度,默認為None,表示樹的⽣⻓過程中對深度不做任何限制
min_samples_split:⽤於指定根節點或中間節點能夠繼續分割的最⼩樣本量, 默認為2
min_samples_leaf:⽤於指定葉節點的最⼩樣本量,默認為1
max_leaf_nodes:⽤於指定最⼤的葉節點個數,默認為None,表示對葉節點個數不做任何限制
class_weight:⽤於指定因變量中類別之間的權重,默認為None,表示每個類別的權重都相等;如果 為
balanced,則表示類別權重與原始樣本中類別的⽐例成反⽐;還可以通過字典傳遞類別之間的
權重 差異,其形式為{class_label:weight}
隨機森林思想
隨機森林中每顆決策樹都不限制節點字段選擇,有多棵樹組成的隨機森林
在解決分類問題的時候采用投票法、解決預測問題的時候采用均值法
隨機森林函數
RandomForestClassifier(n_estimators=10, criterion='gini', max_depth=None, min_samples_split=2, min_samples_leaf=1, max_leaf_nodes=None, bootstrap=True, class_weight=None)
n_estimators:⽤於指定隨機森林所包含的決策樹個數
criterion:⽤於指定每棵決策樹節點的分割字段所使⽤的度量標准,⽤於分類的隨機森林,默認的 criterion值
為'gini';⽤於回歸的隨機森林,默認的criterion值為'mse'
max_depth:⽤於指定每棵決策樹的最⼤深度,默認不限制樹的⽣⻓深度
min_samples_split:⽤於指定每棵決策樹根節點或中間節點能夠繼續分割的最⼩樣本量, 默認為2
min_samples_leaf:⽤於指定每棵決策樹葉節點的最⼩樣本量,默認為1
max_leaf_nodes:⽤於指定每棵決策樹最⼤的葉節點個數,默認為None,表示對葉節點個數不做任 何限制
bootstrap:bool類型參數,是否對原始數據集進⾏bootstrap抽樣,⽤於⼦樹的構建,默認為True
class_weight:⽤於指定因變量中類別之間的權重,默認為None,表示每個類別的權重都相等
代碼案例
獲取數據
# 導入第三方模塊 import pandas as pd import numpy as np import matplotlib.pyplot as plt from sklearn import model_selection from sklearn import linear_model # 讀⼊數據 Titanic = pd.read_csv(r'Titanic.csv') Titanic
數據處理
# 刪除⽆意義的變量,並檢查剩余變量是否含有缺失值 Titanic.drop(['PassengerId','Name','Ticket','Cabin'], axis = 1, inplace = True) Titanic.isnull().sum(axis = 0) # 對Sex分組,⽤各組乘客的平均年齡填充各組中的缺失年齡 fillna_Titanic = [] for i in Titanic.Sex.unique(): update = Titanic.loc[Titanic.Sex == i,].fillna(value = {'Age': Titanic.Age[Titanic.Sex == i].mean()}, inplace = False) fillna_Titanic.append(update) Titanic = pd.concat(fillna_Titanic) # 使⽤Embarked變量的眾數填充缺失值 Titanic.fillna(value = {'Embarked':Titanic.Embarked.mode()[0]}, inplace=True) Titanic.head(
獲得參數值
from sklearn.model_selection import GridSearchCV from sklearn import tree # 預設各參數的不同選項值 max_depth = [2,3,4,5,6] min_samples_split = [2,4,6,8] min_samples_leaf = [2,4,8,10,12] # 將各參數值以字典形式組織起來 parameters = {'max_depth':max_depth, 'min_samples_split':min_samples_split, 'min_samples_leaf':min_samples_leaf} # ⽹格搜索法,測試不同的參數值 grid_dtcateg = GridSearchCV(estimator = tree.DecisionTreeClassifier(), param_grid = parameters, cv=10) # 模型擬合 grid_dtcateg.fit(X_train, y_train) # 返回最佳組合的參數值 grid_dtcateg.param_grid
構建決策樹
from sklearn import metrics # 構建分類決策樹 CART_Class = tree.DecisionTreeClassifier(max_depth=3,min_samples_leaf=4,min_samples_split=2) # 模型擬合 decision_tree = CART_Class.fit(X_train,y_train) # 模型在測試集上的預測 pred = CART_Class.predict(X_test) # 模型的准確率 print('模型在測試集的預測准確率:\n',metrics.accuracy_score(y_test,pred)) print('模型在訓練集的預測准確率:\n', metrics.accuracy_score(y_train,CART_Class.predict(X_train)))
K近鄰模型
概念
思想:根據位置樣本點周邊K個鄰居樣本完成預測或者分類
K值選擇
1.先猜測
2.交叉驗證
3.作圖選擇最合理的k值,准確率(越大越好) MSE(越小越好)
如果k值過小,會導致模型過擬合,反之,又會時模型欠擬合
距離
歐式距離:兩點之間的直線距離
曼哈頓距離:默認兩點直接有障礙物
余弦相似度:eg:論文查重
K近鄰模型函數
neighbors.KNeighborsClassifier(n_neighbors=5, weights='uniform', p=2, metric='minkowski',p=2)
n_neighbors:⽤於指定近鄰樣本個數K,默認為5
weights:⽤於指定近鄰樣本的投票權重,默認為'uniform',表示所有近鄰樣本的投票權重⼀樣;如果 為'distance',則表示投票權重與
距離成反⽐,即近鄰樣本與未知類別的樣本點距離越遠,權重越⼩, 反之,權重越⼤
metric:⽤於指定距離的度量指標,默認為閔可夫斯基距離
p:當參數metric為閔可夫斯基距離時,p=1,表示計算點之間的曼哈頓距離;p=2,表示計算點之間 的歐⽒距離;該參數的默認值為2
代碼案例
獲取數據
# 導入第三方包 import pandas as pd # 導入數據 Knowledge = pd.read_excel(r'Knowledge.xlsx') # 返回前5行數據 Knowledge.head()