模型假设检测、岭回归、Lasso回归、Lodistic回归模型、决策树与随机森林、K近邻模型
模型假设检测、岭回归、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()