简而言之,基于事实的人工智能
使用基于事实的建模来启动一次性学习
在早期的一篇文章中,基于事实的人工智能——改进知识图,我提供了基于事实的建模在人工智能中的前景,同时提供了背景知识以供消化。在这里我们直奔事实。
在人工智能研究中已经变得很明显的是,机器学习(ML)、深度学习(DL)和神经网络一般来说都不是容易“一次性学习”的机制。
一般而言,神经网络必须在大的训练数据集上进行训练,从而产生一种机制,该机制基于接近训练数据集的实时数据来提供概率结果。
在一组熊猫图像上训练一个合适的神经网络,然后提供一张新的熊猫图像,神经网络将给出它认为新图像是什么的概率,希望预测是“熊猫”。
神经网络提供的训练数据越少,无论其内部结构如何优化,它提供有利结果的机会就越小。也就是说,你不能可靠地为一个合适的神经网络提供一张熊猫的照片,并期望它能识别另一张不同的熊猫照片。一般来说,它无法一次性学会一个概念或一套规则。
这与人类的学习形成了鲜明的对比,在人类的学习中,一个人可以很容易地掌握和应用所学的知识,只需要被引入问题空间一次。在问题空间的广大领域中,这是真实的。
一次性学习是机器学习和深度学习的一个公认问题,该领域的专家正在努力解决这个问题。在我看来,如果没有某种形式的一次性学习,ML/DL 策略不太可能到达人工通用智能(AGI) 。
ML/DL 方法中的一个问题是,数据以累积权重的方式通过节点网络传递,并且在每个节点处几乎没有逻辑应用于数据,而是基于统计的数学应用于由节点接收的累积权重的值。对输入数据应用统计数学的结果提供了按概率分级的输出数据,提供了对输入数据的概率逻辑。
例如,包含 ML/DL 的自动驾驶汽车在停车标志处停下来,因为从统计上看这是一件好事;因为从统计学上来说,这就是它被训练的目的。
基于这种策略的一些直通(或前馈)网络的问题是,如果一个人的脸在统计上有鼻子、眼睛、嘴、眉毛和下巴,给定一张“脸”的照片,其中一只眼睛被替换为鼻子,反之亦然,一只眼睛被替换为嘴(反之亦然),网络会将图像分类为脸,不管这个命题有多荒谬。这是因为图像仍然有鼻子、眼睛、嘴巴、眉毛和下巴。
对神经网络的兴起有影响的 Geoffrey Hinton 已经意识到了这个问题,并且正在开发和推广他所谓的胶囊网络,该胶囊网络在网络内的早期阶段节点执行本地化的逻辑处理,以便更好地调整提供给后期阶段网络节点的精确权重,从而提供输入数据分类的更真实的近似。这个想法是,给这样一个网络提供一张荒谬的脸的图片,网络将而不是把图像分类为一张脸,因为网络早期的本地化逻辑要求脸的各个部分在解剖学上正确的位置。
这并没有让我们更接近一次性学习,而是引入了一个概念,即网络节点必须执行统计数学之外的某种形式的逻辑。
神经网络的另一个问题是,许多问题本质上不是统计性的,而是需要谓词逻辑的技巧。为了让这篇文章简短,我不会争论为什么,而是简单地说,你可能会直接为人工智能提供一个模型,而不是试图通过统计来训练人工智能学习模型。也就是说,只需给人工智能一个中的模型。
让我们看一个例子。下面的对象-角色建模(ORM) 图提供了适当跟踪和存储在电影院观看电影的座位预订所需的细节。
对象-角色模型
可立即识别为数据的图,其中数据是概念模型的表示,该信息捕获了预订电影座位所必需的约束:
如果某订票有某座位**,那么
那张订票是给某时段那张是在某电影院那张包含某排那张包含那张**座位
这种谓词处理超出了大多数神经网络,因为它们不包含节点级别的谓词逻辑处理;但我觉得这是一次性学习技术的发展方向。
简单的前馈神经网络在执行上述模型的规则时无法胜任,但是对于 AGI 来说,这种模型很常见。
需要在节点/神经元级别和节点内进行本地化谓词检查。
存储为 ORM 模型的基于事实的模型非常适合存储在神经网络的节点矩阵中,因为它们具有内在的基于图形的表示法,其中图形中的每个节点代表它所代表的逻辑模型的一部分。
基于谓词逻辑的人工智能解决方案在过去受到了负面报道。例如, Cyc 项目在过去被贴上了失败的标签;据称是因为 Cyc 的早期迭代完全依赖于谓词逻辑和归纳。然而,AGI 必须能够处理谓词逻辑的基本前提是毋庸置疑的。如果 AGI 是谓词逻辑和神经网络的混合体,那么谓词逻辑必须存储在它的模型中。似乎 Cycorp 已经意识到这一点,已经开始研究深度学习和基于事实的推理。
我在 Viev 的研究旨在提供构建基于事实的模型的工具,这些模型的元模型可以整合到新一轮的神经网络中,这些神经网络在节点/神经元级别整合了逻辑处理。
在人工智能的逻辑存储中使用对象角色建模的一个好处是,在许多情况下,不需要自然语言生成。生成自然语言所需的工作显著减少,因为 ORM 首先以自然语言存储事实,并且以与一阶逻辑的句子同态的逻辑结构存储事实。
在上面的例子中,人工智能对爱丽丝所做的一般陈述“我在电影院预定了座位”的反应,可以很容易地识别爱丽丝所谈论的世界的候选模型,并横过图表来问问题,例如,“那是哪个时段的?”,或者“你订了几个座位?”“那是什么电影?”用已经存储在模型中的语言进行外推。
在模型中存储数据,以及模型作为数据存储在哪里
对象-角色建模是一种基于事实的建模,除了存储关于事实的元信息,比如人们可以在电影院预订座位,ORM 还可以存储关于这些事实的实际数据。
如上所述的相同模型可以存储关于 Alice 已经在电影院预订了座位的信息;如下所示,其中 Alice 的 Person_Id 为 1:
对象-角色模型中的示例事实数据
因此,对象角色建模是基于事实的人工智能的核心,不仅模型可以存储为数据,而且与模型相关的事实也可以存储在模型中。模型和事实数据只是数据。
神经网络已经是数据的图表。简而言之,基于事实的人工智能是将模型/模式和它们的相关数据合并为神经网络或基于谓词逻辑的人工智能中的图内节点。
我希望这对寻找新道路的人工智能研究人员有所帮助。如果时间允许,我会写更多关于基于事实的人工智能和对象角色建模的文章。
— — — — — — — — — -
NB 本文表达的模型原始版本版权归 DataConstellation 所有,在 GitHub 上的 ActiveFacts 项目下共享:https://github.com/cjheath/activefacts。示例和许可证位于:https://github.com/cjheath/activefacts-examples
因子分析教程
特征值、要素创造和克朗巴赫的阿尔法
因子分析的目标是用较少的变量(称为因子)来描述相关变量之间的可变性。它基于这样一种想法,即存在一些“潜在的”因素,这些因素可以描述多个变量。
来源:自创图片
如果我们想在建立模型之前减少变量的数量,这是非常有用的。
本教程使用的数据是航空公司乘客满意度数据集,可以在这里找到:https://www . ka ggle . com/teejmahal 20/Airline-Passenger-satisfaction
该数据集包含一项航空公司乘客满意度调查。它有 103,904 条意见和 25 个栏目,其中 14 个栏目代表了客户对一项调查的回应,该调查评估了航班的不同方面(机上 wifi 服务、食物和饮料、在线登机、座位舒适度等)。这 14 列对于我们即将进行的因子分析非常重要。
任何因素分析的第一步都是查看所有变量的相关图,看是否有任何变量是无用的或与其他变量相关性太大。
import seaborn as snsplt.figure(figsize=(20,10))
c= df.corr()
sns.heatmap(c)
一些变量高度相关,尤其是与调查答案相关的变量。然而,真正突出的是“出发延误分钟数”和“到达延误分钟数”之间极高的相关性(0.98)。有道理。如果飞机比预计的晚起飞,它也应该晚到达。考虑到这种极高的相关性,我决定从数据集中删除该列。
df.drop(['Arrival Delay in Minutes'], axis=1, inplace=True)
现在我们已经去掉了无用的变量,这里是将用于因子分析的 14 个变量。
Inflight wifi service
Departure/Arrival time convenient
Ease of Online booking
Gate location
Food and drink
Online boarding
Seat comfort
Inflight entertainment
On-board service
Leg room service
Baggage handling
Checkin service
Inflight service
Cleanliness
要素分析
那么我们的 14 个变量是否可以描述成更少的潜在变量(因子)?让我们来看看,但是首先,我们必须安装并导入所需的包。
!pip install factor_analyzer
from factor_analyzer import FactorAnalyzer
为了弄清楚我们需要多少个因子,我们可以看看特征值,它是一个衡量一个因子能解释多少变量方差的指标。大于 1 的特征值意味着因子比唯一变量能解释更多的方差。特征值为 2.5 意味着该因子可以解释 2.5 个变量的方差,依此类推。
***#Subset of the data, the 14 columns containing the survey answers*** x =df[df.columns[6:20]] fa = FactorAnalyzer()
fa.fit(x, 10)***#Get Eigen values and plot them*** ev, v = fa.get_eigenvalues()
ev
plt.plot(range(1,x.shape[1]+1),ev)
考虑到第三个因子后特征值的大幅下降,我们在这里只使用 3 个因子。这些因子的特征值分别为 3.7、2.3 和 2.1,这意味着它们描述了大约 8.1 个变量的方差。
FactorAnalyzer 函数用于指定所需的因子数量以及旋转类型。简单来说,旋转的思想是旋转因子,以便实现更简单、更可解释的结构。存在许多类型的旋转。下面,我将使用 varimax 旋转,它使平方负载的方差之和最大化,同时确保创建的因子不相关(正交性)。我们来看看是哪些因素造成的。
fa = FactorAnalyzer(3, rotation='varimax')
fa.fit(x)
loads = fa.loadings_
print(loads)
出局:
[[ 0.16826952 0.12827119 0.75809134]
[-0.02950837 0.05968117 0.50138365]
[ 0.03023106 0.02091435 0.93277526]
[-0.0338282 -0.03231121 0.50404385]
[ 0.75263893 0.01094635 0.00616734]
[ 0.39545345 0.1138114 0.35906543]
[ 0.78999049 0.08146326 0.02725824]
[ 0.7456934 0.46674984 0.01203424]
[ 0.09388069 0.70115382 0.02900913]
[ 0.07445487 0.48144209 0.08065029]
[ 0.02346305 0.76474833 0.02769279]
[ 0.14351222 0.28418169 0.02888186]
[ 0.01813146 0.79977083 0.01825226]
[ 0.85842046 0.08814824 -0.00170807]]
因子负载越高,变量对所述因子越重要。这里将使用 0.5 的负载截止值。这个临界值决定了哪些变量属于哪个因子。例如,我们看到第一个因子包含变量 5、7、8 和 14(分别为 0.75、0.78、0.74 和 0.85 的载荷)。
以下是创建的 3 个因素、它们包含的变量及其可能的“可解释性”:
- 舒适度:食物和饮料、座位舒适度、机上娱乐、清洁度
- 服务:机上服务、行李搬运、机上服务
- 便利性:机上 Wifi、出发/到达时间便利性、在线预订、登机口位置。
这很好,但是我们怎么知道我们的因素是好的呢?那么,克朗巴赫阿尔法可以用来衡量一个因素的变量是否形成一个“连贯”和可靠的因素。α值大于 0.6 实际上是可以接受的。下面是使用 pingouin 包获取 Cronbach alpha 的代码。
!pip install pingouin
import pingouin as pg***#Create the factors*** factor1 = df[['Food and drink', 'Seat comfort', 'Inflight entertainment', 'Cleanliness']]
factor2 = df[['On-board service', 'Baggage handling', 'Inflight service']]
factor3 = df[['Inflight wifi service', 'Departure/Arrival time convenient', 'Ease of Online booking', 'Gate location']]***#Get cronbach alpha*** factor1_alpha = pg.cronbach_alpha(factor1)
factor2_alpha = pg.cronbach_alpha(factor2)
factor3_alpha = pg.cronbach_alpha(factor3)print(factor1_alpha, factor2_alpha, factor3_alpha)
出局:
(0.876288, array([0.875, 0.878])) (0.794292, array([0.792, 0.796])) (0.767975, array([0.766, 0.77 ]))
α被评估为 0.87、0.79 和 0.76,这表明它们是有用的和连贯的。我们可以使用这些新的因素作为变量进行其他分析或预测。下面是将因子应用于整个数据帧并创建 3 个新变量的代码,这 3 个变量可用于替换 14 个变量。
new_variables = fa.fit_transform(x)
非常感谢你的阅读!
国家分类的因子分析和聚类分析
让我们更多维度地了解这个世界!!!
由格伦·卡斯滕斯-彼得斯在 Unsplash 上拍摄的照片
最近,我被一则新闻吸引住了,根据世界银行的分类,坦桑尼亚已经提前五年达到了中等偏下收入水平。出于对他们如何做出判断的好奇,我看了一下世界银行的官方网站这里。
基本上,世界银行通过考虑人均国民总收入(GNI )(现值美元)将世界经济分为四个收入组——高、中上、中下和低。
毫无疑问,这是一个很好的指标,代表了基本上生活在该经济领域的居民的平均收入水平,这反过来又反映了该国的总体经济发展水平。尽管如此,我认为情况应该不止如此,因为同一收入组的国家在不同方面可能仍有很大差异。
因此,基于从世界银行数据库中选取的一组有趣的指标,我首先尝试应用因子分析,看看这些指标能代表什么维度,然后是聚类分析,对经济体进行重新分类。希望这篇文章能帮助我们更好地了解这个世界。关于本文的代码,可以参考 Github 链接这里。
数据
F 首先,这项工作选取了不同方面的 29 个指标。为了防止因具有显著尺度差异的数字指标(如国内生产总值(GDP)或人口规模)而导致的一些潜在偏差,我主要选择了比率或增长指标,并纳入了一些非传统指标,如糖尿病患病率和移动电话用户数。
指标选中
选定指标清单
从上面的列表中,您可能会注意到,由于数据的可用性,指标的年份并不相同。我相信这是世界银行使用单一指标(人均国民总收入)进行经济分类的主要原因之一。
我们所能做的最好的事情就是选择有合理数量的国家提供数据的指标(> 140 个经济体),然后选择最近的一年。经过筛选,共有159 个国家纳入本次演习。
相关矩阵
现在,让我们用下面的代码绘制一个相关矩阵,看看指标之间的关系。
从相关矩阵中,我们可以观察到一些有趣但合理的关系。举个例子,
(a) 获得电力(占人口的百分比)与至少使用基本饮用水服务的人口百分比之间的正相关关系——电力和饮用水是社会中的基本服务。两者应在相似的阶段同时发展,因此在一个国家内具有相似的可及性水平。
(b) 弱势就业(占总就业的百分比)与农业就业(占总就业的百分比)之间的正相关关系 — 与工业和服务部门的就业相比,农业就业应该更加弱势。
*【c】*农村人口(占人口的百分比)与使用互联网的个人(占人口的百分比)之间的负相关 —农村人口占总人口的比例越高,经济可能越不发达。因此,农村人口比例与上网人口比例呈负相关,上网人口比例代表了一个经济体的技术发展水平。
因素分析
事实上,变量之间还有许多其他有趣的关系。为了更快更好地了解全貌,我们可以应用因子分析将 29 个指标缩减为更少的因子。
但是有多少因素应该减少到?我们可以通过绘制一个 scree 图得到一个概念,x 轴是因子数,y 轴是特征值。一般来说,如果一个因子的特征值大于或接近 1,我们会包括它。下图显示了可能有 7 个因素。
对于因子分析背后的概念,这篇文章给出了很好的解释。
碎石地块
因子分析的 Scree 图
由载荷解释的差异
7 个因子的选择解释了 29 个指标总方差的 71%。百分比越高,模型越好。
因子加载
接下来,我们看一下因子加载的热图,它基本上是变量和因子的相关系数。它显示了由特定因素上的变量所解释的方差。
让我们深入研究 7 个因素的含义,看看哪些变量与每个因素高度相关。请注意,下面的解释是主观的。
因素 0 — 获得社会基本服务 (农村/城市人口获得电力,使用互联网的个人和至少使用基本饮用水服务的人,移动电话用户)
因素 1 — 青年就业状况 (就业与人口比率,15-24 岁,劳动力参与率,15-24 岁,女性/男性)
因素二 — 整体经济增长 (GDP 增长率和人均 GDP 增长率)
因素 3 — 工业发展 (工业增加值(包括建筑业)和二氧化碳排放量)
因素 4 — 健康状况 (糖尿病患病率与 PM2.5 空气污染)许多研究已经固化了汽车排放的颗粒物与糖尿病之间的联系。有兴趣的话,这篇 文章 不错。
要素 5——制造业能力&制成品贸易 (工业就业、商品贸易和制造业增加值)
因素 6 — 专业服务发展 (服务贸易、服务增值和安全互联网服务器)
现在,我们知道这 7 个因素代表了经济的 7 个完全不同的方面。然而,少数指标与所有 7 个因素的相关性很低,即出生率、死亡率和婴儿死亡率。如此低的相关性可能是有意义的,因为这些指标更像是经济中许多要素的最终产品。因此,很难将它们归入上述任何因素。
聚类分析
接下来,我们将应用聚类分析对经济进行分类。在下文中,我们将应用最常用的方法之一— 系统聚类,用自底向上的方法、欧几里德距离和沃德方法来计算相似度。对于层次聚类的详细解释,这篇文章给出了一个很好的教训。
标准化
每个指标都有自己的尺度。例如,农村人口占总人口的比例总是高于 GDP 增长率。为了防止这种规模差异导致无与伦比的权重和不可靠的结论,我们必须首先对数据进行标准化。
层次聚类分析
标准化数据后,我们可以使用名为aggregate veclustering的库来执行聚类。
并且为了可视化聚类结果,应用了**树状图,**记录合并或分裂序列的树形图。但是,请注意,最终形成的集群数量完全基于您的判断。如果聚类太多,分类可能会太细。如果太少,经济可能无法很好地分类。
系统树图
层次聚类的树状图
从树状图来看,可能有 12 个集群。基于这一选择,我们接下来对数据集应用函数agglomerate clustering,将 n_clusters 设置为 12,将 affinity 设置为欧几里德距离,将 linkage 设置为 Ward 方法。
按集群排列的国家名单
聚类结果以国家列表的形式显示如下。
按组列出的国家列表
星团的特征
将 159 个国家分成 12 个组后,最重要的是了解每个组的特征,并调查为什么这些国家被分组在一起。所以让我们来看看下面的热图。我提取了与 7 个因素高度相关的 20 个变量,并按因素组排序,即前五行代表因素 0——获得社会基本服务。
根据集群的特征,我试图将 12 个集群进一步分为 4 大类(最发达、较发达、欠发达和最不发达经济体)。然而,即使在一个大群体中,集群的特征仍然有所不同。请参考下面的详细描述。
大多数发达经济体
*共同特征:*良好的社会基本服务可及性,良好的工业发展和相对良好的健康状况
集群 0 (美、英、日)——青年劳动力参与水平高但经济增长缓慢
集群 2 (法国、意大利和西班牙)——制成品贸易能力强,但青年劳动力参与水平低
集群 7 (爱尔兰和卢森堡)——经济增长非常快,专业服务发展出色,但制造业能力相对较弱
更发达的经济体
*共同特征:*基本服务可及性较好,但青年劳动力参与和专业服务发展水平相对较低
集群 1 (巴西、阿根廷和乌拉圭)——工业发展落后,制造业和制成品贸易能力薄弱
集群 5 (卡塔尔和沙特阿拉伯)——工业发展良好,但卫生状况极差
集群 8 (中国、韩国和南非)——良好的工业发展和制造能力,经济适度增长
欠发达经济体
*共同特征:*制造业和制成品贸易能力中等,但专业服务发展水平低,获得社会基本服务的机会少
集群 6 (印度、埃及和孟加拉国)——工业发展很快,但青年劳动力参与率很低,健康状况不佳
集群 9 (越南和柬埔寨)——青年劳动力参与率非常高,经济增长非常快
第 11 类 (墨西哥、印尼和菲律宾)——平均工业发展和经济增长
最不发达经济体
*共同特征:*经济增长中等,但工业发展非常落后,社会基本服务难以获得
集群 3 (阿富汗、巴基斯坦和喀麦隆)——制造业和制成品贸易能力非常弱,卫生状况相对较差
集群 4 (津巴布韦和乌干达)——青年劳动力参与率非常高,但专业服务发展较差,制造业和制成品贸易能力非常弱
集群 10 (吉布提和纳米比亚)——制造业和制成品贸易能力高于平均水平,但青年劳动力参与水平低
总而言之,请参考下面的热图。方框内的数字是该集群在该方面(因子)的排名。数字越小,集群在这方面的性能越好。
与世界银行现行分类的比较
最后但同样重要的是,将我们的分类(最发达、较发达、欠发达和最不发达)与世界银行的 ( 高收入、中上收入、中下收入和低收入)进行比较会很有趣。
我们的分类与世界银行的分类的比较
根据比较表, **55%的国家在两种分类方法下被归入同一组。**令人惊讶的是,高收入组和低收入组分别获得了 70%和 94%的匹配概率。相比之下,两个中等收入群体的匹配概率相对较低(< 40%)。
结论
上述结果表明人均国民总收入(GNI)可能只显示了画面的一半。除此之外,还有许多其他故事,尤其是对中等收入群体/发展中经济体而言。这些国家的经济模式和社会状况可能会有很大差异,即使它们的人均国民总收入水平相似。
本文利用了两种流行的统计方法——因子分析和聚类分析来帮助我们从不同的维度理解经济并对国家进行分类。我希望这能提高你在更多维度上分析世界经济的兴趣,并有一个超越官方分类的更深层次的思考。
非常感谢,下次再见。
参考
- 柴坦尼亚·瑞迪·帕特拉。(2018).理解层次聚类技术的概念。
- 杰佩·安德森。(2019).因素分析 101 。
- 奥尔加·卡赞。(2018).担心空气污染的一个可怕的新理由。
- 世界银行数据小组。(2019).按收入水平划分的新国家分类:2019–2020。
如果你对我写的东西感兴趣,不要错过成为 Medium 会员的机会。您将可以完全访问所有…
medium.com](https://medium.com/@hudsonko/membership)
如果你有兴趣了解聚类分析在选股中的应用,你可以看看下面的另一篇文章。谢了。
时间抛开复杂的时间序列模型,简单的基本面分析也可以帮助赚钱!!!
towardsdatascience.com](/clustering-analysis-on-stock-selection-2c2fd079b295)
因子分析-我的 ML 奥利奥检测器
“美貌得眼球,个性得人心”。这些线条描绘了我们视野之外的事物的重要性。一种机器学习算法怎么样,它可以找到关于内在美的信息,比如我的心脏,它可以找到奥利奥的奶油层,尽管外面有令人倒胃口的松脆饼干。
要素分析
因子分析是一种用于降维的无监督机器学习算法。该算法从观察变量中创建因子来表示公共方差,即由于观察变量之间的相关性而产生的方差。是的,这听起来有点专业,所以让我们把它分成比萨饼和切片。
用因素表示特征(作者提供的图片)
x 为变量, F 为因子, l 为因子载荷,也可视为因子对相应变量的权重。因子的数量等于变量的数量。
故事时间
让我们用一个例子让一切更清楚。假设我们每个人现在都是招聘人员,我们想为我们的公司招聘员工。采访过程已经结束,对于被采访者的每一种性格,我们都给他们打了分。受访者的各种性格有疏远、放松、粗心、健谈、懒惰等…大约有 32 个变量。我们可以看到放松、粗心和懒惰的特征是相互关联的,因为这些人不会成功。由于这些变量是相关的,我们可以尝试形成一个称为“不成功行为”的因素,它将解释常见的差异,即由于这些特征之间的相关性而产生的差异。
相似或相关的特征可以被分组并表示为因素(图片由作者提供)
数据集和代码可以从我的 GithubRepo 下载
因子分析的步骤
因子分析涉及的各个步骤是
- 巴特利特球形度试验和 KMO 试验
- 确定因子的数量
- 解释这些因素
确保您已经移除了异常值,对数据进行了标准缩放,并且要素必须是数字。
我将在以下软件包的帮助下用 python 实现这一点
- 因子分析器
- numpy
- 熊猫
- matplotlib
巴特利特球形试验
Bartlett 检验检查给定数据中是否存在相关性。它测试相关矩阵是一个相同矩阵的零假设(H0)。全同矩阵包括所有对角元素为 1。因此,零假设假设变量之间不存在相关性。我们想要拒绝这个零假设,因为因子分析旨在解释共同方差,即由于变量之间的相关性而产生的变化。如果 p 检验统计值小于 0.05,我们可以确定相关性不是相同的矩阵,即相关性存在于具有 95%置信水平的变量中。
from factor_analyzer.factor_analyzer import calculate_bartlett_sphericitychi2,p = calculate_bartlett_sphericity(dataframe)
print("Chi squared value : ",chi2)
print("p value : ",p)#OUTPUT:Bartlett Sphericity TestChi squared value : 4054.19037041082
p value : 0.0
使用 pandas 读取数据集并将数据集存储在 dataframe 中。我们将数据集存储在名为“dataset”的数据帧中。只需将“数据集”通过 calculate _ bartltett _ sphericty 函数,它将测试零假设并返回卡方值和 p 检验统计量。由于 p 检验统计量小于 0.05,我们可以得出结论,变量之间存在相关性,这是应用因子分析的绿色信号。
凯泽-迈耶-奥尔金(KMO)试验
KMO 检验测量的是变量中可能是普通方差的方差的比例。预计会有更大的比例,因为它代表变量之间存在更多的相关性,从而为因子分析等维度缩减技术的应用让路。KMO 分数总是在 0 到 1 之间,大于 0.6 的值非常受欢迎。我们也可以说它是衡量我们的数据对因子分析的适合程度的一个标准。
from factor_analyzer.factor_analyzer import calculate_kmokmo_vars,kmo_model = calculate_kmo(dataset)
print(kmo_model)#OUTPUT:
KMO Test Statistic 0.8412492848324344
只需将包含数据集信息的 dataframe 传递给 calculate_kmo 函数。该函数将返回存储在变量“kmo_vars”中的每个变量的方差比例,并且我们的整个数据的方差比例存储在“kmo_model”中。我们可以看到,我们的数据的总体方差比例为 0.84。这表明我们的数据有更多的相关性和降维技术,如因子分析可以应用。
确定因子的数量
数据集中因子的数量等于数据集中变量的数量。所有的因素都不能提供大量有用的关于变量间共同方差的信息。所以我们必须决定因素的数量。因子的数量可以根据因子解释的公共方差的数量来决定。一般来说,我们将画出因子和它们的特征值。特征值只不过是因子解释的方差的数量。我们将选择特征值大于 1 的因子的数量。
但是为什么要选择特征值大于 1 的因子呢?答案很简单。在均值为 0、标准差为 1 的标准正态分布中,方差为 1。因为我们对数据进行了标准缩放,所以特征的方差为 1。这就是选择特征值(方差)大于 1 的因子的原因,即这些因子比单个观察变量解释更多的方差。
from factor_analyzer import FactorAnalyzerfa = FactorAnalyzer(rotation = None,impute = "drop",n_factors=dataframe.shape[1])fa.fit(dataframe)
ev,_ = fa.get_eigenvalues()plt.scatter(range(1,dataframe.shape[1]+1),ev)
plt.plot(range(1,dataframe.shape[1]+1),ev)
plt.title('Scree Plot')
plt.xlabel('Factors')
plt.ylabel('Eigen Value')
plt.grid()
确定因素数量(图片由作者提供)
特征值函数将返回原始特征值和公因数特征值。现在,我们将只考虑原始特征值。从图中我们可以看到,特征值从第 7 个因子下降到 1 以下。因此,最佳因子数为 6。
解释这些因素
创建最佳数量的因子,在我们的示例中为 6。然后,我们必须利用负荷、方差和共性来解释这些因素。
装货
fa = FactorAnalyzer(n_factors=6,rotation='varimax')
fa.fit(dataset)
print(pd.DataFrame(fa.loadings_,index=dataframe.columns))
因子加载(图片由作者提供)
负荷表明一个因素在多大程度上解释了一个变量。加载分数的范围从-1 到 1。接近-1 或 1 的值表示因子对这些变量有影响。值接近 0 表示因子对变量的影响较小。
例如,在因子 0 中,我们可以看到特征“疏远”和“害羞”健谈比其他变量具有更高的负载。由此我们可以看出,因子 0 解释了矜持人群中的普遍差异,即疏远和害羞人群中的差异。
因子 0(保留)(图片由作者提供)
差异
使用“get_factor_variance”函数可以找出每个因素解释的差异量。
print(pd.DataFrame(fa.get_factor_variance(),index=['Variance','Proportional Var','Cumulative Var']))
由因素解释的差异(图片由作者提供)
第一行代表由每个因素解释的方差。比例方差是由总方差中的一个因子解释的方差。累积方差只不过是每个因素的比例方差的累积和。在我们的案例中,这 6 个因素合起来可以解释总方差的 55.3%。
在非旋转情况下,方差将等于特征值。旋转会改变比例方差的分布,但累积方差将保持不变。倾斜旋转允许因子之间相关,而正交旋转保持因子不相关。
社区
公度是每个变量的方差的比例,可以用因子来解释。旋转对变量的公度没有任何影响。
print(pd.DataFrame(fa.get_communalities(),index=dataframe.columns,columns=['Communalities']))
社群(作者图片)
由因子解释的每个变量的方差的比例可以从上面推断出来。例如,我们可以考虑变量“talkatv ”,其方差的 62.9%可以由所有因素共同解释。
这就是关于因子分析的全部内容,因子分析可用于发现潜在的方差,这是由于观察到的变量之间的相关性,比如我的心脏发现了奥利奥的奶油层,尽管外层松脆的饼干令人倒胃口。
基于隐式反馈数据的项目推荐因式分解机
超越经典的矩阵分解方法,包括用户/项目辅助特征,并直接优化项目排名顺序
介绍
在本文中,我们将介绍因式分解机(FM ),它是一个灵活而强大的协同过滤推荐建模框架。然后,我们将描述直接优化项目排名顺序的专门损失函数如何使将 FM 模型应用于隐式反馈数据成为可能。我们将通过使用新的开源 FM 建模库的真实世界隐式反馈数据集来演示这些要点。向前!
推荐系统
随着数字经济规模的不断扩大和复杂性的不断增加,推荐系统为每个用户提供个性化的相关内容的作用比以往任何时候都更加重要。拥有越来越大的产品目录的电子商务网站可以同时向数百万用户呈现个性化的店面。数字内容提供商可以帮助用户浏览更多的书籍、文章、歌曲、电影等。比花一生的时间找到最符合每个用户特定兴趣和口味的小子集还要多。例如,网飞在 2015 年报告称,其推荐系统影响了网站上大约 80%的流媒体时间,并进一步估计该系统的价值每年超过 1B 美元。【1】
推荐系统的两种广泛的高级方法是基于内容的过滤(CBF) 和协同过滤(CF)。 CBF 模型将用户和项目表示为属性或特征的向量(如用户年龄、状态、收入、活动水平;项目部门、类别、流派、价格)。相比之下,CF 方法仅依赖于过去的用户行为:该模型分析共现模式,以确定用户和/或项目的相似性,并试图仅使用用户记录的交互来推断用户对看不见的项目的偏好。基于 CF 的方法具有不受领域限制(即不需要特定的业务知识或特性工程)的优势,并且通常比 CBF 模型更准确和更具可扩展性。【2】
矩阵分解
许多最受欢迎和最成功的 CF 方法都是基于矩阵分解(MF)的,由于 2006-2009 Netflix 奖的举办,其发展速度迅速加快,获奖作品大量使用了 MF 技术,包括现在流行的 SVD++算法。【3】MF 模型试图学习用户和项目在共享潜在因素空间中的低维表示或嵌入。本质上,观察到的稀疏用户-项目交互矩阵被“分解”成包含用户和项目嵌入的两个低秩矩阵的近似乘积。在学习了这些潜在因素之后,可以计算用户/项目相似性,并且通过比较用户/项目潜在因素表示来推断未观察到的偏好。
作者图片
许多流行的 MF 算法通过最小化观察和预测评级之间的平方误差来学习这些用户/项目潜在因素,其中预测评级被计算为相关用户和项目潜在因素的内积。一些模型规范还包括全局用户/项目偏差和/或正则化项,以防止过度拟合。常见的 MF 损失函数可以表示为:
隐性反馈
然而,当处理隐式反馈数据时,这种公式就失效了,在这种情况下,您不会直接观察到任何显式的数字评级或肯定/否定的响应,而只能观察到原始的用户行为(例如,观看、页面浏览、购买、点击)。隐式反馈数据在现实推荐环境中更为常见,事实上,仅使用显式反馈数据(即使存在)构建的推荐系统通常表现不佳,因为评级不是随机丢失的,而是与潜在的用户偏好高度相关。【4】为了使 MF 方法适应隐式反馈数据,胡等人【5】引入了评级的概念,作为二元隐含偏好(用户是否观察到该项目),用数字置信权重表示该二元偏好的假定强度。这个模型公式是在 SparkML 和隐式 Python 库中实现的流行隐式反馈 ALS 算法的基础:
虽然简单有效,但这种方法有几个主要缺点。首先,通过将数据表示为用户/项目交互的矩阵,不可能包括辅助特征,例如在 CBF 模型中使用的用户/项目属性和/或关于交互本身的其他上下文信息。当存在丰富的辅助功能时,这是一个重大的机会损失,也阻止了模型为新用户/项目生成信息性预测,通常称为冷启动问题。第二,将用户隐式反馈编码为二进制(0,1)评级并最小化模型的预测误差是用户偏好的非常间接的表示——你不能确定未被观察到的项目实际上对用户来说是负面的,当然一些正面(和负面)的项目比具有完全相同的编码(0,1)评级的其他项目更受欢迎。
考虑大多数推荐实际上是如何提供给用户的:作为一个或多个有序的项目列表。因此,直觉上,真正的目标应该是为每个用户导出正确的项目排序。这将允许我们生成推荐,其中所有项目都按照与每个用户的相关性排序,最相关的项目出现在每个用户的推荐项目列表的最顶端。
作者的亚马逊 Prime 视频主页
为了克服这些限制,我们需要一个更通用的模型框架,它可以扩展潜在因素方法,以纳入任意的辅助特征,以及使用隐式反馈数据直接优化项目排序的专用损失函数。进入因式分解机和学习排名。
因式分解机
因子分解机器(FM)是通用的监督学习模型,将任意实值特征映射到低维潜在因子空间,可以自然地应用于各种预测任务,包括回归、分类和排序。FMs 可以在非常稀疏的数据下准确估计模型参数,并以线性复杂度进行训练,允许它们扩展到非常大的数据集【6】——这些特性使 FMs 非常适合现实世界的推荐问题。与上面讨论的输入用户-项目交互矩阵的经典 MF 模型不同,FM 模型将用户-项目交互表示为实值特征向量和数字目标变量的元组-这种数据格式应该为任何训练过标准回归或分类模型的人所熟悉。
典型地,对于协同过滤,基本特征将是用户和项目指示符的二进制向量,使得每个训练样本恰好具有对应于给定用户/项目组合的两个非零条目。然而,这些用户/项目指示符可以用任意辅助特征来扩充,例如,用户或项目属性和/或与交互本身相关的上下文特征(例如,星期几、添加到购物车订单等)。).
作者图片
FM 模型方程由特征之间的 n 向相互作用组成。二阶模型(到目前为止最常见)包括每个基本特征的权重以及每个成对特征组合的交互项。
这个模型公式可能看起来很熟悉——它只是一个二次线性回归。然而,与分别估计每个交互项的多项式线性模型不同,FMs 使用因式分解的交互参数:特征交互权重表示为两个特征的潜在因子空间嵌入的内积:
这极大地减少了要估计的参数数量,同时通过打破相互作用项之间严格的独立性标准来促进更精确的估计。考虑一个有 1,000,000 个用户和 10,000 个项目的现实推荐数据集。二次线性模型将需要估计 U+I+UI ~ 100 亿个参数。维度 F=10 的 FM 模型将只需要 U+I+F(U+I)~ 1100 万个参数。此外,许多常见的 MF 算法(包括 SVD++,ALS)可以重新制定为更通用/灵活的 FM 模型类的特例。【7】
然而,如何使 FM 模型适应隐式反馈数据并不是显而易见的。一种天真的方法是将所有观察到的用户-项目交互标记为(1),将所有未观察到的交互标记为(-1),并使用常见的分类损失函数(如铰链或对数损失)来训练模型。但是对于真实世界的推荐数据集,这将需要创建数十亿未观察到的用户项目训练样本,并且由于交互稀疏性而导致严重的类别不平衡。这种方法也具有与上面讨论的隐式反馈 MF 适应相同的概念问题:它仍然最小化评级预测误差,而不是直接优化项目排名顺序。
学习排名
直接学习排序顺序而不是最小化预测误差的优化技术被称为排序学习(LTR)。LTR 模型在成对或成列的训练样本上训练,而不是在单个观察值上训练。损失函数基于项目的相对顺序,而不是它们的原始分数。使用 LTR 的模型已经在搜索、信息检索和协同过滤方面产生了最先进的结果。这些技术是使 FM 模型适应隐式反馈推荐问题的关键。
用于项目推荐的最流行的 LTR 技术之一是贝叶斯个性化排名(BPR)。 BPR 试图通过最大化模型参数的后验概率(MAP)来为每个用户学习项目的正确排序,给定观察到的用户项目偏好的数据集和选择的先验分布。假设每个用户观察到的项目(隐式反馈)优于未观察到的项目,并且假设所有成对的偏好是独立的。为了学习这些偏好,创建由[用户(u),观察项目(I),未观察项目(j)]元组组成的训练样本,并最大化关于模型参数的以下对数似然函数。【第八期】
其中 ( > u|theta) 是模型对用户(u)的预测项目排名。这可以使用上述训练数据通过最大化用户观察到的项目优于他们未观察到的项目的联合概率来学习。我们可以使用 sigmoid 函数将该概率定义为映射到[0,1]的用户观察到的(I)和未观察到的(j)项目的预测效用分数之间的差异:
其中实值用户项目效用分数 f(u,i|theta) 和 f(u,j|theta) 是使用上面给出的主 FM 模型等式生成的。将所有这些放在一起并包括一个正则项,最大化的标准变成:
更进一步,加权近似成对等级(WARP) 不是简单地随机采样未观察到的项目(j),而是对每个观察到的训练样本采样许多未观察到的项目,直到它为用户找到等级反转,从而产生更有信息的梯度更新。这在具有大量项目和高度倾斜的项目流行度(非常常见)的上下文中尤其重要。【9】基本程序是:
1.为用户随机抽取一个未观察到的项目,并计算其效用分数。如果未观察项目的分数超过观察项目的分数加上固定的余量,则进行梯度更新,否则继续对负项目进行采样
2.在发现边界违规之前,根据采样的负项数量调整渐变更新的幅度-如果采样的负项越多,更新幅度就越小,因为模型当前更有可能对用户偏好进行正确排序
事实上,如果您使用(0,1)乘数缩放梯度更新的幅度,BPR 可以被视为 WARP 的特殊情况,其中负样本的最大数量等于 1,导致梯度更新乘数恒定为 1。相对于 BPR,使用 WARP 会增加每个历元的训练时间,但通常会产生更快的收敛和更好的模型性能。
模型评估
现在,所有的理论都清楚了,让我们看看这些组件如何在一个众所周知的真实数据集上产生高质量的推荐。我们将使用作者的新 RankFM 包训练一个隐式反馈 FM 模型,该包实现了上述技术,并将其性能与之前讨论的流行的隐式反馈 ALS MF 算法进行比较(通过隐式包)。目标是表明,与类似指定的经典 MF 模型相比,包含辅助特征并使用 LTR 优化技术训练的 FM 模型产生更好的性能。
在本练习中,我们将使用 2017 年 Instacart 订单数据。它包含 200,000 个用户,50,000 个项目,340 万个订单,以及超过 3,200 万个记录的用户-项目交互。对数据的快速探索性研究揭示了高度的稀疏性:中间用户在 9 个订单中仅购买了 48 个项目,而中间项目在 60 个订单中仅被 35 个用户购买。总体交互稀疏率为 99.87%。
我们将随机划分总体交互数据,用 75%来训练模型,剩下的 25%来评估验证指标和模型性能。为了反映重复购买携带更强偏好信号的想法,我们将结合使用每个用户商品购买计数的日志定义的样本权重。我们将用一组表示每个商品的超市部门和通道的商品特性来扩充主要的用户-商品交互数据。不幸的是,这个数据集没有用户辅助功能可以利用。
现在我们来训练 RankFM 模型。我们将使用 50 个潜在因素,最多 100 个负样本的偏差损失,以及一个逆比例学习计划,该计划将随着时间的推移降低学习速率,以帮助 SGD 收敛。RankFM 将打印每个训练时期的对数似然性,以便您可以逐个时期地监控训练时间和性能增益:
我们可以使用主 FM 模型方程和 predict() 方法生成实值效用分数。没有出现在训练数据中的用户和项目可以被丢弃,或者在结果得分向量中将得分设置为 np.nan 。我们可以使用 recommend() 方法为验证集中的每个用户生成 TopN 个推荐项目。有一个有用的标志,让您选择是否包括以前观察到的训练项目或只生成新项目的建议。结果是一个 pandas 数据框架,其中包含 UserID 索引值和每个用户推荐的项目,这些项目按预期的偏好从左到右排列:
最后,我们将评估延迟验证数据的性能指标。RankFM 包括一个独立的评估模块,该模块实现了许多流行的推荐器指标,包括命中率、倒数排名、折扣累积收益和精度/召回。
使用具有 50,000 个独特项目的数据集,其中中值用户购买少于 50 个项目,我们能够在很少的功能工程和所需的数据准备的情况下获得 80%以上的验证命中率。不算太寒酸。
基线模型对比
现在,让我们将 RankFM 的性能与我们的基线 ALS 算法进行比较。为此,我们首先需要将用户-项目交互数据转换成一个稀疏的 CSR 矩阵。我们将使用完全相同的数据分割,并输入我们生成的样本权重作为置信度得分来训练 ALS 模型。
现在我们有了所需输入格式的数据,我们可以拟合 ALS 模型并为验证用户生成 TopN 建议。我们将使用与 RankFM 相同的潜在因子维度,否则使用默认值。
最后,我们将计算用于评估 RankFM 模型的同一组拒绝交互的模型的命中率、精确度和召回率。
虽然完整的分析需要在各种超参数组合中适当调整两个模型,但我们可以看到,使用相同的相互作用数据和大致相等的模型规格(即潜在因素的数量),FM 模型公式和 LTR 优化技术可以获得适度的性能增益(5–10%)。如果用户有更少的记录交互(在 Instacart 数据中,每个用户至少有 3 个订单)和/或我们有更多信息用户/商品辅助功能,我们可能会看到相对于基线 ALS MF 模型的更大性能增益。
总结
在本文中,我们探索了因子分解机器(FM)作为一个通用而强大的模型框架,特别适合于协同过滤推荐问题。与传统的矩阵分解(MF)方法不同,FM 模型可以自然地扩展到包括用户、项目或上下文辅助特征,以增加主要交互数据。然后,我们展示了学习-排序(LTR)损失函数,如贝叶斯个性化排序(BPR)和加权近似成对排序(WARP)是如何成功地使 FM 模型适应隐式反馈数据的关键。为了证明这些观点,我们展示了一个隐式反馈 FM 模型,它在一个众所周知的开源隐式反馈推荐数据集上优于流行的 ALS MF 基线算法。最后,我们介绍了 RankFM :一个新的 python 包,用于构建和评估带有隐式反馈数据的推荐问题的 FM 模型。
参考文献
【1】c .戈麦斯-乌里韦,n .亨特。网飞推荐系统:算法、商业价值和创新 (2015),美国计算机学会管理信息系统汇刊
【2】y .科伦,r .贝尔,c .沃林斯基。推荐系统的矩阵分解技术 (2009),IEEE
【3】y .科伦,r .贝尔,c .沃林斯基。奈飞奖的贝尔科尔解决方案 (2008 年)www.netflixprize.com
【4】h . Steck。非随机缺失数据推荐系统的训练和测试 (2010)。KDD
胡。隐式反馈数据集的协同过滤 (2008)。电气电子工程师学会
s·伦德尔。因子分解机器 (2010)。ICDM 2010
【7】s·伦德尔。因子分解机器 (2010)。ICDM 2010
【8】s .伦德尔,c .弗赖登塔尔,z .甘特纳,l .施密特-蒂梅。 BPR:来自隐式反馈的贝叶斯个性化排序 (2009)。UAI 2009
【9】s .伦德尔,c .科登泰勒。根据隐式反馈改进项目推荐的成对学习 (2014)。2014 年美国计算机学会
错误统计推断的原因
本文讨论了错误的类型和几个重要的因素,可能有助于错误的统计推断
假设检验是研究人员根据他们的发现或数据做出精确陈述的过程。然后,他们收集证据来伪造准确的声明或主张。这种精确的陈述或主张被称为零假设。如果有强有力的证据来证伪零假设,我们可以拒绝零假设,并采用替代假设。这是假设检验的基本思想。
统计检验中的错误类型
在正式的假设检验中,会出现两种不同类型的错误。它们是:
第一类:当零假设为真,但假设检验结果显示有证据拒绝它时,出现第一类错误。这被称为假阳性。
第二类:当零假设不为真,但在假设检验中没有被拒绝时,出现第二类错误。
大多数假设检验程序在理想条件下很好地控制了第一类误差(5%)。这可能会给出一个错误的想法,即只有 5%的概率报告的发现是错误的。但事情没那么简单。概率可以远远高于 5%。
数据的常态
数据的正态性是一个可以打破统计检验的问题。如果数据集很小,数据的正态性对于某些统计过程(如置信区间或 p-检验)非常重要。但如果数据足够大,正态性并不会产生显著影响。
相互关系
如果数据集中的变量相互关联,可能会导致较差的统计推断。看下面这张图:
在这个图表中,两个变量似乎有很强的相关性。或者,如果将一系列数据视为一个序列,这意味着值与其相邻值相关,并且数据中可能存在一些聚类或自相关。数据集中的这种行为会对统计测试产生负面影响。
相关性和因果关系
这在解释统计测试的结果时尤其重要。“相关性并不意味着因果关系”。这里有一个例子。假设,你有研究数据显示,更多没有受过大学教育的人认为在工作场所女性应该比男性获得更少的报酬。你可能已经进行了很好的假设检验并证明了这一点。但是必须注意从中得出什么结论。很可能,大学教育和“女性应该得到更少的报酬”这一信念之间存在关联。但是说没有大学学历是这种信念的原因是不公平的。这是一种相关性,但不是直接的因果关系。
从医学数据中可以提供一个更清楚的例子。研究表明蛀牙少的人不太可能患心脏病。你可能有足够的数据从统计学上证明这一点,但你实际上不能说蛀牙导致了心脏病。没有那样的医学理论。
多样性
这是一个广泛的问题。我用几句话来提一下。讨论这个问题本身就做了一篇大文章。对同一问题进行多重假设检验,或对相同或不同的亚组进行多重假设检验,可能会得出误导性的结论。例如,你想进行一项关于“更多每天睡眠少于 6 小时的人患糖尿病”的研究。你决定对不同的群体进行测试,比如男性和女性,吸烟者和不吸烟者,运动员和非运动员,饮酒者和不饮酒者。假设的影响在这些群体中可能比其他群体更强。如果您在不同的子群中对相同的数据集进行相同的假设检验,结果可能会产生误导。有很多方法可以解决这个问题。我将在以后的文章中讨论这个问题。
统计推断的过程很简单。有很多因素会影响统计测试的结果。在这里,我试图简单地提到其中的几个。
未能扩展| 5 实施人工智能的挑战以及如何解决这些挑战
活动讲座
伊恩·斯科特| TMLS2019
来自多伦多机器学习峰会的演讲:【https://torontomachinelearning.com/
关于演讲者
伊恩是德勤的首席数据科学家,也是 Omnia AI 的合伙人。他拥有 20 多年为金融服务和其他行业提供高级分析项目、解决方案和软件的经验,领导涉及高级建模和机器学习的大规模数据密集型分析项目的开发和交付。在其他职位中,Ian 曾是一家大数据公司的副总裁和一家服务于金融服务行业的分析软件公司的 CTO。他拥有哈佛大学的物理学博士学位。
关于谈话
许多成熟的组织热衷于利用人工智能对他们的数据进行创新,但当他们尝试时,却很难看到任何价值。大多数专业人员会认识到技术缺陷带来的挑战,但如果不解决这些关键的组织挑战,最终会导致无法交付价值。在本次演讲中,斯科特博士将讨论传统组织的人工智能交付状态,以及如何加速价值之路。
使用犹太法典和 Python 公平分配债务
用博弈论分割遗产的古老方法
坦纳·马迪斯在 Unsplash 上拍摄的照片
根据 Experian 的一项研究,2016 年 10 月至 12 月间死亡的 73%的美国人都有一些未偿还的债务【1】。不幸的是,负债而死对许多人来说是一种新常态,我预计这一比例在未来还会增加。尽管逃了税,但当你死后,债务不会简单地消失。未偿还的债务通常会通过你的遗产来收回,除非你使用退休账户或人寿保险来保护自己免受债权人的伤害。如果你的遗产不能偿还所有债务怎么办?你的债务如何公平分配?
债务分配方法
- 平均分配
按照债权人的数量平均分配遗产
Estate = 100
Creditors = [100, 200, 300]## Equal DivisionPayments = {'0_100': 33.33, '1_200': 33.33, '2_300': 33.33}
在这种情况下,每个债权人得到 33 1/3 美元。
- 比例除法
比例分割将更多的财产判给最高的债权人
Estate = 300
Creditors = [100, 200, 300]## Equal DivisionPayments = {'0_100': 50, '1_200': 100, '2_300': 150}
在这种情况下,每个债权人将获得其要求金额的一半,最大的债权人将获得最大的一笔金额。
- 犹太法典部
直到 1985 年,Robmann Aumann 和 Michael Maschler 编写了一种算法来解决下面的奇怪除法,这种方法仍然是一个数学之谜:
Estate = 200
Creditors = [100, 200, 300]## Equal DivisionPayments = {'0_100': 50, '1_200': 75, '2_300': 75}
拆分既不是等额拆分,也不是比例拆分。分割实际上是基于竞争金额的等分。
该算法
下面的五个步骤详细说明了由 Aumann 和 Maschler 提出的有争议的和算法的等分。
- 按从低到高的顺序排列债权人
- 在所有债权人之间平均分配财产,直到最低的债权人得到一半的债权
- 删除最低的债权人,重复步骤 2,直到所有债权人拥有一半的索赔权或产业是空的
- 反向操作:从遗产中给予最高债权人,直到损失(分配和索赔之间的差额)等于次高债权人的损失。
- 重复第 4 步,直到所有的钱都分配完
给定算法后,我想创建一个函数来实现一个有争议的和的等分。我写了带有债务函数的 talmud _ debts 包来完成这个任务。还有一个带有 jupyter 笔记本实现的 GitHub 。
pip install talmud_debts
这将安装带有债务功能的软件包。要运行该函数,请导入 talmud _ debts 并在 python 中调用 debits 函数。预期的参数是遗产大小(整数)和要支付的债权人数组。
from talmud_debts import debtsEstate = 200
Creditors = [100,200, 300]debts(Estate, Creditors)
输出是一个有序的字典,债权人由一个索引定义,然后是债务金额。0_100 表示最低债权人的预期支出。
Python 中算法的伪代码
步骤 1–3
第一步是对数组进行排序,使债务从索引 0 处的最低值到索引 n 处的最高值。我生成了一些帮助器函数来为字典值添加一个或一个浮点数。我使用了 for 和 while 循环 O(N**2)来分配所有债权人,直到至少一半的债务被给予最低的债权人。我跳出了循环,用值更新了第二个字典,然后删除了最低的债权人。
步骤 4–5
另一个 while 循环,for 循环组合用于获得债权人的最新损失。如果破产财产少于最高债权人的损失与次高债权人的损失之间的差额,则将剩余部分分配给损失最大的债权人。否则,在具有最大损失的债权人匹配下一个最大损失之后,循环重复。
总的来说,这个算法实现既有趣又有挑战性。实现这个算法的想法来自 Presh Talwalkar 的书 《博弈论的快乐》 。该算法适用于任何数量的债权人和任何规模的财产。如果遗产规模大于债权人的总和,该函数将打印一个声明,说明所有债务都可以支付。我可以在 LinkedIn 上找到我,我希望我们能像兰尼斯特家一样,永远偿还我们的债务。
[1]https://www . credit . com/blog/Americans-are-dead-in-a-average-62k-of-debt-168045/
[3]http://www.cs.cmu.edu/~arielpro/15896s15/docs/paper8.pdf
fairmodels:让我们和有偏见的机器学习模型战斗吧
第 3 部分:缓解
作者图片
TL;速度三角形定位法(dead reckoning)
R 包fair models通过模型可视化促进了偏差检测。它实施了一些可以减少偏差的缓解策略。它能够方便地检查公平性指标,并在不同的机器学习(ML)模型之间进行比较。
长版本
偏见抑制是机器学习公平领域的一个重要课题。对于 python 用户来说,已经有一些算法被实现、很好地解释和描述(参见 AIF360 )。 fairmodels 提供了一些流行的、有效的偏差缓解技术的实现,可以让你的模型更加公平。
我有一个有偏差的模型,现在怎么办?
有一个有偏见的模型并不是世界末日。有很多方法可以处理它。 fairmodels 实现了各种算法来帮助你解决这个问题。首先,我必须描述一下预处理算法和后处理算法之间的区别。
- ****预处理算法在模型训练前对数据进行处理。他们试图通过数据推断来减轻特权子群和非特权子群之间的偏差。
- ****后处理算法改变用 DALEX 解释的模型的输出,使其输出不那么偏向特权子群。
这些算法是如何工作的?
在本节中,我将简要描述这些偏差缓解技术的工作原理。这里使用的更详细的例子和一些可视化代码可以在这篇短文中找到。
预处理
不同的冲击消除器(费尔德曼等人,2015)
(图片由作者提供)完全不同的影响消除。蓝色和红色分布被转换成“中间”分布。
该算法适用于数字、序数特征。它更改列值,使非特权(蓝色)和特权(红色)子组的分布彼此接近。一般来说,我们希望我们的算法不要根据特性的价值来判断,而是根据百分位数来判断(例如,从两个小组中雇用 20%的最佳申请人)。该算法的工作方式是,它找到这样的分布,即最小化推土机的距离。简而言之,它找到“中间”分布,并为每个子组更改该特征的值。
重新加权(卡米兰等人,2012 年)
(图片由作者提供)在这个模型示例中,S=1 是一个特权子群。S 和 y 的每个唯一组合都有一个权重。
重新加权是一种简单而有效的工具,可以最大限度地减少偏差。该算法查看受保护的属性和真实标签。然后,假设受保护的属性和 y 是独立的,它计算分配有利标签(y=1)的概率。当然,如果有偏差,他们会有统计上的依赖性。然后,该算法将计算出的理论概率除以该事件的真实经验概率。重量就是这样产生的。利用这两个向量(受保护变量和 y ),我们可以为数据中的每个观察值创建权重向量。然后,我们将它传递给模型。就这么简单。但是一些模型没有权重参数,因此不能从该方法中受益。
重采样(卡米兰等人,2012 年)
(图片由作者提供)均匀采样。圆圈表示重复,x 表示省略观察。
重采样与先前的方法密切相关,因为它隐含地使用重新加权来计算在特定情况下必须省略/重复多少个观察值。假设有 2 组人,被剥夺的(S = 0)和被偏爱的(S = 1)。当标签为正时,该方法复制来自剥夺子群的观察值,并省略标签为负的观察值。然后对有利的组执行相反的操作。实现了两种重采样方法- 均匀和优先。均匀随机选取观察值(如图所示),而优先利用概率选取/忽略接近截止值的观察值(默认值为 0.5)。
后处理
后处理发生在创建解释器之后。为了创建解释器,我们需要模型和 DALEX 解释器。 Gbm 模型将在 成人 数据集上训练,预测某个人年收入是否超过 5 万。
[library](https://rdrr.io/r/base/library.html)([gbm](https://github.com/gbm-developers/gbm))
[library](https://rdrr.io/r/base/library.html)([DALEX](https://modeloriented.github.io/DALEX))
[library](https://rdrr.io/r/base/library.html)([fairmodels](https://modeloriented.github.io/fairmodels/index.html))data("adult")
adult$salary <- [as.numeric](https://rdrr.io/r/base/numeric.html)(adult$salary) -1
protected <- adult$sex
adult <- adult[[colnames](https://rdrr.io/r/base/colnames.html)(adult) != "sex"] # sex not specified
# making model
[set.seed](https://rdrr.io/r/base/Random.html)(1)
gbm_model <-[gbm](https://rdrr.io/pkg/gbm/man/gbm.html)(salary ~. , data = adult, distribution = "bernoulli")
# making explainer
gbm_explainer <- [explain](https://rdrr.io/pkg/DALEX/man/explain.html)(gbm_model,
data = adult[,-1],
y = adult$salary,
colorize = FALSE)
拒绝基于选项的分类(pivot) (Kamiran 等人,2012)
(图片由作者提供)红色-特权,蓝色-无特权。如果该值接近(-theta + cutoff,theta + cutoff)和特殊情况,概率将位置(和值)更改到 od cutoff 的另一侧。
ROC pivot 基于基于拒绝选项的分类实施。如果一个观察值来自非特权组并且在截止值的左边,则算法切换标签。然后对特权群体执行相反的操作。但有一个假设,即观察值必须接近(就概率而言)临界值。因此,用户必须输入某个值θ,以便算法知道观察值必须多接近开关的截止值。但是有一个问题。如果只是改变了标签,DALEX 解释者将很难正确计算模型的性能。因此,在该算法的 fairmodels 实现中,被转换(旋转)的是概率,而不是标签。它们只是移动到另一侧,但与截止点的距离相等。
切断操作
(图片由作者提供)plot(ceteris _ pari bus _ cut off(fo object,cumulated = TRUE))
截断操作对于最小化模型中的偏差可能是一个很好的主意。我们只需选择临界值将改变的指标和子组。该图显示了最小值在哪里,并且对于该截止值来说,奇偶损失将是最低的。如何为特定子群创建具有不同截止值的公平对象?这很容易!
fobject <- [fairness_check](https://modeloriented.github.io/fairmodels/reference/fairness_check.html)(gbm_explainer,
protected = protected,
privileged = "Male",
label = "gbm_cutoff",
cutoff = [list](https://rdrr.io/r/base/list.html)(Female = 0.35))
*现在*公平对象(fo object)是一个具有指定截止值的结构,它将影响公平度量和性能。
公平性和准确性之间的权衡
如果我们想减少偏见,我们必须意识到这一行动可能带来的弊端。假设静态平价对我们来说是最重要的指标。降低该指标的奇偶损失将(可能)导致假阳性的增加,这将导致准确性下降。在这个例子中(你可以在这里找到)一个 gbm 模型被训练,然后用不同的偏差缓解技术处理。
作者图片
我们越是试图减少偏差,我们得到的准确性就越低。这对于这个指标来说是很自然的事情,用户应该意识到这一点。
摘要
在 fairmodels 中实现的去偏置方法当然值得一试。它们很灵活,大多数适合每种型号。最重要的是,它们很容易使用。
接下来读什么?
了解更多信息
- 查看包的 GitHub 网站了解更多详情
- 教程关于 fairmodels 套装的全部功能
- 关于偏差缓解技术的教程
fairmodels:让我们和有偏见的机器学习模型战斗吧
第 2 部分:可视化
作者图片
TL;速度三角形定位法(dead reckoning)
R 包fair models通过模型可视化促进了偏差检测。它实施了一些可以减少偏差的缓解策略。它能够方便地检查公平性指标,并在不同的机器学习(ML)模型之间进行比较。
长版本
就像我在之前的博客文章中写的那样,机器学习(ML)中的公平性是一个发展中的领域,没有很多可视化偏见的工具。当然,柱状图是最简单的方法,也是最容易解释的。然而,还有其他方法来解决这个问题,并对歧视有更深入的了解。在本章中,我将使用 fairmodels R 包对模型偏差进行更详细的可视化分析。
使用的指标以及什么是奇偶校验丢失?
在我们开始可视化公平或偏见之前,我们需要一些警告。
- *首先,与 fairness_check() 函数不同,我们不会查看子组之间在公平性指标上的差异。我们将关注使用混淆矩阵创建的指标,例如*真实阳性率、F1 分数、阴性预测值等。通过这种方式,大多数公平性指标将被涵盖。
- 我们需要某种方法来比较两个以上子群(受保护变量中的值)的不同指标,例如针对许多种族。这个问题的一个很好也很容易理解的解决方案是对特权子群和非特权子群的度量值之间的所有欧几里德距离求和。它将被称为 奇偶丢失。 可以对所有混淆矩阵度量进行计算。这里是 TPR 的例子。
(图片由作者提供)TPR 的奇偶损失是特权子群和非特权子群之间的欧几里德距离之和
有了这样累积度量,我们将能够快速比较偏差有多显著,甚至在不同的度量之间。
这有什么大惊小怪的?
由于这一点,可视化不同的指标比以往任何时候都更容易。像以前一样,我们将使用用 fairness_check() 创建的 fairness_object ,并应用不同的函数从不同的角度显示偏差。我们将使用 COMPAS 数据集,预测某个人在 2 年后是否不再是惯犯。这样,模型的输出将是这个人应该得到一个有利结果(不是累犯)的概率。我们的受保护(敏感)变量将是一个具有 6 个级别的因子,代表不同的种族。你可以在找到这个例子的代码。下面是显示如何创建 fairness_object 的代码。
准备数据
**library**(fairmodels)
**library**(DALEX)
**library**(ranger)
**library**(gbm)
data("compas")
*# positive outcome - not being recidivist*
two_yr_recidivism <- factor(compas$Two_yr_Recidivism, levels = c(1,0))
y_numeric <- as.numeric(two_yr_recidivism) -1
compas$Two_yr_Recidivism <- two_yr_recidivism
df <- compas
df$Two_yr_Recidivism <- as.numeric(two_yr_recidivism) -1
训练模型和解说
gbm_model <- gbm(Two_yr_Recidivism ~., data = df)
lm_model <- glm(Two_yr_Recidivism~.,
data=compas,
family=binomial(link="logit"))
rf_model <- ranger(Two_yr_Recidivism ~.,
data = compas,
probability = TRUE)
explainer_lm <- explain(lm_model, data = compas[,-1], y = y_numeric)
explainer_rf <- explain(rf_model, data = compas[,-1], y = y_numeric)
explainer_gbm <- explain(gbm_model, data = compas[,-1], y = y_numeric)
准备公平对象
fobject <- fairness_check(explainer_lm, explainer_rf, explainer_gbm,
protected = compas$Ethnicity,
privileged = "Caucasian")
一旦我们有了公平对象,我们就可以开始视觉化。
(图片由作者提供)plot(fairness_heatmap(fobject))
****公平性热图是一种可视化模型和指标之间相似性的好方法。它是可定制的,度量标准可以标准化,文本可以放大甚至关闭,梯度的中点可以改变,模型可以根据度量标准切换轴。由于这个情节由 3 个独立的情节组成,我们可以改变标题和副标题的情节。
(图片由作者提供)plot(fairness_radar(fobject))
对于模型和指标的比较,最好使用公平雷达** 。很明显,如果模型覆盖的领域越少,偏差就越小。对于某个度量,假设 TNR 很容易说最奇偶损失在 lm 中,最少在 ranger 中。如果我们添加更多的模型,它可能会开始变得不可读。**
(作者提供的图片)plot(stack_metrics(fobject))
堆叠度量图**将条形图堆叠在一起。不同的颜色表示不同的混淆矩阵度量。
该图非常适合比较各型号的总体奇偶损失。当有大量和少量的解释者时,视觉上是令人愉快的。一般来说,累积的奇偶校验损失越低越好。然而,它在相互比较指标之间存在不足。
(图片由作者提供)plot(fairness _ PCA(fo object))
公平性 PCA 有助于看出模型和度量之间的相似性。它就像标准的双标图一样。模特之间的距离越近,她们就越像。在底部和左侧的轴上,有关于通过每个组件可以解释多少差异的信息。
(图片由作者提供)plot(choose_metric(fobject))
选米 剧情是所有剧情中最简单的。我们只需选择指标,它会显示所有型号的该指标的奇偶损失。当然,奇偶损失越少越好。**
(图片由作者提供)绘图(group_metric(fobject))
**组指标**图有所不同。首先,它显示了子组之间的度量,而不是它的奇偶损失。条形越靠近特权子群越好。右侧是模型的性能图,可以比较常见的指标,如 AUC、精确度、F1 分数。此外,为了便于子组之间的直观比较,添加了参数 parity_loss ,当该参数设置为 TRUE 时,计算并显示非特权子组和特权子组之间的欧几里德距离,而不是原始指标得分。
(图片由作者提供)plot(性能和公平性(fobject))
****性能和公平性图在左侧和底部轴分别显示了指标的奇偶校验损失和准确性。左轴是倒置的,所以右上角有最好的模型(在这些指标中)。对于许多模型来说,这是一个很好的工具来可视化性能如何影响公平指标。
(图片由作者提供)plot(all_cutoffs(fobject))
****所有临界值图显示了随着临界值度量的变化,奇偶损耗将如何变化。所有亚组的临界值都是一致变化的。在该图中,我们可以看到存在哪个截止度量(不是 NA ),并且我们可以知道将某些截止设置为某个值将导致更少的奇偶校验丢失。
(图片由作者提供)plot(ceteris _ pari bus _ cut off(fobject,“African_American”))
*其他条件不变的情况下,剧情比它的前作更有趣。此处的截止值仅针对选定的亚组(此处为非裔美国人)而变化,其他亚组的截止值不变。此外,还显示了累积奇偶性损失最小的截止值。这样,通过改变特定子组的截止值,我们可以将奇偶损失变得尽可能低。这当然会影响模型的性能。此外,还有参数累积,当设置为*真时,将触发面的折叠,所有选择的度量将被累积。
为什么我们需要 fairmodels 包?
呈现的图是灵活的(度量标准可以改变,参数可以设置等等),并从多个角度给出关于偏差的信息。考虑到这一点,可以更好地理解模型做出的区别性决策。当创建许多模型时,最好从偏差的不同方面相互比较。在这个过程的最后,应该清楚哪种模式在公平性和性能方面最有希望。
接下来读什么?
了解更多信息
- 查看包的 GitHub 网站了解更多详情
- 教程介绍了 fairmodels 套装的全部功能
- 关于偏差缓解技术的教程
人工智能中的公平
来源:维基媒体(https://commons . Wikimedia . org/wiki/File:Domenico _ Becca fumi _ 012 . jpg)
做好人容易,难的是做公正人。维克多·雨果
简介
人工智能系统的普及不再是一个新事物,从产品、电影推荐到打车服务,它无处不在。随着时间的推移,它们的采用也越来越普及。公平是基于个人或群体的固有或后天特征而对他们没有任何偏见或偏袒,因此一个不太公平的制度会偏向某一类个人。
AI 不公平的问题
有许多著名的案例强调了人工智能系统中公平的重要性。最近的一篇论文《不完美的图像化:GANs 加剧面部数据增强和 Snapchat 自拍镜头偏见的影响》强调了同样的事情。它说,“在这篇论文中,我们表明,在数据沿着某些轴(如性别、种族)表现出偏差的情况下,生成敌对网络(GANs)的故障模式加剧了生成数据中的偏差。”许多顶级研究人员一直在谈论偏见,在这个方向上有很多积极的研究。
COMPAS 预测一个犯罪是否可能再次犯罪。与其他种族相比,这一制度在某种程度上歧视非裔美国人。问题是数据是有偏见的,但它们也不是很透明,这加剧了情况。后来的一项研究表明,与非专家做出的预测相比,该系统的准确率仅为 65%左右。后来还发现,即使没有种族和性别等敏感特征,这种风险也是可以预测的。如果 COMPAS 考虑到公平的立场,这样的错误是可以避免的,尤其是在这样一个关键的领域
发现偏见的另一个非常有趣的领域是医疗保健。题为“剖析用于管理人口健康的算法中的种族偏见”的论文发现,一种特殊的算法可以帮助医院和保险机构根据训练数据确定哪个病人将从针对高风险个人的高端医疗服务中受益更多,其中黑人病人与白人的比例为 7T1。尽管这代表了现实,但这种不平衡的数据问题通常需要缓解。
偏置
深入一点,简化一下我们手头的问题,有两类偏差,算法偏差和数据偏差。
与数据相关的常见偏差有历史偏差、表示偏差、测量偏差、评估偏差、聚合偏差、人口偏差、抽样偏差、内容生产偏差、时间偏差、流行性偏差、观察者偏差和资金偏差。显示偏差的一个很好的例子是辛普森悖论,在这个悖论中,子群的特征与聚合时相比是非常不同的。这意味着,当组中的组件之间有足够的相似性时,我们需要在一个级别上聚合数据,这通常很难实现。因此,我们需要确定何时聚合以及聚合多少,这不是基于我们的方便,而是取决于数据需要如何分离。
说到算法,我们可以把歧视分为直接歧视、间接歧视、系统歧视、统计歧视、可解释歧视和不可解释歧视。系统性歧视的一个很好的例子是亚马逊的人工智能招聘算法,它在本质上有点性别歧视。
检查这些系统中是否存在偏见和歧视行为的方法取决于具体情况。就优先顺序而言,发现一种偏向优于另一种偏向的重要性,以及首先解决哪种歧视纯粹是习惯性质的。但是,我们应该努力从算法和数据中排除尽可能多的偏见,并努力在有效性和公平性之间保持健康的平衡。
公平的工具
领导者有许多有趣的方法来实现人工智能中的公平。我想提一下这方面非常有趣的想法:
ML 公平健身房依赖于通过使用模拟来理解 ML 决策系统的长期影响的基本思想,因此试图创建一个复制的社会动态系统。该仿真框架还可以扩展到多智能体交互环境。“公平机器学习的延迟影响”等论文告诉我们,考虑动态和时间因素是多么重要。
IBM 的 AI Fairness 360 是一个解决数据和算法公平性问题的开源工具。它实现了一些研究论文中提到的技术,并为我们提供了偏差检测、偏差缓解和偏差解释工具。
命运:人工智能中的公平、问责、透明和道德在微软的这一产品中,我们获得了极其有效的工具来评估可视化仪表板和偏差缓解算法。这是比较系统的性能和公平性之间的权衡的好工具。
就连欧盟委员会(EU commission)关于人工智能的白皮书也在事后强调了公平。但正如我们慢慢看到的那样,目前活跃的研究正在朝着更好理解的方向发展,并取得了巨大进展。随着这些算法解释能力的提高,追踪偏差并进行必要的干预以确保公平性将变得相对容易得多。诸如《概念主义:深入神经网络》、《可解释性的构建模块》、特征可视化等论文展示了在这些方向上的进展。当谈到可解释的人工智能时,现在有许多工具可供我们使用,我们可以用它们来理解甚至非常复杂的黑盒算法是如何工作的。工具是 Lime,Shap,使用代理更简单的模型和特征重要性图是非常有帮助的。对于高级,非结构化数据应用程序,如深度学习技术,如 GradCam 和注意力可视化,也因可解释性而变得流行。
确保 AI 公平实践的实践
Google 还提供了一些公平的做法,这些做法基本上基于两个主要的理念。确保算法如何做出决策的透明度,并组建不同性质的团队。主要的想法是捕捉关于数据和算法的许多不同的观点,以确保偏见的问题可以从各个角度进行攻击。除了团队中有来自不同领域的人之外,开源社区也可以作为一个扩展团队。社区团体也有助于提高认识和确保透明度。还应该更加警惕地监控模型漂移以及系统的部署后性能。应该对数据的来源、数据收集方法、数据预处理、数据后处理、信息技术标记、可能存在的敏感领域(如种族、性别、宗教)以及数据是否足够多样和平衡(就所有存在的类别而言)进行深入研究。
在最近的论文“更广泛的影响”中有一个新的部分,它也涵盖了论文中算法使用的伦理方面。这表明研究人员越来越敏感,不仅要开发更精确的系统,还要开发更公平的系统。最著名的深度学习和机器学习会议 NeurIPS 2020 公布了更广泛影响部分的指导方针如下:
作者必须声明其作品的广泛影响,包括伦理方面和未来的社会后果。作者应该讨论积极和消极的结果,如果有的话。例如,作者应该讨论谁可能从这项研究中受益,谁可能从这项研究中处于不利地位,系统失败的后果是什么,任务/方法是否利用了数据中的偏差。如果作者认为这不适用于他们,作者可以简单地说明这一点。
结论
总之,我们可以看到这项研究,以及工程界,现在正在认真对待人工智能中的不公平问题,我们可以看到好的工作正在出现。我觉得在未来,这将成为这些人工智能系统满足公平标准的先决条件,无论是训练数据的使用还是算法的使用。一个棘手的问题是,要在日益复杂的系统中追踪错误的偏差,以及对其进行训练的大量数据。一个很好的例子可以是 GPT-3 750 亿参数语言模型(深度学习系统),它是在大到 2000 GB 的语料库上训练的。如果对这些系统的理解和关于公平的研究的进展速度与新方法的发展一致,那么未来是安全的,我们可以看到一个更安全和公平的空间。在未来,我们可能会看到一个特定的机构来确保这些系统的公平性,该机构由来自不同领域的专家组成,类似于 FDA。这可能还需要开发标准化的程序来检查偏见和其他道德标准,以免为时过晚,这也应该可以很好地适应巨大的数据源。
参考文献
https://arxiv.org/pdf/1803.04383.pdf
https://arxiv.org/pdf/1908.09635.pdf
https://blog . tensor flow . org/2019/12/fairness-indicators-fair-ml systems . html
https://www.ibm.com/blogs/research/2018/09/ai-fairness-360/
https://ai . Google blog . com/2020/02/ml-fairness-gym-tool-forexploring-long . html
https://advances.sciencemag.org/content/4/1/eaao5580
http://www . crj . org/assets/2017/07/9 _ Machine _ bias _ rejoinder . pdf
https://science.sciencemag.org/content/366/6464/447
刑事司法决策的公正性
机器学习算法是否确保了刑事司法系统的公平,还是让不平等永久化?
图片来自 pixabay
风险评估是刑事司法系统不可或缺的一部分。他们帮助法官建立危险意识,并帮助确定谁可能处于危险之中。例如,用于告知法官量刑决定的风险评估应该能够预测被告在缓刑期间或之后是否会犯下新的罪行。关于其他被告的数据或信息是形成这种风险评估的一个非常重要的部分。
在刑事司法系统中,越来越多的人支持使用算法模型(机器学习)来进行风险评估,以帮助法官进行决策——这些模型从过去和现在的被告的信息中学习。倡导者认为,机器学习可能会导致更有效的决策,并减少人类判断中固有的偏见。批评者认为,这种模型延续了历史数据中的不平等,因此伤害了历史上被边缘化的人群。虽然公平不是一个纯粹的技术问题,但我们仍然可以利用基本的统计框架来评估公平,因此,令人信服的现象仍然出现。
在这项研究中,我们将探索一种称为 COMPAS 的风险评估算法,由 Northpointe(现为 equivant )创建。COMPAS 调查被告的犯罪记录和其他个人信息,以评估他们在未来两年内再次犯罪的可能性。你可以阅读更多关于 ProPublica 对这个问题进行的调查,该调查引起了人们对在决策中利用机器学习的道德影响的关注。
我们将观察白种人和非裔美国人的风险得分。COMPAS 风险分值 1 表示“低风险”,而风险分值 10 表示“高风险”此外,我们将遵循 ProPublica 的分析,过滤筛选前天数超过或低于 30 天的数据。
首先,让我们想象一下每十分位数的被告人数:
样本中有 3,175 名非洲裔美国人被告和 2,103 名高加索人被告,我们可以看到,对于高加索人群体,分布似乎偏向较低的风险十分位数分数。
接下来,我们来看看每十分位数暴力得分的被告人数。等级 1 表示暴力的“低风险”,等级 10 表示暴力的“高风险”:
我们还看到,对于白种人群体,分布偏向于低风险暴力十分位数分数。对于这两种想象,我们不能把这种差异仅仅归因于种族。可能存在混杂因素,如性别、年龄和 COMPAS 评分检查的其他属性会影响这些风险评分。在本文的其余部分,我们将看看三个常用的统计标准,用于回答“这个算法公平吗?”
- 均衡阳性率(假设被告是白种人,我们预测其再次犯罪的次数等于假设被告是非裔美国人,我们预测其再次犯罪的次数)。
- 均衡错误率(对于白种人和非裔美国人来说,我们将实际上再次犯罪的被告错误分类的比例是相同的,对于两组来说,我们将实际上没有再次犯罪的被告错误分类的比例是相同的)。
- 校准(在所有获得风险分数 r 的被告中,平均而言,他们中的 r 比例实际上应被归类为积极——也就是说,可能再次犯罪)
根据上述标准,下面分别列出了三种可能性:
P(δ(X) = 1 | A = Caucasian) = P(δ(X) = 1 | A = African American) where δ is our decision rule and X is our dataP(δ(X) = 1 | Y = 0, A = Caucasian) = P(δ(X) = 1 | Y = 0, A = African American),
P(δ(X) = 0 | Y = 1, A = Caucasian) = P(δ(X) = 0 | Y = 1, A = African American)P(Y = 1 | R = r, A = Caucasian) = P(Y = 1 | R = r, A = African American) = r
虽然我们没有被告在预测时是否再次犯罪的真实数据,但我们可以观察当我们使用 COMPAS 风险评分创建分类器来预测一个人是否会再次犯罪时会发生什么。
我们首先观察当决策阈值出现在每个十分位数分数时分类器的结果。忽略十分位数 10 和 1 的比率,因为实现这两个十分位数的平等是微不足道的(你能看出为什么吗?).
对于正利率,我们发现:
从这个可视化,我们可以清楚地看到,分类器不满足均衡所有阈值的阳性率。就所有决策阈值而言,非裔美国人比白种人更有可能被归类为“高风险”。
我们仍然可以获得相等的正利率。向下滚动到下一个标准,看看我们如何推断出一个类似的方法来均衡正比率。
在这种情况下,强制实施相等的正比率能解决所有的公平问题吗?我们可以提出不可否认不公平的决策规则,但仍然满足相等正比率的标准。在这种情况下,平均阳性率不足以解决公平性问题,因为在刑事司法系统中,重要的不仅仅是被告被贴上“高风险”标签的数量。例如,我们可以将每个人归类为“高风险”,但这无疑是不公平的。
对于错误率,我们发现:
从这些可视化,我们可以清楚地看到,分类器不满足均衡所有阈值的错误率。特别是,第一张图表显示在接下来的两年中没有复发的非裔美国人更有可能被错误归类为“高风险”。第二张图表显示在接下来的两年内再次犯罪的白种人更有可能被错误地贴上“低风险”的标签。
但是,我们仍然可以通过选择误差率相等的两个阈值来均衡误差率。实现这一点的常见方法是利用 ROC 曲线。我们寻找下图所示的两条曲线的交点。
我们可以通过选择两个阈值来均衡错误率,每个组一个阈值,使得真阳性率和假阳性率相等。这是真的,因为假阴性率正好是(1 —真阳性率)。
虽然均衡错误率将确保两组具有相同的误分类比例,但复杂的问题仍然出现。首先,在判决时,法官不知道谁是真正的“高风险”或“低风险”被告。被告的种族差异常常给人以风险评估不公平的印象。其次,为了使非裔美国人和白种人的错误率相等,有必要使其中一个群体的预测更差。
与其恶化对其中一组的预测,不如批判性地思考为什么不同组之间的错误率不同,并尝试解决一些潜在的原因。
对于校准,我们发现:
为了实现校准,必须满足前面提到的约束条件,即“在获得相同 COMPAS 分数的被告中,与白人被告相比,黑人被告再次犯罪的比例相当。”
在给定 COMPAS 分数的情况下,“积极结果率”是被告实际重新认罪的比率。
我们可以通过上面的图表来形象化这个标准,这正是 Northpointe 认为 COMPAS 算法所要达到的目标。虽然上面的图表看起来不太准确,但我们在一些十分位数中看到的偏差可能是由于相应组和十分位数中的数据不足。例如,10 分位数有 227 名非裔美国人被告和 50 名白种人被告。
考虑到公平性,校准通常是很自然的,因为它是一种先验的保证。决策者在决策时看到分数 R(X) = r,并根据这个分数知道积极结果的平均频率是多少。
为什么这些都很重要?
原来,ProPublica 对 Northpointe 的风险评估算法 COMPAS 的分析发现,黑人被告远比白人被告更有可能被错误分类为再犯风险较高的人,而白人被告更有可能被错误分类为再犯风险较低的人。我们已经表明,这种说法是均衡错误率旨在解决,而 COMPAS 未能满足。有趣的是,Northpointe 声称 COMPAS 算法是公平的,因为它是经过校准的(虽然上面的图表看起来没有经过校准,而且因为我们只处理了一个数据样本,所以我们可以假设给定所有数据的情况下,评分算法实际上都是经过校准的)。
机器学习者和科学家在创建分类算法时努力满足的两个常见的非歧视标准是充分性和分离性。在这项研究中,分离说,分类器的决定是独立的种族条件是否累犯发生。这意味着对于累犯实际发生的例子,分类器输出肯定判定(可能累犯)的概率在种族之间不应该不同。这正是均衡错误率的定义,而 ProPublica 认为 COMPAS 算法不满足这一定义,因此是不公平的。充分性说,累犯是否发生是独立于种族的分类器决定的条件。这意味着,对于分类器输出肯定判定的所有例子,这些例子中实际发生累犯的概率在种族之间不应该不同。这正是我们案例中校准的定义,也是 Northpointe 在 COMPAS 算法中所满足的,他们认为这是公平的。
那么,为什么不同时满足这两个标准呢?被称为“不相容结果的结果集合证明这三个公平标准不能独立出现。这意味着我们只能满足这些标准中的一个。如果我们校准 COMPAS 算法,那么我们也不能均衡错误率。
总之,统计公平标准本身不能作为“公平的证明”但是,它们可以为思考公平问题提供一个起点,并有助于揭示关于决策的重要规范性问题。在这项研究中,我们揭示了公平的不同潜在解释之间的权衡和紧张关系,试图找到一个有用的解决方案。这项研究揭示了将权力下放给机器学习和算法以指导有影响的决策的伦理含义,并表明公平的纯技术解决方案非常复杂,很多时候是不充分的。在量刑决策和预测性警务中,也许最好放弃使用学习模型,除非在非歧视性数据(不包括种族作为属性)上进行训练,并由所有相关领域的公平专家进行评估。
伯特的假工作分类
Python 中的文本分类
近日,爱琴海大学公布了 就业骗局爱琴海数据集 。该数据包含大约 18K 个现实生活中的招聘广告。其目的是为研究界提供一个清晰的雇佣诈骗问题的图景。在本帖中,我们将使用 BERT 对 就业骗局爱琴海数据集 中的虚假职位描述进行分类。
在我们开始之前,让我们简单回顾一下 BERT 方法。
BERT 代表来自变压器的双向编码器表示。描述 BERT 算法的论文由 Google 发布,可以在这里找到。BERT 的工作原理是随机屏蔽单词标记,并用基于上下文的向量来表示每个被屏蔽的单词。BERT 的两个应用是“预训练”和“微调”。
预训练 BERT
对于预训练 BERT 算法,研究人员训练了两个无监督学习任务。第一个任务被描述为屏蔽 LM。其工作原理是随机屏蔽 15%的文档,并预测这些被屏蔽的标记。第二个任务是下一句预测(NSP)。这是由问题回答和自然语言推理等任务激发的。这些任务需要模型来准确捕捉句子之间的关系。为了解决这个问题,他们对二进制预测任务进行了预训练,该任务可以从单一语言的任何语料库中轻松生成。他们在论文中给出的例子如下:如果你有句子 A 和 B,A 有 50%的时间被标注为“isNext”,另外 50%的时间是从语料库中随机选取的句子,被标注为“notNext”。针对这一任务的预训练被证明对于问题回答和自然语言推理任务是有益的。
微调伯特
微调 BERT 的工作原理是用自我关注对连接在一起的文本对进行编码。自我注意是学习当前单词和先前单词之间相关性的过程。这一点的一个早期应用是在长短期记忆()论文(Dong2016)中,研究人员利用自我注意进行机器阅读。BERT 的好处在于,通过对具有自我关注的串联文本进行编码,可以捕捉句子对之间的双向交叉关注。
在本文中,我们将应用 BERT 来预测一个职位发布是否是欺诈性的。这篇文章的灵感来自于 BERT to the Rescue ,它使用 BERT 对 IMDB 数据集进行情感分类。从 伯特到营救 的代码可以在这里找到。
由于我们对单句分类感兴趣,相关的架构是:
在上图中,BERT 算法的输入是单词序列,输出是编码的单词表示(向量)。对于单句分类,我们使用每个单词的向量表示作为分类模型的输入。
现在让我们开始吧!
- 导入包
import pandas as pd
import numpy as np
import torch.nn as nn
from pytorch_pretrained_bert import BertTokenizer, BertModel
import torch
from keras.preprocessing.sequence import pad_sequences
from sklearn.metrics import classification_report
2.数据探索
首先,让我们将数据读入数据框并打印前五行。我们还可以将最大显示列数设置为“无”:
pd.set_option('display.max_columns', None)
df = pd.read_csv("fake_job_postings.csv")
print(df.head())
为简单起见,让我们看看“描述”和“欺诈”栏:
df = df[['description', 'fraudulent']]
print(df.head())
我们的分类模型的目标在“欺诈”列中。为了了解“欺诈”值的分布和种类,我们可以使用集合模块中的“计数器”:
from collections import Counter
print(Counter(df['fraudulent'].values))
“0”值对应于正常的工作发布,“1”值对应于欺诈性发布。我们看到数据略有不平衡,这意味着正常的职位发布(17K)比欺诈性发布(866)多。
在继续之前,让我们删除“NaN”值:
df.dropna(inplace = True)
接下来,我们希望平衡我们的数据集,使“欺诈”和“非欺诈”类型的数量相等。我们还应该随机改变目标:
df_fraudulent= df[df['fraudulent'] == 1]
df_normal = df[df['fraudulent'] == 0]
df_normal = df_normal.sample(n=len(df_fraudulent))
df = df_normal.append(df_fraudulent)
df = df.sample(frac=1, random_state = 24).reset_index(drop=True)
再次验证我们得到了想要的结果:
print(Counter(df['fraudulent'].values))
接下来,我们想要格式化数据,以便它可以用作我们的 BERT 模型的输入。我们将数据分为训练集和测试集:
train_data = df.head(866)
test_data = df.tail(866)
我们生成一个包含“描述”和“欺诈”关键字的字典列表:
train_data = [{'description': description, 'fraudulent': fraudulent } for description in list(train_data['description']) for fraudulent in list(train_data['fraudulent'])]test_data = [{'description': description, 'fraudulent': fraudulent } for description in list(test_data['description']) for fraudulent in list(test_data['fraudulent'])]
从字典列表中生成元组列表:
train_texts, train_labels = list(zip(*map(lambda d: (d['description'], d['fraudulent']), train_data)))
test_texts, test_labels = list(zip(*map(lambda d: (d['description'], d['fraudulent']), test_data)))
生成令牌和令牌 id:
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased', do_lower_case=True)
train_tokens = list(map(lambda t: ['[CLS]'] + tokenizer.tokenize(t)[:511], train_texts))
test_tokens = list(map(lambda t: ['[CLS]'] + tokenizer.tokenize(t)[:511], test_texts))train_tokens_ids = list(map(tokenizer.convert_tokens_to_ids, train_tokens))
test_tokens_ids = list(map(tokenizer.convert_tokens_to_ids, test_tokens))train_tokens_ids = pad_sequences(train_tokens_ids, maxlen=512, truncating="post", padding="post", dtype="int")
test_tokens_ids = pad_sequences(test_tokens_ids, maxlen=512, truncating="post", padding="post", dtype="int")
请注意,我们将输入字符串截断为 512 个字符,因为这是 BERT 可以处理的最大令牌数。
最后,为我们的测试和训练集生成一个基于“欺诈”值的布尔数组:
train_y = np.array(train_labels) == 1
test_y = np.array(test_labels) == 1
4.模型构建
我们创建了我们的 BERT 分类器,它包含一个“初始化”方法和一个返回令牌概率的“转发”方法:
class BertBinaryClassifier(nn.Module):
def __init__(self, dropout=0.1):
super(BertBinaryClassifier, self).__init__()
self.bert = BertModel.from_pretrained('bert-base-uncased')
self.dropout = nn.Dropout(dropout)
self.linear = nn.Linear(768, 1)
self.sigmoid = nn.Sigmoid()
def forward(self, tokens, masks=None):
_, pooled_output = self.bert(tokens, attention_mask=masks, output_all_encoded_layers=False)
dropout_output = self.dropout(pooled_output)
linear_output = self.linear(dropout_output)
proba = self.sigmoid(linear_output)
return proba
接下来,我们生成训练和测试掩码:
train_masks = [[float(i > 0) for i in ii] for ii in train_tokens_ids]
test_masks = [[float(i > 0) for i in ii] for ii in test_tokens_ids]
train_masks_tensor = torch.tensor(train_masks)
test_masks_tensor = torch.tensor(test_masks)
生成用于训练和测试的令牌张量:
train_tokens_tensor = torch.tensor(train_tokens_ids)
train_y_tensor = torch.tensor(train_y.reshape(-1, 1)).float()
test_tokens_tensor = torch.tensor(test_tokens_ids)
test_y_tensor = torch.tensor(test_y.reshape(-1, 1)).float()
最后,准备我们的数据加载器:
BATCH_SIZE = 1
train_dataset = torch.utils.data.TensorDataset(train_tokens_tensor, train_masks_tensor, train_y_tensor)
train_sampler = torch.utils.data.RandomSampler(train_dataset)
train_dataloader = torch.utils.data.DataLoader(train_dataset, sampler=train_sampler, batch_size=BATCH_SIZE)test_dataset = torch.utils.data.TensorDataset(test_tokens_tensor, test_masks_tensor, test_y_tensor)
test_sampler = torch.utils.data.SequentialSampler(test_dataset)
test_dataloader = torch.utils.data.DataLoader(test_dataset, sampler=test_sampler, batch_size=BATCH_SIZE)
5.微调
我们使用 Adam 优化器来最小化二进制交叉熵损失,并且我们使用 1 个时期的批量大小 1 来训练:
BATCH_SIZE = 1
EPOCHS = 1bert_clf = BertBinaryClassifier()
optimizer = torch.optim.Adam(bert_clf.parameters(), lr=3e-6)for epoch_num in range(EPOCHS):
bert_clf.train()
train_loss = 0
for step_num, batch_data in enumerate(train_dataloader):
token_ids, masks, labels = tuple(t for t in batch_data)
probas = bert_clf(token_ids, masks)
loss_func = nn.BCELoss()
batch_loss = loss_func(probas, labels)
train_loss += batch_loss.item()
bert_clf.zero_grad()
batch_loss.backward()
optimizer.step()
print('Epoch: ', epoch_num + 1)
print("\r" + "{0}/{1} loss: {2} ".format(step_num, len(train_data) / BATCH_SIZE, train_loss / (step_num + 1)))
我们评估我们的模型:
bert_clf.eval()
bert_predicted = []
all_logits = []
with torch.no_grad():
for step_num, batch_data in enumerate(test_dataloader):token_ids, masks, labels = tuple(t for t in batch_data)logits = bert_clf(token_ids, masks)
loss_func = nn.BCELoss()
loss = loss_func(logits, labels)
numpy_logits = logits.cpu().detach().numpy()
bert_predicted += list(numpy_logits[:, 0] > 0.5)
all_logits += list(numpy_logits[:, 0])
print(classification_report(test_y, bert_predicted))
这个模型在预测真实帖子方面做得不错。预测欺诈性帖子的性能没有那么好,但可以通过增加历元数和进一步的特征工程来提高。我鼓励您尝试超参数调整和训练数据,看看是否可以提高分类性能。
总而言之,我们建立了一个 BERT 分类器来预测招聘信息是真实的还是虚假的。如果对 BERT 的其他应用感兴趣,可以阅读 假新闻分类搭配 BERT 和 俄罗斯巨魔推文:分类搭配 BERT 。如果你对伯特方法有兴趣,我鼓励你阅读 伯特拯救 *。*这篇文章的代码可以在 GitHub 上找到。感谢您的阅读!
假新世界
克里斯蒂安·格滕巴赫在 Unsplash 上拍摄的照片
几十年前,在万维网(WWW)出现之前,聊天室是一种流行的消遣方式。在那些日子里,人们意识到(自费)屏幕另一边的人可能不是他或她声称的那个人。有些情况下,人们开始一段虚拟的关系,最终发展到订婚。但其他人就没那么幸运了,在一个特殊的案例中,美国一名女子甚至试图绑架(现实生活中)她的前虚拟男友。这些故事并没有随着万维网的到来而结束,而是进入了一个全新的层次。人们现在在社交媒体网络上描绘完美的生活,其中一些人是数字世界的羡慕对象,过着香槟和喷气式飞机的生活。当然,大部分都是假的。
更糟糕的是,有些人甚至走得更远,创建虚假的个人资料。在某些情况下,这些人是无害的。对他们来说,这仅仅是一个在线游戏,一种对现实生活的逃避。但是有些情况下,这些人是掠食者,捕食最脆弱的人。有些人甚至是恋童癖!我们已经看到媒体报道的各种例子,儿童与另一个人交朋友,认为他或她是同龄人,但当他们在现实生活中遇到他们时,才发现那个人是恋童癖者。不幸的是,其中一些故事没有好的结局。
然而,如果你认为这是网上最大的谎言,你会大吃一惊。未来几年我们将经历的虚拟世界要先进得多。随着人工智能(AI)的兴起,出现了一个新的研究领域,称为合成媒体(SM)。SM 背后的想法是,人工智能可以用来生成图像、文本、语音、视频和几乎任何其他媒体。
运行中的 Nividia GauGAN 系统示例
被操纵的图像已经存在很多年了。Photoshop(用于编辑图片的最有效的程序之一)能够修改现有场景,甚至创建假场景。然而,就在去年,Nividia 宣布了 GauGAN,这是一个令人印象深刻的人工智能系统,能够将孩子们喜欢的涂鸦转换成高分辨率的照片。一条简单的带圆圈的线变成了湖边瀑布的逼真图片。当然,被篡改的照片可能会越来越多。期待看到更多朋友旅行到假的异国情调地点的照片,展示他们数字化增强的身体,同时过着他们压抑的真实生活。
对自动生成文本内容的兴趣始于 50 年代,但在最近几年,已经有了一些重大突破。
- 一个名为“Eugene Goostman”的电脑程序(给人的印象是他是一个青少年)非常接近于愚弄与他聊天的专家,以为他是一个人。
- 一个人工智能系统写了一部小说,这部小说成功通过了日本文学奖的第一轮评选。
- 微软创造了一个能够创作诗歌的诗人 AI,其中一些甚至愚弄了人类评委。
- 英国的新闻协会正在利用人工智能来选择、调整和发布新闻故事。
- 目前脸书上有 30 万个聊天机器人,当你通过脸书聊天室提出询问时,你很可能会遇到其中的一个!
但是这项技术也有它的缺点。OpenAI 刚刚发布了一个 AI 假文本生成器。它的创造者声称,这个系统非常擅长制造假新闻,以至于他们给它贴上了危险的标签。因此,预计在未来几年,新一波的假新闻和大量产生的垃圾邮件将袭击我们。
在电影《超人:钢铁之躯》中用尼古拉斯·凯奇代替艾米·亚当斯的假货
继图像和文本之后,最后的前沿是视频和语音。一项名为 Deep Fakes 的令人印象深刻的技术成功克服了这一前沿。给定一段视频和一个人的照片,它能够把演员的脸和这个人的脸互换。这项技术对电影业来说是革命性的,因为它允许电影制作人以很小的成本制作电影。默默无闻的演员可以出演一部轰动一时的电影,只是为了在最后一刻把自己的脸换成一个名人的脸。然而,这个工具也有一些危险的用途。深度假货用著名女演员盖尔·加朵(神奇女侠)的脸取代了色情电影中的色情明星的脸。在网上发布的另一段视频中,美国前总统巴拉克·奥巴马猛烈抨击唐纳德·特朗普。类似的案例不胜枚举。当然都是假视频。
在未来的几年里,预计会有更多这样的操纵。然而,人工智能算法变得如此之好,以至于要区分真实和虚构将非常困难,如果不是不可能的话。在这些情况下,我们只有一个希望,新的人工智能系统的出现能够发现这些操纵,警告我们,并让我们远离这个虚假的新世界。
请在下面留下你的想法。如果你喜欢这篇文章,请跟我来🐦推特或者🔗领英。
阿列克谢·丁力教授 是马耳他大学的 AI 教授。二十多年来,他一直在人工智能领域进行研究和工作,协助不同的公司实施人工智能解决方案。他的工作被国际专家评为世界级,并赢得了几个当地和国际奖项(如欧洲航天局、世界知识产权组织和联合国等)。他出版了几本同行评审的出版物,并且是马耳他的一部分。由马耳他政府成立的人工智能工作组,旨在使马耳他成为世界上人工智能水平最高的国家之一。
基于递归卷积神经网络的假新闻分类
马库斯·温克勒在 Unsplash 上的照片
介绍
假新闻是一个在过去几年里引起广泛关注的话题,这是有充分理由的。随着社交媒体变得普及,通过传播错误信息来影响数百万人变得更加容易。作为人类,我们经常无法识别我们读到的新闻是真是假。密执安大学的一项研究发现,人类参与者只能在 70%的时候发现假新闻。但是神经网络能做得更好吗?请继续阅读,寻找答案。
本文的目标是回答以下问题:
- 什么样的话题或关键词在真实新闻和假新闻中频繁出现?
- 如何利用深度神经网络识别假新闻故事?
导入基本库
而我下面导入的大多数库都是常用的(NumPy,Pandas,Matplotlib 等。),我还利用了以下有用的库:
- Pandarallel是一个很有帮助的库,可以并行运行对 Pandas 数据帧的操作,并实时监控每个 worker 的进度。
- Spacy是一个用于高级自然语言处理的库。它附带了英语、西班牙语和德语等语言的语言模型。在这个项目中,我安装并导入了英语语言模型 en_core_web_md.
**import numpy as np
import pandas as pd
from pandarallel import pandarallel
pandarallel.initialize(progress_bar=True, use_memory_fs=False, )
import spacy
import en_core_web_md
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline**
数据集
我在这个项目中使用的数据集包含从下面列出的多个 Kaggle 新闻数据集中选择和聚合的数据:
如下面 Pandas 代码的输出所示,数据集大约有 74,000 行,有三列:新闻文章的标题,新闻文章的文本,以及一个二进制 标签,指示新闻是真是假。
**data = pd.read_csv('./data/combined_news_data.csv')
data.dropna(inplace=True)
data.info()<class 'pandas.core.frame.DataFrame'>
Int64Index: 74012 entries, 0 to 74783
Data columns (total 3 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 title 74012 non-null object
1 text 74012 non-null object
2 label 74012 non-null int64
dtypes: int64(1), object(2)
memory usage: 2.3+ MB**
探索性数据分析
伪造和真实新闻文章的分发
如下面使用 Seaborn 生成的图所示,数据集的虚假和真实新闻文章分布大致均匀,这对于二进制分类任务来说是最佳的。
**sns.set(rc={'figure.figsize':(11.7,8.27)})
sns.countplot(data['label'])**
真假新闻文章的分发。
文章长度分布(字数)
我们还可以使用下面的代码检查新闻文章的文章长度分布,该代码创建了一个列,计算每篇文章的字数,并使用 Seaborn 的 distplot 函数显示文章长度的分布。
**data['length'] = data['text'].apply(lambda x: len(x.split(' ')))
sns.distplot(data['length'])**
字数分布。
使用 Pandas 的 describe 函数仔细查看这个分布,会产生以下输出。
**data['length'].describe()count 74012.000000
mean 549.869251
std 629.223073
min 1.000000
25% 235.000000
50% 404.000000
75% 672.000000
max 24234.000000
Name: length, dtype: float64**
平均文章长度约为 550 字,平均文章长度为 404 字。这种分布是右偏的,75%的文章字数在 672 字以下,而最长的文章显然是超过 24000 字的异常值。为了建立一个模型,我们可以通过仅使用每篇文章中的前 500 个左右的单词来确定它是否是假新闻,从而获得令人满意的结果。
数据准备
预处理文本数据
为大多数自然语言处理任务准备数据的第一步是预处理文本数据。对于这个任务,我在下面定义的预处理器函数中执行了以下预处理步骤:
- 使用正则表达式删除不需要的字符,如标点符号、HTML 标签和表情符号。
- 删除停用词(在英语中非常常见的词,通常不需要用于文本分类)。
- 词条化,这是将一个单词简化为其词条或词典形式的过程。比如跑这个词就是跑、跑和*跑这几个词的引理。*****
我使用 Python 的 regex 库从文本数据中移除不需要的字符,并使用 Spacy 的中型英语语言模型(en_core_web_md)来执行停用词移除和词汇化。为了加速这个昂贵的文本处理函数的计算过程,我使用了 Pandarallel 的 parallel_apply 函数,它在四个内核上并行执行过程。
**import re
from spacy.lang.en.stop_words import STOP_WORDS
nlp = en_core_web_md.load()
def preprocessor(text):
text = re.sub('<[^>]*>', '', text)
emoticons = re.findall('(?::|;|=)(?:-)?(?:\)|\(|D|P)', text)
text = re.sub('[\W]+', ' ', text.lower()) + ''.join(emoticons).replace('-', '')
doc = nlp(text)
text = ' '.join([token.lemma_ for token in doc if token.text not in STOP_WORDS])
return textX = data['text'].parallel_apply(preprocessor)
y = data['label']
data_processed = pd.DataFrame({'title': data['title'], 'text': X, 'label': y})**
parallel_apply 函数显示的进度条输出。
基于潜在狄利克雷分配的主题建模
在对文本数据进行预处理后,我能够使用潜在狄利克雷分配(LDA)来比较真实和虚假新闻文章中的主题和最重要的术语。LDA 是一种基于以下假设的无监督主题建模技术:
- 每个文档(在本例中是每篇新闻文章)都是一个由单词组成的包,这意味着在提取主题时不考虑文档中单词的顺序。**
- 每个文档都有一个主题分布,每个主题都由词的分布来定义。
- 所有文档中都有 k 主题。参数 k 是为算法预先指定的。
- 包含属于特定主题的单词的文档的概率可以建模为狄利克雷分布。
在其最简单的形式中,LDA 算法对文档集合中的每个文档 D 遵循以下步骤:
- 通过根据狄利克雷分布给每个单词分配一个主题,在文档 D 中分配每个 k 主题。
- 对于 D 中的每个单词,假设它的主题是错误的,但是每隔一个单词被分配正确的主题。
- 根据以下因素为该单词分配属于每个主题的概率:
-文档中的主题 D
- 该单词在所有文档中被分配给每个主题的次数。 - 对所有文档重复步骤 1-4。
关于 LDA 更详细但更容易理解的概述,请查看埃德温·陈的博客中的页面。
我使用 Scikit-learn 的 LDA 模块来执行主题建模,并使用一个名为 pyLDAvis 的有用的 Python 库来创建真实和虚假新闻的主题模型的交互式可视化。下面给出了这项任务所需的导入。
**from sklearn.decomposition import LatentDirichletAllocation
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.manifold import TSNE
from sklearn.pipeline import Pipeline
import pyLDAvis.sklearn**
真正的新闻
下面给出的代码使用 pyLDAvis 对经过预处理的具有十个不同主题的真实新闻文章执行主题建模,然后创建一个交互式可视化,在二维空间中显示每个主题。
**real_news = data_processed[data_processed['label'] == 1]
num_topics = 10
num_features=5000
vectorizer = CountVectorizer(max_df=0.95, min_df=2, max_features=num_features, stop_words='english')
lda = LatentDirichletAllocation(n_components=num_topics,
max_iter=5,
learning_method='online',
learning_offset=50.,
random_state=0)
lda_pipeline = Pipeline([('vectorizer', vectorizer), ('lda', lda)])
lda_pipeline.fit(real_news['text'])pyLDAvis.enable_notebook()
data_vectorized = vectorizer.fit_transform(data_processed['text'])
dash = pyLDAvis.sklearn.prepare(lda_pipeline.steps[1][1], data_vectorized, vectorizer, mds='tsne')pyLDAvis.save_html(dash, 'real_news_lda.html')**
真实新闻数据的 LDA 可视化。
真实新闻数据中最大话题的热门术语。
上面的可视化允许用户查看十个提取主题中每个主题的相对大小,同时显示每个主题的最相关术语。你可以点击查看完整的交互式可视化。
假新闻
下面给出的代码复制了前面假新闻文章的步骤,以产生类似的交互式可视化效果。
**fake_news = data_processed[data_processed['label'] == 0]
num_topics = 10
num_features=5000
vectorizer = CountVectorizer(max_df=0.95, min_df=2, max_features=num_features, stop_words='english')
lda = LatentDirichletAllocation(n_components=num_topics,
max_iter=5,
learning_method='online',
learning_offset=50.,
random_state=0)
lda_pipeline = Pipeline([('vectorizer', vectorizer), ('lda', lda)])
lda_pipeline.fit(fake_news['text'])
pyLDAvis.enable_notebook()
data_vectorized = vectorizer.fit_transform(data_processed['text'])
dash = pyLDAvis.sklearn.prepare(lda_pipeline.steps[1][1], data_vectorized, vectorizer, mds='tsne')pyLDAvis.save_html(dash, 'fake_news_lda.html')**
假新闻数据的 LDA 可视化。
假新闻数据中最大话题的热门词汇。
你可以在这里查看完整的互动可视化。基于真实和虚假新闻的主题模型可视化,很明显,与真实新闻相比,虚假新闻通常涉及不同的主题。基于可视化和一些话题关键词,如叛国、违规、可悲、狂奔、和暴力,假新闻似乎一般涵盖更具争议性的话题,如所谓的政治丑闻和阴谋论。****
定义和训练模型
我为这个任务设计的深度学习模型是一个递归卷积神经网络模型,由几种不同类型的顺序操作和层组成:
- 标记器用于将每篇文章转换成索引单词(标记)的向量。
- 单词嵌入层,其为每个唯一单词学习具有 m 维的嵌入向量,并将该嵌入应用于每个新闻文章中的前 n 个单词,生成 m x n 矩阵。
- 1D 卷积和最大池层。
- LSTM 层,然后是辍学层。
- 最终完全连接的层。
这些组件将在下面更详细地解释。
分词器
标记器用于将每篇新闻文章分割成一个连续单词的向量,随后通过为每个单词分配一个唯一的整数索引,将该向量转换成整数向量。下图用一个简单的句子演示了这个过程。
由记号赋予器执行的步骤。(图片由作者提供)
字嵌入图层
单词嵌入是单词的可学习矢量表示,表示单词相对于其他单词的意思。深度学习方法可以从文本集合中学习单词嵌入,使得具有相似嵌入向量的单词倾向于具有相似的含义或表示相似的概念。
一个句子的单词嵌入,每个单词有 5 维向量。(图片由作者提供)
1D 卷积和最大池层
这些组件是递归卷积神经网络的卷积部分。如果你学过计算机视觉,你可能熟悉 2D 卷积和池层的图像数据操作。然而,对于文本数据,我们需要使用 1D 卷积和池层。1D 卷积层具有一系列内核,这些内核是低维向量,在计算点积以产生输出向量时,这些内核会在输入向量上递增滑动。在下面的例子中,具有大小为 2 的核的 1D 卷积运算被应用于具有 5 个元素的输入向量。**
1D 卷积运算的例子。(图片由作者提供)
与 1D 卷积层一样,1D 最大池层也对向量进行操作,但通过从输入的局部区域中选择最大值来减小输入的大小。在下面的示例中,池大小为 2 的 max-pooling 操作应用于具有 6 个元素的 vector。
池大小为 2 的 1D 最大池操作示例。(图片由作者提供)
LSTMs
LSTM(长短期记忆)单元形成递归卷积神经网络的递归部分。LSTMs 通常用于涉及序列数据的任务,例如时间序列预测和文本分类。我不会深入探究 LSTMs 背后的数学背景,因为该主题超出了本文的范围,但本质上,LSTM 是神经网络中的一个单元,能够长时间记住重要信息,并在不再相关时忘记信息(因此得名,长短期记忆)。一个 LSTM 单元由三个门组成:**
- 接收输入值的输入门。
- 一个遗忘门,它决定在培训期间获得的过去信息中有多少应该被记住。
- 产生输出值的输出门。
LSTM 单位图。(图片由作者提供)
LSTMs 选择性记忆信息的能力在诸如假新闻分类的文本分类问题中是有用的,因为新闻文章开头的信息可能仍然与文章中间或接近结尾的内容相关。
全连通层
这个模型的最后一部分只是一个完全连接的层,你可以在一个“香草”神经网络中找到。该层接收来自最后一个 LSTM 层的输出,并计算向量值的加权和,对该和应用 sigmoid 激活以产生最终输出-0 和 1 之间的值,对应于文章是真实新闻的概率。
综合考虑
我在下面创建的类是为定制和封装一个包含上述所有组件的模型而设计的。此类表示一个管道,它可以直接适合预处理的文本数据,而不必事先执行标记化和单词索引等步骤。LSTM _ 文本 _ 分类器类扩展了 Scikit-learn 中的 BaseEstimator 和 ClassifierMixin 类,使其行为类似于 Scikit-learn 估计器。
使用这个类,我在下面的代码中创建了一个包含以下组件的模型:
- 一个单词嵌入层,它为每个单词学习一个 64 维嵌入向量,并从新闻文章的前 512 个单词中聚合这些向量,为每个输入文章生成一个512×64 嵌入矩阵。
- 三个卷积层,具有 128 个卷积滤波器和内核大小为 5 ,每个卷积层之后是最大池层。****
- 具有 128 个神经元的两个 LSTM 层,每个层之后是退出层,退出率为10%。****
- 网络末端的全连接层**,带有 sigmoid 激活,输出从 0 到 1 的单个值,指示文章成为真实新闻的**概率。****
lstm_classifier = LSTM_Text_Classifier(embedding_vector_length=64, max_seq_length=512, dropout=0.1, lstm_layers=[128, 128], batch_size=256, num_epochs=5, use_hash=False,
conv_params={'filters': 128,
'kernel_size': 5,
'pool_size': 2,
'n_layers': 3})
下面的可视化让我们很好地了解了这个递归卷积网络的模型架构。
具有单词嵌入层的递归卷积神经网络结构。(图片由作者提供)
培训、验证和测试分离
为了有效地评估此模型的性能,有必要将数据分成单独的训练集、验证集和测试集。根据下面的代码,30%的数据用于测试,剩下的 70%14%(70 的 20%)用于验证,剩下的56%用于训练**。**
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
X_train, X_valid, y_train, y_valid = train_test_split(X_train, y_train, test_size=0.2, random_state=42)
模特培训
在定义了这个复杂的模型之后,我能够在训练集上训练它,同时在验证集上监控它的性能。该模型经过三个时期的训练,并在第二个训练时期结束时根据下面的代码和输出达到其峰值验证性能。
lstm_classifier.fit(X_train, y_train, validation_data=(X_valid, y_valid))Fitting Tokenizer...
Model: "sequential_4"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
embedding_4 (Embedding) (None, 512, 64) 13169920
_________________________________________________________________
conv1d_10 (Conv1D) (None, 512, 256) 82176
_________________________________________________________________
max_pooling1d_10 (MaxPooling (None, 256, 256) 0
_________________________________________________________________
conv1d_11 (Conv1D) (None, 256, 512) 655872
_________________________________________________________________
max_pooling1d_11 (MaxPooling (None, 128, 512) 0
_________________________________________________________________
conv1d_12 (Conv1D) (None, 128, 768) 1966848
_________________________________________________________________
max_pooling1d_12 (MaxPooling (None, 64, 768) 0
_________________________________________________________________
lstm_7 (LSTM) (None, 64, 128) 459264
_________________________________________________________________
dropout_7 (Dropout) (None, 64, 128) 0
_________________________________________________________________
lstm_8 (LSTM) (None, 128) 131584
_________________________________________________________________
dropout_8 (Dropout) (None, 128) 0
_________________________________________________________________
dense_4 (Dense) (None, 1) 129
=================================================================
Total params: 16,465,793
Trainable params: 16,465,793
Non-trainable params: 0
_________________________________________________________________
None
Fitting model...
Train on 41446 samples, validate on 10362 samples
Epoch 1/5
41446/41446 [==============================] - 43s 1ms/step - loss: 0.2858 - accuracy: 0.8648 - val_loss: 0.1433 - val_accuracy: 0.9505
Epoch 2/5
41446/41446 [==============================] - 42s 1ms/step - loss: 0.0806 - accuracy: 0.9715 - val_loss: 0.1192 - val_accuracy: 0.9543
Epoch 3/5
41446/41446 [==============================] - 43s 1ms/step - loss: 0.0381 - accuracy: 0.9881 - val_loss: 0.1470 - val_accuracy: 0.9527
Epoch 00003: early stopping
验证结果
虽然准确度是分类的有用度量,但它不能告诉我们该模型在检测每个类别方面表现如何。下面提供的代码为验证数据集上的模型预测计算了混淆矩阵和分类报告**,以更好地描述模型的性能。混淆矩阵以下列格式提供分类统计数据:**
如何解读一个混淆矩阵?(图片由作者提供)
每个类别的分类报告提供了以下附加指标:
- 精度-类被正确预测的次数除以模型预测该类的总次数。
- 召回—正确预测类别的次数除以测试数据中带有该类别标签的样本总数。
- F1 分数——精确度和召回率的调和平均值。
lstm_classifier.load_model('best_model')from sklearn.metrics import confusion_matrix, classification_report
y_pred = lstm_classifier.predict_classes(X_valid)
print(confusion_matrix(y_valid, y_pred))
print(classification_report(y_valid, y_pred, digits=4))[[4910 204]
[ 271 4977]]
precision recall f1-score support
0 0.9477 0.9601 0.9539 5114
1 0.9606 0.9484 0.9545 5248
accuracy 0.9542 10362
macro avg 0.9542 0.9542 0.9542 10362
weighted avg 0.9542 0.9542 0.9542 10362
基于上述结果,我们可以清楚地看到,该模型在正确检测假新闻方面几乎与正确检测真实新闻一样好,并在验证数据上实现了 95.42%的总体准确率**,这是非常令人印象深刻的。根据混淆矩阵,只有 271 篇文章被误归类为假新闻和只有 204 篇文章被误归类为真新闻。**
测试结果
虽然验证结果可以为我们提供模型在看不见的数据上的性能的一些指示,但是在模型训练过程中根本没有触及的测试集提供了模型性能的最佳客观和统计上正确的度量。下面的代码为测试集生成一个分类报告。
from sklearn.metrics import accuracy_score
y_pred_test = lstm_classifier.predict_classes(X_test)
print(classification_report(y_test, y_pred_test)) precision recall f1-score support
0 0.94 0.95 0.95 11143
1 0.95 0.94 0.95 11061
accuracy 0.95 22204
macro avg 0.95 0.95 0.95 22204
weighted avg 0.95 0.95 0.95 22204
基于上面的输出,该模型在测试集上实现了与其在验证集上的性能相似的性能水平。该模型以 95%的准确率对测试集中的新闻文章进行分类。与人类只能在 70%的时间里发现假新闻的研究相比,这些结果是有希望的,并证明了一个经过训练的神经网络可能比人类读者在过滤假新闻方面做得更好。
结论
- 基于 LDA 可视化,我们可以看到真实和虚假新闻的主题和相关关键词有不同的分布。
- 这个项目中使用的递归卷积神经网络能够在测试数据上以 95%的准确率区分真实和虚假的新闻文章,这表明神经网络可能比人类读者更好地检测假新闻。
您可以在 GitHub 上查看 Jupyter 笔记本和本文的代码。
来源
- 动词 (verb 的缩写)佩雷斯-罗萨斯,b .克莱因伯格,a .勒费夫尔,r .米哈尔恰,假新闻自动检测 , (2018),arXiv.org
- A.Bharadwaj,B. Ashar,P. Barbhaya,R. Bhatia,Z. Shaikh,利用机器学习进行基于来源的假新闻分类,(2020),《国际科学、工程和技术创新研究杂志》
假新闻分类器,以解决新冠肺炎造谣-我
努力解决当今世界面临的最紧迫的问题之一,假新闻
(图片由作者提供)
简介
冠状病毒(新冠肺炎)是一种导致持续疫情的传染病。中国武汉首次发现该病,2019 年 12 月发现首例。截至 2020 年 8 月 21 日,180 个国家和地区报告了超过 2200 万例病例。这个疫情的庞大规模给当代人带来了无数的问题。我遇到的一个严重问题是虚假新闻文章的传播,在当今世界,虚假新闻文章会引起恐慌和大规模歇斯底里。我意识到这个问题的严重性,并决定将我的下一个机器学习项目建立在解决这个问题的基础上。
问题陈述
开发一个假新闻分类器,将一篇关于新冠肺炎的新闻文章恰当地分类为真新闻或假新闻。
工作流程
在开始这个项目之前,我必须搜索包含与新冠肺炎相关的新闻文章列表的数据集。这是一个挑战,因为没有很多记录新冠肺炎新闻文章的数据集。在网上搜索了几天后,我终于找到了一个数据集,里面有与新冠肺炎相关的新闻文章。现在需要的唯一任务是清理数据,在其上拟合合适的机器学习模型,并评估模型的性能。
数据探索和数据工程
步骤 1:检查缺失值。
我通过研究数据和寻找其中缺失的值来开始这个项目。数据集中的每一列都有一些缺失值,但最重要的是,“标签”列有 5 个缺失值。幸运的是,我下载数据集的来源有丢失标签的值,这帮助我从“标签”列中消除了丢失的值。至于其他列,即“标题”、“源”和“文本”,缺少的值被替换为空字符串。
步骤 2:在“标签”栏中寻找不一致的地方。
在处理完丢失的数据后,我想到检查目标标签来寻找可能存在的任何不一致之处。在探索了“标签”一栏后,我发现了两个不同的假标签,同样的可以在下图中看到。发现这个异常后,我决定给假新闻换个标签。最终的标签可以在下面给出的第二张图片中看到。
标签在前面(左)和后面(右)。(图片由作者提供)
步骤 3:合并标题和文本列。
一旦最终确定了目标标签,我就将注意力转向了我将用于分类项目的数据。我决定使用“标题”和“文本”列,因为它们拥有与新冠肺炎最相关的信息。因此,我将这两列合并为一列,并将其命名为“Total”。
第 4 步:删除数据中的标点符号,并将其转换为小写。
“从第 4 步开始,我执行的所有操作都将出现在 总计 列中。”
将我们收集的原始数据直接发送给机器学习算法是不可取的。在此之前,我们需要实施一些预处理步骤,以使数据对于机器学习算法来说是可解释的。因此,我首先使用 Regex 删除数据中的标点符号,然后将数据转换成小写。在对数据进行预处理后,可以在下图中看到“总计”列的第一行。
(图片由作者提供)
步骤 5:将数据分为训练数据和测试数据。
当我清理完数据后,我决定将数据分成一个训练集和一个测试集。我决定将“标签”列分配给一个新变量 y ,并从我的数据框中删除标签列。接下来,我使用 train_test_split 函数来拆分数据。我将 80%的数据分配给训练集,20%分配给测试集。
第六步:在 X_train 和 X_test 上实现 Tf-Idf。
我们目前在 X_train 和 X_test 中拥有的数据仍然需要转换成机器学习算法可以解释的格式,因为这些算法不能很好地处理文本数据。因此,我们需要将它转换成一种形式,使算法能够从数据中辨别模式和有意义的见解。为了实现这一点,我实现了 Tf-Idf。
Tf-Idf,又称词频-逆文档频率。它为我们提供了一种将文档中的每个单词与一个数字相关联的方法,该数字表示每个单词在该文档中的相关程度。使用 Tf-Idf,不是通过术语的原始频率(出现次数)或相对频率(术语计数除以文档长度)来表示文档中的术语,而是通过将术语频率除以包含该单词的语料库中的文档数量来对每个术语进行加权。这种加权方案的总体效果是避免了进行文本分析时的一个常见问题:文档中最频繁使用的单词通常是所有文档中最频繁使用的单词。相反,具有最高 Tf-Idf 分数的术语是当该文档与其他文档相比较时,在该文档中明显频繁出现的术语。
我使用 sklearn 库中的 TfidfVectorizer 将我的文本转换成一个稀疏矩阵。这个矩阵表示我的训练和测试数据中出现的所有单词的 Tf-Idf 值。现在,训练和测试数据由变量 tfidf_train 和 tfidf_test 表示。
因为我现在已经准备好了实现机器学习算法的数据,所以我移动到下一步,这包括在训练数据上拟合我的机器学习算法。
对训练数据拟合机器学习模型并评估模型性能。
步骤 1:选择分类算法,并根据训练数据拟合模型。
我选择支持向量机(SVM)作为我项目的分类算法。此外,我使用线性核来训练我的模型。我选择线性核的 SVM 的原因是,当有很多特性时,线性核工作得很好。此外,大多数文本分类任务是线性可分的。此外,将数据映射到高维空间并不一定会提高模型性能。最后,用线性核训练 SVM 比用其他核要快。因此,我决定与 SVM 合作我的项目。
我从 sklearn 库中导入了 SVM 分类器,并在我的训练数据(即 tfidf_train)上拟合模型。训练部分一完成,我就进入下一步,即评估模型性能。
步骤 2:使用测试数据评估模型性能。
训练部分完成后,我使用测试数据(即 tfidf_test)来预测测试集中出现的新闻文章的标签。我计算出模型的准确率为 94.4%。
(图片由作者提供)
结论
以下关于新冠肺炎的机器学习项目对我来说是一次激动人心的经历。我了解了自然语言处理领域,并且能够理解在我们可以对文本数据实施机器学习算法之前需要的各种数据预处理步骤。我学到了两个新的主要概念,术语频率-逆文档频率和支持向量机。
下一步是将这个项目转换成一个完全响应的 web 应用程序。我的目标是开发前端使用 HTML 和 CSS,而训练有素的 SVM 分类器将作为后端。最后,为了确保前端和后端之间的无缝交互,我将使用 Flask 框架。在 Heroku 云平台上部署 SVM 分类器所需的所有步骤的详细介绍可以在本博客的第二部分中找到。一定要看看那个。
我为这个项目遵循的工作流程可以在我的Github页面找到。我希望你喜欢看我的博客。
基于深度学习方法的假新闻检测器(上)
文本数据的探索性数据分析
在这一系列文章中,我将展示我们如何使用深度学习算法来检测假新闻,并比较一些神经网络架构。
这是这个系列的第一部分,在这里我想对文本进行探索性的数据分析。
unsplash.com
假新闻的话题和新闻业本身一样古老——错误信息、恶作剧、宣传和讽刺早就存在了。所以假新闻是无法核实、没有来源、可能不真实的信息。
维基还说:“假新闻的撰写和发布通常是为了误导,以损害某个机构、实体或个人,和/或在经济上或政治上获利,通常使用耸人听闻的,不诚实的,或完全捏造的标题来增加读者群。同样, clickbait 故事和头条也从这项活动中获得广告收入。”
假新闻破坏了严肃的媒体报道,使记者更难报道重大新闻。BuzzFeed 的一项分析发现,关于 2016 年美国总统大选的 20 大假新闻报道在脸书的关注度超过了 19 家主要媒体的 20 大选举报道。缺乏知名出版商的匿名托管假新闻网站也受到了批评,因为它们很难以诽谤罪起诉假新闻来源。
在 21 世纪,假新闻的影响变得广泛!随着时间的推移,互联网已经发展到难以想象的高度,大量的信息不断涌入,这使得互联网成为大量不需要的、不真实的和误导性的信息的宿主,这些信息可以由任何人制作。假新闻已经从通过电子邮件发送发展到攻击社交媒体。除了指旨在欺骗读者点击链接、最大化流量和利润的编造故事外,该术语还指讽刺新闻,其目的不是误导,而是告知观众并分享关于真实新闻和主流媒体的幽默评论。所以问题很大。让我们尝试用深度学习的方法来检测假新闻。
对于我的训练数据集,我想采用 Kaggle 竞赛开放数据集。我们来为它做一个简单的探索性数据分析。
列车数据的报头
我们有以下几列:
- id:新闻文章的唯一 id
- 标题:新闻文章的标题
- 作者:新闻文章的作者
- 正文:文章的正文;可能不完整
- 标签:将文章标记为潜在不可靠的标签
1:不可靠
0:可靠
在我的 EDA 中,我想分析标题、文本和标签列**。**
第一步,我想知道我的班级分布。
阶级平衡
正如我们看到的,数据集中的类是平衡的。
接下来就是分析标题和正文栏目中的一组假新闻和非假新闻。文本统计可视化是简单但非常有洞察力的技术。
首先,我将通过标签查看每个标题和 new 文本中的字符数。这可以让我们大致了解新闻标题的长度。
每个标题中出现的字符数
我对新的文本做了同样的分析。
每个新文本中出现的字符数
主要见解是,新闻标题和未经预处理的文本在假新闻中比在非假新闻中更短。
现在,我将转到单词级别的数据探索。让我们根据标签来画出每篇新闻标题和正文中出现的字数。
每篇新闻标题中出现的字数
我对新的文本做了同样的分析。
出现在每个新闻文本中的字数
主要见解是,新闻标题和未经预处理的文本在假新闻中比在非假新闻中更短。
无停用词的词频
下一步是没有停用词的分析。停用词是任何语言中最常用的词,如“the”、“a”、“an”等。由于这些单词的长度可能很小,这些单词可能会导致上图向左倾斜。要获得包含停用词的语料库,可以使用 nltk 库。Nltk 包含许多语言的停用词。因为我们只处理英语新闻,所以我将从语料库中过滤掉英语停用词。
标题语料库分析
我对新的文本做了同样的分析。
新闻文本语料库分析
假新闻和非假新闻的标题和正文语料不同,词序也不同。
Ngram 分析
下一步是 Ngram 分析。n 元语法就是 n 个单词的连续序列。例如《河岸》、《三个火枪手》等。如果字数为二,则称之为 bigram。对于 3 个单词,它被称为三元模型等等。
查看最常见的 n 元语法可以让你更好地理解这个单词的上下文。为了构建我们的词汇表,我们将使用 Countvectorizer。Countvectorizer 是一种简单的方法,用于以适当的形式标记、矢量化和表示语料库。
新闻标题 Ngram 分析
我对新的文本做了同样的分析。
New 的文本 Ngram 分析
在这里我们可以看到,假新闻中的文字和标题是不同的,但不是假新闻是相同的。
皱胃向左移
我们来做个话题建模,对比一下假新闻和不假新闻。主题建模是使用无监督学习技术提取文档集合中出现的主要主题的过程。
潜在狄利克雷分配(LDA)是一种易于使用且高效的主题建模模型。每个文档由主题的分布来表示,每个主题由词的分布来表示。
一旦我们按主题对文档进行分类,我们就可以对每个主题或主题组进行进一步的数据探索。
第一个分析是 LDA 对于假新闻标题和非假新闻标题的分析。让我们来看看主题:
假新闻标题的 LDA
我们也可以用 python 中的库 pyLDAvis 来分析:
用于假新闻标题可视化的 LDA(主题-1)
让我们为假新闻标题做同样的事情。
LDA 为不假冒新闻的标题
用于非伪造新闻标题可视化的 LDA(主题-1)
我们可以看到,假新闻标题和非假新闻标题的主题建模是不同的。
让我们对新的文本做同样的分析。
以下是针对假新闻的文本 EDA:
LDA 为假新闻的文本
用于假新闻的文本可视化的 LDA(主题-1)
同样的分析也适用于非假新闻:
LDA for not fake new 的文本
用于非伪造新闻的文本可视化的 LDA(主题-1)
研究结果显示,假新闻和非假新闻的话题是不同的,并且进一步发现假新闻的话题标题和正文是不同的。
我对文本的探索性数据分析的最后一个阶段是词云分析。Wordcloud 是一种表现文本数据的好方法。出现在单词云中的每个单词的大小和颜色表明了它的频率或重要性。用 python 创建单词云很容易,但我们需要语料库形式的数据。幸运的是,我在上一节中准备了它。
下面是 new 标题的词云分析:
新闻文本的词云分析
以及对新闻文本进行对比词云分析:
新闻文本的词云分析
在结果中,我们可以看到在新闻的标题和文字中使用的一些词有多频繁,无论是假的还是假的。
结论
文本探索性数据分析的结果是比较虚假新闻和非虚假新闻的不同技术。通过这种方法,我们可以创建自己的规则来检测伪造。这种方式难度相当大,需要大量的常规工作。此外,在此示例中,我们可以看到,充满关于美国选举新闻的数据集以及这些数据将难以检测假新闻中的一些一般规则和风格。
让我们给深度学习方法一个机会,让它自动完成。这些故事的下一部分再见。
第二部分你可以阅读——“深度学习方法假新闻检测器(第二部分)建模”
第二部分您可以阅读—“采用深度学习方法的假新闻检测器(第三部分)部署”
你能在 Git 仓库中找到的所有代码— 链接。
基于深度学习方法(第二部分)建模的假新闻检测器
创建用于假新闻检测的深度学习神经网络。
在这一系列文章中,我将展示我们如何使用深度学习算法来检测假新闻,并比较一些神经网络架构。
这是这个系列的第二部分,我想用 Keras 和 Tensorflow 创建几个深度学习模型。在本系列的前部分,我对假新闻和非假新闻做了探索性的数据分析。我用不同的分析技术来比较假的和非假的新闻,让我们把这项工作交给神经网络吧。
要开始建模,我们需要进行数据预处理。让我们检查列车数据框中的 NA 值:
NA 数据检查
正如我们所看到的,我们的数据集中有很多 NA 值。在我的模型中,我计划只使用标题和文本列。为了解决 NA 值问题,我决定用文本替换标题中的 NA 值,反之亦然。这种方法帮助我为训练保存更多的数据。
NA 替换结果
因此,我的火车专栏里没有任何 NA。
下一步是文本预处理。我想进行与我在 EDA 中相同的预处理步骤:
- 替换标点符号;
- 小写字母盘
- 按单词拆分
- 堵塞物
- 删除停用词
接下来的步骤是一个热词表示和序列创建,对于标题列,最大句子长度为 20,对于文本列,最大句子长度为 100。这一步对于创建正确形式的数据集以用于神经网络非常重要。
我的第一个模型将只用于带有二进制目标假/假的标题列。
标题模型的模型拱门
第一层是嵌入。单词嵌入是对文本的学习表示,其中具有相同含义的单词具有相似的表示。单词嵌入实际上是一类技术,其中单个单词被表示为预定义向量空间中的实值向量。每个单词都被映射到一个向量,向量值以类似神经网络的方式学习,因此该技术通常被归入深度学习领域。这种方法的关键是对每个单词使用密集分布的表示法。
每个单词用一个实值向量来表示,往往是几十维或者几百维。这与稀疏单词表示所需的数千或数百万维形成对比,例如一键编码。
分布式表示是基于单词的使用来学习的。这允许以相似方式使用的单词产生相似的表示,自然地捕捉它们的意思。这与单词包模型中清晰但脆弱的表示形成对比,在单词包模型中,除非明确管理,否则不同的单词具有不同的表示,不管它们如何使用。
Keras 提供了一个嵌入层,可用于文本数据上的神经网络。
它要求输入数据是整数编码的,因此每个字都由一个唯一的整数表示。嵌入层用随机权重初始化,并将学习训练数据集中所有单词的嵌入。
第二层是 LSTM。这一层的主要概念是:
- 它使用顺序信息。
- 它有一个记忆,可以记录到目前为止已经计算过的内容。
我说过我们试图解决二进制分类问题,所以:
- 我们输入每个单词,单词在某些方面相互关联。
- 当我们看到那篇文章中的所有单词时,我们在标题/正文的末尾进行预测。
- rnn 从最后一个输出绕过输入,能够保留信息,并能够在最后利用所有信息进行预测。
https://colah.github.io/posts/2015-08-Understanding-LSTMs/
我的网络的输出是用于二进制分类的具有 1 个输出 sigmoid 激活函数的密集层。为了编译我的模型,我使用二进制交叉熵作为损失函数和准确性度量。对于优化器,我像往常一样使用 Adam。
让我们运行模型并检查结果:
模型训练过程
正如我们所见,该模型有点过度拟合,这在ащк LSTM 架构和 LSTM 层中非常常见。为了避免这种情况,我们可以使用脱落层。我想在 Kaggle 排行榜上查看我的成绩。比赛已经结束,但我可以查看我的结果。
我的第一次提交
让我们创建相同的模型(仅将最大句子长度更改为 1000,并将嵌入向量特征更改为 100),但仅针对文本列,并查看结果。
模型训练过程
这个结果还算不错,但比仅仅是冠名的车型还要糟糕。为了增加这些结果,我可以增加这个(文本)数据的历元数,或者稍微改变一下我的架构。
文本模型第二版的模型拱门
如您所见,我添加了 GlobalMaxPool1D 来对输入制图表达进行缩减采样,添加了密集图层来生成更多要素,添加了 Dropout 来避免模型过度拟合。
GlobalMaxPool1D 的工作原理:
- 通过获取时间维度上的最大值对输入制图表达进行缩减采样。
- 全局最大池=池大小等于输入大小的普通最大池层(精确地说,减去过滤器大小+ 1)。
- 全局池层可用于多种情况。首先,它可用于降低某些卷积层输出的特征图的维度,以取代分类器中的平坦层,有时甚至是致密层(Christlein 等人,2019)。此外,它还可以用于例如单词识别(Sudholt & Fink,2016)。这是由于它允许检测噪声,从而“大输出”(例如上面例子中的值 9)。然而,这也是全局最大池的缺点之一,和常规一样,我们接下来将讨论全局平均池。
或者换个角度来看:
让我们开始训练:
模型训练过程
该模型比前一个版本执行得更好,但对我来说,我们需要更多的纪元才能获得更好的结果。让我们在 Kaggle 上检查一下这个模型:
我的第二次提交
我可以将精度提高到与以前的模型相同的水平,但让我们想象一下,我们需要一个好的模型,它将在 10 个时期内给出好的结果。所以我创造了第四个模型:
多输入模型 arch
在这里,您可以看到,我创建了一个多输入模型,将两个以前的架构合并为一个。我使用的函数式 API 是一种创建模型的方法,比 tf.keras.Sequential API 更灵活。功能 API 可以处理具有非线性拓扑的模型、具有共享层的模型以及具有多个输入或输出的模型。使用这种架构,我可以从以前的两种架构中为两个独立的功能获得最好的东西,并将其合并到一个模型中。
好吧,让我们来看看训练结果:
模型训练过程
是之前所有车型的最好成绩。让我们在 Kaggle 上检查一下。
我的第三次提交
所以,结果看起来很棒。这将是这场激烈竞争中的第三名。
结论
作为这个分析的结果,我们可以看到不同的数据量(标题/正文),不同的神经网络架构带来不同的结果。有时,最好将两个模型合并为一个,而不是试图调整其中一个。
在这些故事的第三部分,我将尝试部署这个模型,并为假新闻检测建立实时管道。
您可以阅读的第一部分—“采用深度学习方法的假新闻检测器(第一部分)EDA ”
你能在 Git 仓库中找到的所有代码— 链接。
附言
所有建模都通过 Azure Data Science 虚拟机进行了训练和评分:
- NC12 型(2 个 NVIDIA K80)