栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

2022福大数学建模赛题B题-多元 Logistic回归分类模型-附Python完整代码

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

2022福大数学建模赛题B题-多元 Logistic回归分类模型-附Python完整代码

题目:第3题,请根据附件 2 所提供的部分食物寒热属性(分为三类:性平、性温热、性凉寒),对附 件 1 中的食物进行分类,判断这些食物是属于性平、性温热或性凉寒中哪一类,并说明你分类 的合理性;

思路:如果食品寒热属性与其成分之间都是线性关系,那么可以考虑采用多元 Logistic回归
模型来分类,后续查看其模型预测准确率,若准确率高,则进一步进行线性检验,若较低。则采用BP神经网络模型,它适用于非线性映射关系,最后通过对比两个模型训练集的准确性来衡量其优劣性能。

多元逻辑回归模型介绍:

它可以划分 3个二元 logistic regression模型

对于二元 logistic regression,如食物是否寒性模型的数学公式如下:

通过sigmoid函数将线性的值映射到0-1之间,再离散化变为0和1。通过此方法可最后得到回归系数,这里的回归系数要用发生比率来解释。

我们最后计算得出模型的准确率为 60.14%,食物 K-S曲线示意图如下,KS值低于0.4,效果一般。

 代码如下:这里注意把附件二的文本放在txt文件上读取。

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn import preprocessing
from sklearn import metrics
import re
from sklearn import model_selection
from sklearn import linear_model

# 自定义绘制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()

# 读取数据
df1 = pd.read_excel(r'食物成分表.xlsx', index_col=0).reset_index(drop=True)
df3 = df1.drop(['可食部分(%)'], axis=1)
scaler = preprocessing.MinMaxScaler()#标准化
df33 = scaler.fit_transform(df3[df3.columns[1:17]]) #训练和导出结果
df33 = pd.DataFrame(df33, columns=df3.columns[1:17])#转换格式
df3 = pd.concat([df3['名  称'], df33], axis=1)#标准化后数据
df3['catef'] = ''#添加列,分类
print(df3.head())  # 查看前5条数据

#自定义函数,根据附件2分类标注数据
def TagCategory(datastr,f,tap):
    for line in f:
        a = re.split('。|、|;|(|)|\n| ', line)#分割字符串保存到a
        a = [x.strip() for x in a if x.strip() != '']#去除空字符串
        for ss in a:
            index0 = datastr.str.find(ss)#找到则返回所要找字符串在指定字符串位置,没有则返回-1
            ind = index0[index0.values != -1].index#不为-1的即表示有
            df3['catef'][ind] = tap#标注

mingcheng = df3['名  称'].astype(str)#提取名称所在列
f0 = open(r'性平.txt', encoding='utf-8')
f1 = open(r'性凉寒.txt', encoding='utf-8')
f2 = open(r'性温热.txt', encoding='utf-8')
TagCategory(mingcheng,f0,0)#性平标为0
TagCategory(mingcheng,f1,1)#性凉寒标为1
TagCategory(mingcheng,f2,2)#性温热标为2
print(df3.head())#查看前5行

#标注后,数据分为已知分类数据集和未知数据集
NonNulldf = df3[(df3['catef'].notnull()) & (df3['catef'] != "")]
IsNulldf = df3[(df3['catef'] == "")]

#已知数据集的处理
predictors = NonNulldf.columns[1:17]# 提取出所有自变量名称
X = NonNulldf.loc[:,predictors]# 构建自变量矩阵
y = pd.to_numeric(NonNulldf['catef'])# 提取因变量

# 将数据集拆分为训练集和测试集
X_train, X_test, y_train, y_test = model_selection.train_test_split(X, y, random_state = 1234)

# 利用训练集建模
sklearn_logistic = linear_model.LogisticRegression(multi_class='multinomial',solver="newton-cg", max_iter=100000)
sklearn_logistic.fit(X_train, y_train)
# 返回模型的各个参数
print(np.around(sklearn_logistic.intercept_,decimals=2), np.around(sklearn_logistic.coef_,decimals=2))

# 模型预测
sklearn_predict = sklearn_logistic.predict(X_test)
# 预测结果统计
print(pd.Series(sklearn_predict).value_counts())

# 混淆矩阵
cm = metrics.confusion_matrix(y_test, sklearn_predict, labels = [0,1,2])
label=['性平','性凉寒','性温热']
cm = pd.DataFrame(cm,index=label,columns=label)
print(cm)

#评价指标
Accuracy = metrics._scorer.accuracy_score(y_test, sklearn_predict)
Sensitivity = metrics._scorer.recall_score(y_test, sklearn_predict,average=None)
Specificity = metrics._scorer.recall_score(y_test, sklearn_predict, pos_label=0,average=None)
print('模型准确率为%.2f%%:' %(Accuracy*100))
print('正例覆盖率:',Sensitivity*100)

# 中文和负号的正常显示
config = {"font.family": 'serif',"mathtext.fontset": 'stix',"font.serif": ['SimSun']}
plt.rcParams.update(config)
plt.rcParams['axes.unicode_minus'] = False

# 混淆矩阵的可视化
# 绘制热力图
sns.heatmap(cm, annot = True, cmap = 'GnBu')
plt.xlabel('预测值')
plt.ylabel('真实值')
plt.show()# 图形显示

# y得分为模型预测正例的概率
y_score = sklearn_logistic.predict_proba(X_test)[:,1]
# 调用自定义函数,绘制K-S曲线
plot_ks(y_test = y_test, y_score = y_score, positive_flag = 1)

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/958863.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号