ChatGPT 代码解释器 让人人都是数据分析师
OpenAI终于开放Code Interpreter给所有Plus用户使用了,这是一个天大的好消息,我迫不及待就开始了测试,测试结果也是喜出望外。由于Python代码的加持,能发挥Code Interpreter最大能力的领域就是数据分析了。普通的Excel数据分析根本不在话下,专业的数据分析也可以通过跟ChatGPT对话来进行,彻底改变了数据分析的方式。
为了充分展示Code Interpreter的能力,我特地从Kaggle上找了一个数据集,并交给它一系列从简单的数据分析并生成图表到复杂的机器学习建模任务,由浅入深的探索了Code Interpreter的能力。
不管你日常使用Excel进行数据分析,还是用Python代码,都能从这个案例知道如何使用Code Interpreter以及它的能力。
这个数据集是关于奈飞 (Netflix) 8000多部电影和电视的数据,包括导演,演员,评级,发布时间,观看时间,节目类型,节目描述等数据。
我会首先介绍如何安装Code Interpreter,然后一步步让它完成从简单到复杂的数据分析任务。最后,我对Code Interpreter对数据分析领域的影响和它本身的限制做了一个总结。
如何安装Code Interpreter
目前ChatGPT的代码解释器 (Code Interpreter)的使用前提是要有ChatGPT Plus账号。登录ChatGPT以后,点击左下角用户名右边的三个点形状的按钮,打开ChatGPT的设置窗口。
在新打开的窗口中,点击左侧的”Beta features”,然后把右侧下方的Code interpreter切换到打开状态。
关闭窗口,把鼠标悬停在ChatGPT主界面上方的”GPT-4″按钮上,然后在弹出的下拉菜单里选择”Code interpreter”。
这样我们就成功激活了Code interpreter。
数据清理和预处理
ChatGPT的一个缺陷是无法直接上传文件,必须要通过网页连接或者第三方插件才能读取文件。然而有了代码解释器 (Code Interpreter),你可以直接上传数据文件了。
它支持512M以内的文件上传,并且上传前还可以解压缩。这个大小对于数据分析来说很足够了,你可以上传一个几百万行的csv文件。
激活了Code Interpreter以后,聊天输入框内的左边会出现一个加号,点击它就可以打开本地电脑的文件浏览器了。
我直接把从Kaggle上下载的解压包上传,省的再解压缩了。
上传以后,我就直接开始给它任务了:
作为一个专业的数据分析员,请遵循标准的数据分析程序。让我们一步一步来。
ChatGPT在进行初步的数据分析之后,给出的回复是这样的:
很好,让我们开始数据分析过程。以下是我们通常遵循的步骤:
- 数据收集:在这种情况下,你已经提供了一个数据集。
- 数据处理:这包括数据清理,处理缺失值,以及其他必要的转换。
- 探索性数据分析(EDA):这包括通过统计和可视化来了解数据的特征。
- 建模(如有必要):根据分析的目标,我们可能建立统计或机器学习模型。
- 解释:最后,我们解释结果并作出结论或建议。
让我们从第一步开始。你提供了一个名为
archive.zip
的文件,所以让我们提取它并检查其内容,以更好地了解数据集。
archive.zip
文件包含一个CSV文件,名为netflix_titles.csv
。这似乎是一个关于Netflix标题的数据集。让我们继续进行数据分析过程的下一步,即数据处理。我们将阅读CSV文件,看看前几行,以了解它的结构和它所包含的数据类型。
该数据集包含以下几列:
show_id
: 每个节目的唯一标识符。type
: 节目的格式(电影或电视节目)。title
: 该节目的标题。director
: 该节目的导演。cast
: 参与演出的演员。country
: 制作该节目的国家。date_added
: 该节目被添加到Netflix的日期。release_year
: 该节目最初发布的年份。rating
: 该节目的评级。duration
: 该节目的持续时间。listed_in
: 该节目的类型。description
: 对该节目的简短描述。在我们进一步进行分析之前,检查数据是否有缺失值或需要处理的不一致之处,是有好处的。让我们检查一下我们的数据集中的缺失值。
下面是每一列中缺失值的计数:
director
: 2634个缺失值cast
: 825个缺失值country
: 831个缺失值date_added
: 10个缺失值rating
: 4个缺失值duration
: 3个缺失值
director
,cast
, andcountry
这几列有相当多的缺失值。根据我们的分析目标,我们可以用一个适当的值(如’未知’)来填补这些值,或者我们可以决定忽略这些列,如果它们与我们的分析不相关。在
date_added
,rating
, 和duration
列中,只有几个缺失值。我们可以考虑删除这些列中有缺失值的行,或者如果我们能确定一个合适的值,就把它们填进去。下一步是探索性数据分析。然而,我们需要先决定如何处理这些缺失值。你想如何进行?
如果你点击ChatGPT的回复里面的”Show Work”按钮,就会展开如下代码:
import zipfile
import os
# Path to the zip file
zip_path = "/mnt/data/archive.zip"
# Directory to extract to
extract_dir = "/mnt/data/archive/"
# Create directory to extract to if it doesn't exist
os.makedirs(extract_dir, exist_ok=True)
# Open the zip file
with zipfile.ZipFile(zip_path, 'r') as zip_ref:
# Extract all the contents of zip file in the directory
zip_ref.extractall(extract_dir)
# List the contents of the directory after extraction
contents = os.listdir(extract_dir)
contents
Code Interpreter不仅为我们分析了数据,展示了分析过程,同时还输出了代码。对于会Python代码的同学来说,会更加清楚Code Interpreter进行数据分析的底层逻辑。不懂代码也没关系,Code Interpreter为每一行都添加了注释。
通过以上代码和注释,你会发现ChatGPT其实在解压缩文件这个环节也是用了Python的os
和zipfile
库。我们其实并未让它解压缩,一切都是自动运行的。接下来它读取了各列的名称,并用它的理解对各个列名进行了诠释。这也是用ChatGPT分析数据的一大优势—它知道什么是奈飞,电影和电视这些话题,所以能够帮我们比较准确的解读数据。
接下来它把每一列的缺失数据的总和都列举出来,并且根据缺失值的数量和分析的目标,给了处理这些缺失值的建议。因为如果有空数据的话,分析起来可能会报错,不合理的数据也会干扰分析的结果,所以数据的清洗通常是数据分析过程中一个非常重要的环节。
因为ChatGPT存在随机性,有时它可能不会给出数据清洗的建议,这时候你可以主动要求它给出数据清洗的建议。也可以跳过这一步,后续遇到问题它会自行清理,谁叫它是机器呢,不嫌麻烦。但是为了减少碳足迹,我们就让按照它给出的建议清洗数据吧。于是我给了它这样一个Prompt:
将导演、演员和国家的缺失值填写为 “未知”,并删除添加日期、评级和观看时间的缺失值的行。
ChatGPT是这样回复的:
所有缺失值都已成功处理。该数据集不再包含任何缺失值。
现在我们可以进入下一个步骤: 探索性数据分析(EDA)。在这一步,我们将深入研究数据集,了解数据的分布,不同变量之间的关系,并确定任何有趣的模式或见解。
你想在这个数据集中探索哪些具体方面?例如,我们可以看看电影与电视节目的分布,分析多年来增加的内容,或者看看哪些国家生产的内容最多,等等。
探索性数据分析 (EDA)
如果把数据看作一个拼图的话,EDA就是拼图的第一步。它帮助我们了解拼图的大概样子,找到重要的部分,并开始建立联系。
EDA在数据分析中起着至关重要的作用,因为它可以帮助我们初步熟悉数据集,并确定可以为进一步分析提供信息的关键特征。例如,在市场营销中,EDA可以帮助识别客户群,了解购买模式,并发现市场趋势。在医疗保健领域,它可以揭示病人数据的模式,识别风险因素,并帮助进行疾病诊断。在金融领域,EDA可以帮助分析市场趋势,识别投资机会,并检测欺诈。
既然Code Interpreter告诉我们下一步它将探索数据,那么就让它这样进行吧:
作为一个专业的数据分析师,请自己做出决定。
它这样回复:
好吧,让我们从探索数据的一般方面开始。以下是我们可以采取的几个步骤:
- 类型分布(电影与电视节目):这可以让我们了解到Netflix上最普遍的那种内容。
- 逐年增加的内容:这项分析可以让我们看到Netflix上增加的内容随时间推移的趋势。
- 按国家划分的内容生产:这可以告诉我们哪些国家是Netflix上的主要内容生产国。
- 评级分布:这可以让我们了解Netflix上最普遍的内容种类(就成熟度评级而言)。
让我们从类型的分布开始(电影与电视节目)。
该图显示,数据集中的电影比电视节目多,表明Netflix的电影收藏量比电视节目多。
接下来,让我们分析一下这些年Netflix上内容的增加趋势。要做到这一点,我们首先需要从
date_added
列中提取年份。注意,我们目前的数据是一个字符串,所以我们要把它转换成日期时间格式,然后再提取年份。该图显示了每年添加到Netflix的电影和电视节目的数量。我们可以看到多年来内容增加的明显趋势,2016年前后增加的电影数量明显增加,每年增加的电视节目数量也在稳步增加。从2018年到2020年,增加的内容有一个特别明显的上升。
接下来,让我们看看哪些国家生产的内容最终出现在Netflix上。由于一些节目列出了多个国家,我们需要将这些条目拆分,以获得准确的计数。为了这次分析的目的,我们将考虑前10个国家。
柱状图显示了Netflix上的内容生产数量的前10个国家。到目前为止,美国是最大的生产国,其次是印度、英国、加拿大和法国。
最后,让我们看一下Netflix上的内容评级分布。这可以提供一个关于目标受众在年龄组和内容成熟度方面的想法。
该图显示了Netflix上内容评级的分布。最常见的评级是 “TV-MA”,这是为成熟的观众准备的,其次是 “TV-14″,适合14岁以上的儿童,以及 “TV-PG”,这表明有家长监督。
我们的探索性数据分析到此结束。这些见解使我们对数据集和Netflix上的内容类型有了很好的了解。
你想继续进行建模,或者在数据集中还有什么想探索的吗?建模通常是为预测或分类任务做的,如果我们的目标只是了解数据集,可能就没有必要了。
Code Interpreter根据它对数据内容和分析目标的理解,从4个角度给出了探索性分析。这些角度确实是很好的切入口,让我们能很快地了解数据集的大概情况,为后面更深入的分析做了铺垫。
在分析过程中,它会根据分析目标自动转换数据类型,比如把字符串型的日期格式转化为pandas日期对象以便通过Python的Pandas库处理数据。它还根据分析目标自动生成了图表,并给出了分析的结论,虽然我们并没有要求它这么做。默认情况下,如果柱状图可以展示数据,它生成的就是柱状图,你也可以要求它换一种图表类型。
最后,它列出了后续的步骤,是继续探索数据还是开始建模。
Code Interpreter的EDA做的还是很完善的,我其实只是让它根据自己的经验来操作。对于一开始拿到数据并没有分析思路的人来说,Code Interpreter为我们做了很多辛苦的工作,虽然它并不觉得累。
接下来我们给它一些其它的分析视角看看它的表现。
我:
分析电影的持续时间。
ChatGPT:
持续时间一栏包含电影的长度(分钟)和电视节目的季数。为了分析电影时长,我们首先需要把电影和电视节目分开。然后,我们可以查看电影时长的分布,找出最短、最长和平均的电影时长。
让我们先把电影分开,提取以分钟为单位的持续时间。
这里有一些关于Netflix上电影时长的统计数据:
- 最短的电影是3分钟长。
- 最长的电影是312分钟长。
- 电影的平均长度约为100分钟。
- 第25个百分点(即25%的电影比这个长度短)是87分钟。
- 第50个百分位数,或中位数(即一半的电影比这个长度短)是98分钟。
- 第75百分位数(即75%的电影比这个长度短)是114分钟。
这些统计数据提供了一个关于电影长度的一般概念。然而,将分布可视化可以提供一个更直观的理解。让我们绘制一个电影长度的直方图。
该直方图显示了Netflix上电影时长的分布。大多数电影的长度在80到120分钟之间,峰值在90-100分钟左右。极短或极长的电影较少,这一点从分布的两端的下降趋势可以看出。
对电影长度的分析到此结束。在这个数据集中,你还有什么想探讨的吗?
我:
向我展示节目类型和它们的数量之间的关系
ChatGPT:
为了分析节目类型和它们的数量之间的关系,我们首先需要分割
listed_in
列,因为每个条目可以包含由逗号分隔的多个节目类型。让我们计算每个节目类型的出现次数,并将结果可视化。在这个分析中,我们将考虑所有类型,而不仅仅是电影或电视节目的类型。
柱状图显示了Netflix的内容按类型的计数。”国际电影”、”电视剧 “和 “喜剧 “等类型的计数最高,意味着它们是Netflix上最常见的内容类型。
我们对节目类型及其计数的分析到此结束。在这个数据集中,你还有什么想要探索的吗?
自然语言处理
接下来我们看看Code Interpreter能否用自然语言处理 (NLP) 来处理和分析数据。NLP是一个研究领域,专注于使计算机能够理解人类语言并与之互动,其方式类似于我们彼此之间的沟通方式。它允许计算机处理、分析并从大量的文本数据中获得洞察力。ChatGPT就是利用NLP技术进行语言建模、理解句法和语义关系、处理情感分析。这些NLP能力使ChatGPT能够进行类似人类的对话,并根据它收到的输入提供有意义的回应。
Code Interpreter可以使用Python的一个非常流行的NLP的库NLTK(自然语言工具包)。可以用来执行广泛的NLP任务,如标记化、部分语音标记、命名实体识别、情感分析和文本分类。通过利用NLTK,没有丰富数据分析经验的人也可以有效地处理和分析文本数据。
比如我给它这样一个任务:
分析标题中最频繁的词。
通过分析词频的方法,我们可以把文本中单词的出现频率计算并展示出来,从而可以帮我们快速了解文本中的主要内容。
我们来看下ChatGPT (Code Interpreter)的输出:
分析标题中最常见的单词可以深入了解流行主题或趋势。 例如,“爱”、“战争”、“世界”等词语可能表示内容中涵盖的常见主题。
我们首先从“标题”列中提取所有单词,然后计算每个单词的频率。 为了获得有意义的结果,我们将排除不提供太多信息的常见英语单词(例如“the”、“a”、“and”)。 这些被称为“停用词”。 让我们找出最常用的 20 个单词。
对于给您带来的不便,我们深表歉意,由于当前环境的权限有限,我似乎无法下载该组英文停用词。
解决方法是手动定义一组基本的英语停用词。 该集合不会像 NLTK 提供的那样全面,但它应该适合我们的目的。 让我们继续采用这种方法。
条形图显示了排除一组基本的英语停用词后 Netflix 影片中最常见的 20 个单词。
“爱”、“男人”、“世界”、“生活”和“故事”等词是最常见的,这表明这些主题在 Netflix 内容中很普遍。
请记住,此分析可能会受到未包含在我们的基本停用词集中的其他常用词的影响。
您还想在这个数据集中探索什么吗?
由于Code Interpreter所在的沙盒环境缺少更多停止词的语料包,所以它并没有排除像’&’, ‘-‘, ‘with’, ‘i’ 这样对分析词频毫无意义的停止词。那我们就把不想要的停止词提交给ChatGPT,让它排除掉吧。而且词频通常通过词云才能获得更好的展示效果,于是我提交了如下Prompt:
请删除停用词 ‘&’、’my’、’2’、’with’、’i’、’on’、’you’、’man’、’little’、’one’、’-‘、 ‘from’。 使用词云展示。
ChatGPT的输出如下:
词云提供了 Netflix 影片中最常见单词的视觉表示,每个单词的大小与其频率相对应。 “爱”、“世界”、“生活”、“故事”、“女孩”、“婴儿”和“圣诞节”等常用词尤其突出,表明这些主题在 Netflix 内容中很普遍。
请记住,词云中单词的确切位置和颜色是随机生成的,不具有任何意义。 重要的方面是单词的相对大小。
您还想在这个数据集中探索什么吗?
时间序列分析
时间序列分析可以帮助我们理解随时间变化的数据模式和趋势。通过分析和理解这些模式,我们可以做出有价值的决策,以及预测未来。例如,在金融领域,时间序列分析有助于根据历史数据预测股票价格或市场趋势。 在天气预报中,它使我们能够预测温度变化或降雨模式。
我们来让Code Interpreter帮我们分析电视/电影的节目类型是如何随着时间变化的。
我的Prompt:
观察电影和电视节目的类型如何随着时间的推移而变化。
ChatGPT的回答:
分析电影和电视节目的类型如何随着时间的推移而变化,可以深入了解观众偏好或内容制作策略的趋势和变化。
为此,我们需要:
- 电影和电视剧分开。
- 拆分“listed_in”列,因为每个条目可以包含多个节目类型。
- 按“release_year”分组并统计每年每种类型的频率。
我们先从电影开始吧。 为了清楚起见,我们将随着时间的推移绘制排名前 5 的节目类型。
折线图显示随时间变化的前 5 种类型的电影数量。 类型包括“国际电影”、“剧情片”、“喜剧”、“纪录片”和“动作与冒险”。
我们可以观察到,“国际电影”、“剧情片”和“喜剧”的数量逐年显着增加,特别是2000年以后。“纪录片”也有增加,但幅度不大。 多年来,“动作与冒险”类型一直保持相对稳定。
接下来,我们对电视剧进行同样的分析。
折线图显示随时间变化的前 5 种类型的电视节目数量。 类型包括“国际电视节目”、“电视剧”、“喜剧电视节目”、“犯罪电视节目”和“儿童电视节目”。
我们可以看到,“国际电视节目”、“电视剧”和“电视喜剧”的数量逐年显着增加,特别是2010年之后。“犯罪电视节目”和“儿童电视节目”也有所增加, 但没有那么明显。
这些趋势表明 Netflix 制作和添加的内容类型发生了变化,电影和电视节目的国际内容和戏剧明显增加。
您还想在这个数据集中探索什么吗?
统计推断
统计推断 (Statistical Inference)这种方法根据有限的数据样本得出结论并对总体进行预测。通过使用假设检验和置信区间等统计技术,我们可以量化与我们的估计相关的不确定性。
我们来看下发行时间 (release_year) 和添加时间 (date_added) 这两列数据是否存在相关性。我给ChatGPT这样一个问题:
执行相关性检测以查看“release_year”和“date_added”之间是否存在显着的线性关系。
ChatGPT这样回复:
要执行相关性检验,我们需要确保两个变量都是数值变量。 ‘release_year’ 已经是数字,但 ‘date_added’ 是一个日期时间对象。 我们需要从“date_added”中提取年份并将其用于我们的相关性测试。
皮尔逊相关系数可以用来衡量两个变量之间线性关系的强度和方向。 取值范围为-1到1。接近1的值表示强正关系,接近-1的值表示强负关系,接近0的值表示没有线性关系。
让我们计算“release_year”与该节目添加到 Netflix 的年份之间的皮尔逊相关系数。 “release_year”和“year_added”之间的 Pearson 相关系数约为 0.11。 这表明这两个变量之间存在弱正线性关系。
换句话说,节目在临近上映年份时有轻微的趋势被添加到 Netflix,但这种关系并不是很强。 其他因素(例如许可协议和内容策略)很可能在决定节目何时添加到 Netflix 时发挥重要作用。
您还想在这个数据集中探索什么吗?
数据挖掘
数据分析中的数据挖掘是指从大型复杂数据集中提取有用的信息并发现可以指导决策的隐藏关系或趋势。它使我们能够发现原本可能隐藏的有价值的信息,从而更好地理解并做出明智的决策。例如,在零售业,数据挖掘可以帮助识别客户购买行为的模式,从而使企业能够制定个性化营销策略并提高销售额。 在医疗保健领域,它可以帮助分析患者记录以发现风险因素或预测疾病结果,从而实现更好的医疗保健管理。
让我们发现导演和节目类型这两组数据之间是否存在隐藏的关系。
发现导演和节目类型之间的关联。
ChatGPT的回复:
分析导演和节目类型之间的关联可以深入了解某些导演为人们所熟知的特定内容类型。
为此,我们需要:
- 拆分“导演”列,因为每个条目可以包含多个以逗号分隔的导演。
- 拆分“listed_in”列,因为每个条目可以包含多个节目类型。
- 按“导演”分组并统计每种类型的频率。
但是,请注意,这个操作可能会导致数据量太大,因为有许多独特的导演和节目类型。 为了便于分析,我们来看看执导过最多剧集的前 20 名导演。
让我们继续采用这种方法。
上表代表了前 20 名导演(执导过最多节目的导演)与其节目类型之间的关联。 每个单元格代表导演在特定类型中的演出数量。
例如,凯茜·加西亚-莫利纳 (Cathy Garcia-Molina) 执导了 7 部“喜剧”类型的节目,而苏哈斯·卡达夫 (Suhas Kadav) 执导了 16 部“儿童和家庭电影”类型的节目。
为了更好地可视化这些数据,我们可以生成热图。 热图可以帮助我们了解节目在导演和节目类型方面最集中的地方。 让我们继续吧。
热图直观地展示了排名前 20 位的导演(执导过最多节目的导演)与其节目类型之间的关联。 每个单元格中的颜色强度代表导演在特定类型中的演出数量。 较暗的单元格表示显示次数较多。
例如,热图显示导演 Suhas Kadav 与“儿童和家庭电影”类型特别相关,而 Rajiv Chilaka 与“儿童电视”类型特别相关。 导演凯茜·加西亚-莫利纳 (Cathy Garcia-Molina) 与“喜剧”相关,阿努拉格·卡什亚普 (Anurag Kashyap) 与“惊悚片”相关。
请记住,一位导演可以与多种类型相关联,并且此分析仅包括根据他们执导的节目数量排名前 20 位的导演。
您还想在这个数据集中探索什么吗?
机器学习建模
数据分析中的机器学习建模是指训练计算机算法自动学习模式并根据输入数据做出预测或决策的过程。该模型可以对新的、未见过的数据进行概括并做出准确的预测。
Code Interpreter利用Pyton丰富的机器学习库来建模,比如scikit-learn。在这个例子中,我问ChatGPT它可以建哪些模型:
您可以为此数据集构建哪些机器学习模型?
ChatGPT这样回复:
机器学习模型的选择取决于您感兴趣的具体问题或任务。以下是一些潜在的任务以及可以使用的相应模型:
内容推荐:如果您有兴趣根据用户的观看历史记录向用户推荐类似的内容,则可以使用协作过滤模型(如矩阵分解)或基于内容的过滤模型(根据项目属性推荐类似的项目)。
类型预测:如果您想根据其他特征(如导演、演员、描述)来预测电影或电视节目的类型,您可以使用监督学习模型。 这些可能包括决策树、随机森林、支持向量机或神经网络。
情绪分析:如果您想预测用户评论的情绪,您可以使用自然语言处理模型,如朴素贝叶斯、逻辑回归,甚至更复杂的模型,如循环神经网络 (RNN) 或 Transformer。
趋势预测:如果您有兴趣预测未来趋势(例如特定类型的电影或电视节目的数量),您可以使用 ARIMA 或指数平滑等时间序列预测模型。
请注意,这些模型的有效性在很大程度上取决于数据的质量和数量,以及特征工程和模型调整步骤。 此外,应仔细进行模型解释和评估,以避免过度拟合并确保模型能够很好地推广到未见过的数据。
如果您有兴趣的特定任务或问题,请告诉我,我可以提供更详细的建议。
虽然我们的数据量不大,才8千多行,也可以让Code Interpreter建几个模型,看它是否在吹牛。我提交了如下Prompt:
利用文本数据(如标题和描述)和分类数据(如导演、演员、国家/地区和评级)构建基于内容的推荐系统。
来看看ChatGPT的回复:
当然,我们可以构建一个基于内容的推荐系统。 基于内容的推荐系统通过使用项目特征来提供推荐。 在这种情况下,项目特征是电影或电视节目的各种特征,例如标题、描述、导演、演员、国家和评级。
以下是我们如何创建这样一个推荐系统的总体概述:
- 预处理:此步骤涉及清理和准备模型中使用的数据。 这包括填充缺失值以及将文本数据转换为模型可以使用的数字格式。
- 特征提取:在这一步中,我们将使用 one-hot 编码等技术将分类数据转换为数值数据,并使用 TF-IDF或 CountVectorizer等技术将文本数据转换为数值数据。
- 相似度分数计算:接下来,我们将计算不同项目(在本例中为电影或电视节目)之间的相似度分数。 计算相似度分数的方法有多种,例如余弦相似度、杰卡德相似度或欧几里德距离。
- 推荐:一旦我们有了相似度分数,我们就可以推荐与给定项目最相似的项目。
让我们从预处理步骤开始。 我们之前已经处理了缺失值,因此我们可以继续将文本和分类数据转换为我们的模型可以使用的格式。 为简单起见,我们将使用 CountVectorizer 技术,它将文本文档集合转换为标记计数矩阵。 我们将其应用于“标题”、“描述”、“导演”、“演员”、“国家/地区”和“评级”列。
为此,我们首先将这些列组合成每部电影或电视节目的单个文本文档,然后应用CountVectorizer。
CountVectorizer 将我们组合的文本数据转换为标记计数矩阵。 生成的矩阵有 8790 行(对应于我们的 8790 部电影和电视节目)和 53198 列(对应于文本数据中的不同标记)。
下一步是计算不同电影和电视节目之间的相似度得分。 有多种方法可以计算这些分数,例如余弦相似度、杰卡德相似度或欧几里得距离。 在这里,我们将使用余弦相似度,这是文本数据的常见选择。
余弦相似度计算两个向量之间角度的余弦。 如果向量相同,则余弦为 1(对应于 0 度的角度)。 如果向量正交(即根本不相似),则余弦为 0(对应于 90 度角)。 因此,余弦相似度越接近1,项目越相似。
让我们计算计数矩阵的余弦相似度分数。
余弦相似度矩阵已成功创建。 该矩阵的大小为 8790×8790,这意味着每一行(和每一列)对应于一部电影或电视节目,矩阵中的每个单元格包含两部电影或电视节目之间的余弦相似度得分。
接下来,我们定义一个函数,它将电影或电视节目标题作为输入,并输出最相似的电影或电视节目的列表。 该函数将执行以下步骤:
- 获取与标题匹配的电影或电视剧的索引。
- 获取该电影或电视节目与所有其他电影或电视节目的余弦相似度分数列表。 将此列表转换为元组列表,其中第一个元素是位置,第二个元素是相似度分数。
- 根据相似度分数对元组列表进行降序排序。
- 获取排序列表的顶部元素。
- 返回顶部元素对应的标题。
推荐系统似乎按预期工作。 对于电影《盗梦空间》,它推荐了以下10部电影:
- Final Account
- The World Is Not Enough
- The Last Shaman
- 9
- Mars Attacks!
- Dead in a Week (Or Your Money Back)
- High Risk
- Catch Me If You Can
- Snowden
- A Bridge Too Far
这些推荐基于内容特征的相似性,例如标题、描述、导演、演员、国家/地区和评级。
您想用另一部电影或电视节目标题来测试推荐系统吗?
总体而言,它构建的基于内容的推荐系统所采用的方法是可靠的。使用 CountVectorizer 将文本数据转换为数字形式是一个不错的选择。 它非常简单,适合处理简单的计数功能。
然而,CountVectorizer潜在的弱点是只统计单词的出现次数,没有考虑上下文,这可能会丢失一些信息。 更完善的方法是使用 TF-IDF 甚至 Word2Vec 或 Doc2Vec ,它们可以捕获更多语义信息。Code Interperter没有采用更复杂的方法可能是因为当前的沙盒环境无法加载更庞大的Python库或者算力的限制。
我们再来让它建一个模型:
根据导演、演员、国家/地区、发行年份和类型等特征预测电影的评级。
来看看ChatGPT的回复:
预测电影评级是机器学习中的一个常见问题,通常被视为回归问题(如果预测准确的评分)或分类问题(如果预测评分类别)。 在我们的例子中,评级是一个具有多个类别的分类变量,因此我们可以使用多类别分类算法。
一些适合此任务的算法包括决策树、随机森林、朴素贝叶斯、支持向量机,甚至神经网络。 为了简单起见,我们可以从决策树分类器开始。
然而,在训练分类器之前,我们需要对数据进行预处理。 您提到的功能(“导演”、“演员”、“国家/地区”、“发行年份”、“节目类型”)大多是分类的,可能有许多独特的值。 我们需要将它们转换为可以与分类器一起使用的格式,这通常涉及将分类变量编码为数字变量。
让我们首先更详细地检查这些功能和目标变量(“评级”)。
这是我们所拥有的:
- 有 18 个独特的评级。 然而,似乎存在一些错误,因为“74 分钟”、“84 分钟”和“66 分钟”不是有效的评分。 在使用“评级”变量作为分类目标之前,我们需要清理它。
- 有 4,529 位独特的导演。 这是一个高基数分类变量,对其进行编码以与分类器一起使用可能会产生大量特征。 我们可能需要考虑使用这些信息的其他方式,例如将不太常见的类别分组在一起。
- 大约有 36,440 名独特的演员。 这是一个很大的数字,处理这个功能可能会很棘手。 一种选择可能是仅考虑主要演员(例如,列出的前几个),或者创建一个表示演员数量的特征。
- 有 749 个独特的国家。 这是另一个高基数分类变量。 与“导演”功能一样,我们可能需要将不太常见的类别分组在一起。
- 有 74 个独特的发行年份。 这是一个数值特征,可以直接与大多数分类器一起使用。
- 有 42 种独特的节目类型。 我们可以使用 one-hot 编码对该变量进行编码,这会向数据集添加 42 个二进制特征。
在进行进一步的预处理和模型训练之前,我们需要清理“评级”变量并处理缺失值和不正确的值。 接下来我们就这样做吧。
我让它继续。
不正确的评级已替换为“未知”。 清理后的“评级”变量现在具有以下唯一值:
- ‘PG-13’
- ‘TV-MA’
- ‘PG’
- ‘TV-14’
- ‘TV-PG’
- ‘TV-Y’
- ‘TV-Y7’
- ‘R’
- ‘TV-G’
- ‘G’
- ‘NC-17’
- ‘Unknown’
- ‘NR’
- ‘TV-Y7-FV’
- ‘UR’
这些代表用于对标题进行分类的不同内容评级系统。 有“PG-13”、“PG”、“R”、“G”、“NC-17”、“NR”和“UR”等电影分级,以及“TV-MA”等电视分级, “TV-14”、“TV-PG”、“TV-Y”、“TV-Y7”、“TV-G”和“TV-Y7-FV”。
接下来,让我们讨论高基数分类特征。 一种常见的策略是将不太常见的类别分组为“其他”类别。 对于这个数据集,我们可以将此策略应用于“导演”、“演员”和“国家”变量。 我们将为每个功能设置一个阈值,出现频率低于该阈值的类别将被分组到“其他”类别中。
之后,我们将准备对这些分类特征进行编码并准备用于训练分类模型的数据。
让我们继续这个计划。
我让ChatGPT继续:
将不太常见的类别分组为“其他”类别后,我们现在有:
- 13位独特的导演
- 大约 459 名独特的演员
- 60 个独特的国家
- 42 种独特的节目类型
这仍然是一个很大的类别,特别是对于“演员”而言。 对于“演员”和“节目类型”,我们可能需要考虑其他方法,例如仅考虑前几个演员或主要类型。
下一步是对这些分类特征进行编码。 为此,我们可以使用one-hot编码或目标编码。 One-hot 编码将显着增加数据的维度,尤其是对于高基数特征。 目标编码可能是更好的选择,因为它将分类变量转换为单个新列并捕获有关目标变量的有价值的信息。
然而,在继续编码之前,将数据分成训练集和测试集是有益的。 这样,我们可以确保我们的编码方法不会将测试集中的信息泄漏到训练集中。
让我们继续拆分数据。 为了简单起见,我们只考虑“director”、“country”和“release_year”作为预测“ rating”的特征。 如果需要,我们将在更高级的分析中处理“演员”和“节目类型”特征。
我让ChatGPT继续:
我们已成功将数据拆分为包含 7,045 个实例的训练集和包含 1,762 个实例的测试集。 每个实例都有 3 个特征:“导演”、“国家”和“发行年份”。
下一步是对分类特征进行编码。 如前所述,我们将为此使用目标编码。 目标编码将分类特征的每个类别替换为该类别的目标变量的平均值。 例如,如果“导演 A”执导的电影的平均评分为 7.5,则“导演 A”将在“导演”功能中替换为 7.5。
让我们继续将目标编码应用于“导演”和“国家”特征。 我们将在训练数据上安装编码器,然后转换训练数据和测试数据。
我带来的不便表示歉意。
category_encoders
模块在此环境中不可用。 作为替代方案,我们可以执行一种称为频率编码的简单编码类型,其中每个类别都被训练数据中的频率替换。 这种类型的编码仍然可以捕获有关目标变量的一些信息,因为出现频率较高的类别可能与出现频率较低的类别相比具有不同的平均评级。让我们继续对“导演”和“国家”特征进行频率编码。
我们已经使用频率编码成功地对“导演”和“国家”特征进行了编码。 DataFrame 中的“导演”和“国家”列现在分别表示训练数据中每个导演和国家/地区的出现频率。
以下是编码训练集和测试集的前几行:
训练集:
导演 国家 发布年份 5471 5471 0.683605 0.318524 2017 530 530 0.298935 0.298935 0.318524 2015 5594 0.683605 0.318524 2017 996 0.683605 0.026544 2021 6951 0.298935 0.298935 0.020014 0.020014 2018 测试集:
导演 国家 发布年份 4970 4970 0.683605 0.318524 2018 3362 3362 0.683605 0.318524 2019 5494 0.298935 0.298935 0.009510 0.009510 2017 1688 1688 0.298935 0.298935 0.318524 2020 1349 1349 0.298935 0.298935 0.003549 0.003549 2012 接下来,我们需要对目标变量“评级”进行编码。 由于这是一个多类分类问题,我们可以使用标签编码将每个唯一的评分简单地转换为唯一的整数。 之后,我们可以训练我们的分类模型。
我让ChatGPT继续:
我们已经使用标签编码成功地对目标变量“评级”进行了编码。 每个唯一的评级都被分配了一个唯一的整数,如下所示:
- ‘G’: 0
- ‘NC-17’: 1
- ‘NR’: 2
- ‘PG’: 3
- ‘PG-13’: 4
- ‘R’: 5
- ‘TV-14’: 6
- ‘TV-G’: 7
- ‘TV-MA’: 8
- ‘TV-PG’: 9
- ‘TV-Y’: 10
- ‘TV-Y7’: 11
- ‘TV-Y7-FV’: 12
- ‘UR’: 13
- ‘Unknown’: 14
现在我们的数据已经过正确的预处理,我们可以继续训练分类模型。 如前所述,我们将从决策树分类器开始,因为它简单且可解释。 让我们继续吧。
我让ChatGPT继续:
对于造成的混乱,我深表歉意。 测试集中的唯一类数量与整个数据集中的唯一类数量似乎存在差异,导致分类报告不匹配。
当训练集和测试集不包含所有相同的类时,可能会发生这种情况,这可能是由于数据的随机分割而发生的。 在这种情况下,目标变量中似乎存在测试集中未表示的类。
为了解决这个问题,我们可以在“classification_report”函数中指定“labels”参数,以确保它考虑所有可能的类。 让我们纠正这个问题并再次生成分类报告。
我为疏忽表示歉意。 看来我忘记导入此代码中使用的“numpy”库。 让我纠正这个问题并再次生成分类报告。
这是决策树分类器的分类报告:
precision recall f1-score support G 0.00 0.00 0.00 12 NC-17 0.00 0.00 0.00 0 NR 0.14 0.06 0.09 16 PG 0.28 0.11 0.16 62 PG-13 0.25 0.29 0.27 87 R 0.22 0.19 0.20 163 TV-14 0.45 0.46 0.46 414 TV-G 0.00 0.00 0.00 43 TV-MA 0.48 0.70 0.57 662 TV-PG 0.28 0.08 0.13 185 TV-Y 0.21 0.06 0.09 52 TV-Y7 0.50 0.11 0.18 65 TV-Y7-FV 0.00 0.00 0.00 0 UR 0.00 0.00 0.00 0 Unknown 0.00 0.00 0.00 1 micro avg 0.42 0.42 0.42 1762 macro avg 0.19 0.14 0.14 1762 weighted avg 0.38 0.42 0.38 1762
该模型似乎难以预测某些类别,例如“G”、“NC-17”、“TV-G”、“TV-Y7-FV”、“UR”和“未知”。 这可能是由于这些类别在数据中代表性不足。
加权平均精度、召回率和 F1 分数约为 0.38 至 0.42,表明还有改进的空间。
这是一个在可用特征的子集上训练的简单模型,它不处理高基数分类特征(例如“cast”和“genre”)或文本特征(例如“description”)。 可以处理这些功能的更复杂的模型可能能够实现更好的性能。 此外,类平衡或模型调整等技术也可以帮助改善结果。
我让ChatGPT继续:
为了提高模型的性能,我们可以尝试更复杂的方法。 我们可以使用随机森林分类器,通过组合多个决策树的预测,它往往比单个决策树表现得更好。 此外,随机森林不太容易出现过度拟合。
然而,我们应该注意到,处理“演员”和“节目类型”等高基数分类特征并不简单。 如前所述,一种方法可能是仅考虑主要演员或主要类型。 为了演示,我们将排除这些功能并重点关注“导演”、“国家”和“发行年份”。
让我们继续根据我们的数据训练随机森林分类器。 我们还将使用交叉验证来更好地估计模型的性能。
随机森林分类器的交叉验证分数约为:
- 0.41
- 0.42
- 0.42
- 0.42
- 0.40
这些分数代表分类器在数据的不同分区上的准确性。 正如我们所看到的,分数略低于决策树分类器的分数。 这可能是由于随机森林算法固有的随机性,也可能是决策树过度拟合训练数据。
同样重要的是要注意,准确性可能不是这个问题的最佳指标,特别是如果目标变量中的类不平衡的话。 其他指标(例如精确率、召回率或 F1 分数)可能提供更多信息。
最后,如前所述,可以处理高基数分类特征(“演员”和“节目类型”)和文本特征(“节目描述”)的更高级模型可能能够实现更好的性能。 这样的模型可能涉及用于“描述”特征的自然语言处理(NLP)技术,以及用于“演员”和“节目类型”特征的更复杂的编码方法。 然而,开发这样的模型将是一项更复杂的任务,并且超出了此交互的范围。
如果您想进一步操作或需要其他帮助,请告诉我。
总结一下:我让ChatGPT创建两个机器学习模型,第一个内容推荐系统对它而言还是比较轻松的,第二个预测电影评级就很吃力了。由于沙盒环境的限制,Code Interpreter无法导入sklearn的category_encodes
模块。在建模过程中,也会忘记导入关键的库,虽然它自己会纠错。
在建立预测电影评级的过程中,它先尝试了简单的决策树分类器,但是由于加权平均精度、召回率和 F1 分数都不太理想,又尝试了随机森林分类器。然而效果并不理想,需要更复杂的编码方法来创建更高级的模型,这些已经超出Code Interpreter的能力了。
Code Interpreter对数据分析领域的影响
你是否曾听过一句话—人人都是数据分析师。在ChatGPT和Code Interpreter出现之前,我们离这个美好的愿望还有一段距离。但是自从Code Interpreter出现以后,我相信这句话不再是一句口号,而是越来越成为现实。
经过以上案例的测试,我们可以看到Code Interpreter的能力。我用来测试的方法已经涉及专业的数据分析了,但是对大多数用Excel来进行数据分析的人而言,Code Interpreter堪称完美。大多数日常办公涉及的数据分析对Code Interpreter来说根本不在话下。你可以直接上传Excel,通过对话的方式让ChatGPT帮你进行数据分析,生成各种漂亮的图表。
对于专业的数据分析师或者数据科学家而言,Code Interperter依然会帮你做很多繁重的工作。你需要的是精通统计学,熟知不同情景下的数据分析方法,这样才能更好地指导Code Interpreter完成很多复杂的工作。对于更复杂的涉及机器学习建模的数据分析,Code Interpreter就比较吃力了,所能提供的是一些基本的建模和思路,由于沙盒环境的限制,缺少很多必要的代码库和计算资源。
总的来说,我们能看到低代码在数据分析领域的趋势。我们会越来越少地亲自写代码,更多地是管理数据分析的流程,让ChatGPT这样的人工智能工具根据我们的指导来分析数据。我们用ChatGPT帮我们省下来的时间可以去熟悉业务,强化数学和统计学知识,精通机器学习建模的各个环节。
Code Interpreter在数据分析上的不足
虽然Code Interpreter在数据分析方面有革命性的影响,但是还存在诸多限制:
- 需要Plus账号。Code Interpreter这个OpenAI自研的功能目前只对Plus会员开放,势必会影响它的大规模普及。而且就算有Plus账号的话,每三个小时25条会话的限制对于一些大型的项目使用起来不太方便。
- 无法联网。Code Interpreter用来进行分析的Python库都是内置在沙盒环境中的,一些没有内置的库无法通过联网下载。而且如果你要分析的话题比较新,那么ChatGPT由于缺乏实时的知识,可能会不了解你的项目,从而影响判断的准确性。
- 不稳定。目前它对你上传的数据所记忆的时间是有限制的,超过了时间限制你可能需要重新上传数据。由于模型本身的随机性,每次它的分析方法可能有差异。
- 缺少一些中文支持。在数据分析过程中,最好还是用英文来对话,否则可能会显示不正常或者分析的能力会不如英文环境。
- 机器学习能力不足。对于常规的数据分析,Code Interpreter是没有问题的,但是如果涉及复杂的机器学习建模,它就有些吃力了。
我的总结
Code Interpreter让我们仅仅通过对话就能分析庞大而复杂的数据。我们更需要关注的是如果指导这些人工智能工具为我们处理复杂而繁重的工作,而不是写代码本身。
尽管Code Interpreter目前存在一些限制,但它无疑是一个强大的工具。随着它的不断迭代,这些限制应该也会越来越少。代码解释器让我们离每个人都可以成为数据分析师的未来又近了一步。