Python Day36 学习

article/2025/8/25 17:42:10

对列表、字典、元组、集合进行总结

@浙大疏锦行

摘自讲义

机器学习管道Pipeline

Q1. 什么是机器学习管道Pipeline?

摘自讲义

    Q. 关于“转换器”?

摘自讲义

# 导入StandardScaler转换器
from sklearn.preprocessing import StandardScaler# 初始化转换器
scaler = StandardScaler()# 1. 学习训练数据的缩放规则(计算均值和标准差),本身不存储数据
scaler.fit(X_train)# 2. 应用规则到训练数据和测试数据
X_train_scaled = scaler.transform(X_train)
X_test_scaled = scaler.transform(X_test)# 也可以使用fit_transform一步完成
# X_train_scaled = scaler.fit_transform(X_train)
```

   Q. 关于“估计器”

估计器(Estimator)是实现机器学习算法的对象或类。它用于拟合(fit)数据并进行预测(predict)。估计器是机器学习模型的基本组成部分,用于从数据中学习模式、进行预测和进行模型评估。

估计器的主要方法是fit和predict。fit方法用于根据输入数据学习模型的参数和规律,而predict方法用于对新的未标记样本进行预测。估计器的特点是有状态的,即它们在训练过程中存储了关于数据的状态信息,以便在预测阶段使用。估计器通过学习训练数据中的模式和规律来进行预测。因此,估计器需要在训练集上进行训练,并使用训练得到的模型参数对新数据进行预测。

常见的估计器包括分类器(classifier)、回归器(regresser)、聚类器(clusterer)

from sklearn.linear_model import LinearRegression
# 创建一个回归器
model = LinearRegression()
# 在训练集上训练模型
model.fit(X_train_scaled, y_train)
# 对测试集进行预测
y_pred = model.predict(X_test_scaled)

Q2. 对“管道”的概念再理解?

摘自讲义

了解了分类器和估计器,所以可以理解为在机器学习是由转换器(Transformer)和估计器(Estimator按照一定顺序组合在一起的来完成了整个流程。

机器学习的管道(Pipeline)机制通过将多个转换器和估计器按顺序连接在一起,可以构建一个完整的数据处理和模型训练流程。在管道机制中,可以使用Pipeline类来组织和连接不同的转换器和估计器。Pipeline类提供了一种简单的方式来定义和管理机器学习任务的流程。

管道机制是按照封装顺序依次执行的一种机制,在机器学习算法中得以应用的根源在于,参数集在新数据集(比如测试集)上的重复使用。且代码看上去更加简洁明确。这也意味着,很多个不同的数据集,只要处理成管道的输入形式,后续的代码就可以复用。(这里为我们未来的python文件拆分做铺垫),也就是把很多个类和函数操作写进一个新的pipeline中。

这符合编程中的一个非常经典的思想:don't repeat yourself。(dry原则),也叫做封装思想,我们之前提到过类似的思想的应用: 函数、类,现在我们来说管道。

Q3. "管道”的应用

Pipeline最大的价值和核心应用场景之一,就是与交叉验证和网格搜索等结合使用,来:

1. 防止数据泄露: 这是在使用交叉验证时,Pipeline自动完成预处理并在每个折叠内独立fit/transform的关键优势。

2. 简化超参数调优: 可以方便地同时调优预处理步骤和模型的参数。

Q4. 对“信贷数据集”进行管道工程,重构整个代码

没有进行管道工程的代码如下:

# 先运行之前预处理好的代码
import pandas as pd
import pandas as pd    #用于数据处理和分析,可处理表格数据。
import numpy as np     #用于数值计算,提供了高效的数组操作。
import matplotlib.pyplot as plt    #用于绘制各种类型的图表
import seaborn as sns   #基于matplotlib的高级绘图库,能绘制更美观的统计图形。
import warnings
warnings.filterwarnings("ignore")# 设置中文字体(解决中文显示问题)
plt.rcParams['font.sans-serif'] = ['SimHei']  # Windows系统常用黑体字体
plt.rcParams['axes.unicode_minus'] = False    # 正常显示负号
data = pd.read_csv('data.csv')    #读取数据# 先筛选字符串变量 
discrete_features = data.select_dtypes(include=['object']).columns.tolist()
# Home Ownership 标签编码
home_ownership_mapping = {'Own Home': 1,'Rent': 2,'Have Mortgage': 3,'Home Mortgage': 4
}
data['Home Ownership'] = data['Home Ownership'].map(home_ownership_mapping)# Years in current job 标签编码
years_in_job_mapping = {'< 1 year': 1,'1 year': 2,'2 years': 3,'3 years': 4,'4 years': 5,'5 years': 6,'6 years': 7,'7 years': 8,'8 years': 9,'9 years': 10,'10+ years': 11
}
data['Years in current job'] = data['Years in current job'].map(years_in_job_mapping)# Purpose 独热编码,记得需要将bool类型转换为数值
data = pd.get_dummies(data, columns=['Purpose'])
data2 = pd.read_csv("data.csv") # 重新读取数据,用来做列名对比
list_final = [] # 新建一个空列表,用于存放独热编码后新增的特征名
for i in data.columns:if i not in data2.columns:list_final.append(i) # 这里打印出来的就是独热编码后的特征名
for i in list_final:data[i] = data[i].astype(int) # 这里的i就是独热编码后的特征名# Term 0 - 1 映射
term_mapping = {'Short Term': 0,'Long Term': 1
}
data['Term'] = data['Term'].map(term_mapping)
data.rename(columns={'Term': 'Long Term'}, inplace=True) # 重命名列
continuous_features = data.select_dtypes(include=['int64', 'float64']).columns.tolist()  #把筛选出来的列名转换成列表# 连续特征用中位数补全
for feature in continuous_features:     mode_value = data[feature].mode()[0]            #获取该列的众数。data[feature].fillna(mode_value, inplace=True)          #用众数填充该列的缺失值,inplace=True表示直接在原数据上修改。# 最开始也说了 很多调参函数自带交叉验证,甚至是必选的参数,你如果想要不交叉反而实现起来会麻烦很多
# 所以这里我们还是只划分一次数据集
from sklearn.model_selection import train_test_split
X = data.drop(['Credit Default'], axis=1)  # 特征,axis=1表示按列删除
y = data['Credit Default'] # 标签
# 按照8:2划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)  # 80%训练集,20%测试集from sklearn.ensemble import RandomForestClassifier #随机森林分类器from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score # 用于评估分类器性能的指标
from sklearn.metrics import classification_report, confusion_matrix #用于生成分类报告和混淆矩阵
import warnings #用于忽略警告信息
warnings.filterwarnings("ignore") # 忽略所有警告信息
# --- 1. 默认参数的随机森林 ---
# 评估基准模型,这里确实不需要验证集
print("--- 1. 默认参数随机森林 (训练集 -> 测试集) ---")
import time # 这里介绍一个新的库,time库,主要用于时间相关的操作,因为调参需要很长时间,记录下会帮助后人知道大概的时长
start_time = time.time() # 记录开始时间
rf_model = RandomForestClassifier(random_state=42)
rf_model.fit(X_train, y_train) # 在训练集上训练
rf_pred = rf_model.predict(X_test) # 在测试集上预测
end_time = time.time() # 记录结束时间print(f"训练与预测耗时: {end_time - start_time:.4f} 秒")
print("\n默认随机森林 在测试集上的分类报告:")
print(classification_report(y_test, rf_pred))
print("默认随机森林 在测试集上的混淆矩阵:")
print(confusion_matrix(y_test, rf_pred))

下面开始“管道工程”

步骤1. 导入库和数据加载
# 导入基础库
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import time # 导入 time 库
import warnings# 忽略警告
warnings.filterwarnings("ignore")# 设置中文字体和负号正常显示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False# 导入 Pipeline 和相关预处理工具
from sklearn.pipeline import Pipeline # 用于创建机器学习工作流
from sklearn.compose import ColumnTransformer # 用于将不同的预处理应用于不同的列
from sklearn.preprocessing import OrdinalEncoder, OneHotEncoder, StandardScaler # 用于数据预处理(有序编码、独热编码、标准化)
from sklearn.impute import SimpleImputer # 用于处理缺失值# 导入机器学习模型和评估工具
from sklearn.ensemble import RandomForestClassifier # 随机森林分类器
from sklearn.metrics import classification_report, confusion_matrix # 用于评估分类器性能
from sklearn.model_selection import train_test_split # 用于划分训练集和测试集# --- 加载原始数据 ---
# 我们加载原始数据,不对其进行任何手动预处理
data = pd.read_csv('data.csv')print("原始数据加载完成,形状为:", data.shape)
# print(data.head()) # 可以打印前几行看看原始数据

打印结果

原始数据加载完成,形状为: (7500, 18)
步骤2. 分离特征和标签,划分数据集
# --- 分离特征和标签 (使用原始数据) ---
y = data['Credit Default'] # 标签
X = data.drop(['Credit Default'], axis=1) # 特征 (axis=1 表示按列删除)print("\n特征和标签分离完成。")
print("特征 X 的形状:", X.shape)
print("标签 y 的形状:", y.shape)# --- 划分训练集和测试集 (在任何预处理之前划分) ---
# 按照8:2划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 80%训练集,20%测试集print("\n数据集划分完成 (预处理之前)。")
print("X_train 形状:", X_train.shape)
print("X_test 形状:", X_test.shape)
print("y_train 形状:", y_train.shape)
print("y_test 形状:", y_test.shape)

打印结果

特征和标签分离完成。
特征 X 的形状: (7500, 17)
标签 y 的形状: (7500,)数据集划分完成 (预处理之前)。
X_train 形状: (6000, 17)
X_test 形状: (1500, 17)
y_train 形状: (6000,)
y_test 形状: (1500,)
步骤3. 定义预处理步骤

Columtransformer的核心

# --- 定义不同列的类型和它们对应的预处理步骤 ---
# 这些定义是基于原始数据 X 的列类型来确定的# 识别原始的 object 列 (对应你原代码中的 discrete_features 在预处理前)
object_cols = X.select_dtypes(include=['object']).columns.tolist()
# 识别原始的非 object 列 (通常是数值列)
numeric_cols = X.select_dtypes(exclude=['object']).columns.tolist()# 有序分类特征 (对应你之前的标签编码)
# 注意:OrdinalEncoder默认编码为0, 1, 2... 对应你之前的1, 2, 3...需要在模型解释时注意
# 这里的类别顺序需要和你之前映射的顺序一致
ordinal_features = ['Home Ownership', 'Years in current job', 'Term']
# 定义每个有序特征的类别顺序,这个顺序决定了编码后的数值大小
ordinal_categories = [['Own Home', 'Rent', 'Have Mortgage', 'Home Mortgage'], # Home Ownership 的顺序 (对应1, 2, 3, 4)['< 1 year', '1 year', '2 years', '3 years', '4 years', '5 years', '6 years', '7 years', '8 years', '9 years', '10+ years'], # Years in current job 的顺序 (对应1-11)['Short Term', 'Long Term'] # Term 的顺序 (对应0, 1)
]
# 构建处理有序特征的 Pipeline: 先填充缺失值,再进行有序编码
ordinal_transformer = Pipeline(steps=[('imputer', SimpleImputer(strategy='most_frequent')), # 用众数填充分类特征的缺失值('encoder', OrdinalEncoder(categories=ordinal_categories, handle_unknown='use_encoded_value', unknown_value=-1)) # 进行有序编码
])
print("有序特征处理 Pipeline 定义完成。")# 标称分类特征 (对应你之前的独热编码)
nominal_features = ['Purpose'] # 使用原始列名
# 构建处理标称特征的 Pipeline: 先填充缺失值,再进行独热编码
nominal_transformer = Pipeline(steps=[('imputer', SimpleImputer(strategy='most_frequent')), # 用众数填充分类特征的缺失值('onehot', OneHotEncoder(handle_unknown='ignore', sparse_output=False)) # 进行独热编码, sparse_output=False 使输出为密集数组
])
print("标称特征处理 Pipeline 定义完成。")# 连续特征 (对应你之前的众数填充 + 添加标准化)
# 从所有列中排除掉分类特征,得到连续特征列表
# continuous_features = X.columns.difference(object_cols).tolist() # 原始X中非object类型的列
# 也可以直接从所有列中排除已知的有序和标称特征
continuous_features = [f for f in X.columns if f not in ordinal_features + nominal_features]# 构建处理连续特征的 Pipeline: 先填充缺失值,再进行标准化
continuous_transformer = Pipeline(steps=[('imputer', SimpleImputer(strategy='most_frequent')), # 用众数填充缺失值 (复现你的原始逻辑)('scaler', StandardScaler()) # 标准化,一个好的实践 (如果你严格复刻原代码,可以移除这步)
])
print("连续特征处理 Pipeline 定义完成。")

打印结果

有序特征处理 Pipeline 定义完成。
标称特征处理 Pipeline 定义完成。
连续特征处理 Pipeline 定义完成。

代码继续

# --- 构建 ColumnTransformer ---
# 将不同的预处理应用于不同的列子集,构造一个完备的转化器
# ColumnTransformer 接收一个 transformers 列表,每个元素是 (名称, 转换器对象, 列名列表)
preprocessor = ColumnTransformer(transformers=[('ordinal', ordinal_transformer, ordinal_features), # 对 ordinal_features 列应用 ordinal_transformer('nominal', nominal_transformer, nominal_features), # 对 nominal_features 列应用 nominal_transformer('continuous', continuous_transformer, continuous_features) # 对 continuous_features 列应用 continuous_transformer],remainder='passthrough' # 如何处理没有在上面列表中指定的列。# 'passthrough' 表示保留这些列,不做任何处理。# 'drop' 表示丢弃这些列。
)print("\nColumnTransformer (预处理器) 定义完成。")
# print(preprocessor) # 可以打印 preprocessor 对象看看它的结构
步骤4. 构建完整Pipeline
# --- 构建完整的 Pipeline ---
# 将预处理器和模型串联起来
# 使用你原代码中 RandomForestClassifier 的默认参数和 random_state
pipeline = Pipeline(steps=[('preprocessor', preprocessor), # 第一步:应用所有的预处理 (我们刚刚定义的 ColumnTransformer 对象)('classifier', RandomForestClassifier(random_state=42)) # 第二步:随机森林分类器 (使用默认参数和指定的 random_state)
])print("\n完整的 Pipeline 定义完成。")
# print(pipeline) # 可以打印 pipeline 对象看看它的结构
步骤5. 使用Pipeline进行训练和评估
# --- 1. 使用 Pipeline 在划分好的训练集和测试集上评估 ---
# 完全模仿你原代码的第一个评估步骤print("\n--- 1. 默认参数随机森林 (训练集 -> 测试集) ---") # 使用你原代码的输出文本
# import time # 引入 time 库 (已在文件顶部引入)start_time = time.time() # 记录开始时间# 在原始的 X_train, y_train 上拟合整个Pipeline
# Pipeline会自动按顺序执行 preprocessor 的 fit_transform(X_train),
# 然后用处理后的数据和 y_train 拟合 classifier
pipeline.fit(X_train, y_train)# 在原始的 X_test 上进行预测
# Pipeline会自动按顺序执行 preprocessor 的 transform(X_test),
# 然后用处理后的数据进行 classifier 的 predict
pipeline_pred = pipeline.predict(X_test)end_time = time.time() # 记录结束时间print(f"训练与预测耗时: {end_time - start_time:.4f} 秒") # 使用你原代码的输出格式print("\n默认随机森林 在测试集上的分类报告:") # 使用你原代码的输出文本
print(classification_report(y_test, pipeline_pred))
print("默认随机森林 在测试集上的混淆矩阵:") # 使用你原代码的输出文本
print(confusion_matrix(y_test, pipeline_pred))

打印结果

--- 1. 默认参数随机森林 (训练集 -> 测试集) ---
训练与预测耗时: 1.8732 秒默认随机森林 在测试集上的分类报告:precision    recall  f1-score   support0       0.77      0.97      0.86      10591       0.83      0.30      0.44       441accuracy                           0.78      1500macro avg       0.80      0.64      0.65      1500
weighted avg       0.79      0.78      0.74      1500默认随机森林 在测试集上的混淆矩阵:
[[1031   28][ 308  133]]

今日学习到这里,学得有点晕了,还是得慢慢来,明日继续!!!


http://www.hkcw.cn/article/wtAKbaYjci.shtml

相关文章

003 flutter初始文件讲解(2)

1.书接上回 首先&#xff0c;我们先来看看昨天最后的代码及展示效果&#xff1a; import "package:flutter/material.dart";void main(){runApp(MaterialApp(home:Scaffold(appBar:AppBar(title:Text("The World")), body:Center(child:Text("Hello…

深入理解C#中的LINQ:数据查询的终极利器

在现代软件开发中&#xff0c;数据处理和查询是几乎所有应用程序的核心需求。无论是从数据库检索数据、过滤内存中的集合&#xff0c;还是解析XML文档&#xff0c;开发者都需要高效、灵活的方式来操作数据。C# 提供的 LINQ&#xff08;Language Integrated Query&#xff0c;语…

133.在 Vue3 中使用 OpenLayers 实现画多边形、任意编辑、遮罩与剪切处理功能

&#x1f3ac; 效果演示截图&#xff08;先睹为快&#xff09; ✨ 功能概览&#xff1a; ✅ 鼠标画任意形状多边形&#xff1b; ✏️ 点击“修改边界”可拖动顶点&#xff1b; &#x1f7e5; 点击“遮罩”后地图除多边形区域外变红&#xff1b; ✂️ 点击“剪切”后仅显示选…

爬虫到智能数据分析:Bright Data × Kimi 智能洞察亚马逊电商产品销售潜力

前言 电商数据分析在现代商业中具有重要的战略价值&#xff0c;通过对消费者行为、销售趋势、商品价格、库存等数据的深入分析&#xff0c;企业能够获得对市场动态的精准洞察&#xff0c;优化运营决策&#xff0c;预测市场趋势、优化广告投放、提升供应链效率&#xff0c;并通…

2025年信息素养大赛 图形化编程复赛 官方样题绘制图形答案解析

今天给大家做一下2025年全国青少年信息素养大赛 图形化编程复赛、决赛官方样题1 编程题&#xff0c;绘制图形及答案解析。 题外话&#xff1a;2024年对Scratch画笔画图考的比较多&#xff0c;例如7月20日的复赛小高组就考了4道数形结合的画图编程题&#xff0c;点击查看&#x…

ONLYOFFICE文档API:编辑器的品牌定制化

在当今数字化办公时代&#xff0c;文档编辑器已成为各类企业、组织和开发者不可或缺的工具之一。ONLYOFFICE 文档提供的功能丰富且强大的文档编辑 API&#xff0c;让开发者能够根据自己的产品需求和品牌特点&#xff0c;定制编辑器界面&#xff0c;实现品牌化展示&#xff0c;为…

【unity游戏开发——编辑器扩展】EditorApplication公共类处理编辑器生命周期事件、播放模式控制以及各种编辑器状态查询

注意&#xff1a;考虑到编辑器扩展的内容比较多&#xff0c;我将编辑器扩展的内容分开&#xff0c;并全部整合放在【unity游戏开发——编辑器扩展】专栏里&#xff0c;感兴趣的小伙伴可以前往逐一查看学习。 文章目录 前言一、监听编辑器事件1、常用编辑器事件2、示例监听播放模…

企业如何制定互联网营销策略?

互联网环境的变化速度&#xff0c;让很多企业不懂得在这个流量时代该如何更好地抓住推广时机。企业在制定互联网营销策略的过程中&#xff0c;该如何让策略能够成功生效&#xff0c;令其为企业发展赋能呢&#xff1f;下面就让我们分四步来简单了解下。 一、明确品牌定位 在制定…

Windows10下搭建sftp服务器(附:详细搭建过程、CMD连接测试、连接失败问题分析解决等)

最终连接sftp效果 搭建sftp服务器 1、这里附上作者已找好的 freeSSHd安装包 ,使用它进行搭建sftp服务器。 2、打开freeSSHd安装包,进行安装 (1)、选择完全安装 (2)、安装完成后,对提示窗口选择关闭 (3)、安装完成后,提示是否安装私有密钥。我们选择"是" (4)、安…

第五十九节:性能优化-GPU加速 (CUDA 模块)

在计算机视觉领域,实时性往往是关键瓶颈。当传统CPU处理高分辨率视频流或复杂算法时,力不从心。本文将深入探索OpenCV的CUDA模块,揭示如何通过GPU并行计算实现数量级的性能飞跃。 一、GPU加速:计算机视觉的必由之路 CPU的强项在于复杂逻辑和低延迟任务,但面对图像处理中高…

Linux---系统守护systemd(System Daemon)

一、systemd 概述 1. 定位与作用 init 系统替代品&#xff1a;作为 Linux 系统的第 1 个进程&#xff08;PID1&#xff09;&#xff0c;替代传统的 SysVinit 和 Upstart&#xff0c;负责管理系统服务、启动流程、资源分配等。统一管理&#xff1a;通过 单元&#xff08;Unit&…

Lua语言学习

为什么要用Lua 大部分的手机系统出于安全考虑禁止从网络上下载代码后动态的将这些下载的代码加载到内存中执行 所以&#xff0c;当你更新游戏时&#xff0c;就必须让用户从手机市场下载更新版本的程序&#xff0c;游戏程序通常体积较大&#xff0c;重新下载不仅耗时还耗流量&…

Maven 仓库类型与镜像策略

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…

蓝牙和wifi相关的杂项内容总结

蓝牙的传输速率演进 蓝牙技术的传输速率随着版本的演进不断提升&#xff0c;不同版本和模式&#xff08;经典蓝牙 BR/EDR 和低功耗蓝牙 BLE&#xff09;的速率差异显著。以下是蓝牙传输速率的完整发展历程和技术细节&#xff1a; 经典蓝牙&#xff08;BR/EDR&#xff09;的速…

AAA稳态LED太阳光模拟器的特点剖析

AAA稳态LED太阳光模拟器作为光伏测试领域的重要设备&#xff0c;其技术特点直接关系到太阳能电池研发与质量控制的精度。以下从光谱匹配性、辐照均匀性、稳定性、能效比及智能化设计五个维度展开深度剖析&#xff1a; 一、光谱匹配性的突破性进展 传统氙灯光源在AM1.5G标准光谱…

cadence PCB 精度设置成小数点4位方法

1. allegro 在进行PCB设计时&#xff0c;单位一般默认为Mils&#xff0c;会遇到&#xff0c;精度只能选择2位&#xff0c;不能增加到4位&#xff0c; 精度的范围只能设置为0-2&#xff0c;不能设置为3或4 2. Setup -> User preference&#xff0c;进行设置&#xff0c…

VirtualBox安装 Rocky

这不是 CentOS要完蛋了吗&#xff0c;找了Rock Linux 。下载了一个差不多需要10G&#xff0c;艹。 然后在virtual BOX中安装&#xff0c;安装成功了 安装和Centos一样&#xff1a; 《VirtualBox安装以及安装CentOS7》 有几点需要注意就行了&#xff1a; 准备工作 确保主机的…

【MySQL】C语言连接

要使用C语言连接mysql&#xff0c;需要使用mysql官网提供的库&#xff0c;大家可以去官网下载 我们使用C接口库来进行连接 要正确使用&#xff0c;我们需要做一些准备工作: 保证mysql服务有效在官网上下载合适自己平台的mysql connect库&#xff0c;以备后用 下载开发库 s…

SpringBoot 日志

今天我们来学习日志&#xff0c;日志是啥玩意呢&#xff0c;其实我们之前使用过超简易版的日志&#xff0c;就是打印&#xff0c;我感觉大家应该都一样&#xff0c;使用打印来检查代码是不是执行到这里了&#xff0c;通过控制台打印的日志来发现问题&#xff0c;排查问题&#…

C语言——深入理解指针(1)

一、内存和地址 1.1 内存 在讲内存之前&#xff0c;我们先看一个生活中的案例&#xff1a; 假设有一栋宿舍楼&#xff0c;把你放在楼里&#xff0c;楼上有100个房间&#xff0c;但是房间没有编号&#xff0c;你的一个朋友来找你玩&#xff0c;如果想找到你&#xff0c;就得挨…