Python机器学习 第2版 习题答案 郭羽含_第1页
Python机器学习 第2版 习题答案 郭羽含_第2页
Python机器学习 第2版 习题答案 郭羽含_第3页
Python机器学习 第2版 习题答案 郭羽含_第4页
Python机器学习 第2版 习题答案 郭羽含_第5页
已阅读5页,还剩62页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1.6习题答案1.单项选择题1)B

2)C

3)B

4)D

5)A

6)A

7)B(最低),D(最高)

8)C

9)D

10)C2.应用题1)答:特点:1简单易学;2解释型语言;3面向对象;4免费和开源;5跨平台和可移植性;6丰富的标准库;7可扩展性和可嵌入性;

应用领域:1操作系统管理与维护;2科学计算与数据可视化;3图形用户界面开发;4文本处理;5网络编程及web开发;6数据库编程;7游戏开发;2)

答:1代码缩进:同一个级别的代码块缩进量必须相同;

2适当的注释:单行注释可以采用“#”开头;多行注释可以采用一对三引号将需注释内容括起来;3清晰的模块导入:import语句导入一个模块,尽量避免一次导入多个模块;

4代码过长折行处理;

5必要的空格和空行;

6常量名中所有字母大写,由下划线连接各个单词,类名中首字母大写;

3.编程题1)a=float(input("请输入第一个学生成绩:"))b=float(input("请输入第二个学生成绩:"))c=float(input("请输入第三个学生成绩:"))avg=(a+b+c)/3print("平均分为:",avg)2)ch=input("请输入一个字符:")ifch.isdigit():print("数字")elifch.isalpha():print("字母")else:print("其他字符")3)s=0foriinrange(1,101):if'8'instr(i):s+=iprint("含8的数之和为:",s)4)计算1+2!+3!+...+20!的和sum=0

x=1

foriinrange(1,21):

x=x*i

sum=sum+x

print('1+2!+3!+......+20!的和=',sum)2.6习题答案1.单项选择题1)A.

2)B.

3)C.

4)C.

5)A.

6)A.

7)C.

8)D.

9)A.2.编程题1)

元组与列表的主要区别:元组(tuple)是不可变类型,其中的元素不能增删改;列表(list)是可变类型,其中的元素可以增删改。判断是否能向s=(9,7,8,3,2,1,55,6)中添加元素:不能添加,因为元组是不可变对象。2)s=[9,7,8,3,2,1,55,6]print("元素个数:",len(s))print("最大数:",max(s))print("最小数:",min(s))s.append(10)s.remove(55)print("最终列表:",s)3)b=(1,2,3,4,5,6,7,8,9)print("元素和为:",sum(b))3.8习题答案1.单项选择题1)242)1493)404)None5)<class'tuple'>(2,3,4,5)2.简答题1)答:在Python语言中使用def语句定义函数,具体语法格式如下:def函数名([参数列表]):函数体2)答:lambda语句创建匿名函数,lambda语句中,冒号前是函数参数,若有多个参数须使用逗号分隔;冒号后是返回值。lambda为定义匿名函数时的关键字,arguments为传入函数的参数,expression为返回值。3)答:递归函数是指在函数的定义中使用函数自身的方法。即一个函数在内部调用当前函数本身。设置递归终止条件就是为了当递归调用满足这个终止条件时,递归便结束调用不再继续,如果不设置终止条件,将会导致无限递归函数调用,其最终结果会系统耗尽内存,造成栈溢出。4)答:包是一种使用“.模块名”来组织Python模块名称空间的方式。具体来讲就是:包就是一个包含有__init__.py文件的文件夹。模块往往对应着Python的脚本文件(.py),包含了所有该模块定义的函数、变量和类。模块是最高级别的程序组织单元,它能够将程序代码和数据封装以便重用。模块是一个包含所有你定义的函数和变量的文件,其后缀名是.py。模块可以被别的程序引入,使用import语句可以导入模块,使用该模块中的函数等功能。包的导入与模块的导入相似,使用import语句导入包中模块时,需要指定对应的包名。包的导入与模块的导入相似,使用import语句导入包中模块时,需要指定对应的包名。使用方法:import模块名from包名import模块5)答:正则表达式语言就是用于描述这些规则的语言,正则表达式是由普通字符(如字符a到z)及特殊字符(称为元字符,包括:.^$*+?{}[]\|())组成的文字模式。正则表达式的模式可以包含普通字符(包括转义字符)、字符类和预定义的字符类、边界匹配符、重复限定符、选择分支、分组和引用等。3.编程题1)

deffact(n):ifn==0:return1returnn*fact(n-1)n=int(input("请输入整数n:"))print(fact(n))2)deffiber(n):ifn<=2:return1returnfiber(n-1)+fiber(n-2)foriinrange(1,21):print(fiber(i),end='')3)defmin_num(a,b,*c):

ifc:

r=min(c)

returnmin(a,b,r)

else:

returnmin(a,b)

print('最小值为:',min_num(8,2))

print('最小值为:',min_num(16,1,7,4,15))4)importre

tel_numb=input("请输入一个电话号码:")

post_num=input("请输入一个邮政编码:")

net_add=input("请输入一个网络地址:")

ifre.match(r'^(\(\d{3}\)|\d{3}-)?\d{8}$',tel_numb):

print("您输入的电话号码是:\n",tel_numb)

else:

print("请输入正确的电话号码")

ifre.match(r'^\d{6}$',post_num):

print("您输入的邮政编码是:\n",post_num)

else:

print("请输入正确的邮政编码")

ifre.match(r'^https?://\w+(?:\.[^\.]+)+(?:/.+)*$',net_add):

print("您输入的网址是:\n",net_add)

else:

print("请输入正确网址")4.6习题答案1.单项选择题1)D2)D3)B4)B5)A6)D7)C8)B2.编程题1)importnumpyasnparr=np.arange(20).reshape(4,5)print("创建的(4,5)数组:\n",arr)print("\n=====数组基本属性=====")print(f"数组维度数(轴的个数)ndim:{arr.ndim}")#输出2(二维)print(f"数组形状shape:{arr.shape}")#输出(4,5)print(f"数组元素总数size:{arr.size}")#输出20print(f"数组数据类型dtype:{arr.dtype}")#输出int64(视环境)print(f"每个元素字节数itemsize:{arr.itemsize}")#输出8(int64占8字节)print(f"数组总字节数nbytes:{arr.nbytes}")#输出160(20*8)print(f"数组是否为连续内存布局flags.c_contiguous:{arr.flags.c_contiguous}")2)importnumpyasnp#1.创建随机数组(5行3列,取值0~9的整数)np.random.seed(42)#固定随机种子,结果可复现arr=np.random.randint(0,10,size=(5,3))print("原始随机数组:\n",arr)#2.替换操作:将数组中大于7的元素替换为0arr_replace=arr.copy()arr_replace[arr_replace>7]=0print("\n替换后(>7→0):\n",arr_replace)#3.排序操作:按每行升序排序(axis=1)arr_sorted=arr.copy()arr_sorted.sort(axis=1)print("\n每行升序排序后:\n",arr_sorted)#4.重塑操作:将5x3数组重塑为3x5arr_reshape=arr.reshape(3,5)print("\n重塑为3x5数组:\n",arr_reshape)#5.转置操作:原数组转置(5x3→3x5)arr_transpose=arr.Tprint("\n原数组转置后:\n",arr_transpose)#6.合并操作:创建另一个同结构随机数组,与原数组合并arr2=np.random.randint(0,10,size=(5,3))arr_hstack=np.hstack((arr,arr2))#水平合并(5x6)arr_vstack=np.vstack((arr,arr2))#垂直合并(10x3)print("\n另一个随机数组:\n",arr2)print("\n水平合并(hstack)后(5x6):\n",arr_hstack)print("\n垂直合并(vstack)后(10x3):\n",arr_vstack)3)importmatplotlib.pyplotaspltimportnumpyasnp#设置中文显示(避免乱码)plt.rcParams["font.family"]="SimHei"plt.rcParams["axes.unicode_minus"]=False#1.准备数据x=[-3.00,-2.50,-1.75,-1.15,-0.50,0.15,0.75,1.25,1.85,2.45]y=[4,12,50,120,205,255,170,100,20,14]#2.创建画布并绘制条形图plt.figure(figsize=(10,6))#设置画布大小plt.bar(x,y,width=0.15,color="skyblue",edgecolor="black")#绘制条形图#3.添加图表标签和标题plt.xlabel("X值",fontsize=12)plt.ylabel("Y值",fontsize=12)plt.title("条形图示例(表4-6数据)",fontsize=14)plt.grid(axis="y",linestyle="--",alpha=0.7)#添加水平网格线#4.显示图表plt.show()4)importpandasaspd#1.构建员工数据(对应表4-8)data={"姓名":["张伟","李强","王磊","刘洋","陈婷","杨勇","赵敏","孙娜","周晨","吴静"],"职位":["经理","开发工程师","开发工程师","经理","开发工程师","经理","开发工程师","经理","开发工程师","开发工程师"],"部门":["人力资源","信息技术","信息技术","人力资源","信息技术","人力资源","信息技术","人力资源","信息技术","信息技术"],"工资":[75000,85000,80000,90000,70000,95000,65000,88000,72000,78000],"入职年份":[2015,2017,2018,2016,2019,2014,2020,2013,2021,2017]}df=pd.DataFrame(data)print("员工原始数据:\n",df)#任务a:计算每个部门的平均工资dept_avg_salary=df.groupby("部门")["工资"].mean()print("\n=====任务a:各部门平均工资=====")print(dept_avg_salary)#任务b:找出每个部门入职最早的员工#步骤:按部门分组,找到入职年份最小的行(保留所有列)dept_earliest_emp=df.loc[df.groupby("部门")["入职年份"].idxmin()]print("\n=====任务b:各部门入职最早的员工=====")print(dept_earliest_emp[["部门","姓名","入职年份"]])#任务c:找出每个部门工资高于平均工资的员工,按工资降序排列#步骤1:将部门平均工资合并到原数据df["部门平均工资"]=df["部门"].map(dept_avg_salary)#步骤2:筛选工资>部门平均的员工high_salary_emp=df[df["工资"]>df["部门平均工资"]]#步骤3:按工资降序排列high_salary_emp_sorted=high_salary_emp.sort_values(by="工资",ascending=False)print("\n=====任务c:各部门工资高于均值的员工(降序)=====")print(high_salary_emp_sorted[["部门","姓名","工资","部门平均工资"]])5.5习题答案1.填空题1)多领域交叉、概率论、统计学、逼近论、凸分析、算法复杂度理论、模拟、实现2)样本、实例、特征或属性3)分类、回归、聚类、降维4)sklearn.classification、sklearn.regression、sklearn.cluster、sklearn.datasets2.简答题1)答:机器学习核心应用领域包括:·计算机视觉:人脸识别、医疗影像诊断、自动驾驶目标检测、工业质检;·自然语言处理(NLP):机器翻译、情感分析、智能客服、文本生成;·推荐系统:电商商品推荐、视频/音乐推荐、广告精准投放;·金融领域:信用风控、量化交易、反欺诈识别;·医疗健康:疾病辅助诊断、药物研发、患者预后分析;·其他:语音识别、农业病虫害识别、教育个性化推荐。2)答:机器学习核心分类维度及结果如下:·按学习方式(核心维度):监督学习(含分类、回归)、无监督学习(含聚类、降维)、半监督学习、强化学习;·按模型类型:生成模型(如朴素贝叶斯)、判别模型(如逻辑回归);·按算法复杂度:传统机器学习(决策树、SVM)、深度学习(神经网络/Transformer);·按功能:分类、回归、聚类、降维、推荐、排序等。3)答:各概念定义如下:·数据集:用于机器学习任务的所有数据集合,是后续划分的基础(行=样本,列=特征);·训练集:占比60%~80%,用于模型拟合数据规律、调整参数,是训练核心数据;·测试集:占比10%~20%,不参与训练,用于评估模型泛化能力,避免过拟合;·验证集:占比10%~20%,用于超参数调优和模型选择,数据量小时可用k折交叉验证替代。4)答:机器学习核心流程为:①需求与目标分析:明确业务问题、定义任务类型(分类/回归等)、确定评估指标;②数据收集:从数据库、API、公开数据集等渠道获取原始数据;③数据预处理:含数据清洗(缺失/异常值处理)、特征工程(选择/转换/构造)、格式转换;④数据集划分:分为训练集、验证集、测试集;⑤模型选择与训练:根据任务选择算法,用训练集训练模型;⑥模型评估:用验证集/测试集评估性能,分析过拟合/欠拟合;⑦超参数调优:通过网格搜索等优化参数,提升性能;⑧模型部署:将最优模型部署到生产环境;⑨监控与迭代:持续监控效果,用新数据更新模型。5)答:常用数据集获取接口/渠道如下:·Python库内置接口:sklearn.datasets(经典数据集)、torchvision.datasets(视觉数据集)、tensorflow_datasets(TF专用)、huggingface.datasets(NLP/视觉/语音数据集);·公开数据集平台/API:UCI机器学习仓库、KaggleDatasets(支持API调用)、阿里云/百度AI开放平台、ImageNet/COCO(视觉标杆数据集)、政府/科研机构开放API;·自定义接口:爬虫、SQL数据库查询、企业内部RESTfulAPI。6.6习题答案1.单项选择题1)A2)D3)A4)C

5)A6)A7)A8)A2.简答题1)答:线性回归基于最小二乘法,核心是最小化预测值与真实值的残差平方和以拟合自变量与因变量的线性关系,目标是找到最优权重使残差最小;正则化回归则在线性回归损失函数中加入L1、L2或L1+L2正则化惩罚项,通过限制权重大小控制模型复杂度,解决过拟合问题,两者的区别在于线性回归损失函数仅含残差平方和、过拟合风险高、无特征选择能力,适用于特征少且无多重共线性场景,而正则化回归因惩罚项降低了过拟合风险,其中Lasso和弹性网还具备特征选择能力,适用于特征多、有多重共线性的场景。2)答:三者均为正则化线性回归算法,核心目标是解决普通线性回归的过拟合和多重共线性问题,均基于最小二乘法并通过加入惩罚项限制权重大小,且都需调整正则化强度参数α;不同之处在于岭回归用L2范数惩罚项,无特征选择能力但能缓解多重共线性,适用于特征多、多重共线性强的场景,Lasso回归用L1范数惩罚项,能实现特征稀疏化但可能在高相关特征中仅选一个,适用于需筛选核心特征的场景,ElasticNet回归融合L1+L2范数惩罚项,兼顾稀疏化和稳定性,解决了Lasso高相关特征选择的缺陷,适用于特征多且高相关、样本少的场景。3.编程题1)importnumpyasnpimportpandasaspdfromsklearn.linear_modelimportLinearRegression,Ridge,Lassofromsklearn.preprocessingimportStandardScalerfromsklearn.metricsimportr2_score#1.构建数据集(表6-1)data={"X1":[7,1,11,11,7,11,3,1,2,21,1,11,10],"X2":[26,29,56,31,52,55,71,31,54,47,40,66,68],"X3":[6,15,8,8,6,9,17,22,18,4,23,9,8],"X4":[60,52,20,47,33,22,6,44,22,26,34,12,12],"Y":[78.5,74.3,104.3,87.6,95.9,109.2,102.7,72.5,93.1,115.9,83.8,113.3,109.4]}df=pd.DataFrame(data)#2.划分特征(X)和目标(Y),标准化(正则化回归需标准化)X=df[["X1","X2","X3","X4"]]y=df["Y"]scaler=StandardScaler()X_scaled=scaler.fit_transform(X)#均值0,方差1#3.训练普通线性回归lr=LinearRegression()lr.fit(X_scaled,y)y_pred_lr=lr.predict(X_scaled)print("=====普通线性回归=====")print(f"权重系数(X1,X2,X3,X4):{lr.coef_}")print(f"截距:{ercept_}")print(f"R²得分:{r2_score(y,y_pred_lr):.4f}")#4.训练岭回归(α=1,可调整)ridge=Ridge(alpha=1.0)ridge.fit(X_scaled,y)y_pred_ridge=ridge.predict(X_scaled)print("\n=====岭回归=====")print(f"权重系数(X1,X2,X3,X4):{ridge.coef_}")print(f"截距:{ercept_}")print(f"R²得分:{r2_score(y,y_pred_ridge):.4f}")#5.训练Lasso回归(α=0.1,可调整)lasso=Lasso(alpha=0.1)lasso.fit(X_scaled,y)y_pred_lasso=lasso.predict(X_scaled)print("\n=====Lasso回归=====")print(f"权重系数(X1,X2,X3,X4):{lasso.coef_}")print(f"截距:{ercept_}")print(f"R²得分:{r2_score(y,y_pred_lasso):.4f}")#6.特征重要性分析(基于Lasso稀疏性)print("\n=====特征重要性(Lasso筛选)=====")important_features=[f"X{i+1}"fori,coefinenumerate(lasso.coef_)ifabs(coef)>0.1]print(f"核心特征:{important_features}")#构建最终线性回归方程(以Lasso筛选的核心特征为例)final_X=df[important_features]final_lr=LinearRegression()final_lr.fit(final_X,y)print(f"最终回归方程:Y={final_ercept_:.2f}+"+"+".join([f"{final_lr.coef_[i]:.2f}*{feat}"fori,featinenumerate(important_features)]))2)importnumpyasnpimportpandasaspdimportmatplotlib.pyplotaspltfromsklearn.linear_modelimportRidgefromsklearn.preprocessingimportStandardScalerfromsklearn.metricsimportmean_squared_error,r2_score#设置中文显示plt.rcParams["font.family"]="SimHei"plt.rcParams["axes.unicode_minus"]=False#1.构建数据集(表6-2)data={"月份":[1,2,3,4,5,6,7,8,9,10,11,12],"交通流量":[3100,2000,2100,700,700,1200,500,1100,1000,1200,500,1200]}df=pd.DataFrame(data)#2.预处理:特征(月份)需转为二维数组,标准化X=df[["月份"]].values#岭回归要求X为二维y=df["交通流量"].valuesscaler_X=StandardScaler()X_scaled=scaler_X.fit_transform(X)scaler_y=StandardScaler()#可选:对y标准化(提升收敛速度)y_scaled=scaler_y.fit_transform(y.reshape(-1,1)).ravel()#3.训练岭回归模型ridge=Ridge(alpha=0.5)#正则化强度α=0.5ridge.fit(X_scaled,y_scaled)#4.预测(还原标准化结果)y_pred_scaled=ridge.predict(X_scaled)y_pred=scaler_y.inverse_transform(y_pred_scaled.reshape(-1,1)).ravel()#5.模型评估mse=mean_squared_error(y,y_pred)r2=r2_score(y,y_pred)print("=====岭回归模型评估=====")print(f"均方误差(MSE):{mse:.2f}")print(f"R²得分:{r2:.4f}")print(f"回归方程(标准化):y_scaled={ercept_:.4f}+{ridge.coef_[0]:.4f}*X_scaled")#6.可视化结果plt.figure(figsize=(10,6))plt.scatter(df["月份"],y,color="red",label="实际流量",s=80)#实际值plt.plot(df["月份"],y_pred,color="blue",label="岭回归预测",linewidth=2)#预测值plt.xlabel("月份",fontsize=12)plt.ylabel("交通流量",fontsize=12)plt.title("交通流量-月份岭回归拟合",fontsize=14)plt.xticks(range(1,13))plt.grid(linestyle="--",alpha=0.7)plt.legend()plt.show()#7.输出各月份预测值df["预测流量"]=y_pred.round(0)print("\n=====各月份实际/预测流量=====")print(df[["月份","交通流量","预测流量"]])7.9习题答案一、单项选择题1)A2)A3)C4)A5)D6)A7)A8)D9)A10)D二、问答题1)答:近邻算法思想:这是一种“惰性学习”算法,其核心思想是“物以类聚”。对于一个新的待分类样本,算法会在训练集中找出与之在特征空间中最相似的k个已知类别的样本(即“最近邻”),然后通过投票(分类问题)或取平均(回归问题)的方式来决定该新样本的类别。其关键在于距离度量(如欧氏距离)和k值的选择。朴素贝叶斯算法思想:这是一种基于贝叶斯定理和特征条件独立性假设的概率分类算法。其思想是先计算在给定特征条件下,样本属于各个类别的后验概率。具体来说,它利用训练数据来估计:a)每个类别的先验概率(P(Y));b)每个特征在给定类别下的条件概率(P(XiY))。对于新样本,算法通过贝叶斯公式计算其属于每个类别的概率,并将概率最大的类别作为预测结果。2)答:支持向量机的核心目标是找到一个最优的分隔超平面,该平面不仅能将不同类别的样本正确分开,而且要使两类样本中离该平面最近的样本点(即支持向量)到平面的距离(即间隔)最大化。这个最大化间隔的过程等价于求解一个凸二次规划问题。对于线性不可分的数据,SVM通过引入松弛变量容忍部分错误分类,并通过核技巧将原始数据映射到更高维的特征空间,使得在高维空间中变得线性可分,从而避免了直接在高维空间中进行复杂计算。常用核函数及其特点:a)线性核:K(特点:参数少,计算速度快。适用于特征维数高、样本量大的情况,或当问题本身近似线性可分时。b)多项式核:K(特点:`d`为多项式次数。当次数`d`较高时,计算复杂度会显著增加,且容易过拟合。c)高斯核:K(特点:也称为径向基函数核。是最常用、最灵活的核函数。`γ`参数控制模型的复杂度,`γ`越大,模型越复杂,越容易过拟合;`γ`越小,模型越平滑。适用于大多数非线性问题。d)Sigmoid核:K(特点:其形状类似于神经网络中的Sigmoid激活函数,在某些特定场景下有效,但并非总是正定,使用不如高斯核普遍。三、编程题1)importnumpyasnpfromsklearn.preprocessingimportLabelEncoderfromsklearn.naive_bayesimportCategoricalNB#使用适合离散特征的分类器#1.定义数据集(对应表7-1)data=[['≤30','高','否','中','否'],['≤30','高','否','优','否'],['31-40','高','否','中','是'],['>40','中','否','中','是'],['>40','低','是','中','是'],['>40','低','是','优','否'],['31-40','低','是','优','是'],['≤30','中','否','中','否'],['≤30','低','是','中','是'],['>40','中','是','中','是'],['≤30','中','是','优','是'],['31-40','中','否','优','是'],['31-40','高','是','中','是'],['>40','中','否','优','否']]#转换为NumPy数组data=np.array(data)X=data[:,:-1]#特征:年龄、收入、是否学生、信誉y=data[:,-1]#标签:购买计算机#2.将类别标签编码为数字(朴素贝叶斯需要数值输入)encoders=[LabelEncoder()for_inrange(X.shape[1])]X_encoded=np.zeros(X.shape,dtype=int)foriinrange(X.shape[1]):X_encoded[:,i]=encoders[i].fit_transform(X[:,i])label_encoder_y=LabelEncoder()y_encoded=label_encoder_y.fit_transform(y)#3.训练朴素贝叶斯模型(这里使用CategoricalNB,适用于分类特征)model=CategoricalNB()model.fit(X_encoded,y_encoded)#4.预测新样本(例如:年龄≤30,收入中,是学生,信誉优)new_sample=['≤30','中','是','优']new_sample_encoded=[encoders[i].transform([new_sample[i]])[0]foriinrange(len(new_sample))]new_sample_encoded=np.array(new_sample_encoded).reshape(1,-1)prediction=model.predict(new_sample_encoded)prediction_proba=model.predict_proba(new_sample_encoded)print(f"新样本{new_sample}的预测结果:{'购买'ifprediction[0]==1else'不购买'}")print(f"预测概率:[不购买:{prediction_proba[0][0]:.3f},购买:{prediction_proba[0][1]:.3f}]")2)importnumpyasnpimportpandasaspdfromsklearn.preprocessingimportLabelEncoderfromsklearn.treeimportDecisionTreeClassifier,plot_treeimportmatplotlib.pyplotaspltimportwarningswarnings.filterwarnings("ignore")#设置中文字体plt.rcParams['font.sans-serif']=['SimHei','MicrosoftYaHei','DejaVuSans']#用来正常显示中文标签plt.rcParams['axes.unicode_minus']=False#用来正常显示负号#1.定义数据集(对应表7-2)data_dict={'序号':list(range(1,15)),'数量':['多','少','多','多','多','多','少','少','多','少','多','少','多','多'],'页数':[100,50,50,120,40,140,130,50,160,50,30,170,60,100],'是否促销':['是','是','是','否','否','是','是','是','是','否','否','是','否','否'],'评价':['B','A','B','B','A','A','B','A','B','B','B','B','A','A'],'销量':['高','低','低','低','高','高','低','高','高','低','高','低','高','高']}df=pd.DataFrame(data_dict)#2.数据预处理:将分类变量编码,数值变量保留X=df[['数量','页数','是否促销','评价']].copy()y=df['销量']#编码分类特征cat_columns=['数量','是否促销','评价']label_encoders={}forcolincat_columns:le=LabelEncoder()X[col]=le.fit_transform(X[col])label_encoders[col]=le#编码目标变量le_y=LabelEncoder()y_encoded=le_y.fit_transform(y)#高->1,低->0#3.训练决策树模型model=DecisionTreeClassifier(criterion='entropy',random_state=42)#使用信息熵model.fit(X,y_encoded)#4.评估模型(在训练集上,实际应划分测试集)train_score=model.score(X,y_encoded)print(f"决策树模型在训练集上的准确率:{train_score:.3f}")#5.可视化决策树plt.figure(figsize=(15,10))feature_names=['数量(0:少,1:多)','页数','是否促销(0:否,1:是)','评价(0:A,1:B)']class_names=['低','高']plot_tree(model,feature_names=feature_names,class_names=class_names,filled=True,rounded=True,fontsize=10)plt.title("图书销量预测决策树")plt.tight_layout()plt.show()#6.预测一个新样本(例如:数量多,页数80,促销是,评价A)#注意:需要先将分类值转化为编码new_sample={'数量':'多','页数':80,'是否促销':'是','评价':'A'}new_sample_encoded=[]forcolin['数量','页数','是否促销','评价']:ifcolinlabel_encoders:new_sample_encoded.append(label_encoders[col].transform([new_sample[col]])[0])else:new_sample_encoded.append(new_sample[col])prediction=model.predict([new_sample_encoded])print(f"\n新样本{new_sample}的预测销量:{le_y.inverse_transform(prediction)[0]}")8.7习题答案一、单项选择题1)B2)A3)B4)D5)B6)D7)D8)B二、问答题1)答:算法思想:k均值是一种迭代求解的质心聚类算法。首先,随机选择k个点作为初始的聚类中心。然后,将每个样本点分配到距离它最近的聚类中心所在的簇中。接着,根据每个簇中所有样本点重新计算该簇的聚类中心(即各维度特征的均值)。重复步骤前两个步骤,直到聚类中心的位置不再发生显著变化或达到预设的迭代次数。优点:原理简单,易于理解和实现。对于近似球形分布且簇间分离度较好的数据,聚类效果较好。当簇间区别明显时,收敛速度快。缺点:需要预先指定簇数k,而k值的选择通常比较困难,需要经验或多次尝试。对初始质心的选择敏感,不同的初始值可能导致不同的聚类结果。对噪声和异常点敏感,因为它们会显著影响质心的计算。不适合发现非凸形状的簇(如环形、半月形)或大小差别很大的簇。主要适用于数值型数据。2)答:算法思想:DBSCAN是一种基于密度的聚类算法。其核心思想是:一个簇是由密度可达关系连接起来的最大样本点集合。它定义了三个关键概念:核心点:在给定半径(eps)的邻域内,包含至少一定数量(min_samples)样本的点。边界点:在核心点的邻域内,但自身不满足核心点条件的点。噪声点:既不是核心点也不是边界点的点。算法从任意一个核心点出发,寻找所有从它出发密度可达的样本(包括其他核心点和边界点),这些样本形成一个簇。重复此过程,直到所有核心点都被访问过。优点:不需要预先指定簇的个数k。能够识别并过滤噪声点(异常值)。可以发现任意形状的聚类(非球形),对簇的形状没有假设。聚类结果对输入样本的顺序不敏感(核心思想决定)。缺点:对参数(eps和min_samples)非常敏感,参数设置不当可能导致聚类效果很差。当数据集的密度不均匀或簇间密度相差较大时,聚类效果不佳。处理高维数据时,由于“维度灾难”,距离度量可能失效,效果下降。样本量很大时,尽管有索引优化,计算复杂度仍然较高。三、编程题1)fromsklearn.datasetsimportmake_blobsfromsklearn.clusterimportKMeansimportmatplotlib.pyplotaspltimportwarningswarnings.filterwarnings("ignore",category=UserWarning)#1.生成数据集centers=[[5,2],[-3,2],[-2,-4],[2,-3]]X,y_true=make_blobs(n_samples=2000,centers=centers,n_features=2,cluster_std=1.0,random_state=42)#2.使用KMeans进行聚类kmeans=KMeans(n_clusters=4,init='k-means++',n_init=10,random_state=42)y_pred=kmeans.fit_predict(X)#3.获取聚类中心和标签cluster_centers=kmeans.cluster_centers_labels=kmeans.labels_#4.可视化聚类结果plt.figure(figsize=(8,6))#绘制所有样本点,按聚类结果着色scatter=plt.scatter(X[:,0],X[:,1],c=y_pred,cmap='viridis',s=20,alpha=0.6,edgecolors='k',linewidths=0.5)#绘制聚类中心plt.scatter(cluster_centers[:,0],cluster_centers[:,1],c='red',marker='X',s=200,label='Centroids',edgecolors='k',linewidths=1.5)plt.title('K-MeansClusteringonBlobData(k=4)')plt.xlabel('Feature1')plt.ylabel('Feature2')plt.legend()plt.colorbar(scatter,label='ClusterLabel')plt.grid(True,linestyle='--',alpha=0.5)plt.axis('equal')plt.show()print(f"聚类中心坐标:\n{cluster_centers}")print(f"轮廓系数(仅供参考,需要导入metrics):")#若要计算轮廓系数,可取消以下注释#fromsklearn.metricsimportsilhouette_score#score=silhouette_score(X,labels)#print(f"SilhouetteScore:{score:.3f}")2)fromsklearn.datasetsimportmake_moonsfromsklearn.clusterimportDBSCANimportmatplotlib.pyplotaspltimportnumpyasnp#1.生成半月状数据集X,y_true=make_moons(n_samples=2000,noise=0.15,random_state=42)#2.使用DBSCAN进行聚类dbscan=DBSCAN(eps=0.2,min_samples=20)y_pred=dbscan.fit_predict(X)#3.识别核心点、边界点和噪声点core_sample_mask=np.zeros_like(dbscan.labels_,dtype=bool)core_sample_mask[dbscan.core_sample_indices_]=Truelabels=dbscan.labels_#统计聚类情况n_clusters=len(set(labels))-(1if-1inlabelselse0)n_noise=list(labels).count(-1)print(f'估计的簇数量:{n_clusters}')print(f'估计的噪声点数量:{n_noise}')#4.可视化聚类结果plt.figure(figsize=(10,8))#分离核心点和噪声点core_points=X[core_sample_mask]core_labels=labels[core_sample_mask]noise_points=X[labels==-1]#绘制核心点(按簇着色)unique_labels=set(core_labels)colors=plt.cm.Spectral(np.linspace(0,1,len(unique_labels)))fori,(label,color)inenumerate(zip(sorted(unique_labels),colors)):iflabel==-1:continue#跳过噪声点,噪声点单独绘制#绘制该簇的核心点mask=core_labels==labelplt.scatter(core_points[mask,0],core_points[mask,1],c=[color],marker='o',s=30,edgecolors='k',linewidths=0.5,label=f'Cluster{label}'ifi==0else"")#绘制噪声点(如果有)iflen(noise_points)>0:plt.scatter(noise_points[:,0],noise_points[:,1],c='black',marker='x',s=20,linewidths=0.5,label='Noise')plt.title(f'DBSCANClusteringonMoonData\n(Estimatedclusters:{n_clusters},Noise:{n_noise})')plt.xlabel('Feature1')plt.ylabel('Feature2')plt.legend(loc='upperright')plt.grid(True,linestyle='--',alpha=0.3)plt.axis('equal')plt.tight_layout()plt.show()9.6习题答案一、单项选择题1)A2)B3)C4)A5)B6)C7)A8)B9)D10)B11)C二、问答题1)答:中心化(使每个特征的均值为0)是PCA标准预处理步骤。原因如下:简化计算与解释:协方差矩阵的计算公式在数据已中心化时简化为1m第一主成分将直接通过数据方差最大的方向,而非数据的“重心”方向。去除偏差:如果数据未中心化,第一个主成分可能会强烈地指向数据的均值方向,这通常不是我们关心的最大方差方向。中心化能确保PCA寻找的是数据变异的主要方向,而不是其位置。未中心化的影响:如果未进行中心化,PCA的主成分方向将受到数据原始均值的严重影响。第一个主成分可能主要反映了数据的整体偏移,而非数据结构本身的最大方差方向,从而导致降维效果变差,难以捕捉数据真正的变化模式。2)答:贡献率定义:第i个主成分的贡献率是指该主成分所解释的方差占原始数据总方差的比例。累计贡献率则是前k个主成分的贡献率之和,表示降维后保留了多少原始信息。剩余方差的意义:剩余的5%方差可能包含以下信息:噪声:大部分可能是测量误差、随机波动等无关信息。细微结构:可能包含一些对整体模式影响甚微的细节或特异性信息。高阶非线性关系:PCA是线性方法,可能无法捕获数据中存在的复杂非线性结构,这部分信息会丢失在剩余方差中。在实际应用中,如果累计贡献率达到95%(90%+5%),通常认为降维后的数据已经保留了绝大部分有价值的信息,剩余的5%可以酌情舍弃以简化模型。3)答:与特征选择的区别:特征选择:从原始特征集中挑选一个子集,保留的是原始特征本身。它依赖于特征的重要性评估(如过滤法、包裹法、嵌入法)。PCA降维:通过线性变换创建一组全新的特征(主成分),这些特征是原始特征的线性组合。它不保留任何原始特征,而是保留数据的全局方差结构。PCA保留的信息:PCA保留的是数据在特征空间中的全局方差信息,即数据点分布的主要方向。它试图用尽可能少的主成分来最大化地解释原始数据的总体变异。处理强相关特征的表现:PCA非常擅长处理特征间强相关的数据。因为强相关性意味着数据存在冗余,PCA可以通过寻找少数几个不相关的方向(主成分)来捕捉这些相关特征背后的共同模式,从而有效去除冗余,实现高效的降维。4)答:数据变化:原始二维空间中的每个样本点(x1,分布特点:在投影后的一维空间中:类内紧致:属于同一类别的样本点,其投影值会紧密地聚集在一起(方差小)。类间分离:属于不同类别的样本点,其投影值的中心(均值)会尽可能远离。最大判别性:投影方向是经过优化选择的,使得上述“类内紧致、类间分离”的程度达到最大。因此,降维后的数据非常有利于后续的分类任务(例如,只需设置一个简单的阈值即可区分两类)。三、操作题1)importnumpyasnpfromsklearn.decompositionimportPCAfromsklearn.datasetsimportmake_classificationfromsklearn.preprocessingimportStandardScaler#生成示例数据集:100个样本,10个特征X,_=make_classification(n_samples=100,n_features=10,random_state=42)#通常建议先标准化(特别是特征量纲不一时)scaler=StandardScaler()X_scaled=scaler.fit_transform(X)#应用PCA,降至3维pca=PCA(n_components=3)X_pca=pca.fit_transform(X_scaled)print("原始数据形状:",X.shape)print("降维后数据形状:",X_pca.shape)print("各主成分贡献率:",pca.explained_variance_ratio_)print("累计贡献率:",np.cumsum(pca.explained_variance_ratio_))2)importnumpyasnpimportmatplotlib.pyplotaspltfromsklearn.decompositionimportPCAfromsklearn.preprocessingimportStandardScaler#模拟不同量纲的数据:身高(cm)、体重(kg)、收入(万元)np.random.seed(42)height=np.random.normal(170,10,100)#均值170cm,标准差10weight=np.random.normal(70,15,100)#均值70kg,标准差15income=np.random.normal(15,8,100)#均值15万元,标准差8X=np.column_stack((height,weight,income))#不进行标准化pca_raw=PCA(n_components=2)X_pca_raw=pca_raw.fit_transform(X)#进行标准化scaler=StandardScaler()X_scaled=scaler.fit_transform(X)pca_scaled=PCA(n_components=2)X_pca_scaled=pca_scaled.fit_transform(X_scaled)#比较结果print("===未标准化===")print("主成分贡献率:",pca_raw.explained_variance_ratio_)print("主成分方向(特征向量):\n",pca_ponents_)print("\n===标准化后===")print("主成分贡献率:",pca_scaled.explained_variance_ratio_)print("主成分方向(特征向量):\n",pca_ponents_)3)fromsklearn.datasetsimportload_digitsfromsklearn.discriminant_analysisimportLinearDiscriminantAnalysisfromsklearn.model_selectionimporttrain_test_splitfromsklearn.svmimportSVCfromsklearn.metricsimportaccuracy_score#1.加载数据(10类,每类约180个样本)digits=load_digits()X,y=digits.data,digits.target#2.划分训练集和测试集X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.3,random_state=42)#3.应用LDA降维(最多可降至min(特征数,类别数-1)维)#这里特征数64>类别数10-1=9,所以最多降至9维lda=LinearDiscriminantAnalysis(n_components=9)X_train_lda=lda.fit_transform(X_train,y_train)X_test_lda=lda.transform(X_test)print("原始特征维度:",X_train.shape[1])print("LDA降维后维度:",X_train_lda.shape[1])#4.在降维后的数据上训练分类器(例如SVM)svm_clf=SVC(kernel='rbf',random_state=42)svm_clf.fit(X_train_lda,y_train)#5.评估y_pred=svm_clf.predict(X_test_lda)accuracy=accuracy_score(y_test,y_pred)print(f"LDA降维后SVM分类准确率:{accuracy:.4f}")#解释:LDA利用标签信息找到最具判别性的投影方向,降维后的特征更利于分类。#与PCA等无监督降维相比,LDA在分类任务上通常能获得更好或相当的性能,且维度更低。4)importnumpyasnpimportmatplotlib.pyplotaspltfromsklearn.decompositionimportDictionaryLearningfromsklearn.feature_extraction.imageimportextract_patches_2d,reconstruct_from_patches_2d#1.生成合成图像(棋盘格)defgenerate_checkerboard(size=256,square_size=16):"""生成棋盘格图像"""image=np.zeros((size,size))foriinrange(0,size,square_size*2):forjinrange(0,size,square_size*2):image[i:i+square_size,j:j+square_size]=1image[i+square_size:i+2*square_size,j+square_size:j+2*square_size]=1returnimage#生成图像image=generate_checkerboard(size=256,square_size=16)#添加高斯噪声np.random.seed(42)noise=np.random.normal(0,0.2,image.shape)image_noisy=image+noiseimage_noisy=np.clip(image_noisy,0,1)#2.提取图像块作为样本patch_size=(8,8)patches=extract_patches_2d(image_noisy,patch_size,max_patches=1000,random_state=42)patches=patches.reshape(patches.shape[0],-1)#展平#3.使用字典学习(稀疏编码)学习字典n_components=100#字典大小dict_learner=DictionaryLearning(n_components=n_components,alpha=1,max_iter=1000,random_state=42)dict_learner.fit(patches)dictionary=dict_ponents_#4.对噪声图像块进行稀疏编码(去噪)patches_noisy=extract_patches_2d(image_noisy,patch_size)patches_noisy_flat=patches_noisy.reshape(patches_noisy.shape[0],-1)#获取稀疏编码(transform)codes=dict_learner.transform(patches_noisy_flat)#用字典和稀疏编码重构图像块(去噪)patches_denoised_flat=codes@dictionarypatches_denoised=patches_denoised_flat.reshape(patches_noisy.shape)#5.从块重建整张图像image_denoised=reconstruct_from_patches_2d(patches_denoised,image.shape)#6.可视化结果fig,axes=plt.subplots(1,3,figsize=(12,4))axes[0].imshow(image,cmap='gray')axes[0].set_title('原始图像(棋盘格)')axes[1].imshow(image_noisy,cmap='gray')axes[1].set_title('噪声图像')axes[2].imshow(image_denoised,cmap='gray')axes[2].set_title('字典学习去噪后')foraxinaxes:ax.axis('off')plt.tight_layout()plt.show()print("去噪完成!")10.6习题答案单项选择题1)B2)D3)A4)A5)D6)C7)D问答题1)随机森林通过以下步骤实现:①从原始训练集中有放回地随机抽取N个样本(Bootstrap采样),形成多个子训练集;②对每个子训练集,在每次节点分裂时,从全部特征中随机选取m个特征(m<总特征数),从中选择最优分裂特征;③基于上述子集和特征子集,构建多棵决策树,每棵树完全生长(通常不剪枝);④预测时,分类任务采用多数投票,回归任务采用平均值,综合所有树的结果作为最终输出。2)决策树是随机森林的基本组成单元(基学习器);随机森林通过集成多棵决策树,引入样本随机性(Bootstrap)和特征随机性,降低模型方差,提高泛化能力;单棵决策树容易过拟合,而随机森林通过“集体智慧”有效缓解这一问题;因此,随机森林可看作是基于决策树的Bagging集成方法。编程题1)fromsklearn.datasetsimportload_digitsfromsklearn.ensembleimportRandomForestClassifierfromsklearn.model_selectionimporttrain_test_splitfromsklearn.metricsimportaccuracy_score#加载数据digits=load_digits()X,y=digits.data,digits.targetX_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.3,random_state=42)#测试不同n_estimatorsfornin[10,50,100,200]:rf=RandomForestClassifier(n_estimators=n,random_state=42)rf.fit(X_train,y_train)acc=accuracy_score(y_test,rf.predict(X_test))print(f"n_estimators={n},Accuracy:{acc:.4f}")#测试不同max_featuresformfin['sqrt','log2',None]:rf=RandomForestClassifier(n_estimators=100,max_features=mf,random_state=42)rf.fit(X_train,y_train)acc=accuracy_score(y_test,rf.predict(X_test))print(f"max_features={mf},Accuracy:{acc:.4f}")2)fromsklearn.datasetsimportload_winefromsklearn.model_selectionimporttrain_test_splitfromsklearn.ensembleimportAdaBoostClassifier,GradientBoostingClassifierfromsklearn.treeimportDecisionTreeClassifierfromsklearn.metricsimportaccuracy_score#加载数据wine=load_wine()X,y=wine.data,wine.targetX_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.3,random_state=42)#AdaBoo

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论