数据分析中的常用数学模型实战教程笔记(上)
作者:互联网
文章目录
一元线性回归
如果需要查找两个变量之间是否存在线性关系
1.散点图
散点图只能反映出两个变量之间是否存在线性关系
并不能直接断定两个变量没有关系(还可能存在非线性关系)
2.公式计算
利用线性计算公式推导两个变量之间的关系
大于0.8说明两个变量存在明显的线性关系
大于0.5小于0.8说明两个变量存在线性关系
大于0.3小于0.5说明两个变量可能存在线性关系
小于0.3说明两个变量之间不存在线性关系(没有关系、非线性)
# 数学概念
因变量:受自变量的影响而改变
自变量:由实验者操纵、掌握的变量
自变量是原因,因变量是结果
ex:
x称为⾃变量,y称为因变量
a为模型的截距项,b为模型的斜率项,ε为模型的误差项;
误差项ε的存在主要是为了平衡等号两边的值,通常被称为模型无法解释的部分
一元线性回归代码
import pandas as pd
import statsmodels.api as sm
import matplotlib.pyplot as plt
df1 = pd.read_csv(r'Salary_Data.csv')
# 先画出工作年限和薪资待遇的散点图
# 绘制散点图
plt.scatter(x = df1.YearsExperience, # 指定散点图的x轴数据
y = df1.Salary, # 指定散点图的y轴数据
color = 'steelblue' # 指定散点图中点的颜色
)
# 添加x轴和y轴标签
plt.xlabel('YearsExperience')
plt.ylabel('Salary')
# 添加标题
plt.title('Salary&YearsExperience')
# 显示图形
plt.show()
# 使用线性回归公式计算方程
fit = sm.formula.ols('Salary~YearsExperience',data=df1).fit()
fit.params
Intercept 25792.200199 截距项
YearsExperience 9449.962321 斜率项
公式:
Salary = 25792.200199 + 9449.962321YearsExperience
多元线性回归模型
1.对于一元线性回归模型来说,其反映的是单个自变量对因变量的影响,
然而实际情况中,影响因变量的自变量往往**不止一个**,
从而需要将一元线性回归模型扩展到多元线性回归模型
2.训练集
主要就是用来模拟出数学模型
测试集
主要就是用来测试模拟的数学模型是否准确
通常将数据集的80%作为训练集,20%作为训练集
我们在研究因变量与自变量关系的时候,如果自变量不止一个,
那么我们需要确保多个自变量之间互相没有干扰(不能有关系)
通常采取的策略是先转换成数值型变量,之后随即删除一个用来解决自变量之间强烈相关性问题
3.离散型变量
非数值类型的数据
连续型变量
数字类型的数据
4.多个自变量之间一定不能存在强烈的关系
多元线性回归代码
from sklearn import model_selection
df2 = pd.read_excel(r'Predict to Profit.xlsx') #读取数据
df2.head()
# 将数据拆分成训练集(80%)和测试集(20%)
train,test = model_selection.train_test_split(df2,test_size=0.2,random_state=1234)
# 依据训练集创建模型(State不是数值型变量 带入模型需要加C)
model = sm.formula.ols('Profit~RD_Spend+Administration+Marketing_Spend+C(State)',
data=train).fit()
# 离散型变量转换用 C(数据字段) 非数字都可以
# .fit() 拟合
print('模型的偏回归系数分别为:\n', model.params)
模型的偏回归系数分别为:
Intercept 58581.516503
C(State)[T.Florida] 927.394424
C(State)[T.New York] -513.468310
RD_Spend 0.803487
Administration -0.057792
Marketing_Spend 0.013779
dtype: float64
排除干扰随机删除一项,只保留new york和florida
# 利用模型验证
# 先删除实际因变量利润 用模型产生预测利润
test_X = test.drop(labels='Profit',axis=1)
# 模型预测
pred = model.predict(exog = test_X)
print('对比预测值和实际值的差异:\n',
pd.DataFrame({'Prediction':pred,
'Real':test.Profit}))
对比预测值和实际值的差异:
Prediction Real
8 150621.345801 152211.77
48 55513.218079 35673.41
14 150369.022458 132602.65
42 74057.015562 71498.49
29 103413.378282 101004.64
44 67844.850378 65200.33
4 173454.059691 166187.94
31 99580.888894 97483.56
13 128147.138396 134307.35
18 130693.433835 124266.90
预测与实际结果比较相当接近
自定义哑变量
又称虚设变量、名义变量或哑变量,用以反映质的属性的一个人工变量,是量化了的自变量,通常取值为0或1。引入哑变量可使线形回归模型变得更复杂,但对问题描述更简明,一个方程能达到两个方程的作用,而且接近现实。
模型中引入虚拟变量的**作用**
1、分离异常因素的影响,例如分析我国GDP的时间序列,必须考虑“**”因素对国民经济的破坏性影响,剔除不可比的“**”因素。
2、检验不同属性类型对因变量的作用,例如工资模型中的文化程度、季节对销售额的影响。
3、提高模型的精度,相当于将不同属性的样本合并,扩大了样本容量(增加了误差自由度,从而降低了误差方差)
-{
生成有state变量衍生的哑变量
dummies = pd.get_dummies(变量名.State)
将哑变量与原始数据集水平合并
Profit_New = pd.concat([变量名,dummies], axis = 1)
删除不需要的值
Profit_New.drop(labels = ['State','*****'], axis = 1, inplace = True)
}
# 生成由State变量衍生的哑变量
dummies = pd.get_dummies(df2.State)
# 将哑变量与原始数据集水平合并
Profit_New = pd.concat([df2,dummies], axis = 1)
Profit_New.head()
# 删除不需要的值 手动剔除new york
Profit_New.drop(labels = ['State','New York'], axis = 1, inplace = True)
# 拆分数据集Profit_New
train, test = model_selection.train_test_split(Profit_New, test_size = 0.2, random_state=1234)
# 建模
model2 = sm.formula.ols('Profit~RD_Spend+Administration+Marketing_Spend+Florida+California', data = train).fit()
print('模型的偏回归系数分别为:\n', model2.params)
# model2测出各种系数
模型的偏回归系数分别为:
Intercept 58068.048193
RD_Spend 0.803487
Administration -0.057792
Marketing_Spend 0.013779
Florida 1440.862734
California 513.468310
dtype: float64
这里就删除了new york进行建模预测
# 利用模型验证
# 先删除实际因变量利润 用模型产生预测利润
test_X = test.drop(labels='Profit',axis=1)
# 模型预测
pred = model2.predict(exog = test_X)
print('对比预测值和实际值的差异:\n',
pd.DataFrame({'Prediction':pred,
'Real':test.Profit}))
对比预测值和实际值的差异:
Prediction Real
8 150621.345802 152211.77
48 55513.218079 35673.41
14 150369.022458 132602.65
42 74057.015562 71498.49
29 103413.378282 101004.64
44 67844.850378 65200.33
4 173454.059692 166187.94
31 99580.888895 97483.56
13 128147.138397 134307.35
18 130693.433835 124266.90
和未引入哑变量(手动删除一项、)的预测结果相差不大
模型检验之F检验
F检验(F-test),最常用的别名叫做**联合假设检验**,此外也称方差比率检验、方差齐性检验。
它是一种在零假设之下,统计值服从F-分布的检验。
其通常是用来分析用了超过一个参数的统计模型,以判断该模型中的全部或一部分参数是否适合用来估计母体。
*检验模型的合理性*
计算得到的F值,再与对应F分布表查询,若大于表中的值,则接受原假设(两样本的方差相同),否则拒绝原假设。
#导入第三方模块
import numpy as np
#计算建模数据中因变量的均值
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))
print('F统计量的值:',F)
out:
F的统计量的值:174.6372
可以看出计算出来的F统计量值174.64远远大于理论值2.50,
所以应当拒绝原假设,即多元线性回归模型是显著的,也就是说回归模型的偏回归系数都不全为0。
————————————————
原代码:https://blog.csdn.net/weixin_49855757/article/details/109231165
结论
模型检验之T检验
*检验系数的合理性*
# 查看T检验
model2.summary()
P>|t| 系数越小,影响利润的程度越大、高
首先是 RD_Spend 0.000 # 研发成本
其次是 Administration 0.265 # 管理成本
才是 Marketing_Spend 0.359 # 销售额
最后才是是地区 # 跟地区关系不大
线性回归模型的短板
1.自变量的个数多于样本量
2.多个自变量之间存在多重共线性
岭回归模型
目的是优化线性回归
为解决多元线性回归模型中可能存在的不可逆问题,统计学家提出了岭回归模型
该模型的思路是在线性回归模型的目标函数之上添加一个 l2 正则项(惩罚项)
用于平衡模型方差和偏差
l2其实本质就是平方项
线性回归模型的目标函数
为了保证回归系数β \betaβ可求,岭回归模型在目标函数上加了一个L2范数的惩罚项
其中λ为非负数,λ 越大,则为了使J ( β ) 最小,回归系数 β 就越小。
————————————————
详细可看:https://blog.csdn.net/weixin_43374551/article/details/83688913
import pandas as pd
import numpy as np
from sklearn import model_selection
from sklearn.linear_model import Ridge
import matplotlib.pyplot as plt
data=pd.read_excel(r'diabetes.xlsx')
#拆分为训练集和测试集
predictors=data.columns[:-1]
x_train,x_test,y_train,y_test=model_selection.train_test_split(data[predictors],data.Y,
test_size=0.2,random_state=1234)
#构造不同的lambda值
Lambdas=np.logspace(-5,2,200)
#存放偏回归系数
ridge_cofficients=[]
for Lambda in Lambdas:
ridge=Ridge(alpha=Lambda,normalize=True)
ridge.fit(x_train,y_train)
ridge_cofficients.append(ridge.coef_)
#绘制岭迹曲线
plt.rcParams['font.sans-serif']=['Microsoft YaHei']
plt.rcParams['axes.unicode_minus']=False
plt.style.use('ggplot')
plt.plot(Lambdas,ridge_cofficients)
#x轴做对数处理
plt.xscale('log')
plt.xlabel('Log(Lambda)')
plt.ylabel('Cofficients')
plt.show()
'''曲线不容易看出最小值'''
交叉验证
将数据先进行分组,之后取一组作为测试集,其他组作为训练集
依次往复,知道所有的分组都参与了模型的训练和测试为止,最后选出最佳模型
- 交叉验证公式
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 pandas as pd
import numpy as np
from sklearn import model_selection
from sklearn.linear_model import RidgeCV
data=pd.read_excel(r'diabetes.xlsx')
#拆分为训练集和测试集
predictors=data.columns[:-1]
x_train,x_test,y_train,y_test=model_selection.train_test_split(data[predictors],data.Y,
test_size=0.2,random_state=1234)
#构造不同的lambda值
Lambdas=np.logspace(-5,2,200)
#设置交叉验证的参数,使用均方误差评估
ridge_cv=RidgeCV(alphas=Lambdas,normalize=True,scoring='neg_mean_squared_error',cv=10)
ridge_cv.fit(x_train,y_train)
print(ridge_cv.alpha_)
'''
0.013509935211980266
'''
import pandas as pd
import numpy as np
from sklearn import model_selection
from sklearn.linear_model import Ridge,RidgeCV
from sklearn.metrics import mean_squared_error
data=pd.read_excel(r'diabetes.xlsx')
data=data.drop(['AGE','SEX'],axis=1)
#拆分为训练集和测试集
predictors=data.columns[:-1]
x_train,x_test,y_train,y_test=model_selection.train_test_split(data[predictors],data.Y,
test_size=0.2,random_state=1234)
#构造不同的lambda值
Lambdas=np.logspace(-5,2,200)
#设置交叉验证的参数,使用均方误差评估
ridge_cv=RidgeCV(alphas=Lambdas,normalize=True,scoring='neg_mean_squared_error',cv=10)
ridge_cv.fit(x_train,y_train)
# 基于最佳lambda值建模
ridge=Ridge(alpha=ridge_cv.alpha_,normalize=True)
ridge.fit(x_train,y_train)
#返回岭回归系数
print(pd.Series(index=['Intercept']+x_train.columns.tolist(),
data=[ridge.intercept_]+ridge.coef_.tolist()))
# 预测
ridge_pred=ridge.predict(x_test)
# 预测效果验证
RMSE=mean_squared_error(y_test,ridge_pred)
print(RMSE)
RMSE越大越精确
系数越大越不精确
Lasso回归
可以降低模型的复杂度,通过添加l1正则项(惩罚项)
l1其实本质就是绝对值
- Lasso公式
LassoCV(eps=0.001, n_alphas=100, alphas=None, fit_intercept=True, normalize=False, precompute=‘auto’,
max_iter=1000, tol=0.0001, copy_X=True, cv=None, verbose=False, n_jobs=1, positive=False,
random_state=None, selection=‘cyclic’)
• eps:指代λ \lambdaλ最小值与最大值的商,默认为0.001。
• n_alphas:指定λ \lambdaλ的个数,默认为100个。
• alphas:指定具体的λ \lambdaλ列表用于模型的运算。
• fit_intercept:bool类型,是否需要拟合截距项,默认为True。
• normalize:bool类型,建模时是否对数据集做标准化处理,默认为False。
• precompute:bool类型,是否在建模前计算Gram矩阵提升运算速度,默认为False。
• max_iter:指定模型的最大迭代次数。
• tol:指定模型收敛的阈值,默认为0.0001。
• copy_X:bool类型,是否复制自变量X的数值,默认为True。
• cv:指定交叉验证的重数。
• verbose:bool类型,是否返回模型运行的详细信息,默认为False。
• n_jobs:指定使用的CPU数量,默认为1,如果为-1表示所有CPU用于交叉验证的运算。
• positive:bool类型,是否将回归系数强制为正数,默认为False。
• random_state:指定随机生成器的种子。
• selection:指定每次迭代选择的回归系数,如果为’random’,表示每次迭代中将随机更新回归系数;
如果为’cyclic’,则每次迭代时回归系数的更新都基于上一次运算
# 导入第三方模块
import pandas as pd
import numpy as np
from sklearn import model_selection
from sklearn.linear_model import Lasso,LassoCV
from sklearn.metrics import mean_squared_error
# 读取文件
data=pd.read_excel(r'diabetes.xlsx')
data=data.drop(['AGE','SEX'],axis=1)
#拆分为训练集和测试集
predictors=data.columns[:-1]
x_train,x_test,y_train,y_test=model_selection.train_test_split(data[predictors],data.Y,
test_size=0.2,random_state=1234)
#构造不同的lambda值
Lambdas=np.logspace(-5,2,200)
#设置交叉验证的参数,使用均方误差评估
lasso_cv=LassoCV(alphas=Lambdas,normalize=True,cv=10,max_iter=10000)
lasso_cv.fit(x_train,y_train)
lasso_cv.alpha_
''' 0.06294988990221888 '''
相对于岭回归而言,可以看到LASSO回归剔除了两个变量,降低了模型的复杂度,同时减少了均方误差,提高了模型的拟合效果。
* Lasso回归 > 岭回归 > 线性回归 *
Logistich回归模型
我们前面学习的线性回归是用来做预测相关分析
eg:发病率
而Logistich回归不是用来做预测而是用来做分类相关分析
eg:高低学历
Logistich回归本质上还是回归模型但是属于"广义回归"
之前的线性回归属于"狭义回归"
- logistich公式
sklearn.linear_model.LogisticRegression(penalty=‘l2’, dual=False, *tol=0.0001, C=1.0, *fit_intercept=True,
intercept_scaling=1, *class_weight=None, random_state=None, solver=‘liblinear’, *max_iter=100,
multi_class=‘ovr’, verbose=0, warm_start=False, n_jobs=None, l1_ratio=None)
penalty:字符串,可选参数。指定正则化惩罚项使用的范数。
dual:布尔值,可选参数,默认为False。选择原始函数还是对偶函数。对偶函数仅在penalty为’l2’、solver为’liblinear’时才可使用,
如果样本数大于特征数则推荐使用原始函数。
* tol:浮点数,可选参数,默认值为0.0001。模型迭代收敛的阈值。
C:浮点数,可选参数,默认值为1.0。正则化强度的倒数。值越小,正则化越强,该值必须为正数。
* fit_intercept:布尔值,可选参数,默认为True。是否添加截距项。相当于在X数据集上人为添加常数列1,用于计算截距项。
intercept_scaling:浮点数,可选参数,默认为1。
* class_weight:可选参数,指定因变量各类别的权重。
如果为字典,则通过字典的形式传递每个类别的权重
如果为字符串‘balanced’,则每个分类的权重与实际样本中的比例成反比
当各分类存在严重不平衡时,设置balanced会比较好,如果为None,则表示每个分类的权重相等。
random_state:可选参数,设定随机种子,solver为’sag’或’liblinear’时可用。
solver:字符串,可选参数,默认值为’liblinear’。
* max_iter:指定模型求解过程中的最大迭代次数,默认为100
multi_class:字符串,可选参数,默认值为’ovr’。
verbose:整数,可选参数,默认值为0。日志冗长度,对于solver为‘liblinear’和‘lbfgs’将设置为任何正数以表示详细程度。
warm_start:布尔值,可选参数,默认值为False。如果设置为True,则会使用上一次的结果作为初始值,否则会清除上一次结果。
n_jobs:整数或None,可选参数,默认值为None。如果multi_class为’ovr’时指定CPU核心使用数量。
l1_ratio:浮点数或None,可选参数,默认值为None。
import pandas as pd
from sklearn import linear_model
from sklearn import model_selection
from sklearn import metrics
import matplotlib.pyplot as plt
import seaborn as sns
data=pd.read_csv(r'Run or Walk.csv')
predictors=data.columns[4:]
#构建自变量矩阵
X=data[predictors]
#因变量y
y=data.activity
#拆分训练集和测试集
X_train,X_test,y_train,y_test=model_selection.train_test_split(X,y,test_size=0.25,random_state=1234)
#建模
logistic_model=linear_model.LogisticRegression()
logistic_model.fit(X_train,y_train)
#返回参数
print('Intercept:',logistic_model.intercept_)
print('Coef:',logistic_model.coef_)
#模型预测
pred=logistic_model.predict(X_test)
print(pd.Series(pred).value_counts())
#模型评估
#混淆矩阵
cm=metrics.confusion_matrix(y_test,pred,labels=[0,1])
print('混淆矩阵:\n',cm)
Accuracy=metrics.scorer.accuracy_score(y_test,pred)
Sensitivity=metrics.scorer.recall_score(y_test,pred)
Specificity=metrics.scorer.recall_score(y_test,pred,pos_label=0)
print('准确率:%.2f%%' % (Accuracy*100))
print('正例覆盖率:%.2f%%' % (Sensitivity*100))
print('负例覆盖率:%.2f%%' % (Specificity*100))
#绘制混淆矩阵的热力图
sns.heatmap(cm,annot=True,fmt='.2e',cmap='GnBu')
plt.show()
#ROC曲线
#y_score为模型预测正例的概率
y_score=logistic_model.predict_proba(X_test)[:,1]
#计算不同阈值下,fpr和tpr的组合之,fpr表示1-Specificity,tpr表示Sensitivity
fpr,tpr,threshold=metrics.roc_curve(y_test,y_score)
#计算AUC
roc_auc=metrics.auc(fpr,tpr)
#绘制面积图
plt.stackplot(fpr,tpr,color='steelblue',alpha=0.5,edgecolor='black')
#添加ROC曲线的轮廓
plt.plot(fpr,tpr,color='black',lw=1)
#添加对角线作为参考线
plt.plot([0,1],[0,1],color='red',linestyle='--')
plt.text(0.5,0.3,'ROC curve (area=%0.2f)' % roc_auc)
plt.xlabel('1-Specificity')
plt.ylabel('Sensitivity')
plt.show()
模型评估—混淆矩阵
A:表示正确预测负例的样本个数,⽤TN表示。
B:表示预测为负例但实际为正例的个数,⽤FN表示。
C:表示预测为正例但实际为负例的个数,⽤FP表示。
D:表示正确预测正例的样本个数,⽤TP表示。
准确率:表示正确预测的正负例样本数与所有样本数量的⽐值,即(A+D)/(A+B+C+D)。
正例覆盖率:表示正确预测的正例数在实际正例数中的⽐例,即D/(B+D)。
负例覆盖率:表示正确预测的负例数在实际负例数中的⽐例,即A/(A+C)。
正例命中率:表示正确预测的正例数在预测正例数中的⽐例,即D/(C+D),
#混淆矩阵
cm=metrics.confusion_matrix(y_test,pred,labels=[0,1])
print('混淆矩阵:\n',cm)
Accuracy=metrics.scorer.accuracy_score(y_test,pred)
Sensitivity=metrics.scorer.recall_score(y_test,pred)
Specificity=metrics.scorer.recall_score(y_test,pred,pos_label=0)
print('准确率:%.2f%%' % (Accuracy*100))
print('正例覆盖率:%.2f%%' % (Sensitivity*100))
print('负例覆盖率:%.2f%%' % (Specificity*100))
#绘制混淆矩阵的热力图
sns.heatmap(cm,annot=True,fmt='.2e',cmap='GnBu')
plt.show()
模型评估—ROC曲线
计算折线下的⾯积,即图中的阴影部分,这个⾯积称为AUC。
在做模型评估时,希望AUC的值越⼤越好,通常情况下,当AUC在0.8以上时,模型就基本可以接受了。
#ROC曲线
#y_score为模型预测正例的概率
y_score=logistic_model.predict_proba(X_test)[:,1]
#计算不同阈值下,fpr和tpr的组合之,fpr表示1-Specificity,tpr表示Sensitivity
fpr,tpr,threshold=metrics.roc_curve(y_test,y_score)
#计算AUC
roc_auc=metrics.auc(fpr,tpr)
#绘制面积图
plt.stackplot(fpr,tpr,color='steelblue',alpha=0.5,edgecolor='black')
#添加ROC曲线的轮廓
plt.plot(fpr,tpr,color='black',lw=1)
模型评估—KS曲线
两条折线
KS的计算公式为:
KS= Sensitivity-(1- Specificity)= Sensitivity+
Specificity-1。对于KS值⽽⾔,也是希望越⼤越好,通常情况下,当KS值⼤于0.4时,模型基本可以接受
# 自定义绘制ks曲线的函数
def plot_ks(y_test, y_score, positive_flag):
# 对y_test重新设置索引
y_test.index = np.arange(len(y_test))
# 构建目标数据集
target_data = pd.DataFrame({'y_test':y_test, 'y_score':y_score})
# 按y_score降序排列
target_data.sort_values(by = 'y_score', ascending = False, inplace = True)
# 自定义分位点
cuts = np.arange(0.1,1,0.1)
# 计算各分位点对应的Score值
index = len(target_data.y_score)*cuts
scores = np.array(target_data.y_score)[index.astype('int')]
# 根据不同的Score值,计算Sensitivity和Specificity
Sensitivity = []
Specificity = []
for score in scores:
# 正例覆盖样本数量与实际正例样本量
positive_recall = target_data.loc[(target_data.y_test == positive_flag) & (target_data.y_score>score),:].shape[0]
positive = sum(target_data.y_test == positive_flag)
# 负例覆盖样本数量与实际负例样本量
negative_recall = target_data.loc[(target_data.y_test != positive_flag) & (target_data.y_score<=score),:].shape[0]
negative = sum(target_data.y_test != positive_flag)
Sensitivity.append(positive_recall/positive)
Specificity.append(negative_recall/negative)
# 构建绘图数据
plot_data = pd.DataFrame({'cuts':cuts,'y1':1-np.array(Specificity),'y2':np.array(Sensitivity),
'ks':np.array(Sensitivity)-(1-np.array(Specificity))})
# 寻找Sensitivity和1-Specificity之差的最大值索引
max_ks_index = np.argmax(plot_data.ks)
plt.plot([0]+cuts.tolist()+[1], [0]+plot_data.y1.tolist()+[1], label = '1-Specificity')
plt.plot([0]+cuts.tolist()+[1], [0]+plot_data.y2.tolist()+[1], label = 'Sensitivity')
# 添加参考线
plt.vlines(plot_data.cuts[max_ks_index], ymin = plot_data.y1[max_ks_index],
ymax = plot_data.y2[max_ks_index], linestyles = '--')
# 添加文本信息
plt.text(x = plot_data.cuts[max_ks_index]+0.01,
y = plot_data.y1[max_ks_index]+plot_data.ks[max_ks_index]/2,
s = 'KS= %.2f' %plot_data.ks[max_ks_index])
# 显示图例
plt.legend()
# 显示图形
plt.show()
----------------------------------------------------------------------------------------------------------------------
plt.plot([0,1],[0,1],color='red',linestyle='--')
plt.text(0.5,0.3,'ROC curve (area=%0.2f)' % roc_auc)
plt.xlabel('1-Specificity')
plt.ylabel('Sensitivity')
plt.show()
logistic回归模型
参考:https://www.jianshu.com/p/1e18cb531ede?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation
决策树
决策树
根节点
条件
枝节点
条件
叶子节点
实际数据
信息熵
即信息量
熵越⼤,分类越不“纯净”,从而导致无法精准预测分类
熵越小,分类越“纯净”,从而导致能够更加精准预测分类
信息增益越大,意味着用属性a来进行划分获得的"纯度提升"越大。ID3决策树学习算法以信息增益为准则来选择划分属性。
信息熵公式参考:
https://blog.csdn.net/weixin_43374551/article/details/98632847
条件熵
依据不同的条件计算对应下的信息熵
eg:根据用户的学历将用户分成低学历 中学历 高学历
分别计算每个学历下的信息熵
最终求和得到条件熵
# 条件熵越小,该条件影响越大
信息增益
主要就是用来挑选节点字段的
某个条件计算出来的信息增益越大说明该条件对结果影响也越大
我们应该将该字段作为节点字段
# 信息增益在样本量较少的时候可能会出现偏差
称为属性a的"固有值"(intrinsic value),属性a的取值越多,则IV(a)值通常越大。
C4.5算法采用信息增益率来选择划分属性,先从候选划分属性中找出信息增益高于平均水平的属性,再从中选择增益率最高的。
信息增益率
决策树中的ID3算法使⽤信息增益指标实现根节点或中间节点的字段选择,但是该指标存在⼀个⾮常明显的缺点,即信息增益会偏向于取值较多的字段。
为了克服信息增益指标的缺点,提出了信息增益率的概念,它的思想很简单,就是在信息增益的基础上进⾏相应的惩罚。信息增益率的公式可以表示为
sklearn.tree.DecisionTreeClassifier(criterion=‘gini’, splitter=‘best’, max_depth=None, min_samples_split=2,
min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_features=None, random_state=None,
max_leaf_nodes=None, min_impurity_decrease=0.0, min_impurity_split=0.0000001, class_weight=None, presort=False)
1.参数解释:
criterion:字符串,可选参数。指定选择划分属性的方法。可选方法有
(1) ‘gini’(默认):使用基尼指数。
(2) ‘entropy’:使用信息增益。
splitter:字符串,可选参数。指定划分点的策略。
(1) ‘best’(默认):在特征的所有划分点中找出最优的划分点。适合样本量小的情况。
(2) ‘random’:随机的在部分划分点中找出局部最优的划分点。适合样本量大的情况。
max_depth:整数或None,可选参数,默认值为None。指定决策树的最大深度。如果为None,则决策树会完全生长至每个叶结点完全纯净(只包含同类样本)或者所有叶结点的样本数均小于参数min_samples_split。本参数旨在避免过拟合,在样本量大,特征数多的情况下可以使用。
min_samples_split:整数或浮点数,可选参数,默认值为2。对内部结点进行划分时,指定内部结点所包含的最小样本数。
(1) 整数:表示最小的样本数量
(2) 浮点数:表示一个比例,且 向上取整(比例*样本数) 表示最小的样本数量
min_samples_leaf:整数或浮点数,可选参数,默认值为1。叶结点包含的最小样本数量。该参数表示如果一个结点划分后其左右分支包含的样本数不小于min_sample_leaf时,才考虑对其进行划分。
(1) 整数:表示最小的样本数量
(2) 浮点数:表示一个比例,且 向上取整(比例*样本数) 表示最小的样本数量
min_weight_fraction_leaf:浮点数,可选参数,默认为0.。指定叶子结点所有样本权重和的最小值,小于该值则其被剪枝,即其父结点不进行划分,默认值为0表示不考虑权重问题。当样本缺失值较多或样本类别分布偏差很大时,会引入样本权重,此时需要考虑本参数值。
max_features:整数、浮点数、字符串或None,可选参数。指定寻找最优划分属性时允许考虑的最大特征数量。
(1) 整数:max_features表示考虑的最大特征数量
(2) 浮点数:表示一个比例,向下取整(比例*特征数) 为考虑的最大特征数量
(3) ‘auto’:max_features = sqrt(特征数)
(4) ‘sqrt’:max_features = sqrt(特征数)
(5) ‘log2’:max_features = log2(特征数)
(6) None(默认):max_features = 特征数
注意,在至少有一个有效划分结点样本找到之前,对最优划分属性的搜寻不会停止,即使设置了本参数,仍然会超过限制特征数量去搜寻。
random_state:可选参数。设定随机种子。
(1) 整数:random_state是随机数生成器使用的种子
(2) RandomState实例:random_state是随机数生成器
(3) None(默认):随机数生成器是np.random使用的RandomState实例
max_leaf_nodes:整数或None,可选参数,默认值为None。指定最大叶结点数量,旨在限制复杂度避免过拟合。None表示不限制叶结点数量。
min_impurity_decrease:浮点数,可选参数,默认值为0.。当一个结点划分后的纯度增长大于等于该参数值时,才将该结点进行划分。
表示划分后的右分支的样本数量(如果权重参数传入了,则所有数量均加权)。
min_impurity_split:浮点数,默认值为1e-7。纯度阈值,如果一个结点的纯度大于该值则划分,否则该结点即为叶结点。
class_weight:指定各类别的权重。
(1) 字典:形如{class_label: weight}
(2) 字典列表:对于多结果分类问题,需要为每个类别单独设置权重,比如4分类问题,权重应设置为[{0: 1, 1: 1}, {0: 1, 1: 5}, {0: 1, 1: 1}, {0: 1, 1: 1}]而不是[{1:1}, {2:5}, {3:1}, {4:1}]
(3) ‘balanced’:每个类别的权重与实际样本中的比例成反比,权重计算公式为n_samples ( n_classes * np.bincount(y)) np.bincount表示每个类别计数 \dfrac{\text{n\_samples}}{ (\text{n\_classes * np.bincount(y))}} \qquad \text{np.bincount表示每个类别计数}
(n_classes * np.bincount(y))
n_samples
np.bincount表示每个类别计数
(4) None(默认):每个类别的权重都一样
如果fit方法中sample_weight指定了,则类别权重会跟样本权重(sample_weight)相乘。
presort:布尔值,可选参数,默认值为False。指定是否预先对数据进行排序。数据集较大时,预先排序可能会降低训练速度;数据集较小或者限制了数的深度时,则会提升训练速度。
注意:由于在划分的时候特征是随机排列的,因此尽管数据集相同,每次得到的最优划分属性也不一定相同,为了避免这种情况,random_state必须固定。
由于在划分的时候特征是随机排列的,因此尽管数据集相同,每次得到的最优划分属性也不一定相同,为了避免这种情况,random_state必须固定。
公式参考:https://blog.csdn.net/weixin_43374551/article/details/98632847
基尼指数
ID3算法信息增益会偏向于取值较多的变量,极端例子如果一个变量的取值正好是N个,则其条件熵会等于0,在该变量下因变量的信息增益一定是最大的,
为了克服这种缺点,决策树中的C4.5算法使⽤信息增益率指标实现根节点或中间节点的字段选择,但该算法与ID3算法⼀致,都只能针对离散型因变量进⾏分类,对于连续型的因变量就显得束⼿⽆策了。
为了能够让决策树预测连续型的因变量,Breiman等⼈在1984年提出了CART算法,该算法也称为分类回归树,它所使⽤的字段选择指标是基尼指数。
ID3和C4.5只能对离散型因变量进行分类,而CART可以处理连续型因变量。CART算法以基尼指数对根节点或中间节点进行选择。
Python的sklearn模块使用的便是CART算法。
决策树不单单可以解决分类问题,其实还可以解决预测问题
但是信息增益率只能用于分类问题
如果想预测,需要使用基尼指数(既可以做分类也做预测)
条件基尼指数(类似于条件熵)
基尼指数增益:与信息增益类似,即因变量的基尼指数下降速度的快慢,下降的越快,自变量对因变量的影响越强。
公式参考 https://blog.csdn.net/weixin_43374551/article/details/83410070
二叉树
每个节点只能分成两个,如何解决多个条件的情况
eg:
针对学历先分成
低学历
非低学历
针对年龄先成
未成年
成年
随机森林
其实就是由单个单个的决策树组织在一起形成的
随机森林是通过单个单个决策树的选择(投票比例)来决定最终的结果
如果预剪枝不够理想,还可以使用集成的随机森林算法,可以很好的避免单棵决策树过拟合的问题。
如果训练集有N个样本,P个自变量,1个因变量:
利用Bootstrap抽样法,从原始数据中生成k个数据集(样本个数N,变量个数P)
针对这k个数据集中的每一个数据集,构造一棵决策树(变量个数p,从总变量个数P中随机选择),并且每一棵决策树都不剪枝。
针对这k棵决策树形成的随机森林,对分类问题利用投票法,得票最高的类别作为最终的判断结果;对回归问题利用均值法,所有结果的平均值作为最终的预测结果。
在形成随机森林的过程中,由于每棵树的训练样本是随机的,构成树节点的变量也是随机选择的,所以使得随机森林不容易产生过拟合。
函数说明
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 )
分类
import pandas as pd
import numpy as np
from sklearn import model_selection,tree,metrics,ensemble
from sklearn.model_selection import GridSearchCV
import matplotlib.pyplot as plt
data=pd.read_csv(r'data.csv')
#拆分训练集和测试集
predictors=data.columns[1:]
x_train,x_test,y_train,y_test=model_selection.train_test_split(data[predictors],data.Survived,
test_size=0.25,random_state=1234)
#使用网格搜索法,尝试不同组合(最大深度、分支最小样本量、叶节点最小样本量)
#根据经验,数据量较小时树的最大深度可设置10以内,较大时则需设置比较大的树深度,如20左右
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)
#返回最佳参数组合
print(grid_dtcateg.best_params_)
#构建分类决策树
CART_Class=tree.DecisionTreeClassifier(max_depth=grid_dtcateg.best_params_['max_depth'],
min_samples_leaf=grid_dtcateg.best_params_['min_samples_leaf'],
min_samples_split=grid_dtcateg.best_params_['min_samples_split'])
decision_tree=CART_Class.fit(x_train,y_train)
pred=CART_Class.predict(x_test)
print('测试集的预测准确率:',metrics.accuracy_score(y_test,pred))
print('训练集的预测准确率:',metrics.accuracy_score(y_train,CART_Class.predict(x_train)))
#绘制ROC曲线
y_score=CART_Class.predict_proba(x_test)[:,1] #预测值为第2种的概率
fpr,tpr,threshold=metrics.roc_curve(y_test,y_score)
#计算AUC的值
roc_auc=metrics.auc(fpr,tpr)
#绘制面积图
plt.stackplot(fpr,tpr,color='steelblue',alpha=0.5,edgecolor='black')
#添加边际线和对角线
plt.plot(fpr,tpr,color='black',lw=1)
plt.plot([0,1],[0,1],color='red',linestyle='--')
#添加文本信息
plt.text(0.4,0.4,'DecisionTree ROC curve (area = %0.2f)' % roc_auc)
#添加x轴和y轴标签
plt.xlabel('l-Specificity')
plt.ylabel('Sensitivity')
plt.show()
#构建随机森林
RF_class=ensemble.RandomForestClassifier(n_estimators=200,random_state=1234)
RF_class.fit(x_train,y_train)
RFclass_pred=RF_class.predict(x_test)
print('随机森林模型在测试集的预测准确率:',metrics.accuracy_score(y_test,RFclass_pred))
#绘制ROC曲线
y_score=RF_class.predict_proba(x_test)[:,1]
fpr,tpr,threshold=metrics.roc_curve(y_test,y_score)
#计算AUC的值
roc_auc=metrics.auc(fpr,tpr)
#绘制面积图
plt.stackplot(fpr,tpr,color='steelblue',alpha=0.5,edgecolor='black')
#添加边际线和对角线
plt.plot(fpr,tpr,color='black',lw=1)
plt.plot([0,1],[0,1],color='red',linestyle='--')
#添加文本信息
plt.text(0.4,0.3,'RandomForest ROC curve (area = %0.2f)' % roc_auc)
#添加x轴和y轴标签
plt.xlabel('l-Specificity')
plt.ylabel('Sensitivity')
plt.show()
#变量重要程度绘图
importance=RF_class.feature_importances_
Impt_Series=pd.Series(importance,index=x_train.columns)
Impt_Series.sort_values(ascending=True).plot('barh')
plt.show()
预测
import pandas as pd
from sklearn import model_selection,tree,metrics,ensemble
from sklearn.model_selection import GridSearchCV
data=pd.read_excel(r'C:\Users\sc\Desktop\NHANES.xlsx')
#拆分训练集和测试集
predictors=data.columns[:-1]
x_train,x_test,y_train,y_test=model_selection.train_test_split(data[predictors],data.CKD_epi_eGFR,
test_size=0.25,random_state=1234)
#预设各参数
max_depth=[18,19,20,21,22]
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.DecisionTreeRegressor(),param_grid=parameters,cv=10)
grid_dtcateg.fit(x_train,y_train)
#返回最佳参数组合
print(grid_dtcateg.best_params_)
#构建回归的决策树
CART_Reg=tree.DecisionTreeRegressor(max_depth=grid_dtcateg.best_params_['max_depth'],
min_samples_leaf=grid_dtcateg.best_params_['min_samples_leaf'],
min_samples_split=grid_dtcateg.best_params_['min_samples_split'])
CART_Reg.fit(x_train,y_train)
pred=CART_Reg.predict(x_test)
print('决策树均方误差MSE:',metrics.mean_squared_error(y_test,pred))
#构建用于回归的随机森林
RF=ensemble.RandomForestRegressor(n_estimators=200,random_state=1234)
RF.fit(x_train,y_train)
RF_pred=RF.predict(x_test)
print('随机森林均方误差:',metrics.mean_squared_error(y_test,RF_pred))
K近邻模型
K-近邻算法(k-Nearest Neighbor,KNN)是机器学习算法中最简单最容易理解的算法。
该算法的思路是:
给定一个训练数据集,对新的输入实例,在训练数据集中找到与该实例最邻近的K个实例, 这K个实例的多数属于某个类,就把该输入实例分类到这个类中
优点:精度高、对异常值不敏感、无数据输入假定
缺点:计算复杂度高、空间复杂度高
适用数据范围:数值型和标称型
既可以预测分类问题也可以预测预测问题
1.针对离散型变量的预测采用的是频率法(由已知样本频率高低采取频率高的作为判断结果)
2.针对连续型变量的预测采用的是均值法
***k值的选择是非常重要的
权重
距离度量
1.欧式距离
2.曼哈顿距离
3.余弦相似度
关键字
1.过拟合
过拟合(overfitting)与欠拟合(underfitting)是统计学中的一组现象。过拟合是在统计模型中,由于使用的参数过多而导致模型对观测数据(训练数据)过度拟合,以至于用该模型来预测其他测试样本输出的时候与实际输出或者期望值相差很大的现象。
2.欠拟合
欠拟合则刚好相反,是由于统计模型使用的参数过少,以至于得到的模型难以拟合观测数据(训练数据)的现象。
分类
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn import model_selection
from sklearn import neighbors
from sklearn import metrics
data=pd.read_excel(r'data.xlsx')
#拆分为训练集和测试集
predictors=['pre1','pre2','pre3','pre4','pre5']
classification=['class']
x_train,x_test,y_train,y_test=model_selection.train_test_split(data[predictors], data[classification],
test_size=0.25,random_state=1234)
#设置k值集合
K=np.arange(1,int(np.ceil(np.log2(data.shape[0]))))
#存储不同k值的平均准确率
accuracy=[]
for k in K:
#使用10折交叉验证的方法,比对每一k值下KNN模型的预测准确率
cv_result=model_selection.cross_val_score(neighbors.KNeighborsClassifier(n_neighbors=k,
weights='distance'),x_train,y_train,cv=10,scoring='accuracy')
accuracy.append(cv_result.mean())
#查询最大平均准确率的下标
arg_max=np.array(accuracy).argmax()
#绘制折线图
plt.rcParams['font.sans-serif']=['Microsoft YaHei'] #中文和负号正常显示
plt.rcParams['axes.unicode_minus']=False
plt.plot(K,accuracy) #折线图
plt.scatter(K,accuracy) #散点图
plt.text(K[arg_max],accuracy[arg_max],'最佳k值为%s' % int(K[arg_max]))
plt.show() #显示图形
#以最佳K值构建模型
knn_class=neighbors.KNeighborsClassifier(n_neighbors=int(K[arg_max]),weights='distance')
knn_class.fit(x_train,y_train)
predict=knn_class.predict(x_test)
#模型评估
print('Confusion Matrix:\n',pd.crosstab(y_test,predict)) #构建混淆矩阵
print('Overall Accuracy:',metrics.scorer.accuracy_score(y_test,predict)) #整体准确率
print('Assessment Report:\n',metrics.classification_report(y_test,predict)) #模型评估报告
预测
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn import model_selection
from sklearn import neighbors
from sklearn import metrics
from sklearn.preprocessing import minmax_scale
data=pd.read_excel(r'data.xlsx')
#数据归一化,消除量纲影响
predictors=data.columns[:-1]
X=minmax_scale(data[predictors])
#拆分为训练集和测试集
x_train,x_test,y_train,y_test=model_selection.train_test_split(X, data.classify,
test_size=0.25,random_state=1234)
#设置k值集合
K=np.arange(1,int(np.ceil(np.log2(data.shape[0]))))
#存储不同k值的平均MSE
mse=[]
for k in K:
#使用10折交叉验证的方法,比对每一k值下KNN模型的MSE
cv_result=model_selection.cross_val_score(neighbors.KNeighborsRegressor(n_neighbors=k,
weights='distance'),x_train,y_train,cv=10,scoring='neg_mean_squared_error')
mse.append((-1*cv_result).mean()) #将负数转换为正数
#查询最小均方误差的下标
arg_min=np.array(mse).argmin()
#绘制折线图
plt.rcParams['font.sans-serif']=['Microsoft YaHei'] #中文和负号正常显示
plt.rcParams['axes.unicode_minus']=False
plt.plot(K,mse) #折线图
plt.scatter(K,mse) #散点图
plt.text(K[arg_min],mse[arg_min],'最佳k值为%s' % int(K[arg_min]))
plt.show() #显示图形
#以最佳K值构建模型
knn_reg=neighbors.KNeighborsRegressor(n_neighbors=int(K[arg_min]),weights='distance')
knn_reg.fit(x_train,y_train)
predict=knn_reg.predict(x_test)
#模型评估
print('MSE:',metrics.mean_squared_error(y_test,predict)) #均方误差越小越好
#参考:https://blog.csdn.net/weixin_43374551/article/details/83275229
朴素贝叶斯模型
条件概率
全概率公式
针对连续型问题
高斯贝叶斯分类器
针对离散型问题
多项式贝叶斯分类器
针对自变量只有0-1二元值
伯努利贝叶斯分类器
公式参考:https://blog.csdn.net/weixin_43374551/article/details/83449416
高斯贝叶斯分类器
# 导入第三方包
import pandas as pd
# 读入数据
skin = pd.read_excel(r'Skin_Segment.xlsx')
# 设置正例和负例
skin.y = skin.y.map({2:0,1:1}) # 设置一个映射关系,将2映射成0 # 也可以不映射
skin.y.value_counts()
'''245057 rows × 4 columns'''
# 导入第三方模块
from sklearn import model_selection
# 样本拆分
X_train,X_test,y_train,y_test = model_selection.train_test_split(skin.iloc[:,:3], skin.y,
test_size = 0.25, random_state=1234)
# 导入第三方模块
from sklearn import naive_bayes
# 调用高斯朴素贝叶斯分类器的“类”
gnb = naive_bayes.GaussianNB()
# 模型拟合
gnb.fit(X_train, y_train)
# 模型在测试数据集上的预测
gnb_pred = gnb.predict(X_test)
# 各类别的预测数量
pd.Series(gnb_pred).value_counts()
# 导入第三方包
from sklearn import metrics
import matplotlib.pyplot as plt
import seaborn as sns
# 构建混淆矩阵
cm = pd.crosstab(gnb_pred,y_test)
# 绘制混淆矩阵图
sns.heatmap(cm, annot = True, cmap = 'GnBu', fmt = 'd')
# 去除x轴和y轴标签
plt.xlabel('Real')
plt.ylabel('Predict')
# 显示图形
plt.show()
print('模型的准确率为:\n',metrics.accuracy_score(y_test, gnb_pred))
print('模型的评估报告:\n',metrics.classification_report(y_test, gnb_pred))
# 计算正例的预测概率,用于生成ROC曲线的数据
y_score = gnb.predict_proba(X_test)[:,1]
fpr,tpr,threshold = metrics.roc_curve(y_test, y_score)
# 计算AUC的值
roc_auc = metrics.auc(fpr,tpr)
# 绘制面积图
plt.stackplot(fpr, tpr, color='steelblue', alpha = 0.5, edgecolor = 'black')
# 添加边际线
plt.plot(fpr, tpr, color='black', lw = 1)
# 添加对角线
plt.plot([0,1],[0,1], color = 'red', linestyle = '--')
# 添加文本信息
plt.text(0.5,0.3,'ROC curve (area = %0.2f)' % roc_auc)
# 添加x轴与y轴标签
plt.xlabel('1-Specificity')
plt.ylabel('Sensitivity')
# 显示图形
plt.show()
''' ROC曲线达0.94 '''
多项式贝叶斯分类器
离散变量
# 导入第三方包
import pandas as pd
# 读取数据
mushrooms = pd.read_csv(r'mushrooms.csv')
# 数据的前5行
mushrooms.head()
''' 5 rows × 22 columns '''
# 将字符型数据作因子化处理,将其转换为整数型数据
columns = mushrooms.columns[1:]
for column in columns:
mushrooms[column] = pd.factorize(mushrooms[column])[0]
mushrooms.head()
from sklearn import model_selection
# 将数据集拆分为训练集合测试集
Predictors = mushrooms.columns[1:]
X_train,X_test,y_train,y_test = model_selection.train_test_split(mushrooms[Predictors], mushrooms['type'],
test_size = 0.25, random_state = 10)
from sklearn import naive_bayes
from sklearn import metrics
import seaborn as sns
import matplotlib.pyplot as plt
# 构建多项式贝叶斯分类器的“类”
mnb = naive_bayes.MultinomialNB()
# 基于训练数据集的拟合
mnb.fit(X_train, y_train)
# 基于测试数据集的预测
mnb_pred = mnb.predict(X_test)
# 构建混淆矩阵
cm = pd.crosstab(mnb_pred,y_test)
# 绘制混淆矩阵图
sns.heatmap(cm, annot = True, cmap = 'GnBu', fmt = 'd')
# 去除x轴和y轴标签
plt.xlabel('Real')
plt.ylabel('Predict')
# 显示图形
plt.show()
# 模型的预测准确率
print('模型的准确率为:\n',metrics.accuracy_score(y_test, mnb_pred))
print('模型的评估报告:\n',metrics.classification_report(y_test, mnb_pred))
from sklearn import metrics
# 计算正例的预测概率,用于生成ROC曲线的数据
y_score = mnb.predict_proba(X_test)[:,1]
fpr,tpr,threshold = metrics.roc_curve(y_test.map({'edible':0,'poisonous':1}), y_score)
# 计算AUC的值
roc_auc = metrics.auc(fpr,tpr)
# 绘制面积图
plt.stackplot(fpr, tpr, color='steelblue', alpha = 0.5, edgecolor = 'black')
# 添加边际线
plt.plot(fpr, tpr, color='black', lw = 1)
# 添加对角线
plt.plot([0,1],[0,1], color = 'red', linestyle = '--')
# 添加文本信息
plt.text(0.5,0.3,'ROC curve (area = %0.2f)' % roc_auc)
# 添加x轴与y轴标签
plt.xlabel('1-Specificity')
plt.ylabel('Sensitivity')
# 显示图形
plt.show()
''' AUC面积达0.94 '''
伯努利贝叶斯分类器
对产品评价做预测
import pandas as pd
# 读入评论数据
evaluation = pd.read_excel(r'Contents.xlsx',sheet_name=0)
# 查看数据前10行
evaluation.head(10)
''' '''
# 运用正则表达式,将评论中的数字和英文去除
evaluation.Content = evaluation.Content.str.replace('[0-9a-zA-Z]','')
evaluation.head()
# !pip3 install jieba
!pip install jieba
# 导入第三方包
import jieba
# 加载自定义词库
jieba.load_userdict(r'all_words.txt')
# 读入停止词
with open(r'mystopwords.txt', encoding='UTF-8') as words:
stop_words = [i.strip() for i in words.readlines()]
# 构造切词的自定义函数,并在切词过程中删除停止词
def cut_word(sentence):
words = [i for i in jieba.lcut(sentence) if i not in stop_words]
# 切完的词用空格隔开
result = ' '.join(words)
return(result)
# 对评论内容进行批量切词
words = evaluation.Content.apply(cut_word)
# 前5行内容的切词效果
words[:5]
切词后再做处理
# 导入第三方包
from sklearn.feature_extraction.text import CountVectorizer
# 计算每个词在各评论内容中的次数,并将稀疏度为99%以上的词删除
counts = CountVectorizer(min_df = 0.01)
# 文档词条矩阵
dtm_counts = counts.fit_transform(words).toarray()
# 矩阵的列名称
columns = counts.get_feature_names()
# 将矩阵转换为数据框--即X变量
X = pd.DataFrame(dtm_counts, columns=columns)
# 情感标签变量
y = evaluation.Type
X.head()
''' 5 rows × 99 columns '''
from sklearn import model_selection
from sklearn import naive_bayes
from sklearn import metrics
import matplotlib.pyplot as plt
import seaborn as sns
# 将数据集拆分为训练集和测试集
X_train,X_test,y_train,y_test = model_selection.train_test_split(X,y,test_size = 0.25, random_state=1)
# 构建伯努利贝叶斯分类器
bnb = naive_bayes.BernoulliNB()
# 模型在训练数据集上的拟合
bnb.fit(X_train,y_train)
# 模型在测试数据集上的预测
bnb_pred = bnb.predict(X_test)
# 构建混淆矩阵
cm = pd.crosstab(bnb_pred,y_test)
# 绘制混淆矩阵图
sns.heatmap(cm, annot = True, cmap = 'GnBu', fmt = 'd')
# 去除x轴和y轴标签
plt.xlabel('Real')
plt.ylabel('Predict')
# 显示图形
plt.show()
# 模型的预测准确率
print('模型的准确率为:\n',metrics.accuracy_score(y_test, bnb_pred))
print('模型的评估报告:\n',metrics.classification_report(y_test, bnb_pred))
# 计算正例Positive所对应的概率,用于生成ROC曲线的数据
y_score = bnb.predict_proba(X_test)[:,1]
fpr,tpr,threshold = metrics.roc_curve(y_test.map({'Negative':0,'Positive':1}), y_score)
# 计算AUC的值
roc_auc = metrics.auc(fpr,tpr)
# 绘制面积图
plt.stackplot(fpr, tpr, color='steelblue', alpha = 0.5, edgecolor = 'black')
# 添加边际线
plt.plot(fpr, tpr, color='black', lw = 1)
# 添加对角线
plt.plot([0,1],[0,1], color = 'red', linestyle = '--')
# 添加文本信息
plt.text(0.5,0.3,'ROC curve (area = %0.2f)' % roc_auc)
# 添加x轴与y轴标签
plt.xlabel('1-Specificity')
plt.ylabel('Sensitivity')
# 显示图形
plt.show()
''' AUC面积达0.92 '''
上篇完
转载说明出处
标签:数据分析,教程,plt,数学模型,模型,train,test,import,data 来源: https://blog.csdn.net/BlankpuppetCiwei/article/details/112550660