实现动手自主学习的途径是通过大型言语模型(LLM)。Jon Udell 展示了教育科技行业怎么利用人工智能。
译自Learn by Doing: How LLMs Should Reshape Education,作者 Jon Udell。
今日,我的朋友格雷格威尔逊(Greg Wilson)在将 tidyverse/Pandas 习语翻译成 SQL 时,问我以下问题:
好吧,我的 SQL 哪里错了?
drop table if exists person;
create table person(
ident integer not null primary key,
name text not null
);
drop table if exists job;
create table job(
ident integer not null primary key,
name text not null
);
drop table if exists did;
create table did(
person_id integer not null,
job_id integer not null
);
insert into person values (1, "Alice"), (2, "Bob");
insert into job values (20, "cook"), (30, "clean");
insert into did values(1, 20), (2, 20), (1, 30);
select person.name, job.name, count(*)
from person inner join did inner join job
on person.ident = did.person_id and did.job_id = job.ident
group by person.ident, job.ident
order by person.ident, job.ident;
成果中没有显现 (Bob, clean) 的值为 0。为什么?
我将这个问题转发给了我的首席帮手 ChatGPT,它给出了以下回答:
ChatGPT: 您的 SQL 脚本根本没有问题,但是最终的查询句子中联结表的办法有点问题。让我具体阐明一下:
表的创立和刺进数据: 您正确地创立了 person、job 和 did 这三张表,并向其中刺进了数据。这部分看起来没有问题。
最终的联合查询: 您企图将这些表的数据组合起来,以显现每个人做了哪些作业。但是,您运用 INNER JOIN 写的查询不会包含一个人没有作业的组合(如您示例中的 Bob 和“clean”)。这是因为 INNER JOIN 只包含两张表中都有匹配的行。
为了包含一切人和作业的组合,即使一个人没有做某项作业,您应该运用 CROSS JOIN 来创立 person 和 job 的笛卡尔积,然后与 did 表做 LEFT JOIN。这样,您可以得到一切组合,并统计出现的次数。
下面是更正后的查询:
SELECT person.name, job.name, COUNT(did.person_id) as job_count
FROM person
CROSS JOIN job
LEFT JOIN did ON person.ident = did.person_id AND job.ident = did.job_id
GROUP BY person.name, job.name
ORDER BY person.name, job.name;
这个查询会列出每种人和作业的组合,并统计每个人做每项作业的次数。关于 did 表中没有的组合(如您示例中的 Bob 和“clean”),会显现 0 次。
准则 2: 永久不要相信,要验证
遵从准则 2(见7 个辅导言语模型作业的原则),我下一步的举动是:
Jon: 听起起来不错,请写一个测验来证明它可行。
接下来产生的事情我之前提到过,在《言语模型怎么协助一个网站改版》一文中: ChatGPT 编写并运转了测验。如果您还没有看到这种情况产生,那几乎令人难以置信,我感觉许多人还没有看到过。
ChatGPT: 为了测验 SQL 查询,我将设置一个数据库环境的模拟,然后履行查询。这将演示查询在处理您的需求方面的正确性。让咱们进行测验:
创立表: 我将根据您的脚本创立 person、job 和 did 表。刺进数据: 我将刺进您供给的数据到这些表中。履行查询: 我将运转更正后的查询,以显现它怎么处理人和作业的组合,包含一个人没有作业记载的情况。
让咱们从这个测验开始:
import sqlite3
import pandas as pd
# Create an in-memory SQLite database
conn = sqlite3.connect(':memory:')
# Create tables
create_statements = [
'''
CREATE TABLE person (
ident INTEGER NOT NULL PRIMARY KEY,
name TEXT NOT NULL
);
''',
'''
CREATE TABLE job (
ident INTEGER NOT NULL PRIMARY KEY,
name TEXT NOT NULL
);
''',
'''
CREATE TABLE did (
person_id INTEGER NOT NULL,
job_id INTEGER NOT NULL
);
'''
]
for create_statement in create_statements:
conn.execute(create_statement)
# Insert data
person_data = [(1, "Alice"), (2, "Bob")]
job_data = [(20, "cook"), (30, "clean")]
did_data = [(1, 20), (2, 20), (1, 30)]
conn.executemany('INSERT INTO person VALUES (?, ?);', person_data)
conn.executemany('INSERT INTO job VALUES (?, ?);', job_data)
conn.executemany('INSERT INTO did VALUES (?, ?);', did_data)
# Query to combine the tables
query = '''
SELECT person.name AS PersonName, job.name AS JobName, COUNT(did.person_id) AS JobCount
FROM person
CROSS JOIN job
LEFT JOIN did ON person.ident = did.person_id AND job.ident = did.job_id
GROUP BY person.name, job.name
ORDER BY person.name, job.name;
'''
# Execute the query
result = pd.read_sql_query(query, conn)
conn.close()
result
PersonName JobName JobCount
0 Alice clean 1
1 Alice cook 1
2 Bob clean 0
3 Bob cook 1
作为跟进,我要求供给一个以CTEs(通用表达式)管道办法编写的查询版本,并仅供给查询的cross join
组件的输出。
ChatGPT:要显现PersonJobCombos CTE的输出,咱们需求仅运转查询的那部分。该CTE生成一切或许的人员和作业组合,而不考虑一个人是否实践上做过作业。让咱们别离履行此CTE以查看其输出。
# Reconnect to the in-memory SQLite database
conn = sqlite3.connect(':memory:')
# Recreate tables and insert data as before
for create_statement in create_statements:
conn.execute(create_statement)
conn.executemany('INSERT INTO person VALUES (?, ?);', person_data)
conn.executemany('INSERT INTO job VALUES (?, ?);', job_data)
conn.executemany('INSERT INTO did VALUES (?, ?);', did_data)
# Query for PersonJobCombos CTE
person_job_combos_query = '''
WITH PersonJobCombos AS (
SELECT person.ident AS PersonID, person.name AS PersonName, job.ident AS JobID, job.name AS JobName
FROM person
CROSS JOIN job
)
SELECT * FROM PersonJobCombos;
# Execute the PersonJobCombos CTE query
person_job_combos_result = pd.read_sql_query(person_job_combos_query, conn)
conn.close()
person_job_combos_result
PersonID PersonName JobID JobName
0 1 Alice 20 cook
1 1 Alice 30 clean
2 2 Bob 20 cook
3 2 Bob 30 clean
PersonJobCombos CTE的输出显现了人员和作业的一切或许组合:
Alice与“cook”和“clean”都配对。
Bob也与“cook”和“clean”配对。
这展示了人员和作业表的笛卡尔积,创立了每个人与每个作业的组合,而不考虑他们是否实践上做过这份作业。
规矩7:通过实践学习
现在这里有一个为难的坦白。在我上一份作业中,我写了许多SQL,在我当前的作业中我也写了许多。在上一份作业中,我从未发现过对cross join
的需求。在运用Steampipe时,我在许多示例查询中遇到了这种习语,但从未以这种简略的办法出现过。Steampipe查询一般会将cross join
与返回集的JSONB函数结合运用,以我不可思议的办法。在这些情况下,我会借助CTE管道以一系列简略的步骤构建查询,每个步骤都履行一项简略的转化。
我把规矩7放在最终,因为它感觉最重要。在这里,例如,我并没有故意去学习穿插衔接,我只是想知道怎么陈述Bob/clean对的值为0。因为穿插衔接是解决方案的有机部分,我或许会记住并可以参阅这个比如。我希望在面临类似问题时会想到它。
这次练习中我或许学到的不只仅是这些。我碰巧知道怎么从Python内部运用SQLite,但如果我不知道,ChatGPT将会默默地教给我这种办法,并供给另一个有用的示例供我参阅。
从头定义教育
咱们一直需求这种按需学习的办法,现在它正在变得或许。在这个比如中,咱们看到了一个tidyverse/Pandas从业者怎么在SQL中展示了解的习语。作为SQL从业者,我可以反其道而行,了解了解的SQL习语在R或Python中的运用。实践上,我刚刚做到了这一点,而ChatGPT不只可以编写代码,而且可以运转它——现在仅支撑Python(尚不支撑R),但好像不可避免的是LLMs将衔接到多个引擎以履行各种剖析使命。
现在让咱们想象一下一个或许激发Greg的模式和查询的课堂练习。教师或许会这样描绘这个使命:
教师:这些是人们可以做的作业:cook,clean。
这些是人:Alice,Bob。
这是他们做过的作业:Alice:cook,clean;Bob:cook。
展示怎么运用一个或多个SQL表对这种情况建模,并以这种格式陈述数据。
PersonName JobName JobCount
Alice clean 1
Alice cook 1
Bob clean 0
Bob cook 1
你应该期望ChatGPT编写、运转并迭代一个嵌入SQLite并调用必要的SQL句子的Python脚本。当你得到一个可以陈述上述数据的脚本时,自己运转以进行验证,并包含该脚本。
现在回答这个问题:SQL输出怎么包含这一行?
这不在数据中,它从哪里来?
术语cross join
并不在视野中!学生需求查看生成的代码,然后(在LLM的协助下!)解释为什么需求cross join
以及它是怎么起作用的。
一些教师现在或许愿意并可以采用这种全新的办法。许多人或许会比及它嵌入在具有保护措施的课程中,以确保学生走上正轨。但无论怎么,教育范畴行将迎来一场巨大的革新。
程序员和作家Ellen Ullman喜欢说程序员依照自己的形象和希望创立体系。咱们是第一批体验到咱们现在都视为天经地义的生活办法的人:异步的、机器介导的、始终在线的。现在咱们将是第一批体验到LLM辅佐教育的人。
关于可以用Python解决的课程练习,教师和学习者生活在一个散布不均匀的未来。通向这种更均匀散布的、实现这种实践操作性学习的路径尚未被明确指引,但我希望教育作业者正在带着头灯和手电筒走在这条道路上。
本文在如此众生(yylives.cc/)首发,欢迎大家拜访。