[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

智能推荐

攻防世界_难度8_happy_puzzle_攻防世界困难模式攻略图文-程序员宅基地

文章浏览阅读645次。这个肯定是末尾的IDAT了,因为IDAT必须要满了才会开始一下个IDAT,这个明显就是末尾的IDAT了。,对应下面的create_head()代码。,对应下面的create_tail()代码。不要考虑爆破,我已经试了一下,太多情况了。题目来源:UNCTF。_攻防世界困难模式攻略图文

达梦数据库的导出(备份)、导入_达梦数据库导入导出-程序员宅基地

文章浏览阅读2.9k次,点赞3次,收藏10次。偶尔会用到,记录、分享。1. 数据库导出1.1 切换到dmdba用户su - dmdba1.2 进入达梦数据库安装路径的bin目录,执行导库操作  导出语句:./dexp cwy_init/[email protected]:5236 file=cwy_init.dmp log=cwy_init_exp.log 注释:   cwy_init/init_123..._达梦数据库导入导出

js引入kindeditor富文本编辑器的使用_kindeditor.js-程序员宅基地

文章浏览阅读1.9k次。1. 在官网上下载KindEditor文件,可以删掉不需要要到的jsp,asp,asp.net和php文件夹。接着把文件夹放到项目文件目录下。2. 修改html文件,在页面引入js文件:<script type="text/javascript" src="./kindeditor/kindeditor-all.js"></script><script type="text/javascript" src="./kindeditor/lang/zh-CN.js"_kindeditor.js

STM32学习过程记录11——基于STM32G431CBU6硬件SPI+DMA的高效WS2812B控制方法-程序员宅基地

文章浏览阅读2.3k次,点赞6次,收藏14次。SPI的详情简介不必赘述。假设我们通过SPI发送0xAA,我们的数据线就会变为10101010,通过修改不同的内容,即可修改SPI中0和1的持续时间。比如0xF0即为前半周期为高电平,后半周期为低电平的状态。在SPI的通信模式中,CPHA配置会影响该实验,下图展示了不同采样位置的SPI时序图[1]。CPOL = 0,CPHA = 1:CLK空闲状态 = 低电平,数据在下降沿采样,并在上升沿移出CPOL = 0,CPHA = 0:CLK空闲状态 = 低电平,数据在上升沿采样,并在下降沿移出。_stm32g431cbu6

计算机网络-数据链路层_接收方收到链路层数据后,使用crc检验后,余数为0,说明链路层的传输时可靠传输-程序员宅基地

文章浏览阅读1.2k次,点赞2次,收藏8次。数据链路层习题自测问题1.数据链路(即逻辑链路)与链路(即物理链路)有何区别?“电路接通了”与”数据链路接通了”的区别何在?2.数据链路层中的链路控制包括哪些功能?试讨论数据链路层做成可靠的链路层有哪些优点和缺点。3.网络适配器的作用是什么?网络适配器工作在哪一层?4.数据链路层的三个基本问题(帧定界、透明传输和差错检测)为什么都必须加以解决?5.如果在数据链路层不进行帧定界,会发生什么问题?6.PPP协议的主要特点是什么?为什么PPP不使用帧的编号?PPP适用于什么情况?为什么PPP协议不_接收方收到链路层数据后,使用crc检验后,余数为0,说明链路层的传输时可靠传输

软件测试工程师移民加拿大_无证移民,未受过软件工程师的教育(第1部分)-程序员宅基地

文章浏览阅读587次。软件测试工程师移民加拿大 无证移民,未受过软件工程师的教育(第1部分) (Undocumented Immigrant With No Education to Software Engineer(Part 1))Before I start, I want you to please bear with me on the way I write, I have very little gen...

随便推点

Thinkpad X250 secure boot failed 启动失败问题解决_安装完系统提示secureboot failure-程序员宅基地

文章浏览阅读304次。Thinkpad X250笔记本电脑,装的是FreeBSD,进入BIOS修改虚拟化配置(其后可能是误设置了安全开机),保存退出后系统无法启动,显示:secure boot failed ,把自己惊出一身冷汗,因为这台笔记本刚好还没开始做备份.....根据错误提示,到bios里面去找相关配置,在Security里面找到了Secure Boot选项,发现果然被设置为Enabled,将其修改为Disabled ,再开机,终于正常启动了。_安装完系统提示secureboot failure

C++如何做字符串分割(5种方法)_c++ 字符串分割-程序员宅基地

文章浏览阅读10w+次,点赞93次,收藏352次。1、用strtok函数进行字符串分割原型: char *strtok(char *str, const char *delim);功能:分解字符串为一组字符串。参数说明:str为要分解的字符串,delim为分隔符字符串。返回值:从str开头开始的一个个被分割的串。当没有被分割的串时则返回NULL。其它:strtok函数线程不安全,可以使用strtok_r替代。示例://借助strtok实现split#include <string.h>#include <stdio.h&_c++ 字符串分割

2013第四届蓝桥杯 C/C++本科A组 真题答案解析_2013年第四届c a组蓝桥杯省赛真题解答-程序员宅基地

文章浏览阅读2.3k次。1 .高斯日记 大数学家高斯有个好习惯:无论如何都要记日记。他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210后来人们知道,那个整数就是日期,它表示那一天是高斯出生后的第几天。这或许也是个好习惯,它时时刻刻提醒着主人:日子又过去一天,还有多少时光可以用于浪费呢?高斯出生于:1777年4月30日。在高斯发现的一个重要定理的日记_2013年第四届c a组蓝桥杯省赛真题解答

基于供需算法优化的核极限学习机(KELM)分类算法-程序员宅基地

文章浏览阅读851次,点赞17次,收藏22次。摘要:本文利用供需算法对核极限学习机(KELM)进行优化,并用于分类。

metasploitable2渗透测试_metasploitable2怎么进入-程序员宅基地

文章浏览阅读1.1k次。一、系统弱密码登录1、在kali上执行命令行telnet 192.168.26.1292、Login和password都输入msfadmin3、登录成功,进入系统4、测试如下:二、MySQL弱密码登录:1、在kali上执行mysql –h 192.168.26.129 –u root2、登录成功,进入MySQL系统3、测试效果:三、PostgreSQL弱密码登录1、在Kali上执行psql -h 192.168.26.129 –U post..._metasploitable2怎么进入

Python学习之路:从入门到精通的指南_python人工智能开发从入门到精通pdf-程序员宅基地

文章浏览阅读257次。本文将为初学者提供Python学习的详细指南,从Python的历史、基础语法和数据类型到面向对象编程、模块和库的使用。通过本文,您将能够掌握Python编程的核心概念,为今后的编程学习和实践打下坚实基础。_python人工智能开发从入门到精通pdf

推荐文章

热门文章

相关标签