| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 人工智能 -> [因果推断] 倾向得分Propensity Score 原理(二) -> 正文阅读 |
|
[人工智能][因果推断] 倾向得分Propensity Score 原理(二) |
目录 Randomized Controlled Trials(RCT) ATT Average Treatment Effect on the Treated 三 Propensity Modeling? (倾向建模流程) 四 Propensity Score Methods(倾向得分方法) (1)采样手段:without replacement v.s. with replacement (3)相似度度量:Nearest Neighbor v.s Caliper distance (4)匹配数量:one-to-one v.s. many-to-one 3 Stratification and Interval on the Propensity Score 4 Inverse Probability of Treatment Weighting Using the Propensity Score 5 Covariate Adjustment Using the Propensity Score ?1.可量化的指标——标准化偏差 Standardized Bias? Propensity Score Matching——一种去偏方法 PSM是一种处理基于观测数据进行因果建模的方法。PSM解决的是选择偏差问题(即控制混杂因素),倾向得分配比就是利用倾向评分值,从对照组中为处理做中的每个个体寻找一个或多个背景特征相同或相似的个体作为对照。这样就最大程度降低了其他混杂因素的干扰。 文章主要介绍倾向得分匹配(PSM, Propensity Score Matching)方法的原理以及实现。这是一种理论稍微复杂、但实现较为容易的分析方法,适合非算法同学的使用。可用于(基于观察数据的)AB实验、增量模型搭建等领域。 一 前置知识大家已知的是,观测数据是有偏的,即存在特征X既影响目标outcome Y,又影响Treatment T。那么在进行因果建模之前,我们需要进行去偏处理,使得Treatment Y独立于特征X,此时的观测数据近似相当于RCT数据,之后我们就可以使用因果模型进行CATE评估了。 干预效果 Treatment Effect干预效果(Treatment Effect):干预下的潜在结果减去未干预时的潜在结果,即 其中 Yi 表示潜在结果,1和0分别代表是否受到干预。 举个例子:我们想知道我买车给我提升了多少幸福度,理想情况下就是用我买车时的幸福度减去我不买车时的幸福度. ATE (Averaged Treatment Effect) 是计算整体的 Treatment Effect, 例如我们实验有一个 Control 组, 一个 Treatment 组. ATE 会计算这个 Treatment 对于这个组会产生怎样的 Effect. 这个指标在我们实际的算法过程中很少用. Randomized Controlled Trials(RCT)在RCT中,实验组和对照组的样本是随机分流的,这就保证了实验组和对照组的样本在分布上是一致的,此时有? 即我们的协变量X和Treatment之间没有confounder: ? Observational StudiesObservational studies和RCT在实验设计上存在区别为,即对于样本是实验组还是对照组并不是完全随机的,即存在X同时影响着T和Y。 实验组和对照组的样本分布存在差异使得 ? (对照测试组同样) 因此我们无法通过观测数据得到一个无偏的ATE。因此我们需要采用例如Propensity score methods的方法来帮助我们估计ATE。 ATT Average Treatment Effect on the Treated相较于个人的干预效果,我们更希望了解人群整体的干预效果,毕竟我们通常用策略干预的是一个人群。 应用PSM,我们通常希望计算得到被干预的用户的平均干预效果,即ATT(average treatment effect on the treated) 其中变量 D 代表是否收到干预。 可以看到 E[Y(0) | D = 1] 代表被干预的用户假如不被干预的情况下的潜在结果,是一个无法观测的数值。 倘若可以建立AB测试,我们利用对照组则可以得到该结果,在无法进行AB测试的情况(例如 D 是一个主动的行为)下,我们可以通过PSM拟合一个虚拟的对照组进行计算。 1. 计算ATT所需满足的假设这里引入一个新的概念,倾向性得分(Propensity Score),即用户受到(参与)干预的概率: P(X) = P(D=1 | X) a.条件独立假设 CIA (Conditional Independence Assumption) 给定一系列可观测的协变量 X ,潜在结果和干预分配相互独立。 ?可认为所有影响到干预分配与潜在结果的变量都同时被观测到。此时X可能是高维度的 若上式成立,则干预分配与潜在结果基于 X 同样条件独立[可证明],即 ?b.共支撑 Common Support 在一些文献中,该条件也被称为strong ignorability. 除了独立外的另一个条件是存在重叠的部分,即: ?这个条件能够排除掉——给定 X 时能准确确定D的情况(也因为如此才有匹配的空间)。 ?2. 估算ATT在满足CIA和common support的情况下,我们能够对ATT进行估算: ?即:在common support 上,以倾向分为权重、对实验组与对照组平均值的差值进行求和。 二 Propensity Score(倾向得分)Propensity score主要是用来估计给定样本协变量情况下,被施加treatment的概率, 即 ?? 在RCT实验中,Propensity score是实验设置的参数,它是已知的;但在Observational study中,实际的Propensity score我们并不知道,因此需要通过数据进行估计。一般来说使用逻辑回归根据变量来预估样本被施加treatment的概率,实际上通过任意二分类模型都可以用来估计Propensity score。 Propensity score的一个假设是“no unmeasured confounders”,通俗点讲就是所有影响treatment的变量都可观测且可度量。即实际对Propensity score建模时,要把所有影响treatment的变量都考虑到。 关于Propensity Score建模时的特征选择上,目前学术界并没有一个一致。 但propensity score的变量一般包含以下四个方面:
因为propensity score本质上是指样本被施加treatment的概率,因此也有理论证明只需要包含影响treatment assignment的变量即可。 三 Propensity Modeling? (倾向建模流程)倾向建模尝试预测访客,潜在顾客和客户执行某些操作的可能性。这是一种统计方法,它考虑了影响所述行为的所有独立变量和混杂变量。 因此,例如,倾向建模可以帮助营销团队预测潜在客户转化为客户的可能性。否则客户会流失。甚至是电子邮件收件人将退订。 那么,倾向得分就是访问者,潜在顾客或客户将执行特定操作的概率。 用倾向建模的技术来分析喝soylent饮料到底有什么作用。为了解释清楚这个概念,接下来要开始一场思想实验。 假定Brad Pitt有一个双胞胎的哥哥,兄弟俩哪都一样:Brad1和Brad2一起起床,吃一样的事物,进行同样强度的体能锻炼等等。有一天,Brad 1 碰巧从街上的促销员那里得到了最后一打Soylent饮料,但Brad 2没有这样的好运气。所以Soylent只出现在了Brad1的食谱上。在这种情况下,可以认为,双胞胎此后出现的任何行为差异就是这个饮料造成的。 将这种情景带入现实世界,我们用下面的方法来估计Soylent对健康的影响:
然而,在实践时找到两个非常相近的双胞胎是很困难的,如果Jay-Z比Kanye平均多睡一个小时,那么怎么保证二者真的很接近呢? Propensity modeling(倾向建模)就是这种双胞胎匹配过程的简化。我们并不是根据所有的变量来匹配两个个体,而是根据一个简单的数字来匹配所有用户-----他们喝soylent的可能性(“倾向”) ?直观上,从因果图上可以看出,当以P(X)为条件时,X和T相互独立。因此,我们可以将倾向性得分看作是在特征空间上执行某种降维操作。它将X中的所有特征压缩到一个Treatment倾向上。 如何建立倾向模型
选择了适合您的模型后(在本文中,我们将重点介绍回归),构建模型包括三个步骤: a. 选择您的倾向模型的特征 首先,您需要为倾向模型选择功能。例如,您可以考虑:
您的想象力是唯一的极限。 当您仅对预测感兴趣时,选择功能会更容易。您可以只添加您知道的所有功能。特征的相关性越差,系数就越接近0。如果您想了解该预测的因素,则变得更加困难。 假设在训练模型时,您在历史数据的50%上对其进行训练,并在剩余的50%上对其进行测试。换句话说,您可以在测试组中的模型中隐藏要预测的变量,并尝试使模型预测值—这样一来,您便可以了解如何对已经具有实际值的事物进行预测。 b.建立您的倾向模型; 在回归分析中,回归方程中的系数是实际总体参数的估计值。我们希望这些系数估算值是最好的估算值. 假设您要求一个估算,例如您正在考虑的服务成本。您将如何定义一个合理的估计?
c 计算您的倾向得分: 因变量为是否被干预Treatment,自变量为用户特征变量。套用LR或者其他更复杂的模型,如LR + LightGBM等模型估算倾向性得分。 这里把treatment-T(有没有诊所),Outcome - Y(infant mortality 死亡率),都标明了;两个混杂变量,poverty rate 贫穷率 和 per capita doctors 人均医生数。 目标:为每一个实验组的村庄创建/找到新的对照组: 针对每一个实验组的村庄,找到其特征类似的对照组。 不是 那么最终出来的结果就是, 构建倾向性模型后,在计算倾向性分数之前,先使用数据集对其进行训练。如何训练倾向模型和计算倾向分数取决于您选择线性回归还是逻辑回归。 在线性回归模型中,它将字面上的系数乘以值,然后得到一个连续的数。因此,如果您的公式是customer_value = 0.323(每月会话数),其中0.323是每月会话数的系数,则它将您当月的会话数乘以0.323。 对于逻辑回归,预测值将为您提供对数奇数,并且计算可以将其转换为概率。这个概率就是我们所说的“分数”。 倾向模型必须与您的实际数据配合使用,这一点很重要。这是倾向建模和实验如何相辅相成的完美示例。实验可以验证倾向得分的准确性。 无论您对准确性有多自信,都可以进行实验。可能有您尚未考虑的因素。或者,例如,该模型可能会意外地针对数量(例如,会话到潜在顾客的转化率)进行优化,而不考虑对质量的影响(例如,潜在顾客到客户的转化率,保留率等) 使用实验来验证倾向模型至关重要。它使您高枕无忧。 同样,倾向建模是优化器可以使用的工具,而不是完全了解实验和优化的工具。充分利用开放式回归的优势–深入了解并确保正在查看的数据在变得疯狂之前是有意义的。 d.?倾向得分Matching 匹配的概念就简单了。即对于实验组的每一个样本,在对照组找到与之匹配(即二者相似)的一个样本,组成一个样本对,最后基于所有的样本对进行建模,以达到控制混淆的目的。这里的匹配方法如果用的是倾向性得分PS,那就是PSM的概念了。 计算出Propensity Score后,在对照组中需要寻找到与实验组行为(贫穷率、人均医生数)相似的村庄,此过程被称为Matching。 在这里我们采取最简单的临近匹配法,对每一个实验组村庄进行遍历,找到ps值最接近的对照组村庄作为新对照组集合中的元素,即为new_control_index。 因为我们需要为有诊所的村庄(T = 1) 一一对应找无诊所(T=0)村庄 所以,以index=0的实验组村庄为例(ps=0.416571),在健康诊所项目启动前,与其贫穷率、人均医生数最为接近的对照组成员为index=5村庄(ps=0.395162)。 这里的计算方式就是非常简单的:ps(index=5) - ps(index = 1)是最小 ?到此为止,每个实验组村庄都找到了其新的对照组归宿~ 实验组 VS 新对照组 评估建立健康诊所对新生儿死亡率的影响 新对照组村庄(未建立健康诊所)新生儿死亡率比实验组村庄(建立健康诊所)足足高出7%,从而证明这个NGO组织的健康诊所项目对新生儿死亡率的降低有显著作用。 如何使用倾向模型进行更智能的实验在回归模型中,您不能假定要素与尝试预测的变量具有因果关系。 可以轻松查看模型,例如,可以看到在试用期间下载X应用程序可以很好地表明潜在客户会转化为客户。但是,绝对没有证据表明在试用期间增加更多的应用下载量将使任何人更有可能转化为客户。 不要用倾向得分代替(非常有价值的)优化知识。倾向建模与其他工具一样,不会告诉您如何进行优化,您可以使用自己的经验,知识和直觉来挖掘这些见解。 例如,您可能知道,由于您的倾向模型,客户很可能流失。但是,您花费在防止客户流失上的价值是否高于该客户的生命周期价值?您的模型无法回答这个问题,它不能代替批判性思维。 当我们轻轻地跨过所有注意事项时,让我们看一下优化器可以利用的三个有价值的倾向模型:
倾向建模不是规定性的。知道一组线索具有更高的单独转换倾向并不是特别有价值。有价值的是将这些知识与优化知识相结合,以运行更智能,更有针对性的实验并提取可传递的见解。 未来不是一门精确的科学。(可以说,精确科学不是精确科学。)但是,您可以通过倾向建模以合理的确定性程度预测未来。您所需要的只是一个严格的流程和一位数据科学家。 这是逐步的过程:
四 Propensity Score Methods(倾向得分方法)想研究‘读研究生’对于收入的影响。一种简单的做法是直接对比‘读过’和‘没有读过’这两类群体的收入差异,但这种做法并不科学。因为还可能存在其他变量影响着研究结果,如性别,年龄,父母学历,父母是否做教育工作等因素都会干扰到研究。 因此,PSM正是为了减少这种干扰。PSM可实现找到类似的两类人,他们的基本特征都基本一致,主要区别在于‘是否读过’研究生。这样可减少干扰因素差异带来的数据偏差和混杂干扰。 倾向得分匹配的实现步骤其实就如其名称中提到的,主要有两步:倾向得分的计算,以及基于倾向得分的匹配。 目前主要的4种propensity score方法包括:Matching,Stratification,IPW,covariate adjustment。在各种方法中,具体的实现上又有一定的区别。 1 倾向得分预测预测用户被干预的概率,其实就是一个常见的二分类问题,常见的机器学习模型都可以在这里使用。 特征选择需要注意的是在特征选择上,具体需要哪些特征呢?有两个基本的原则是需要遵守的:
而至于特征的量级,不同的文献中有不同的说法: ?为方便起见,通常在实际应用中我们会选取尽量多的特征,同时也会用到一些机器学习中常规的特征筛选方法。 重要特征当我们已知一些特征十分重要(对干预、结果)时,我们可能通过一些方式加强这些特征对匹配的影响:
换句话说:就是在重要特征上做完全匹配,再辅助倾向分匹配(当预期在不同分组上会有不同的ATT时尤其推荐这么做)。 2 Propensity Score Matching当不使用propensity score时,可以直接基于协变量进行匹配,直接计算两个样本协变量之间的马氏距离,这种方式通常称为CVM(Coviate Matching)。 完成倾向分模型及预测后,每个样本会得到一个propensity score,此时便可以进行匹配步骤了:为每个被干预的样本匹配一个(或多个)虚拟的对照样本。 matching 也无法解决隐形的遗漏变量问题(或内生性问题)。 Matching 是一个有争议的方法,我认识很多老师他们对PSM 包括其它传统的matching是有看法的,觉得有点鸡肋, 原因一是任何matching都是基于一套weighting 规则, 怎么证明这套weighting 规则就比你直接加控制变量进去好? 原因二是有时候用了matching 也构建不出一个很好的对照组,规则严了找不到好的common support,规则松了对照组和不matching 前也差不了多少。 匹配的基础思路很简单,即找到一个距离最近的样本,实现的具体方法按照渐进的顺序阐述如下: Matching的过程
Matching方法的整体思路相对简单,但实际实现中在细节上有所不同,也就出现了matching的很多变种。 (1)采样手段:without replacement v.s. with replacement即在matching过程中,我们对于untreated样本是否允许重复采样。在with replacement模式下,同一个untreated样本可能会出现在多个pair对中,即我们构造的数据中存在大量重复样本,此时需要考虑方差估计的问题(是否会出现过拟合);在without replacement模式下,untreated样本一旦被某个treated样本匹配后便不再使用。 ?实现上,会有有放回和无放回两种实现方式:
除了是否放回之外,还有一个可调整的地方在于对单个用户是否可匹配多个样本(over-sampling):通过匹配最近的多个邻居降低了variance,提升了匹配的稳定性。但此时需要给每个邻居赋予权重(eg. 按距离衰减)。 从上表可知:本次PSM分析使用最邻近匹配方式,并且精确匹配优先的算法,且使用放回抽样方法。总共待匹配项(‘读过研究生’的样本数量)为233个,全部都实现精确匹配成功,匹配成功率为100%。 (2)匹配方式:greedy v.s. optimalgreedy matching时,treated样本是随机选择的,然后从untreated中选择与当前treated样本score相似的样本;停止条件是untreated样本与所有的treated样本构成了pair对,或者穷尽完了所有可以匹配到untreated样本的treated样本。之所以这个方法称为greedy,是因为在每一次给treated样本匹配untreated样本时,都选择当前score最接近的样本(尽管这个untreated可能和后续某个treated样本更合适),因此这样的步骤是贪心的。 对于optimal matching,其形成pair的过程是minimize the total within-pair difference of propensity score,即全局优化。但是这两者在生成balanced matched samples上效果基本相当。 (3)相似度度量:Nearest Neighbor v.s Caliper distance在上述matching过程中,如何衡量untreated和treated之间的相似度呢? 有两种主要的方法:
前者就是在选择score与当前treated样本最接近的untreated样本,当有多个同距离的untreated样本时,随机选择一个即可。但是这种方法并没有对最大可接受的距离做限制,因此无法保证选出的untreated样本就是好的。 后者相比于前者就是增加了一个caliper distance的限制,即对于给定的treated样本,先圈定这个样本的caliper distance范围,接着在这个范围中去寻找score最近的untreated样本,如果没有的话,当前treated样本就被丢弃。可以看到caliper distance的方法更注重样本的质量。 当最近的邻居也相距很远的时候,Nearest Neighbor 匹配会存在低质匹配的风险。很自然的,我们想到可以限定样本间分数差值的上限,即caliper。
对于caliper width(即我们最多能接大能接受的距离范围)的设定目前还没有统一的标准。有一种方法是选择和logit of propensity score的标准差成比例的caliper distance(有理论证明logit of propensity score大概率是服从正态分布的)。假设treated和untreated样本中的propensity score同方差,使用总体样本的标准差*0.2作为caliper width可以减少confounders带来的bias。 (4)匹配数量:one-to-one v.s. many-to-oneMatching中最基本的方式就是one-to-one,即一个treated样本对应一个untreated样本。 除此之外还有many-to-one maching,即m个untreated样本与1个treated样本匹配,对于不同的treated样本,m也是可变的;相比于固定的m,动态的m值可以带来bias reduction。 Full matching指一个treated和至少一个untreated,或者一个untreated和至少一个treated样本。 3 Stratification and Interval on the Propensity Score分层匹配可以看作radius matching的一种相似版本,即将倾向得分分成多个区间,在每个区间内进行匹配。需要注意的是,分层的依据除了propensity score,也可以用一些我们认为重要的特征(如性别、地区),在相同特征的用户间进行匹配。 根据样本的propensity score进行分层。先对样本的propensity score进行排序,然后对样本分桶。常见的一种做法是等频分成5个桶。当然,随着分桶数的增多,桶内样本的相似度会增大,桶间样本的相似度会减少,可以带来进一步bias reduction的收益。在每个分层下,treated和untreated样本的propensity score是相似的,进而可以近似进行ATE的估计。 4 Inverse Probability of Treatment Weighting Using the Propensity ScoreIPTW(简称IPW)是使用propensity score来对样本进行加权从而生成同分布的synthetic sample。这种方法最早是由Rosenbaum在1987年提出的。 5 Covariate Adjustment Using the Propensity ScoreCovariate adjustment方法是这四种方法中唯一一个需要额外建模的方法。它本质上是做了一个线性回归(outcome是binary时候使用逻辑回归),模型的X是treatment status+propensity score,Y是outcome。此时treatment的效应就是由回归的系数所决定。 五 匹配质量检验与匹配增量计算鉴于我们基于倾向分做匹配,完成后需要检测其他特征在实验组与对照组之间的分布是否相近。 1.可量化的指标——标准化偏差 Standardized Bias?通过标准化偏差我们可以衡量 X 在实验组与对照组分布的差异大小,通常我们认为低于5%的偏差是可以接受的(当然越小越好) 其中 V1m 代表匹配后实验组特征X的方差。? 我们也可以在匹配前后分别计算该值,去看看通过匹配让Standardized Bias减少了多少。 2. 对样本均值的假设检验——T检验我们也可以通过双侧T检验去判断两组的变量均值 X 是否有显著差异。缺点是匹配前后偏差的减少量无法很直观的感受到。进一步的,我们也可以基于倾向分先做一个分层,再进行T-Test。这样可以看到不同分值下匹配的质量。 3. 联合显著性/伪 R2另一种思路是我们把特征 X 当作自变量,是否干预当作因变量,计算判定系数R2.在完成匹配后,两组间的协变量 X 应该不存在系统性差异(即无法通过X预测用户是否受到干预),从而R2 应该很低。类似的,可以对所有变量做一个联合F-Test,匹配有效的话,匹配后会拒绝假设(即解释变量对被解释变量的共同影响不显著) 除此之外,我们还可以通过QQplot的可视化、计算匹配后两组方差的比值、计算匹配前后倾向分偏差减小量等方式衡量匹配质量。但总体来说还是推荐前两种方式——计算SB和T检验,它们兼具了可解释性和可量化性。假如匹配的质量达不到要求,那么我们就要回到上一步对匹配算法进行调整。 4.? 匹配结果示例匹配之后,常见的趋势会如下图一所示:
5 增量计算因为满足平行趋势假设,我们可以用双重差分法(DID)去计算干预带来的增量;需注意的是,计算实验组与对照组的差异时,我们通常需要取一段时间的均值,避免波动带来的影响。 最终得到的结论类似于:用户在购买商品后,能够给来访率带来1.5%(30天日均)的提升。 6 其他情况在一些情况下,也会有其他结果的出现。 a. 无显著增量用户在干预之后来访率有一个短暂的提升,但随着时间的推移两组用户趋于一致。这种情况下我们通常认为干预并没有给用户来访带来显著的提升。为了识别出这种情况,我们也可以通过假设检验或计算差值中位数的方式进行验证。 b 不满足平行趋势假设从下图可以看到,左侧区域实验组与对照组的趋势不一致(不平行),这代表我们前面完成的匹配质量较差,需要优化匹配模型。对于平行趋势的检验,除了图示法(肉眼看是否平行)我们也可以通过T检验的方式来验证。 六 其他相关1 PSM存在的问题PSM+DID的方式会存在以下两个问题:
2 ATT与ATE的区别
可以认为ATE是人群整体的干预增量效果,而ATT是实际被干预人群的干预增量效果。通常我们通过PSM+DID计算的是ATT,因为ATE还会涉及人群的干预率。更详细的解释可以参考stackexchange上的这个回答: 3 Bias与Variance的Trade-offs在匹配算法的步骤,我们有提到bias与variance:
可以认为bias代表算法本身的拟合能力而variance代表算法的稳定性,在匹配的不同方法中它们也存在trade-offs: 4 敏感性测试 Sensitivity Analysis在前置知识介绍的部分有提到,做PSM需要满足两个假设——条件独立和共支撑。 对于第一个条件,其含义便是我们需要观测到所有同时影响到treatment和outcome的特征,否则估算的ATT会存在偏差。对于common support,我们实际上计算的是倾向得分重叠区域的ATT,其实际上也可能是有偏的。在这种情况下,我们需要去进行sensitivity analysis。换句话说,我们计算得到的增量结果其实是不稳健的,我们可以通过纳入不确定性的估计来估算一个ATT的区间,使之稳定性得到提升。 总结在文章的最后,我们对PSM的整体流程进行一个梳理(可以看到真的不复杂),同时对PSM的优点与缺点进行简单的介绍。 1 完整流程
2 PSM的优缺点优点
缺点
整体来说,若不过分追求准确性,PSM+DID是一个对因果增量预估的较为靠谱的方式。当实现过程中存在卡点或假设无法满足时,除了优化模型还可以尝试看看逆概率加权和合成控制法等其他方法。 参考文章: 倾向得分匹配(PSM)的原理以及实现 - 知乎 一文读懂因果推测、倾向模型(结合实例) |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/26 6:26:47- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |