[Python数据分析] 5-挖掘建模(监督学习)_name = column_list[i]-程序员宅基地

技术标签: 监督学习  数据分析  机器学习  Python3  数据挖掘  回归  分类  

# I.理论部分:机器学习是过程,模型是这个过程的结果
# 1)机器学习和建模
# i.学习:通过接收到的数据,归纳提取相同与不同
# ii.机器学习:让计算机以数据为基础,进行归纳和总结
# iii.模型:数据解释现象的系统
# 2)数据集:通常来说各部分占比:训练集6:验证集2:测试集2
# i.训练集:训练拟合模型
# ii.验证集:通过训练集训练出多个模型后,使用验证集数据纠正或比较预测
# iii.测试集:模型泛化能力的考量(泛化:对未知数据的预测能力)
# 常用方法:K-fold交叉验证:将数据集分成K份,每份轮流做一遍测试集,其他做训练集
# 3)根据是否有标注可以分为:
# i.监督学习:提炼输入数据和标注间的关系,根据标注的离散和连续分两类:
#     1.离散:分类学习(KNN,朴素贝叶斯,决策树,支持向量机,集成方法)
#     2.连续:回归学习(罗吉斯特映射,人工神经网络)
# ii.无监督学习:将数据的特征在不同的模型中进行不同的表现
#     1.聚类分析:基于切割的K-means,基于层次的聚类算法,基于密度的DBSCAN,基于图的Split
#     2.关联分析
# iii.半监督学习:

# II.监督学习编码实现(分类及回归)
# 接:[Python] 7.利用Python进行数据分析-预处理理论的结果,以下为内容,具体内容可以看前一章
import numpy as np
import pandas as pd
pd.set_option("display.max_columns", None)
from sklearn.preprocessing import MinMaxScaler, StandardScaler  # 归一化,标准化
from sklearn.preprocessing import LabelEncoder, OneHotEncoder  # 标签化,独热化
from sklearn.preprocessing import Normalizer  # 规范化/正规化
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis  # LDA降维
from sklearn.decomposition import PCA  # PCA降维
# sl:satisfaction_level---False:MinMaxScaler,True:StandardScaler
# le:last_evaluation---False:MinMaxScaler,True:StandardScaler
# npr:number_project---False:MinMaxScaler,True:StandarScaler
# amh:average_monthly_hours---False:MinMaxScaler,True:StandarScaler
# tsc:time_spend_company---False:MinMaxScaler,True:StandarScaler
# wa:Work_accident---False:MinMaxScaler,True:StandarScaler
# pl5:promotion_last_5years---False:MinMaxScaler,True:StandarScaler
# dp;department---False:LabelEncodering,True:OneHotEncodering
# slr:salary---False:LabelEncodering,True:OneHotEncodering
def hr_preprocessing(sl=False, le=False, npr=False, amh=False, tsc=False, wa=False,
                     pl5=False, dp=False, slr=False, low_d=False, ld_n=1):
    df = pd.read_csv(r"D:\Work\data\HR.csv")
    df = df.dropna(subset=["satisfaction_level","last_evaluation"])
    df = df[df["satisfaction_level"]<=1][df["salary"]!="nme"]
    label = df["left"]
    df = df.drop("left",axis=1)
    scaler_list = [sl,le,npr,amh,tsc,wa,pl5]
    column_list = ["satisfaction_level","last_evaluation","number_project",
                   "average_monthly_hours","time_spend_company","Work_accident",
                   "promotion_last_5years"]
    for i in range(len(scaler_list)):
        if not scaler_list[i]:
            df[column_list[i]] = \
                MinMaxScaler().fit_transform(df[column_list[i]].values.reshape(-1, 1)).reshape(1, -1)[0]  # 二维取第0个
        else:
            df[column_list[i]] = \
                StandardScaler().fit_transform(df[column_list[i]].values.reshape(-1, 1)).reshape(1, -1)[0]
    scaler_list = [dp, slr]
    column_list = ["department","salary"]
    for j in range(len(scaler_list)):
        if not scaler_list[j]:
            if column_list[j] == "salary":
                df[column_list[j]] = [map_salary(s) for s in df["salary"].values]
            else:
                df[column_list[j]] = \
                    LabelEncoder().fit_transform(df[column_list[j]])
            column_list[j] = \
                MinMaxScaler().fit_transform(df[column_list[j]].values.reshape(-1, 1)).reshape(1, -1)[0]
        else:
            df = pd.get_dummies(df,columns=[column_list[j]])
    if low_d:
        return PCA(n_components=ld_n).fit_transform(df.values),label
    return df, label
d = dict([("low",0),("medium",1),("high",2)])
def map_salary(s):
    return d.get(s,0)

# 1.分类(输出离散数据,寻找决策边界,用精度等指标对其进行衡量)
def hr_modeling(features,label):
    # 1.数据集的设定
    # 没有包可以同时设定训练集,验证集和测试集,但有一个可以直接切分训练集和测试集的函数
    from sklearn.model_selection import train_test_split
    # 定义特征(也就是left)
    f_v = features.values
    # 特征名称(决策树画图用)
    f_names = features.columns.values
    # 定义标注
    l_v = label.values
    # 设置(训练集+测试集)和验证集,并指定验证集占总体的20%
    X_tt,X_validation,Y_tt,Y_validation = train_test_split(f_v,l_v,test_size=0.2)
    # 同理设置训练集和测试集,并指定测试集占(训练集+测试集)的25%,即总量的20%
    X_train,X_test,Y_train,Y_test = train_test_split(X_tt,Y_tt,test_size=0.25)
    # 2.引入模型评价指标:分类准确率,召回率,f值
    from sklearn.metrics import accuracy_score,recall_score,f1_score
    # 3.模型建立,引入一个列表,一会儿装模型用
    models = []
    # Classifier-i.KNN(K-Nearest Neighbors)
    # 概念:欧氏距离,曼哈顿距离,闵可夫斯基距离,KD-Tree的索引方法
    # 基本思想:待分类项的K个邻居中A类别的个数大于B类别的个数,则这个点更倾向于A类别
    from sklearn.neighbors import NearestNeighbors,KNeighborsClassifier
    models.append(("KNN",KNeighborsClassifier(n_neighbors=3)))  # 指定neighbors个数为3
    # Classifier-ii.朴素贝叶斯(对离散的特征效果好,连续的特征会被先转成离散的再计算)
    # 数据要求: 离散特征间是相互独立的,对特征有比较严格的要求
    # 类别: 伯努利朴素贝叶斯(0, 1二值),高斯朴素贝叶斯(服从高斯分布)
    # 基本思想:对于给出的待分类项,求解在此项出现的条件下各个类别出现的概率,哪个最大,就认为此待分类项属于哪个类别。
    from sklearn.naive_bayes import GaussianNB,BernoulliNB
    models.append(("BernoulliNB",BernoulliNB()))
    models.append(("GaussianNB",GaussianNB()))
    # Classifier-iii.决策树
    # 概念:中间节点-特征,叶子结点-标注
    # 评价手段:此处log的底数为2
        # 熵: 事件的不确定性:H(X)=-SIGMA(Pi*log(Pi))
        # 信息增益-ID3:I(X,Y)=H(Y)-H(Y|X)=H(X)-H(X|Y),X对Y的影响大小,值越大反应先应该进行X特征的切分
        # 信息增益率- C4.5: GainRation(X->Y)=I(X,Y)/H(Y),在前者的基础上额外考虑标志本身的影响, 值越大应先进行X特征的切分
        # Gini系数-CART(不纯度):Gini(D)=1-SIGMA(Ck/D)^2,值越大反应先应该进行X特征的切分
    # 几个注意点:
        # 连续值的切分:将连续值进行排序,对间隔进行切分,单独计算取最好值
        # 规则用尽:投票
        # 过拟合:剪枝(前剪枝,后剪枝)
    # 添加库,同时要把Graphviz加入环境变量目的是为了做图
    import pydotplus
    from sklearn.tree import DecisionTreeClassifier,export_graphviz
    models.append(("DecisionTreeGini",DecisionTreeClassifier()))
    models.append(("DecisionTreeEntropy",DecisionTreeClassifier(criterion="entropy")))
    # Classifier-iv.支持向量机
    # 概念:https://www.zhihu.com/question/21094489
    # 思路:先映射再计算(产生维度灾难)->先计算再扩维(采用核函数-kernel)
    # 几个注意点:
        # 相较于决策树,SVM的边界更加平滑
        # 少部分异常值:引入松弛变量,最终是为了减少过拟合的现象
        # 样本不平衡:根据具体业务场景
        # 多分类方案:https://www.cnblogs.com/CheeseZH/p/5265959.html
          # One-Other(训练时依次把某个类别的样本归为一类,其他剩余的样本归为另一类,将未知样本分到具有最大分类函数值的类)
          # One-One(在任意两类样本之间设计一个SVM,对一个未知样本进行分类时,最后得票最多的类别即为该未知样本的类别)
    from sklearn.svm import SVC
    models.append(("Original SVM Classfier",SVC()))
    models.append(("SVM Classfier",SVC(C=1000)))
    # Classifier-v.集成方法
    # 概念:组合多个模型,以获得更好的效果(将若干个弱可学习的算法集成为强可学习的算法)
    # 常见的算法复杂度,n为数据规模:多项式复杂度(n^p),阶乘复杂度(n!),指数级复杂度(m^n)
    # 应当尽可能的去设计多项式复杂度的算法
        # 弱可学习: 多项式学习算法的效果不明显
        # 强可学习: 多项式学习算法的效果较为明显
    # 集成方法:
        # [独立]袋装法(bagging): 用训练集训练若干独立的子模型, 对于分类问题取各个子模型的投票
            # 应用: 随机森林,注意点:
                # 1.树的数目:多次尝试进行确定
                # 2.每棵树采用的特征数:少于50个特征可以选择全部特征,更多了每棵树可以不使用全部的特征, 避免过拟合
                # 3.树的训练集怎么选:一般和树的数目一样多,放回抽样
        # [串联]提升法(boost): 用训练集训练若干串联起来的子模型, 对于分类问题取各个子模型的加权叠加(而非最后一个模型)
            # 应用: Adaboost(精度高, 几乎不会过拟合,简化了流程)
    # 随机森林
    from sklearn.ensemble import RandomForestClassifier
    models.append(("Original RandForestClassifier",RandomForestClassifier()))
    models.append(("RandForestClassifier",RandomForestClassifier(n_estimators=20,max_features=None,bootstrap=True)))
    # Adaboost
    from sklearn.ensemble import AdaBoostClassifier
    models.append(("Original Adaboost",AdaBoostClassifier()))
    models.append(("Adaboost",AdaBoostClassifier(n_estimators=100,base_estimator=SVC(),algorithm="SAMME")))
    # Regression-ii.罗吉斯特回归(LogisticRegression)通常被用作线性分类
    from sklearn.linear_model import LogisticRegression
    # 此处效果不怎么好,罗吉斯特映射本身还是一种线性模型,此处数据集并不是线性可分的
    # 如果想要比较好的效果可以参照SVM的思路:把数据映射到高维空间,但会因此带来数据灾难
    models.append(("Original LogisticRegression",LogisticRegression()))
    models.append(("LogisticRegression",LogisticRegression(C=1000,tol=1e-10,max_iter=1000)))
    # Regression-v.人工神经网络(通常被当做分类器使用)
    # python3.7暂不支持tensorflow
    # 概念:
        # 1.输入层(转化为0-1)->隐含层->输出层(One-Hot形式)
        # 2.节点之间的转换函数又叫激活函数:sigmoid,thanh,ReLU,softplus
    # 算法:
        # 1.反向传播算法:(1.前向计算 2.计算误差 3.反向单层调整(梯度下降) 4.反向传播 5.迭代直至收敛)
        # 2.随机梯度下降SGD: 每次调整权值时,选取部分样本进行梯度下降(优:收敛快,劣:容易陷入局部最优解)
    # 几个注意点:
        # 1.易受离群点影响, 易过拟合(解决方法:正则化,类似集成的思想的dropout后)
        # 2.属性和结果要在0-1之间,且结果为One-Hot形式
        # 3.输出结果进行Softmax转化(归一化)
    from keras.models import Sequential  # 神经网络的容器
    from keras.layers.core import Dense,Activation  # 引入稠密层和激活函数
    from keras.optimizers import SGD  # 引入随机梯度下降算法
    mdl = Sequential()
    # 搭建模型(输入层->激活函数->输出层->归一化->优化器)
    # 接入输入层,指定下个层的神经元个数为50,输入的维度与输入数据的维度保持一致
    mdl.add(Dense(50,input_dim = len(f_v[0])))
    # 引入激活函数
    mdl.add(Activation("sigmoid"))
    # 接入输出层,对应输出的One-Hot形式,标注值只有两个值
    mdl.add(Dense(2))
    # 归一化
    mdl.add(Activation("softmax"))
    # 构建优化器SGD,lr为学习率(即梯度下降算法中的步长α)
    sgd = SGD(lr=0.01)
    # 建立模型,指定loss函数(官网有),optimizer指定优化器
    mdl.compile(loss="mse",optimizer="adam")
    # 拟合过程,注此处Y_train要是One-Hot形式的,要进行转化,nb_epoch为迭代次数,batch_size为每次选取样本数量
    mdl.fit(X_train,np.array([[0,1] if i == 1 else [1,0] for i in Y_train]),nb_epoch=1000,batch_size=2048)
    # 预测
    xy_lst = [(X_train,Y_train),(X_validation,Y_validation),(X_test,Y_test)]
    for i in range(len(xy_lst)):
        X_part = xy_lst[i][0]
        Y_part = xy_lst[i][1]
        Y_pred = mdl.predict_classes(X_part)
        print(i)
        print("NN","ACC:",accuracy_score(Y_part,Y_pred))
        print("NN","REC:",recall_score(Y_part,Y_pred))
        print("NN","F-SCORE:",f1_score(Y_part,Y_pred))
    # Regression-vi.回归树与提升树(GBDT)(通常被当做分类器使用)
    # 概念:整体思路和决策树是一致的
    from sklearn.ensemble import GradientBoostingClassifier
    models.append(("GBDT",GradientBoostingClassifier(max_depth=6,n_estimators=100)))
    # 4.模型效果评判
    # 遍历models列表中的元素
    for clf_name,clf in models:
        # 用对应的模型去拟合训练集
        clf.fit(X_train,Y_train)
        # 创建一个列表对应训练集,验证集和测试集
        xy_list = [(X_train,Y_train),(X_validation,Y_validation),(X_test,Y_test)]
        # 遍历xy_list的元素,计算对应的评价指标
        for i in range(len(xy_list)):
            X_part = xy_list[i][0]
            Y_part = xy_list[i][1]
            Y_pred = clf.predict(X_part)
            print(i)
            print(clf_name,"ACC:",accuracy_score(Y_part,Y_pred))
            print(clf_name,"REC:",recall_score(Y_part,Y_pred))
            print(clf_name,"F-SCORE:",f1_score(Y_part,Y_pred))
            # 【决策树】下四行为图的输出,
            # 下列代码运行的前提是
            # feature_names对应特征,class_names对应标注及其他的一些设置
            # dot_data = export_graphviz(clf, out_file = None, feature_names = f_names, class_names = ["NL","L"],
            #                            filled = True, rounded = True, special_characters = True)
            # graph = pydotplus.graph_from_dot_data(dot_data)
            # graph.write_pdf("dt_tree.pdf")

# 2.回归(输出连续数据,寻找最优拟合,用SSE或拟合优度对其衡量)
def hr_regr(features,label):
    # 1.数据集的设定
    # 此处研究number_project,average_monthly_hours对last_evaluation的影响,原因:这三者相关性比较强(见上章生成的heatmap)
    # 2.引入模型评价指标:分类准确率,召回率,f值
    from sklearn.metrics import mean_squared_error,mean_absolute_error,r2_score
    # 3.模型建立,引入一个列表,一会儿装模型用
    models = []
    # Regression-i.线性回归(LinearRegression),采用最小二乘法(回归结果和实际值)
    # 概念:https://zh.wikipedia.org/wiki/%E6%A2%AF%E5%BA%A6%E4%B8%8B%E9%99%8D%E6%B3%95
        # 梯度:梯度的绝对值是长度为1的方向中函数最大的增加率
        # 梯度下降法:向梯度表示的最大坡度的反方向按规定步长距离α进行迭代搜索走(往谷底走)
        # 线性回归的进化(正则化):约束了极值,同时避免过拟合问题
        # 岭回归(Ridge)采用L2正则化,Lasso回归采用L1正则化
    from sklearn.linear_model import LinearRegression,Ridge,Lasso
    models.append(("LinearRegression",LinearRegression()))
    models.append(("RidgeRegression",Ridge(alpha=0.8)))
    models.append(("Lasso",Lasso(alpha=0.01)))
    # 4.模型效果评判
    # 遍历models列表中的元素
    for regr_name,regr in models:
        # 用对应的模型去拟合feature和label
        regr.fit(features.values,label.values)
        label_pred = regr.predict(features.values)
        # 计算对应评价参数及指标
        print(regr_name)
        print(regr_name,"Coef",regr.coef_)
        print(regr_name,"intercept",regr.intercept_)
        print(regr_name,"MSE:",mean_squared_error(label.values,label_pred))
        print(regr_name,"MAE:",mean_absolute_error(label.values,label_pred))
        print(regr_name,"R2:",r2_score(label.values,label_pred))

def main():
    features,label=hr_preprocessing()
    # 1.分类选这个
    hr_modeling(features,label)
    # 2.回归选这个
    hr_regr(features[["number_project","average_monthly_hours"]],features["last_evaluation"])
if __name__ == "__main__":
    main()
# 分类预测,以SVM为例
import numpy as np
import pandas as pd
df = pd.read_csv(r"D:\Work\data\HR.csv")
df = df.dropna(subset=["satisfaction_level","last_evaluation"])
df = df[df["satisfaction_level"]<=1][df["salary"]!="nme"]
label = df["left"]
df = df.drop(["left","salary","department"],axis=1)
from sklearn.svm import SVC
df = np.array(df)
x = df
y = label
clf = SVC(C=1000)
clf.fit(x,y)
print(clf.predict([[0.38,0.53,2,157,3,0,0]]))
# [1]即为会离职

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Edward_is_1ncredible/article/details/82194180

智能推荐

c# 调用c++ lib静态库_c#调用lib-程序员宅基地

文章浏览阅读2w次,点赞7次,收藏51次。四个步骤1.创建C++ Win32项目动态库dll 2.在Win32项目动态库中添加 外部依赖项 lib头文件和lib库3.导出C接口4.c#调用c++动态库开始你的表演...①创建一个空白的解决方案,在解决方案中添加 Visual C++ , Win32 项目空白解决方案的创建:添加Visual C++ , Win32 项目这......_c#调用lib

deepin/ubuntu安装苹方字体-程序员宅基地

文章浏览阅读4.6k次。苹方字体是苹果系统上的黑体,挺好看的。注重颜值的网站都会使用,例如知乎:font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, W..._ubuntu pingfang

html表单常见操作汇总_html表单的处理程序有那些-程序员宅基地

文章浏览阅读159次。表单表单概述表单标签表单域按钮控件demo表单标签表单标签基本语法结构<form action="处理数据程序的url地址“ method=”get|post“ name="表单名称”></form><!--action,当提交表单时,向何处发送表单中的数据,地址可以是相对地址也可以是绝对地址--><!--method将表单中的数据传送给服务器处理,get方式直接显示在url地址中,数据可以被缓存,且长度有限制;而post方式数据隐藏传输,_html表单的处理程序有那些

PHP设置谷歌验证器(Google Authenticator)实现操作二步验证_php otp 验证器-程序员宅基地

文章浏览阅读1.2k次。使用说明:开启Google的登陆二步验证(即Google Authenticator服务)后用户登陆时需要输入额外由手机客户端生成的一次性密码。实现Google Authenticator功能需要服务器端和客户端的支持。服务器端负责密钥的生成、验证一次性密码是否正确。客户端记录密钥后生成一次性密码。下载谷歌验证类库文件放到项目合适位置(我这边放在项目Vender下面)https://github.com/PHPGangsta/GoogleAuthenticatorPHP代码示例://引入谷_php otp 验证器

【Python】matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距-程序员宅基地

文章浏览阅读4.3k次,点赞5次,收藏11次。matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距

docker — 容器存储_docker 保存容器-程序员宅基地

文章浏览阅读2.2k次。①Storage driver 处理各镜像层及容器层的处理细节,实现了多层数据的堆叠,为用户 提供了多层数据合并后的统一视图②所有 Storage driver 都使用可堆叠图像层和写时复制(CoW)策略③docker info 命令可查看当系统上的 storage driver主要用于测试目的,不建议用于生成环境。_docker 保存容器

随便推点

网络拓扑结构_网络拓扑csdn-程序员宅基地

文章浏览阅读834次,点赞27次,收藏13次。网络拓扑结构是指计算机网络中各组件(如计算机、服务器、打印机、路由器、交换机等设备)及其连接线路在物理布局或逻辑构型上的排列形式。这种布局不仅描述了设备间的实际物理连接方式,也决定了数据在网络中流动的路径和方式。不同的网络拓扑结构影响着网络的性能、可靠性、可扩展性及管理维护的难易程度。_网络拓扑csdn

JS重写Date函数,兼容IOS系统_date.prototype 将所有 ios-程序员宅基地

文章浏览阅读1.8k次,点赞5次,收藏8次。IOS系统Date的坑要创建一个指定时间的new Date对象时,通常的做法是:new Date("2020-09-21 11:11:00")这行代码在 PC 端和安卓端都是正常的,而在 iOS 端则会提示 Invalid Date 无效日期。在IOS年月日中间的横岗许换成斜杠,也就是new Date("2020/09/21 11:11:00")通常为了兼容IOS的这个坑,需要做一些额外的特殊处理,笔者在开发的时候经常会忘了兼容IOS系统。所以就想试着重写Date函数,一劳永逸,避免每次ne_date.prototype 将所有 ios

如何将EXCEL表导入plsql数据库中-程序员宅基地

文章浏览阅读5.3k次。方法一:用PLSQL Developer工具。 1 在PLSQL Developer的sql window里输入select * from test for update; 2 按F8执行 3 打开锁, 再按一下加号. 鼠标点到第一列的列头,使全列成选中状态,然后粘贴,最后commit提交即可。(前提..._excel导入pl/sql

Git常用命令速查手册-程序员宅基地

文章浏览阅读83次。Git常用命令速查手册1、初始化仓库git init2、将文件添加到仓库git add 文件名 # 将工作区的某个文件添加到暂存区 git add -u # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,不处理untracked的文件git add -A # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,包括untracked的文件...

分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120-程序员宅基地

文章浏览阅读202次。分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120

【C++缺省函数】 空类默认产生的6个类成员函数_空类默认产生哪些类成员函数-程序员宅基地

文章浏览阅读1.8k次。版权声明:转载请注明出处 http://blog.csdn.net/irean_lau。目录(?)[+]1、缺省构造函数。2、缺省拷贝构造函数。3、 缺省析构函数。4、缺省赋值运算符。5、缺省取址运算符。6、 缺省取址运算符 const。[cpp] view plain copy_空类默认产生哪些类成员函数

推荐文章

热门文章

相关标签