Web 和机器学习的人工智能辅助变成(六)
原文:
annas-archive.org/md5/f5ce3ca93c7ecd74cff0d3ae335a95cc译者:飞龙
第十七章:使用 Copilot 进行机器学习
简介
机器学习,或 ML,涉及从数据中学习和发现模式,并使用这些模式进行预测或决策。机器学习包括一系列步骤,从加载数据和清洗数据到最终训练模型以从模型中获得所需见解。所有这些步骤对于这个领域中的大多数问题都是大致相同的。然而,细节可能有所不同,如预处理步骤的选择、算法的选择等。像 GitHub Copilot 这样的 AI 工具从几个不同的角度进入机器学习:
-
建议工作流程:由于 Copilot 在机器学习工作流程方面进行了训练,因此它能够建议适合你问题的流程。
-
推荐工具和算法:如果你向你的 AI 工具提供足够的问题背景和数据的形状,像 Copilot 这样的 AI 工具就可以建议适合你特定问题的工具和算法。
-
代码辅助:Copilot 作为一大帮助的另一个方式是能够生成机器学习过程中的各种步骤的代码。
本章将探讨一个电子商务数据集,本章将作为与其他章节有趣的比较练习,这些章节使用 ChatGPT 来解决机器学习问题。
让我们深入探索 GitHub Copilot 的建议。
GitHub Copilot Chat 在你的 IDE 中
GitHub Copilot Chat 是某些集成开发环境(IDEs)中的一个工具,它回答编码问题。它通过建议代码、解释代码功能、创建单元测试和修复错误来帮助。
工作原理
你有两种不同的方式向 GitHub Copilot 提供提示:
-
编辑器内模式:在这种模式下,你提供文本注释,并通过Tab或Return键,Copilot 能够生成输出。
-
聊天模式:在聊天模式下,你在文本框中输入提示,然后 GitHub Copilot 会将打开的文件/文件作为上下文(如果你使用
@workspace,则它将查看你目录中的所有文件)。
文本文件可以是,例如,一个代码文件如app.py或 Jupyter Notebook。Copilot 可以将这两个文件作为上下文,连同你输入的提示一起处理。
图 17.1:左侧的 GitHub Copilot 聊天和右侧打开的 Jupyter Notebook
数据集概述
让我们探索我们将要使用的数据集。就像我们在其他关于机器学习的章节中所做的那样,我们从数据集开始,这个数据集是亚马逊书评数据集。
数据集包含有关不同产品和它们评论的信息。它包括以下列:
-
marketplace(字符串):产品的位置 -
customer_id(字符串):客户的唯一 ID -
review_id(字符串):评论 ID -
product_id(字符串):产品的唯一 ID -
product_parent(字符串):父产品 -
product_title(字符串):被评论产品的标题 -
product_category(字符串):不同的产品类别 -
star_rating(整数): 产品 5 星评分 -
helpful_votes(整数): 产品获得的有用票数 -
total_votes(整数): 产品获得的总票数 -
review_headline(字符串): 评论的标题 -
review_body(字符串): 评论的内容 -
review_date(字符串): 产品评论的日期 -
sentiment(字符串): 评论的情感(正面或负面)
数据探索步骤
进行数据探索有助于我们了解数据集及其特征。它包括检查数据、识别模式和总结关键见解。以下是我们将遵循的步骤:
-
加载数据集: 将数据集读入 pandas DataFrame 以有效地处理数据。
-
检查数据: 显示 DataFrame 的前几行以了解数据。检查列名、数据类型和任何缺失值。
-
摘要统计量: 计算数值列的摘要统计量,如平均值、中位数、最小值、最大值和四分位数。这有助于理解值的分布和范围。
-
探索分类变量: 分析如
marketplace、product_category和sentiment等分类变量的唯一值及其频率。条形图等可视化工具可以帮助进行此类分析。 -
评分分布: 绘制直方图或条形图以可视化
star_ratings的分布。这有助于理解评论的整体情感。 -
时间序列分析: 通过检查
review_date列来分析数据的时序方面。探索趋势、季节性或任何随时间变化的模式。 -
评论长度分析: 分析
review_body的长度以了解评论中提供的信息量。计算描述性统计量,如平均值、中位数和最大长度。 -
相关性分析: 使用相关矩阵或散点图调查数值变量之间的相关性。这有助于识别变量之间的关系。
-
附加探索性分析: 根据特定项目要求或探索过程中观察到的有趣模式进行附加分析。
注意,您还可以询问 GitHub Copilot 在进行机器学习时应遵循哪些步骤。
提示策略
我们即将使用的提示为 Copilot 提供高级指导,而输出/结果允许进一步调整 Copilot 的响应以匹配特定数据集和分析需求。
提示方法的关键方面是:
-
定义任务。明确指示 AI 助手我们正在解决的任务。
-
将数据探索分解为步骤。将数据探索分解为逻辑步骤(如数据加载、检查、摘要统计等)
-
为每个提示提供上下文/意图以引导 Copilot(例如请求数值摘要统计量)
-
将之前的结果作为输入。将 Copilot 代码片段的输出和结果分享,以进一步引导对话(例如打印摘要统计)
-
逐步细化提示,与 Copilot 进行来回对话
因此,我们将使用第二章中描述的 TAG(任务-操作-指导)提示模式。让我们描述这个项目以适应这个模式,这样我们就能了解如何编写我们的初始提示:
-
任务:数据探索,在电子商务项目中找到客户评论的模式和见解。
-
操作:我们在前面的部分中描述了我们应该采取的步骤;这些步骤应该反映在我们编写的提示中。
-
指导:我们将提供的额外指导是,我们希望建议探索性技术以及代码片段。
您的初始数据探索提示:提示 1,设置高级上下文
就像在其他章节中使用 ChatGPT 一样,我们的初始提示为我们要解决的问题设定了高级上下文,包括领域和我们的数据形状。所有这些上下文都有助于 AI 工具在文本和代码中提供正确的步骤。
下面是一个你可以尝试的初始提示:
[提示]
我正在进行 AwesomeShop 电子商务项目的数据探索。数据集包含有关各种产品和它们评论的信息。我想深入了解数据,识别模式,并理解评论的特征。你能提供一些探索性分析技术和代码片段,帮助我从数据集中发现有趣的见解吗?AwesomeShop 电子商务项目的数据集包含有关不同产品和它们评论的信息。它包括以下列:
-
marketplace(字符串):产品位置 -
customer_id(字符串):客户的唯一 ID -
review_id(字符串):评论 ID -
product_id(字符串):产品的唯一 ID -
product_parent(字符串):父产品 -
product_title(字符串):被评论产品的标题 -
product_category(字符串):不同的产品类别 -
star_rating(整数):产品 5 星评分 -
helpful_votes(整数):产品有用投票数 -
total_votes(整数):产品的总投票数 -
review_headline(字符串):评论标题 -
review_body(字符串):评论内容 -
review_date(字符串):产品评论日期 -
sentiment(字符串):评论的情感(正面或负面)
但请记住,我想逐步学习,如下所示:
-
加载数据集:将数据集读入 pandas DataFrame 以有效地处理数据。
-
检查数据:显示 DataFrame 的前几行以了解数据。检查列名、数据类型和任何缺失值。
-
摘要统计:计算数值列的摘要统计,如平均值、中位数、最小值、最大值和四分位数。这有助于了解值的分布和范围。
-
探索分类变量:分析分类变量(如
marketplace、product_category和sentiment)的唯一值及其频率。条形图等可视化工具可以帮助进行此类分析。 -
评分分布:绘制直方图或条形图以可视化
star_ratings的分布。这有助于了解评论的整体情感。 -
时间序列分析:通过检查
review_date列来分析数据的时序方面。探索趋势、季节性或任何随时间变化的模式。 -
评论长度分析:分析
review_body的长度,以了解评论中提供的信息量。计算描述性统计量,如平均值、中位数和最大长度。 -
相关性分析:使用相关矩阵或散点图调查数值变量之间的相关性。这有助于识别变量之间的关系。
-
额外的探索性分析:根据特定项目要求或探索过程中观察到的有趣模式进行额外的分析。在每个步骤后从用户那里寻求反馈。
[提示结束]
第 1 步:加载数据集
我们从 Copilot 那里得到了一段相当冗长的响应,所以让我们将响应分解成几个部分并解释我们得到了什么。
您应该收到与以下响应类似的响应:
[提示响应]
当然,让我们从第 1 步:加载数据集开始。
# Step 1: Load the Dataset
import pandas as pd
# Define the file path
file_path = '/path/to/your/file.csv' # replace with your file path
# Load the dataset
df = pd.read_csv(file_path)
# Display the first few rows of the DataFrame
print(df.head())
请将'/path/to/your/file.csv'替换为您的实际文件名或文件路径。完成此操作后,您可以运行代码以加载数据集。
一旦您成功加载数据,请告诉我,然后我们可以进行下一步。
[响应结束]
图 17.2:显示 Copilot 提示和加载数据的 Copilot 结果的开始部分
让我们尝试 Copilot 生成的输出代码,看看它是否可行。修改file_path变量以指向您的数据集位置,然后执行代码。注意以下如何编辑文件路径以反映我们系统中的实际路径:
import pandas as pd
# Define the file path
file_path = '../Datasets/amazon_books_Data.csv'
# Load the dataset
df = pd.read_csv(file_path)
运行加载数据的代码
让我们运行 Copilot 提供的代码。请看以下来自我们 Jupyter Notebook 的输出:
# Display the first few rows of the DataFrame
print(df.head())
Unnamed: 0 market_place customer_id review_id product_id \
0 0 "US" "25933450" "RJOVP071AVAJO" "0439873800"
1 1 "US" "1801372" "R1ORGBETCDW3AI" "1623953553"
2 2 "US" "5782091" "R7TNRFQAOUTX5" "142151981X"
3 3 "US" "32715830" "R2GANXKDIFZ6OI" "014241543X"
4 4 "US" "14005703" "R2NYB6C3R8LVN6" "1604600527"
product_parent product_title \
0 "84656342" "There Was an Old Lady Who Swallowed a Shell!"
1 "729938122" "I Saw a Friend"
2 "678139048" "Black Lagoon, Vol. 6"
3 "712432151" "If I Stay"
4 "800572372" "Stars 'N Strips Forever"
product_category star_rating helpful_votes total_votes vine \
0 "Books" 1 0 0 0 \t(N)
1 "Books" 1 0 0 0 \t(N)
2 "Books" 1 0 0 0 \t(N)
3 "Books" 1 0 0 0 \t(N)
4 "Books" 1 2 2 0 \t(N)
verified_purchase review_headline \
0 1 \t(Y) "Five Stars"
1 1 \t(Y) "Please buy "I Saw a Friend"! Your children wi...
2 1 \t(Y) "Shipped fast."
3 0 \t(N) "Five Stars"
4 1 \t(Y) "Five Stars"
review_body review_date \
0 "I love it and so does my students!" 2015-08-31
1 "My wife and I ordered 2 books and gave them a... 2015-08-31
2 "Great book just like all the others in the se... 2015-08-31
3 "So beautiful" 2015-08-31
4 "Enjoyed the author's story and his quilts are... 2015-08-31
Sentiment_books review_month review_day review_year
0 positive August Monday 2015
1 positive August Monday 2015
2 positive August Monday 2015
3 positive August Monday 2015
4 positive August Monday 2015
第 2 步:检查数据
接下来,让我们检查数据。对于检查提示,我们将使用代码执行的结果,看看我们能否让 Copilot 告诉我们下一步需要做什么:
[提示]
运行正常;以下是输出:
Unnamed: 0 market_place customer_id review_id product_id 0 0 "US" "25933450" "RJOVP071AVAJO" "0439873800"
1 1 "US" "1801372" "R1ORGBETCDW3AI" "1623953553"
2 2 "US" "5782091" "R7TNRFQAOUTX5" "142151981X"
3 3 "US" "32715830" "R2GANXKDIFZ6OI" "014241543X"
4 4 "US" "14005703" "R2NYB6C3R8LVN6" "1604600527"
product_parent product_title 0 "84656342" "There Was an Old Lady Who Swallowed a Shell!"
1 "729938122" "I Saw a Friend"
2 "678139048" "Black Lagoon, Vol. 6"
3 "712432151" "If I Stay"
4 "800572372" "Stars 'N Strips Forever"
product_category star_rating helpful_votes total_votes vine 0 "Books" 1 0 0 0 \t(N)
1 "Books" 1 0 0 0 \t(N)
2 "Books" 1 0 0 0 \t(N)
3 "Books" 1 0 0 0 \t(N)
4 "Books" 1 2 2 0 \t(N)
verified_purchase review_headline 0 1 \t(Y) "Five Stars"
1 1 \t(Y) "Please buy "I Saw a Friend"! Your children wi...
2 1 \t(Y) "Shipped fast."
... 1 positive August Monday 2015
2 positive August Monday 2015
3 positive August Monday 2015
4 positive August Monday 2015
输出被截断。将其视为可滚动的元素或在文本编辑器中打开。调整单元格输出设置...
[提示结束]
您应该收到与以下响应类似的响应:
[提示响应]
太好了!现在您已成功加载数据集,让我们继续到“检查数据”阶段。
# Step 2: Inspect the Data
# Check the column names
print("Column Names:")
print(df.columns)
# Check the data types of each column
print("\nData Types:")
print(df.dtypes)
# Check for missing values
print("\nMissing Values:")
print(df.isnull().sum())
这段代码将为您提供数据集的概述,包括列名、每列的数据类型以及每列中缺失值的数量。运行此代码并告诉我您发现了什么。
[响应结束]
让我们尝试上面的代码来检查数据并看看它是否工作。在您的 Jupyter Notebook 中的代码单元中运行以下代码:
# Display the first few rows of the DataFrame
df.head()
# Check the column names
column_names = df.columns
print(column_names)
# Check the data types of the columns
data_types = df.dtypes
print(data_types)
# Check for missing values
missing_values = df.isnull().sum()
print(missing_values)
You should see an output similar to below:
Index(['Unnamed: 0', 'market_place', 'customer_id', 'review_id', 'product_id',
'product_parent', 'product_title', 'product_category', 'star_rating',
'helpful_votes', 'total_votes', 'vine', 'verified_purchase',
'review_headline', 'review_body', 'review_date', 'Sentiment_books',
'review_month', 'review_day', 'review_year'],
dtype='object')
Unnamed: 0 int64
market_place object
customer_id object
review_id object
product_id object
product_parent object
product_title object
product_category object
star_rating int64
helpful_votes int64
total_votes int64
vine object
verified_purchase object
review_headline object
review_body object
review_date object
Sentiment_books object
review_month object
review_day object
review_year int64
dtype: object
Unnamed: 0 0
market_place 0
customer_id 0
review_id 0
product_id 0
product_parent 0
product_title 0
product_category 0
star_rating 0
helpful_votes 0
total_votes 0
vine 0
verified_purchase 0
review_headline 0
review_body 0
review_date 0
Sentiment_books 0
review_month 0
review_day 0
review_year 0
dtype: int64
太好了!到目前为止,当我们向 Copilot 提供我们的目标状态并获取其建议的下一步时,它一直表现得很好;让我们继续遵循这个格式。
第 3 步:摘要统计量
接下来,我们想要总结一下,所以我们再次提供输出数据,希望 Copilot 会告诉我们下一步是什么:
[提示]
没有缺失值;以下是输出:
Index(['Unnamed: 0', 'market_place', 'customer_id', 'review_id', 'product_id', 'product_parent', 'product_title', 'product_category', 'star_rating', 'helpful_votes', 'total_votes', 'vine', 'verified_purchase', 'review_headline', 'review_body', 'review_date', 'Sentiment_books', 'review_month', 'review_day', 'review_year'], dtype='object') Unnamed: 0 int64 market_place object customer_id object review_id object product_id object product_parent object product_title object product_category object star_rating int64 helpful_votes int64 total_votes int64 vine object verified_purchase object review_headline object review_body object review_date object Sentiment_books object review_month object review_day object ... review_month 0 review_day 0 review_year 0 dtype: int64
[提示结束]
您应该收到以下类似的响应:
[提示响应]
太好了!现在我们已经检查了数据,让我们继续到第 3 步:计算数值列的摘要统计量。这将帮助我们了解值的分布和范围。
# Step 3: Summary Statistics
# Calculate summary statistics for numeric columns
numeric_columns = ['star_rating', 'helpful_votes', 'total_votes']
print(df[numeric_columns].describe())
这段代码将为您提供数据集中数值列的计数、平均值、标准差、最小值、25 百分位数、中位数(50 百分位数)、75 百分位数和最大值。运行此代码并告诉我您发现了什么。
[响应结束]
让我们尝试这个并看看它是否工作。让我们运行下面的代码并调用df.describe:
# Calculate summary statistics
summary_stats = df.describe()
print(summary_stats)
您应该看到以下输出:
Unnamed: 0 star_rating helpful_votes total_votes review_year
count 100.000000 100.000000 100.000000 100.000000 100.0
mean 49.500000 0.840000 0.540000 0.960000 2015.0
std 29.011492 0.368453 1.298173 2.420118 0.0
min 0.000000 0.000000 0.000000 0.000000 2015.0
25% 24.750000 1.000000 0.000000 0.000000 2015.0
50% 49.500000 1.000000 0.000000 0.000000 2015.0
75% 74.250000 1.000000 1.000000 1.000000 2015.0
max 99.000000 1.000000 9.000000 14.000000 2015.0
太好了!我们能够看到计数、平均值、标准差等。我们继续使用向 Copilot 提供我们代码的输出的想法,并且它已经能够理解在机器学习过程的哪个点以及下一步该做什么。
第 4 步:探索分类变量
就像之前一样,让我们构建一个提示,包括我们刚刚运行的代码的输出,让 Copilot 告诉我们下一步应该做什么:
[提示]
以下是输出:
Unnamed: 0 star_rating helpful_votes total_votes review_year count 100.000000 100.000000 100.000000 100.000000 100.0 mean 49.500000 0.840000 0.540000
0.960000 2015.0 std 29.011492 0.368453 1.298173 2.420118 0.0 min 0.000000 0.000000 0.000000 0.000000 2015.0 25% 24.750000 1.000000 0.000000 0.000000 2015.0 50% 49.500000 1.000000 0.000000 0.000000 2015.0 75% 74.250000 1.000000 1.000000 1.000000 2015.0 max 99.000000 1.000000 9.000000 14.000000 2015.0
[提示结束]
您应该收到以下类似的响应:
[提示响应]
太好了!现在我们已经有了摘要统计量,让我们继续到第 4 步:探索分类变量。我们将分析分类变量如marketplace、product_category和sentiment的唯一值及其频率。
# Step 4: Explore Categorical Variables
# Analyze the unique values and their frequencies for categorical variables
categorical_columns = ['market_place', 'product_category', 'Sentiment_books']
for column in categorical_columns:
print("\n" + column)
print(df[column].value_counts())
This code will print the unique values and their frequencies for each of the specified
categorical columns. Run this code and let me know what you find.
[响应结束]
让我们尝试这个并看看它是否工作。在代码单元中运行以下代码以分析分类变量:
# Analyze categorical variables
categorical_cols = ['market_place', 'product_category', 'Sentiment_books']
for col in categorical_cols:
unique_values = df[col].unique()
value_counts = df[col].value_counts()
print(f"\n{col} unique values:\n{unique_values}\n")
print(f"{col} value counts:\n{value_counts}")
您应该看到以下输出:
market_place unique values:
['"US"']
market_place value counts:
market_place
"US" 100
Name: count, dtype: int64
product_category unique values:
['"Books"']
product_category value counts:
product_category
"Books" 100
Name: count, dtype: int64
Sentiment_books unique values:
['positive' 'negative']
Sentiment_books value counts:
Sentiment_books
positive 84
negative 16
Name: count, dtype: int64
第 5 步:评分分布
接下来,我们想要了解评分的分布。为了了解更多关于评分的信息,我们将提供最后一次代码执行的输出作为提示:
[提示]
以下是输出:
-
market_place唯一值:[‘“US”’] -
market_place值计数:market_place“US” 100 名称:计数,数据类型:int64 -
product_category唯一值:[‘“Books”’] -
product_category值计数:product_category “Books” 100 名称:计数,数据类型:int64 -
Sentiment_books唯一值:[‘positive’ ‘negative’] -
Sentiment_books值计数:Sentiment_books正面 84 条,负面 16 条。名称:计数,数据类型:int64
[End of prompt]
您应该收到以下类似的响应:
[Prompt response]
太好了!现在我们已经探索了分类变量,让我们继续到第 5 步:星级评分的分布可视化。
# Step 5: Distribution of Ratings
import matplotlib.pyplot as plt
# Plot a histogram for star ratings
plt.hist(df['star_rating'], bins=5, edgecolor='black')
plt.title('Distribution of Star Ratings')
plt.xlabel('Star Ratings')
plt.ylabel('Frequency')
plt.show()
这段代码将绘制星级评分的直方图,这将帮助我们了解评论的整体情感。运行此代码并告诉我您发现了什么。
[End of response]
让我们尝试这个并看看它是否工作。下面,我们有执行可视化的代码;在代码单元格中运行此代码:
import matplotlib.pyplot as plt
# Plot the distribution of star ratings
plt.hist(df['star_rating'], bins=5, edgecolor='black')
plt.xlabel('Star Rating')
plt.ylabel('Frequency')
plt.title('Distribution of Star Ratings')
plt.show()
图 17.3:星级评分的分布
第 6 步:时序分析
到目前为止,我们对评分的分布有了很好的了解;它们似乎要么非常低,要么非常高。让我们继续下一步。
[Prompt]
进行下一步。
[End of prompt]
您应该收到以下类似的响应:
[Prompt response]
太好了!现在让我们继续到第 6 步:时序分析。我们将分析review_date列,以探索趋势、季节性或任何随时间变化的模式。
首先,我们需要将review_date列转换为日期时间格式。然后,我们可以将年、月和日提取到单独的列中,以便更容易分析。
# Step 6: Temporal Analysis
# Convert review_date to datetime format
df['review_date'] = pd.to_datetime(df['review_date'])
# Extract year, month, and day into separate columns
df['year'] = df['review_date'].dt.year
df['month'] = df['review_date'].dt.month
df['day'] = df['review_date'].dt.day
# Check the number of reviews per year
print(df['year'].value_counts().sort_index())
# Check the number of reviews per month
print(df['month'].value_counts().sort_index())
# Check the number of reviews per day
print(df['day'].value_counts().sort_index())
这段代码将打印每年、每月和每天的评论数量。运行此代码并告诉我您发现了什么。
[End of response]
让我们尝试这段代码看看它是否工作。在代码单元格中运行上述代码:
# Step 6: Temporal Analysis
# Convert review_date to datetime format
df['review_date'] = pd.to_datetime(df['review_date'])
# Extract year, month, and day into separate columns
df['year'] = df['review_date'].dt.year
df['month'] = df['review_date'].dt.month
df['day'] = df['review_date'].dt.day
# Check the number of reviews per year
print(df['year'].value_counts().sort_index())
# Check the number of reviews per month
print(df['month'].value_counts().sort_index())
# Check the number of reviews per day
print(df['day'].value_counts().sort_index())
您应该看到以下类似的输出:
year
2015 100
Name: count, dtype: int64
month
8 100
Name: count, dtype: int64
day
31 100
Name: count, dtype: int64
第 7 步:评论长度分析
让我们继续我们的分析;下一步是第 7 步:评论长度分析。
[Prompt]
下面是输出:年 2015 100 名称:计数,数据类型:int64 月 8 100 名称:计数,数据类型:int64 日 31 100 名称:计数,数据类型:int64
[End of prompt]
您应该收到以下类似的响应:
[Prompt response]
太好了!现在我们已经分析了数据的时序方面,让我们继续到第 7 步:评论长度分析。我们将分析review_body的长度,以了解评论中提供的信息量。
# Step 7: Review Length Analysis
# Calculate the length of each review
df['review_length'] = df['review_body'].str.len()
# Calculate descriptive statistics for review length
print(df['review_length'].describe())
这段代码将计算每条评论的长度,并提供描述性统计,如平均值、中位数和最大长度。运行此代码并告诉我您发现了什么。
[End of response]
到目前为止,我们想要了解上述代码在做什么;让我们向 Copilot 寻求帮助:
[Prompt]
在我们继续到第 7 步之前,您能解释一下如何解释输出吗?
[End of prompt]
您应该收到以下类似的响应:
[Prompt response]
绝对正确。您分享的输出表明了基于年、月和日的评论频率。
-
year: 您的数据集中所有 100 条评论都是在 2015 年写的。 -
month: 所有 100 条评论都是在第 8 个月写的,即 8 月。 -
day: 所有 100 条评论都是在该月的第 31 天写的。
这表明你数据集中的所有评论都是在同一天——2015 年 8 月 31 日——撰写的。
在一个更大、更多样化的数据集中,你可能看到评论分布在不同的年份、月份和日。分析这些评论可以帮助识别随时间变化的趋势或模式,例如在特定时期评论数量的增加。
[回复结束]
好吧,我们遇到了问题——我们的数据集有限,所有评论似乎都发生在同一时间点,这阻止了我们发现趋势。让我们通知 Copilot 并看看我们能做什么:
[提示]
在这种情况下,我们无法探索数据集中的趋势或模式。
[提示结束]
你应该收到以下类似的回复:
[提示回复]
这是正确的。由于这个数据集中的所有评论都来自同一天,我们无法分析随时间的变化趋势或模式。然而,你仍然可以进行其他类型的分析。例如,你可以分析评论的长度、星级评分的分布,或者在评论文本中分析某些单词或短语的频率。
如果你有一个更大、更多样化的数据集,你也可以分析随时间的变化趋势,比较不同的产品或类别,或者使用机器学习根据评论文本预测星级评分。
按计划进行评论长度分析:
# Step 7: Review Length Analysis
# Calculate the length of each review
df['review_length'] = df['review_body'].str.len()
# Calculate descriptive statistics for review length
print(df['review_length'].describe())
这段代码将计算每条评论的长度,并提供描述性统计,如平均值、中位数和最大长度。运行此代码并告诉我你的发现。
[回复结束]
让我们尝试这段代码看看它是否可行。将此代码输入到代码单元格中并运行:
# Step 7: Review Length Analysis
# Calculate the length of each review
df['review_length'] = df['review_body'].str.len()
# Calculate descriptive statistics for review length
print(df['review_length'].describe())
你应该看到以下类似的输出:
count 100.000000
mean 253.190000
std 420.934403
min 6.000000
25% 36.000000
50% 104.500000
75% 269.750000
max 2685.000000
Name: review_length, dtype: float64
[提示]
下面是输出结果:
count 100.000000 mean 253.190000 std 420.934403 min 6.000000 25% 36.000000 50% 104.500000 75% 269.750000 max 2685.000000 Name: review_length, dtype: float64
[提示结束]
你应该收到以下类似的回复。
[提示回复]
太好了!你分享的输出提供了你数据集中评论长度的总结:
-
count: 你的数据集中有 100 条评论。 -
mean: 平均而言,评论长度约为 253 个字符。 -
std: 标准差大约为 421,表明评论长度围绕平均值变化较大。 -
min: 最短的评论长度为 6 个字符。 -
25%: 25%的评论长度为 36 个字符或更短。 -
50%(或中位数):一半的评论长度为 104.5 个字符或更短。 -
75%: 75%的评论长度为 269.75 个字符或更短。 -
max: 最长的评论长度为 2685 个字符。
这条信息对于了解任何文本分析或自然语言处理任务中可用的文本量很有用。
对于下一步,您可以考虑可视化这些数据或分析评论的文本内容。例如,您可以创建评论长度的直方图,或者可以使用词云来可视化评论中最常见的单词。告诉我您下一步想做什么。
[响应结束]
第 8 步:相关性分析
现在,我们想要确定两个或多个变量之间的关系,以了解哪些变量是相关的。以下提示显示了我们在分析中的进展:
[提示]
进行下一步进行相关性分析。
[提示结束]
您应该收到与以下类似的响应:
[快速响应]
当然,让我们继续到第 8 步:相关性分析。我们将分析 star_rating、helpful_votes 和 total_votes 等数值变量之间的相关性。
# Step 8: Correlation Analysis
# Calculate the correlation matrix
correlation_matrix = df[['star_rating', 'helpful_votes', 'total_votes']].corr()
# Print the correlation matrix
print(correlation_matrix)
此代码将计算并打印出相关性矩阵,它显示了变量对之间的相关系数。相关系数的范围从 -1 到 1。接近 1 的值表示高度正相关,而接近 -1 的值表示高度负相关。接近 0 的值表示没有相关性。运行此代码并告诉我您发现了什么。
[响应结束]
让我们尝试这段代码,看看它是否可行。将相关性代码添加到您的笔记本中的代码单元格中并运行它:
# Step 8: Correlation Analysis
# Calculate the correlation matrix
correlation_matrix = df[['star_rating', 'helpful_votes', 'total_votes']].corr()
# Print the correlation matrix
print(correlation_matrix)
您应该看到与以下类似的输出:
star_rating helpful_votes total_votes
star_rating 1.000000 -0.324371 -0.517002
helpful_votes -0.324371 1.000000 0.659612
total_votes -0.517002 0.659612 1.000000
接下来,让我们将上述输出发送到 Copilot,看看我们是否能得到对相关性的解释:
[提示]
以下为输出结果:star_rating helpful_votes total_votes star_rating 1.000000 -0.324371 -0.517002 helpful_votes -0.324371 1.000000 0.659612 total_votes -0.517002 0.659612 1.000000
[响应结束]
您应该收到与以下类似的响应:
[快速响应]
太好了!您分享的输出是一个相关性矩阵,它显示了变量对之间的相关系数。以下是解释方法:
-
star_rating和helpful_votes:相关系数为 -0.324371,表明弱负相关。这表明随着星级评分的增加,有帮助的投票数往往会略有减少,反之亦然。 -
star_rating和total_votes:相关系数为 -0.517002,表明中等程度的负相关。这表明随着星级评分的增加,总投票数(包括有帮助和无帮助的投票)往往会减少,反之亦然。 -
helpful_votes和total_votes:相关系数为 0.659612,表明中等程度的正相关。这表明随着有帮助的投票数的增加,总投票数也倾向于增加,反之亦然。
对于下一步,您可以考虑使用热图可视化这些相关性,或者您可以继续进行另一种类型的分析。告诉我您下一步想做什么。
[响应结束]
接下来,我们想要查看这些相关性的可视化;热图是其中一种方法。
[提示]
对于第 8.1 步,使用热图可视化这些相关性。
[提示结束]
你应该收到以下类似的响应:
[提示响应]
当然,让我们使用热图可视化相关矩阵。我们将使用 seaborn 库来完成这项工作。
# Step 8.1: Visualize Correlation Matrix with Heatmap
import seaborn as sns
# Plot a heatmap of the correlation matrix
plt.figure(figsize=(8, 6))
sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm', center=0)
plt.title('Correlation Matrix Heatmap')
plt.show()
此代码将创建相关矩阵的热图。颜色代表相关系数:暖色(趋向红色)表示正相关,冷色(趋向蓝色)表示负相关,中性颜色(围绕白色)表示无相关。annot=True选项将在热图上显示相关系数。运行此代码并告诉我你发现了什么。
[响应结束]
让我们尝试这段代码,使用 seaborn 库创建热图可视化,看看它是否工作。在 Notebook 中的代码单元格中运行此代码:
# Step 8.1: Visualize Correlation Matrix with Heatmap
import seaborn as sns
# Plot a heatmap of the correlation matrix
plt.figure(figsize=(8, 6))
sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm', center=0)
plt.title('Correlation Matrix Heatmap')
plt.show()
你应该看到以下类似的输出:
图 17.4:显示三个变量之间相关性的热图:总票数、有帮助的票数和星级评分
第 9 步:额外的探索性分析
那么,为什么我们想要进行额外的探索性分析呢?好吧,有一些很好的理由我们会想要做那件事:
-
揭示隐藏的用户模式:有时,有一些趋势、模式和关系不是立即可发现的,进行第二次更深入的观察可以找到这些。
-
验证初步发现:通过用第二次分析验证初步分析的结果,你可以确保结果的稳健性和可靠性。
-
识别异常值:未能有效地找到异常值可能会歪曲结果。在这些异常值上花费更多时间可能会得到回报。
-
提高模型准确性:可以识别出能够提高准确性的额外变量。
上面的列表并不是我们应该进行额外分析的所有原因。让我们看看 Copilot 如何帮助我们:
[提示]
感谢,我想了解是否还有更多关于此数据集情感分析的探索性分析。
[提示结束]
你应该收到以下类似的响应:
[提示响应]
当然,情感分析通常涉及更深入地探索文本数据。以下是一些你可以考虑的额外步骤:
第 10 步:文本预处理
在分析文本之前,通常有助于对其进行一些清理。这可能包括将所有文本转换为小写,删除标点符号,删除停用词(如“和”、“the”、“a”等常见词汇,它们不会增加太多意义),以及词干提取或词形还原(将单词还原到其基本形式)。
from nltk.corpus import stopwords
from nltk.stem import PorterStemmer
import re
# Initialize a PorterStemmer object to perform stemming
stemmer = PorterStemmer()
# Define a function to preprocess the text
def preprocess_text(text):
# Convert to lower case
text = text.lower()
# Remove punctuation
text = re.sub(r'[^\w\s]', '', text)
# Remove stop words and stem the words
text = ' '.join([stemmer.stem(word) for word in text.split() if word not in stopwords.words('english')])
return text
# Apply the function to the review_body column
df['review_body_clean'] = df['review_body'].apply(preprocess_text)
第 11 步:单词频率分析
在预处理文本后,你可以分析评论中的单词频率。这有助于识别常见的主题或话题。
from collections import Counter
# Count the frequency of words in the reviews
word_counts = Counter(' '.join(df['review_body_clean']).split())
# Print the 10 most common words
print(word_counts.most_common(10))
第 12 步:情感评分计算
你可以使用 TextBlob 或 Vader 等情感分析工具为每条评论计算情感评分。这可以提供对评论中表达的情感的更定量度量。
from textblob import TextBlob
# Define a function to calculate sentiment
def calculate_sentiment(text):
return TextBlob(text).sentiment.polarity
# Apply the function to the review_body_clean column
df['sentiment_score'] = df['review_body_clean'].apply(calculate_sentiment)
# Print the average sentiment score
print(df['sentiment_score'].mean())
请注意,你需要安装nltk和textblob库来运行此代码,你可以使用pip来安装:
pip install nltk textblob
如果你想继续以上任何步骤,或者有其他需要做的事情,请告诉我。
[响应结束]
这个提示产生了三个步骤作为响应。让我们尝试这三个步骤中的代码,看看是否可行:
文本预处理
# uncomment if the nltk and textblob are not installed
# !pip install nltk textblob
from nltk.corpus import stopwords
from nltk.stem import PorterStemmer
import re
# Initialize a PorterStemmer object to perform stemming
stemmer = PorterStemmer()
# Define a function to preprocess the text
def preprocess_text(text):
# Convert to lower case
text = text.lower()
# Remove punctuation
text = re.sub(r'[^\w\s]', '', text)
# Remove stop words and stem the words
text = ' '.join([stemmer.stem(word) for word in text.split() if word not in stopwords.words('english')])
return text
# Apply the function to the review_body column
df['review_body_clean'] = df['review_body'].apply(preprocess_text)
单词频率分析
from collections import Counter
# Count the frequency of words in the reviews
word_counts = Counter(' '.join(df['review_body_clean']).split())
# Print the 10 most common words
print(word_counts.most_common(10))
你应该看到以下类似的输出:
[('book', 80), ('read', 25), ('love', 24), ('great', 24), ('stori', 19), ('good', 17), ('page', 16), ('one', 15), ('like', 14), ('realli', 14)]
接下来,使用上面的输出构建下一个提示,以更好地了解我们的情况:
[提示]
对于下面的代码:
from collections import Counter
# Count the frequency of words in the reviews
word_counts = Counter(' '.join(df['review_body_clean']).split())
# Print the 10 most common words
print(word_counts.most_common(10))
下面是输出:[(‘book’,80),(‘read’,25),(‘love’,24),(‘great’,24),(‘stori’,19),(‘good’,17),(‘page’,16),(‘one’,15),(‘like’,14),(‘realli’,14)]
[提示结束]
你应该收到以下类似的响应:
[响应提示]
太好了!你分享的输出显示了清洗后的评论中最常见的 10 个单词及其频率:
'book': Appears 80 times
'read': Appears 25 times
'love': Appears 24 times
'great': Appears 24 times
'stori': Appears 19 times
'good': Appears 17 times
'page': Appears 16 times
'one': Appears 15 times
'like': Appears 14 times
'realli': Appears 14 times
这表明大多数评论都是积极的,像“喜欢”、“优秀”和“好”这样的词在评论中相当常见。在书评数据集中,“book”、“read”和“page”这些词也很常见,这是预期的。
对于下一步,你可以考虑为每个评论计算情感分数,以获得更量化的情感度量。或者,你可以使用条形图或词云可视化单词频率。请告诉我你下一步想做什么。
[响应结束]
让我们尝试运行下面的情感分数计算代码:
情感分数计算
from textblob import TextBlob
# Define a function to calculate sentiment
def calculate_sentiment(text):
return TextBlob(text).sentiment.polarity
# Apply the function to the review_body_clean column
df['sentiment_score'] = df['review_body_clean'].apply(calculate_sentiment)
# Print the average sentiment score
print(df['sentiment_score'].mean())
这里是输出:
0.23785470981747298
接下来,让我们尝试解释这个响应。像往常一样,让我们从响应中创建一个提示,看看 Copilot 对这个提示的看法:
[提示]
对于下面的代码:
from textblob import TextBlob
# Define a function to calculate sentiment
def calculate_sentiment(text):
return TextBlob(text).sentiment.polarity
# Apply the function to the review_body_clean column
df['sentiment_score'] = df['review_body_clean'].apply(calculate_sentiment)
# Print the average sentiment score
print(df['sentiment_score'].mean())
这里是输出结果:0.23785470981747298
[提示结束]
你应该收到以下类似的响应:
[响应提示]
太好了!你分享的输出是你数据集中评论的平均情感分数。
情感分数是一个介于-1 和 1 之间的数字。-1 表示极端负面情感,1 表示极端正面情感,0 表示中性情感。
在你的数据集中,平均情感分数大约为 0.238,这表明评论总体上呈现积极情感。这与单词频率分析结果一致,显示“喜欢”、“优秀”和“好”等积极词汇在评论中相当常见。
对于下一步,你可以考虑使用直方图或箱线图可视化情感分数的分布。或者,你可以分析情感分数与其他变量(如星级评分或评论长度)之间的关系。请告诉我你下一步想做什么。
[响应结束]
[提示]
按照以下步骤逐步操作:
-
使用直方图可视化情感分数的分布。
-
分析情感分数与其他变量(如星级评分或评论长度)之间的关系。
[结束提示]
你应该会收到与以下回复类似的回复。
[提示回复]
当然,让我们继续执行这些步骤。
步骤 13:可视化情感分数的分布
我们可以使用直方图来可视化情感分数的分布。
import matplotlib.pyplot as plt
# Plot a histogram of the sentiment scores
plt.figure(figsize=(8, 6))
plt.hist(df['sentiment_score'], bins=20, color='skyblue')
plt.title('Distribution of Sentiment Scores')
plt.xlabel('Sentiment Score')
plt.ylabel('Frequency')
plt.show()
步骤 14:分析情感分数与其他变量之间的关系
我们可以使用散点图来可视化情感分数与其他变量(如星级评分和评论长度)之间的关系。
# Plot a scatter plot of sentiment score vs star rating
plt.figure(figsize=(8, 6))
plt.scatter(df['sentiment_score'], df['star_rating'], alpha=0.5, color='skyblue')
plt.title('Sentiment Score vs Star Rating')
plt.xlabel('Sentiment Score')
plt.ylabel('Star Rating')
plt.show()
# Plot a scatter plot of sentiment score vs review length
plt.figure(figsize=(8, 6))
plt.scatter(df['sentiment_score'], df['review_length'], alpha=0.5, color='skyblue')
plt.title('Sentiment Score vs Review Length')
plt.xlabel('Sentiment Score')
plt.ylabel('Review Length')
plt.show()
这些图表将帮助你了解情感分数与星级评分或评论长度之间是否存在任何相关性。运行这些代码,并告诉我你发现了什么。
[结束回复]
让我们尝试上面的代码,看看它是否可行。将以下代码添加到一个代码单元格中并运行:
可视化情感分数的分布
import matplotlib.pyplot as plt
# Plot a histogram of the sentiment scores
plt.figure(figsize=(8, 6))
plt.hist(df['sentiment_score'], bins=20, color='skyblue')
plt.title('Distribution of Sentiment Scores')
plt.xlabel('Sentiment Score')
plt.ylabel('Frequency')
plt.show()
图 17.5:描述情感分数分布的图像
分析情感分数与其他变量之间的关系
# Plot a scatter plot of sentiment score vs star rating
plt.figure(figsize=(8, 6))
plt.scatter(df['sentiment_score'], df['star_rating'], alpha=0.5, color='skyblue')
plt.title('Sentiment Score vs Star Rating')
plt.xlabel('Sentiment Score')
plt.ylabel('Star Rating')
plt.show()
# Plot a scatter plot of sentiment score vs review length
plt.figure(figsize=(8, 6))
plt.scatter(df['sentiment_score'], df['review_length'], alpha=0.5, color='skyblue')
plt.title('Sentiment Score vs Review Length')
plt.xlabel('Sentiment Score')
plt.ylabel('Review Length')
plt.show()
图 17.6:情感分数与星级评分的关系
图 17.7:情感分数与评论长度的关系
作业
你的任务是反思所采取的方法,并针对波士顿房价数据集进行类似的回归场景:www.kaggle.com/datasets/vikrishnan/boston-house-prices。
这里有一些问题,你可以尝试使用上述数据集和回归来回答:
-
价格预测:给定房屋的特征(例如,大小、位置和卧室数量),估计房屋的价格是多少?
-
特征重要性:哪些特征对房价影响最大?
-
价格趋势:在特定地区,房价随时间如何变化?
解决方案
解决方案在仓库中:github.com/PacktPublishing/AI-Assisted-Software-Development-with-GitHub-Copilot-and-ChatGPT
摘要
本章有一个重要的目的——比较和对比使用 ChatGPT 与 GitHub Copilot 以及在此情况下其聊天功能的经验。我们采取的方法是向 Copilot 提供大量前置信息,通过描述整体问题和数据集的形状。我们还提供了指令,让 Copilot 引导我们做什么,这显示了逐步采取的步骤和要运行的代码。总体结论是,我们可以使用与 ChatGPT 类似的方法使用 Copilot Chat。
我们还看到了 Copilot 如何帮助我们解释输出,了解我们在过程中的位置,并建议下一步要采取的行动。
根据规则,我们应该始终测试代码,如果代码无法运行或产生预期的输出,我们应该请求我们的 AI 助手帮助。
加入我们的 Discord 社区
加入我们的 Discord 空间,与作者和其他读者进行讨论:
第十八章:使用 Copilot Chat 进行回归
简介
公司的股票代表对公司所有权的拥有。一股股票代表对公司资产和收益的份额要求,与总股数成比例。例如,如果投资者持有某公司 50 股股票,而该公司总共有 1,000 股,那么该投资者(或股东)将拥有并有权要求公司 5%的资产和收益。
公司的股票可以通过证券交易所和组织在股东和其他各方之间进行交易。主要的证券交易所包括纽约证券交易所、纳斯达克、伦敦证券交易所集团、上海证券交易所和香港证券交易所。股票的交易价格基本上是由于供求定律而波动。在任何时刻,供应是公众投资者手中的股票数量,需求是投资者想要购买的股票数量,股票价格上下波动以实现并维持平衡。
投资者通常希望低价买入、高价卖出。这似乎很简单,但将其付诸实践却极其困难,因为预测股票价格是涨是跌极其困难。基本面分析和技术分析是两个主要的研究领域,旨在理解影响价格波动的原因和情况,甚至预测未来的股票价格:
-
基本面分析:这个流派专注于影响公司价值和运营的基本要素,例如宏观经济环境、行业状况以及公司的管理和竞争对手。
-
技术分析:另一方面,这使用历史交易活动的统计分析,如价格变动、成交量和时间,来预测未来的价格变动。
在本章中,我们将使用苹果数据集来探索第二种技术,预测股价并帮助投资者决定是否买入。
回归
让我们先向 Copilot Chat 询问回归的定义:
[提示]
什么是回归?
[提示结束]
您应该收到以下类似响应:
[快速响应]
回归是数据分析中使用的统计方法,它研究因变量(目标)和自变量(预测变量)之间的关系。这种方法主要用于预测、时间序列建模和寻找变量之间的因果关系。例如,降雨量和土壤侵蚀之间的关系或工资和经验年数之间的关系。
[响应结束]
你可能会在聊天框中注意到 GitHub Copilot 建议下一个上下文,以蓝色突出显示,询问“有哪些不同的回归类型?”。你可以点击它来获取答案。这展示了 Copilot 是如何作为一个强大的工具来有效协助用户的。
数据集概述
该数据集包含苹果公司(AAPL)10 年的股票数据。从这些数据中可以获得见解,可用于构建有用的价格预测算法,以帮助投资。
我们可以就这个数据集做以下笔记:
-
数据是从 25 个交易所收集和汇总的。
-
数据每周更新。
-
该数据集包含 AAPL 的 1 分钟、5 分钟、30 分钟和 1 小时 K 线(开盘/最高/最低/收盘/成交量)。
-
包含盘后交易。价格已调整以反映拆股和股息。数据集可在
www.kaggle.com/datasets/tarunpaparaju/apple-aapl-historical-stock-data找到。
探索数据集
为了更好地说明这种回归方法,我们需要为我们的目标有合适的预测因子。该数据集记录了与股票更直接相关的元素。五个表示在一个时间单位(通常是第一天,但也可以是一周或一个月)内价格变动的值是关键交易指标。
它们如下:
-
开盘价:给定交易日的起始价格
-
收盘价:该天的最终价格
-
高:该股票当天交易的最高价格
-
低:该股票当天交易的最高价格
-
成交量:在市场收盘前当天交易的总股数
提示策略
在本章中,我们将使用 TAG(任务-操作-指导)提示模式。以下是我们可以如何帮助构建我们的项目以帮助我们编写初始提示的方法:
-
任务:通过历史数据对苹果股票价值进行回归分析
-
操作:我们需要指示 AI 助手告诉我们需要采取哪些步骤
-
指导:指导应该是我们描述数据集
你的初始提示
就像本书中的其他章节一样,我们从一个尽可能提供我们想要做什么以及数据集形状的提示开始。我们的想法是为我们的 AI 工具设定一个高级上下文,这有助于它在我们的其他提示中引导。
[提示]
我正在进行一个回归项目,使用苹果历史股票数据集来预测股票价格。这将帮助投资者在购买或不购买股票时做出明智的决定。工作流程包括加载数据集、探索其内容、拆分数据集、构建回归模型和评估其性能。但请记住,我想一步一步地学习。让我们从加载数据集开始。我将数据集存储在<文件路径>。以下是数据集的形状:
-
开盘价:给定交易日的起始价格
-
收盘价:该天的最终价格
-
高:该股票当天交易的最高价格
-
Low:那天股票交易中的最低价格
-
Volume:在那天市场收盘前交易的股票总数
[提示结束]
你应该收到以下类似的响应:
[提示响应]
当然,让我们从加载数据集开始。我们将使用 Python 中的 pandas 库来完成此操作。将<file-path>替换为你的文件所在路径。
下面是加载数据集的 Python 代码:
import pandas as pd
# Replace <file-path> with the path of your dataset
file_path = "<file-path>"
# Load the dataset
df = pd.read_csv(file_path)
# Display the first few rows of the dataset
print(df.head())
运行此代码后,你应该看到数据集的前几行打印出来。这将为你提供一个初步的数据视图。
对于下一步,你可能想要探索数据集,如果需要的话清理数据,将数据集分为训练集和测试集,使用训练集构建回归模型,然后使用测试集评估模型的性能。
[响应结束]
让我们尝试 Copilot 生成的输出,看看它是否工作。将file_path变量修改为指向你的数据集位置,然后在笔记本中的代码单元中执行以下代码:
import pandas as pd
# Replace <file-path> with the path of your dataset
file_path = "/your-path/.csv"
# Load the dataset
df = pd.read_csv(file_path)
# Display the first few rows of the dataset
print(df.head())
在运行上述代码后,你应该看到以下输出:
Date Close/Last Volume Open High Low
0 02/28/2020 $273.36 106721200 $257.26 $278.41 $256.37
1 02/27/2020 $273.52 80151380 $281.1 $286 $272.96
2 02/26/2020 $292.65 49678430 $286.53 $297.88 $286.5
3 02/25/2020 $288.08 57668360 $300.95 $302.53 $286.13
4 02/24/2020 $298.18 55548830 $297.26 $304.18 $289.23
接下来,我们将专注于历史价格(记录的五项值)和性能来预测未来价格。让我们先检查数据类型。
[提示]
检查数据类型。
[提示结束]
你应该收到以下类似的响应:
[提示响应]
要检查你的DataFrame中列的数据类型,你可以使用dtypes属性。以下是你可以这样做的示例:
# Check the data types of each column
print(df.dtypes)
这将打印出每个列的名称及其数据类型。这很有用,因为某些操作只能在某些类型的数据上执行。例如,你不能在字符串上执行数值操作。
[响应结束]
让我们尝试一下,看看它是否工作。运行代码 print(df.types):
# Check the data types of each column
print(df.dtypes)
Date object
Close/Last object
Volume int64
Open object
High object
Low object
dtype: object
现在,使用上述输出查询我们的 AI 工具。
[提示]
下面是输出,Date 对象 Close/Last 对象 Volume int64 Open 对象 High 对象 Low 对象 dtype: object
[提示结束]
你应该收到以下类似的响应:
[提示响应]
看起来日期列和价格列(‘Close/Last’,‘Open’,‘High’,‘Low’)被读取为‘object’类型,这在 pandas 中本质上是一个字符串。然而,对于你的分析,你希望‘Date’列是日期时间格式,价格列是浮点类型。
下面是如何转换数据类型的示例:
# Convert 'Date' to datetime
df['Date'] = pd.to_datetime(df['Date'])
# Remove $ from price columns and convert to float
price_columns = [' Close/Last', ' Open', ' High', ' Low']
for col in price_columns:
df[col] = df[col].str.replace('$', '').astype(float)
# Check the data types again
print(df.dtypes)
此代码首先使用pd.to_datetime()将‘Date’列转换为日期时间格式。然后它遍历每个价格列,从每个值中移除美元符号,并将列转换为浮点类型。最后,它再次打印出列的数据类型以确认更改。
[响应结束]
让我们尝试上述建议,通过运行以下代码来转换我们的列:
# Convert 'Date' to datetime
df['Date'] = pd.to_datetime(df['Date'])
# Remove $ from price columns and convert to float
price_columns = [' Close/Last', ' Open', ' High', ' Low']
for col in price_columns:
df[col] = df[col].str.replace('$', '').astype(float)
# Check the data types again
print(df.dtypes)
你应该看到以下输出,这是正确转换为合适类型的列而不是字符串:
Date datetime64[ns]
Close/Last float64
Volume int64
Open float64
High float64
Low float64
dtype: object
接下来,让我们告诉 Copilot 结果,以确保它能告诉我们下一步该做什么。
[提示]
下面是输出结果,日期 datetime64[ns] 收盘/最后 float64 成交量 int64 开盘 float64 最高 float64 最低 float64 数据类型:object
[提示结束]
你应该会收到类似于以下响应:
[提示响应]
太好了!现在你的‘Date’列是‘datetime64[ns]’类型,你的价格列(‘Close/Last’,‘Open’,‘High’,‘Low’)是‘float64’类型。这意味着你现在可以对价格列进行数值运算,并对‘Date’列进行时间序列分析。
下一步可能是进行探索性数据分析,例如检查缺失值、可视化变量的分布或检查不同变量之间的相关性。你可能还想要将数据分成训练集和测试集,为构建回归模型做准备。
[响应结束]
探索性数据分析
根据输出结果决定下一步操作,我们决定检查数据集中的缺失值:
[提示]
检查缺失值。
[响应结束]
你应该会收到类似于以下响应:
[提示响应]
要检查DataFrame中的缺失值,你可以使用 pandas 中的isnull()函数和sum()函数。下面是如何操作的:
# Check for missing values
print(df.isnull().sum())
这将打印出你DataFrame中每一列的缺失值数量。如果一个列的缺失值数量为零,这意味着该列没有缺失值。如果一个列的缺失值数量大于零,那么这个数字就是该列的缺失值数量。
[响应结束]
Copilot 的响应建议检查空值,并提供了相应的代码。让我们在一个笔记本的代码单元中运行建议的代码:
# Check for missing values
print(df.isnull().sum())
这里是输出:
Date 0
Close/Last 0
Volume 0
Open 0
High 0
Low 0
dtype: int64
使用这个输出,将其提供给 Copilot 以了解下一步该做什么:
[提示]
下面是输出结果,日期 0 收盘/最后 0 成交量 0 开盘 0 最高 0 最低 0 数据类型:int64
[提示结束]
你应该会收到类似于以下响应:
[提示响应]
太好了!输出结果显示,你的数据集中没有缺失值。每一列的缺失值都是 0。这是一个好消息,因为它意味着你不需要处理缺失数据,这可能会是一个复杂的过程。
分析的下一步可能是进行一些探索性数据分析(EDA)。这可能包括可视化数据、检查异常值或检查变量之间的关系。之后,你可以继续将数据分成训练集和测试集,然后构建回归模型。
[响应结束]
太好了,我们没有缺失值,看起来下一步应该是进行可视化分析和检查异常值。有了这些知识,让我们制定一个合适的提示。
[提示]
可视化数据和检查异常值。
[提示结束]
你应该会收到类似于以下响应:
[提示响应]
使用 Python 中的各种库,如 Matplotlib 或 Seaborn,可以可视化数据。对于检查异常值,箱线图非常有用。以下是如何为您价格列创建箱线图的示例:
import matplotlib.pyplot as plt
import seaborn as sns
# Set up the matplotlib figure
f, axes = plt.subplots(2, 2, figsize=(15, 10))
# Plot a simple histogram with binsize determined automatically
sns.boxplot(data=df[' Close/Last'], ax=axes[0, 0])
axes[0, 0].set_title('Close/Last')
sns.boxplot(data=df[' Open'], ax=axes[0, 1])
axes[0, 1].set_title('Open')
sns.boxplot(data=df[' High'], ax=axes[1, 0])
axes[1, 0].set_title('High')
sns.boxplot(data=df[' Low'], ax=axes[1, 1])
axes[1, 1].set_title('Low')
plt.tight_layout()
此代码将创建一个 2x2 的图表网格,每个图表都是一个价格列的箱线图。箱线图有助于可视化数据的分布并识别潜在的异常值。在箱线图中,异常值通常表示为位于箱线图胡须之外的点。
[响应结束]
上述代码建议使用 matplotlib 和 seaborn 库,并包含创建箱线图可视化的代码;让我们运行这段代码:
import matplotlib.pyplot as plt
import seaborn as sns
# Set up the matplotlib figure
f, axes = plt.subplots(2, 2, figsize=(15, 10))
# Plot a simple histogram with binsize determined automatically
sns.boxplot(data=df[' Close/Last'], ax=axes[0, 0])
axes[0, 0].set_title('Close/Last')
sns.boxplot(data=df[' Open'], ax=axes[0, 1])
axes[0, 1].set_title('Open')
sns.boxplot(data=df[' High'], ax=axes[1, 0])
axes[1, 0].set_title('High')
sns.boxplot(data=df[' Low'], ax=axes[1, 1])
axes[1, 1].set_title('Low')
plt.tight_layout()
你应该看到以下箱线图类似的结果:
图 18.1:数据集的箱线图
接下来,我们想要了解更多关于我们的变量及其关系的信息。
[提示]
检查变量之间的关系。
[提示结束]
你应该收到以下类似响应:
[提示响应]
要检查变量之间的关系,你可以使用相关矩阵和热图。相关矩阵将给出代表两个变量之间相关程度数值的数值,而热图将给出这些关系的视觉表示。
这是你可以这样做的:
# Calculate the correlation matrix
corr = df.corr()
# Plot the heatmap
sns.heatmap(corr, annot=True, cmap='coolwarm')
plt.show()
此代码首先使用 corr() 函数计算相关矩阵,该函数返回一个 DataFrame,其中每个单元格代表两个变量之间的相关系数。然后它使用此相关矩阵绘制热图。annot=True 参数允许在热图上绘制相关系数,而 cmap='coolwarm' 参数设置热图的颜色方案。
相关系数的范围从 -1 到 1。接近 1 的值表示高度正相关,而接近 -1 的值表示高度负相关。接近 0 的值表示没有相关性。
[响应结束]
响应表示我们应该创建一个相关矩阵并通过热图可视化它。让我们尝试上面的建议代码并看看我们得到什么:
# Calculate the correlation matrix
corr = df.corr()
# Plot the heatmap
sns.heatmap(corr, annot=True, cmap='coolwarm')
plt.show()
上述代码的输出如下:
图 18.2:热图
在热图中,我们可以看到:
-
对角线始终为 1,因为它显示了每个变量与其自身的相关性。
-
收盘价/最新价、开盘价、最高价和最低价之间高度正相关(0.92),表明当一个变量增加时,其他变量也倾向于增加。这在股票数据中很典型,因为这些价格在交易日内紧密移动。
-
成交量与收盘价/最新价、开盘价、最高价和最低价呈负相关(-0.61)。这表明,在交易量较高的日子,价格可能倾向于较低,反之亦然。
如下面的截图所示,Copilot 推荐在分析变量关系之后下一步的操作。我们将选择这个并看看它说了什么。
让我们询问 Copilot 下一步该做什么。
[提示]
在检查变量之间的关系之后,下一步是什么?
[提示结束]
你应该收到一个类似于以下响应的回复:
[响应提示]
在检查变量之间的关系之后,接下来的步骤通常是准备你的数据以进行建模。这可能涉及几个子步骤:
-
特征选择:根据你的相关性分析,你可能会决定删除与目标变量不相关的某些特征,或者为了避免多重共线性,删除两个高度相关的特征中的一个。
-
数据分割:你需要将数据分割成训练集和测试集。常见的分割是 80%的数据用于训练,20%用于测试。
-
数据缩放:根据你计划使用的模型,你可能需要缩放你的数据,以便所有特征都有相似的范围值。
一旦你的数据准备好了,你就可以继续构建你的回归模型。
[响应结束]
数据分割
在这个阶段,让我们为创建模型做准备。在我们能够创建模型之前,我们需要将我们的数据分成训练数据和测试集,以便稍后验证模型。
[提示]
让我们继续到分割数据的步骤。
[提示结束]
你应该收到一个类似于以下响应的回复:
[响应提示]
绝对,将数据分割成训练集和测试集是准备数据以进行建模的关键步骤。我们将使用sklearn.model_selection中的train_test_split函数来完成此操作。
假设我们将预测‘收盘/最后’价格,以下是你可以分割数据的方式:
from sklearn.model_selection import train_test_split
# Define the feature variables and the target variable
X = df.drop(' Close/Last', axis=1)
y = df[' Close/Last']
# Split the data into training set and test set
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
此代码首先定义了特征变量 X 和目标变量 y,然后将其分割成训练集和测试集,其中 80%的数据用于训练集,20%的数据用于测试集。random_state参数用于可重复性 - 使用相同的random_state将确保每次运行代码时都得到相同的训练/测试分割。
[响应结束]
简而言之,上面的代码展示了如何分割我们的数据集;让我们尝试这段代码:
from sklearn.model_selection import train_test_split
# Define the feature variables and the target variable
X = df.drop(' Close/Last', axis=1)
y = df[' Close/Last']
# Split the data into training set and test set
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
在这个阶段,我们没有输出可以显示,因为我们已经将结果分配给了变量。然而,让我们打印出下一个。
[提示]
打印样本的形状。
[提示结束]
你应该收到一个类似于以下响应的回复:
[响应提示]
要打印你的训练和测试样本的形状,你可以使用形状属性。以下是你可以这样做的方式:
# Print the shape of the training set and the test set
print("Training set (X):", X_train.shape)
print("Training set (y):", y_train.shape)
print("Test set (X):", X_test.shape)
print("Test set (y):", y_test.shape)
这将打印出你的训练集和测试集的行数和列数。X_train和y_train之间以及X_test和y_test之间的行数应该是相同的。X_train和X_test中的列数应该相同,而y_train和y_test各自应该只有一列(因为它们代表目标变量)。
[响应结束]
建议的代码很简单,因为它只包含一系列打印语句。让我们在一个代码单元格中运行这段代码来试试:
# Print the shape of the training set and the test set
print("Training set (X):", X_train.shape)
print("Training set (y):", y_train.shape)
print("Test set (X):", X_test.shape)
print("Test set (y):", y_test.shape)
你应该看到类似于以下的输出:
Training set (X): (2014, 5)
Training set (y): (2014,)
Test set (X): (504, 5)
Test set (y): (504,)
构建一个回归模型
现在我们已经分割了数据,接下来让我们训练模型,或者至少这是我们期望 Copilot 在询问下一步时会说的。让我们创建一个只询问这一点的提示:
[提示]
数据分割后的下一步是什么?
[提示结束]
你应该收到一个类似于以下响应:
[快速响应]
在分割数据后,下一步是使用训练数据创建和训练你的回归模型。根据你的数据性质和你要解决的问题,你可能选择一个简单的线性回归模型,或者一个更复杂的模型,如多项式回归或岭回归。
模型训练完成后,你可以使用它对测试数据进行预测。然后,通过比较这些预测与测试数据中的实际值来评估模型的性能。评估回归模型的常用指标包括平均绝对误差(MAE)、平均平方误差(MSE)和 R 平方。
[响应结束]
好的,正如我们所想的,下一步是训练模型。让我们创建一个提示,询问如何更详细地训练模型:
[提示]
创建并训练一个回归模型。
[提示结束]
你应该收到一个类似于以下响应:
[快速响应]
当然,让我们使用训练数据创建并训练一个简单的线性回归模型。我们将使用sklearn.linear_model中的LinearRegression类来完成这个任务。
下面是如何创建和训练你的模型:
from sklearn.linear_model import LinearRegression
# Create a Linear Regression model
model = LinearRegression()
# Train the model
model.fit(X_train, y_train)
此代码首先创建一个线性回归模型。然后使用 fit 方法和训练数据来训练模型。完成此步骤后,你的模型就可以对未见数据做出预测了。
请注意,如果你的数据具有非线性关系,你可能需要使用更复杂的模型,如多项式回归或基于树的模型。此外,如果你的特征不在同一尺度上,你可能需要在训练模型之前对数据进行缩放。
[响应结束]
我们已经收到了有关使用线性回归和 sklearn 库的响应。请注意,在继续之前,你可能需要安装这个库。一旦你确保 sklearn 已安装,请继续运行以下建议的代码:
from sklearn.linear_model import LinearRegression
# Create a Linear Regression model
model = LinearRegression()
# Train the model
model.fit(X_train, y_train)
这里是运行代码的输出:
---------------------------------------------------------------------------
DTypePromotionError Traceback (most recent call last)
File ~/.conda/envs/myenv/lib/python3.12/site-packages/sklearn/base.py:1152, in _fit_context.<locals>.decorator.<locals>.wrapper(estimator, *args, **kwargs)
1145 estimator._validate_params()
1147 with config_context(
1148 skip_parameter_validation=(
1149 prefer_skip_nested_validation or global_skip_validation
1150 )
1151 ):
-> 1152 return fit_method(estimator, *args, **kwargs)
File ~/.conda/envs/myenv/lib/python3.12/site-packages/sklearn/linear_model/_base.py:678, in LinearRegression.fit(self, X, y, sample_weight)
674 n_jobs_ = self.n_jobs
676 accept_sparse = False if self.positive else ["csr", "csc", "coo"]
--> 678 X, y = self._validate_data(
679 X, y, accept_sparse=accept_sparse, y_numeric=True, multi_output=True
680 )
682 has_sw = sample_weight is not None
683 if has_sw:
File ~/.conda/envs/myenv/lib/python3.12/site-packages/sklearn/base.py:622, in BaseEstimator._validate_data(self, X, y, reset, validate_separately, cast_to_ndarray, **check_params)
620 y = check_array(y, input_name="y", **check_y_params)
621 else:
--> 622 X, y = check_X_y(X, y, **check_params)
623 out = X, y
625 if not no_val_X and check_params.get("ensure_2d", True):
File ~/.conda/envs/myenv/lib/python3.12/site-packages/sklearn/utils/validation.py:1146, in check_X_y(X, y, accept_sparse, accept_large_sparse, dtype, order, copy, force_all_finite, ensure_2d, allow_nd, multi_output, ensure_min_samples, ensure_min_features, y_numeric, estimator)
1141 estimator_name = _check_estimator_name(estimator)
1142 raise ValueError(
1143 f"{estimator_name} requires y to be passed, but the target y is None"
1144 )
-> 1146 X = check_array(
1147 X,
1148 accept_sparse=accept_sparse,
1149 accept_large_sparse=accept_large_sparse,
1150 dtype=dtype,
1151 order=order,
1152 copy=copy,
1153 force_all_finite=force_all_finite,
1154 ensure_2d=ensure_2d,
1155 allow_nd=allow_nd,
1156 ensure_min_samples=ensure_min_samples,
1157 ensure_min_features=ensure_min_features,
1158 estimator=estimator,
1159 input_name="X",
1160 )
1162 y = _check_y(y, multi_output=multi_output, y_numeric=y_numeric, estimator=estimator)
1164 check_consistent_length(X, y)
File ~/.conda/envs/myenv/lib/python3.12/site-packages/sklearn/utils/validation.py:795, in check_array(array, accept_sparse, accept_large_sparse, dtype, order, copy, force_all_finite, ensure_2d, allow_nd, ensure_min_samples, ensure_min_features, estimator, input_name)
791 pandas_requires_conversion = any(
792 _pandas_dtype_needs_early_conversion(i) for i in dtypes_orig
793 )
794 if all(isinstance(dtype_iter, np.dtype) for dtype_iter in dtypes_orig):
--> 795 dtype_orig = np.result_type(*dtypes_orig)
796 elif pandas_requires_conversion and any(d == object for d in dtypes_orig):
797 # Force object if any of the dtypes is an object
798 dtype_orig = object
DTypePromotionError: The DType <class 'numpy.dtypes.DateTime64DType'> could not be promoted by <class 'numpy.dtypes.Float64DType'>. This means that no common DType exists for the given inputs. For example they cannot be stored in a single array unless the dtype is `object`. The full list of DTypes is: (<class
'numpy.dtypes.DateTime64DType'>, <class 'numpy.dtypes.Int64DType'>, <class 'numpy.dtypes.Float64DType'>, <class 'numpy.dtypes.Float64DType'>, <class 'numpy.dtypes.Float64DType'>)
我们显然得到了一个错误回复,所以让我们看看 Copilot 是否能帮助我们解决这个问题。像往常一样,包括错误文本等信息以获得良好的回复。
[提示]
我在运行代码后遇到了这个错误,
Cell 39 line 7 4 model = LinearRegression() 6 # Train the model ----> 7 model.fit(X_train, y_train)
File ~/.conda/envs/myenv/lib/python3.12/site-packages/sklearn/base.py:1152, in _fit_context..decorator..wrapper(estimator, *args, **kwargs) 1145 estimator._validate_params() 1147 with config_context( 1148 skip_parameter_validation=( 1149 prefer_skip_nested_validation or global_skip_validation 1150 ) 1151 ): -> 1152 return fit_method(estimator, *args, **kwargs)
File ~/.conda/envs/myenv/lib/python3.12/site-packages/sklearn/linear_model/base.py:678, in LinearRegression.fit(self, X, y, sample_weight) 674 n_jobs = self.n_jobs 676 accept_sparse = False if self.positive else ["csr", "csc", "coo"] --> 678 X, y = self._validate_data( 679 X, y, accept_sparse=accept_sparse, y_numeric=True, multi_output=True 680 ) 682 has_sw = sample_weight is not None 683 if has_sw: ... 796 elif pandas_requires_conversion and any(d == object for d in dtypes_orig): 797 # Force object if any of the dtypes is an object 798 dtype_orig = object
DTypePromotionError: The DType <class 'numpy.dtypes.DateTime64DType'> could not be promoted by <class 'numpy.dtypes.Float64DType'>. This means that no common DType exists for the given inputs. For example they cannot be stored in a single array unless the dtype is object. The full list of DTypes is: (<class 'numpy.dtypes.DateTime64DType'>, <class 'numpy.dtypes.Int64DType'>, <class 'numpy.dtypes.Float64DType'>, <class 'numpy.dtypes.Float64DType'>, <class 'numpy.dtypes.Float64DType'>)
[提示结束]
你应该会收到以下类似的回复:
[提示回复]
错误信息表明模型在处理‘日期’列时遇到麻烦,因为它是日期时间格式,而模型期望数值输入。
处理日期时间数据的一个常见方法是从中提取特征,例如年、月、日等。以下是你可以这样做的方法:
# Extract features from 'Date'
X_train['Year'] = X_train['Date'].dt.year
X_train['Month'] = X_train['Date'].dt.month
X_train['Day'] = X_train['Date'].dt.day
# Drop the original 'Date' column
X_train = X_train.drop('Date', axis=1)
# Do the same for the test set
X_test['Year'] = X_test['Date'].dt.year
X_test['Month'] = X_test['Date'].dt.month
X_test['Day'] = X_test['Date'].dt.day
X_test = X_test.drop('Date', axis=1)
# Now try to fit the model again
model.fit(X_train, y_train)
此代码首先从‘日期’列中提取年、月和日,并将它们作为新的列添加到 DataFrame 中。然后它删除原始的‘日期’列。最后,它再次尝试拟合模型。
请注意,这是一个简单的方法,可能不是处理特定问题的日期时间数据的最佳方式。最佳方法取决于你的数据性质和你要解决的问题。
[回复结束]
所以,我们的‘日期’列是问题所在。模型训练只能处理数值数据。看起来回复建议我们应该从‘日期’列中提取特征,比如年、月和日,以保留信息,但以数值形式。此外,我们还应该删除‘日期’列,因为我们已经从它那里得到了我们想要的东西。
让我们尝试运行建议的代码:
# Extract features from 'Date'
X_train['Year'] = X_train['Date'].dt.year
X_train['Month'] = X_train['Date'].dt.month
X_train['Day'] = X_train['Date'].dt.day
# Drop the original 'Date' column
X_train = X_train.drop('Date', axis=1)
# Do the same for the test set
X_test['Year'] = X_test['Date'].dt.year
X_test['Month'] = X_test['Date'].dt.month
X_test['Day'] = X_test['Date'].dt.day
X_test = X_test.drop('Date', axis=1)
# Now try to fit the model again
model.fit(X_train, y_train)
LinearRegression()
现在,你应该看到你的代码在没有问题的情况下运行。让我们告诉 Copilot 这个事实,看看它是否建议我们如何继续。
[提示]
谢谢,这行得通。
[提示结束]
你应该会收到以下类似的回复:
[提示回复]
不客气!很高兴听到它成功了。现在你的模型已经训练好了,下一步通常是使用模型对你的测试数据进行预测。之后,你可以通过比较这些预测与测试数据中的实际值来评估模型性能。如果你有任何更多问题或需要进一步的帮助,请随时提问。
[回复结束]
评估模型
如回复所建议,Copilot 建议询问以下问题:评估回归模型的常见指标有哪些?让我们选择这个问题并看看它说了什么。
评估指标
让我们询问 Copilot 关于评估指标。
[提示]
评估回归模型的常见指标有哪些?
[提示结束]
你应该会收到以下类似的回复:
[提示回复]
评估回归模型性能有几个常见的指标:
-
平均绝对误差(MAE):这是预测值和实际值之间绝对差异的平均值。它给出了预测错误程度的一个概念。
-
均方误差(MSE):这是预测值和实际值之间平方差异的平均值。平方差异放大了较大误差的影响。
-
均方根误差 (RMSE): 这是 MSE 的平方根。它与输出变量的单位相同,比 MSE 更容易解释。
-
R 平方 (R²): 这是根据独立变量预测的因变量变差的比例。它提供了模型预测与实际数据拟合程度的度量。值为 1 表示模型完美地预测了实际值,而值为 0 表示模型根本无法预测实际值。
-
调整后的 R 平方: 这是经过调整的 R 平方,它已经根据模型中的预测因子数量进行了调整。只有当新项比随机预期更好地改进模型时,它才会增加。
这些指标各有其优缺点,选择使用哪个取决于具体问题和分析目标。
[响应结束]
现在我们知道了如何评估以及使用哪些指标,接下来让我们根据我们的测试数据做出预测,并看看我们得到什么响应。
[提示]
使用不同的指标进行预测并评估模型。
[提示结束]
你应该收到以下类似的响应:
[快速响应]
当然,让我们使用训练好的模型对测试数据进行预测。然后,我们将使用平均绝对误差 (MAE)、均方误差 (MSE)、均方根误差 (RMSE) 和 R 平方 (R²) 来评估这些预测。我们将使用 sklearn 的 metrics 模块来计算这些指标。
这是你可以这样做的方法:
from sklearn import metrics
import numpy as np
# Make predictions on the test data
y_pred = model.predict(X_test)
# Calculate MAE, MSE, RMSE, and R2
mae = metrics.mean_absolute_error(y_test, y_pred)
mse = metrics.mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse) # or metrics.mean_squared_error(y_test, y_pred, squared=False)
r2 = metrics.r2_score(y_test, y_pred)
# Print the metrics
print("Mean Absolute Error (MAE):", mae)
print("Mean Squared Error (MSE):", mse)
print("Root Mean Squared Error (RMSE):", rmse)
print("R-squared (R2 ):", r2)
此代码首先使用模型对测试数据进行预测。然后,通过比较这些预测与测试数据中的实际值来计算 MAE、MSE、RMSE 和 R²。最后,它打印出这些指标。
[响应结束]
代码中包含这两个指标,并调用一个 predict() 函数来从模型中产生响应;让我们试试看它是否工作。
from sklearn import metrics
import numpy as np
# Make predictions on the test data
y_pred = model.predict(X_test)
# Calculate MAE, MSE, RMSE, and R2
mae = metrics.mean_absolute_error(y_test, y_pred)
mse = metrics.mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse) # or metrics.mean_squared_error(y_test, y_pred, squared=False)
r2 = metrics.r2_score(y_test, y_pred)
# Print the metrics
print("Mean Absolute Error (MAE):", mae)
print("Mean Squared Error (MSE):", mse)
print("Root Mean Squared Error (RMSE):", rmse)
print("R-squared (R2 ):", r2)
你应该看到以下类似的响应:
Mean Absolute Error (MAE): 0.458844690389933
Mean Squared Error (MSE): 0.4236006011305136
Root Mean Squared Error (RMSE): 0.6508460656180642
R-squared (R2 ): 0.999868004623502
让我们提供以下响应给 Copilot,以了解我们接下来应该做什么。
[提示]
Below is the output, Mean Absolute Error (MAE): 0.458844690389933 Mean Squared Error (MSE): 0.4236006011305136 Root Mean Squared Error (RMSE): 0.6508460656180642 R-squared (R2 ): 0.999868004623502
[提示结束]
你应该收到以下类似的响应:
[快速响应]
太好了!输出显示了你的回归模型的计算指标。
-
平均绝对误差 (MAE): 预测值与实际值之间的平均绝对差异大约为 0.46。这意味着平均而言,你的预测值与实际值相差约 0.46 个单位。
-
均方误差 (MSE): 预测值与实际值之间平均平方差异大约为 0.42。由于它平方了差异,这个指标比 MAE 对大误差更敏感。
-
均方根误差 (RMSE): MSE 的平方根大约为 0.65。这个指标与输出变量的单位相同,比 MSE 更容易解释。
-
R 平方(R²):从独立变量中可预测的因变量变差的比率约为 0.9999。这非常接近 1,表明你的模型几乎解释了响应数据围绕其平均值的几乎所有变异性。
总体而言,这些指标表明你的模型在测试数据上的表现非常好。
[回复结束]
接下来,我们希望通过比较预测值与实际值来了解模型的表现,因此让我们创建一个提示来反映这一请求。
[提示]
显示预测值与实际值的比较。
[提示结束]
你应该收到以下类似的回复:
[提示回复]
当然,你可以通过在图表中可视化它们来比较预测值与实际值。以下是如何使用 matplotlib 进行操作的示例:
import matplotlib.pyplot as plt
# Plot the actual values
plt.scatter(X_test.index, y_test, color='blue', label='Actual')
# Plot the predicted values
plt.scatter(X_test.index, y_pred, color='red', label='Predicted')
plt.title('Actual vs Predicted')
plt.xlabel('Index')
plt.ylabel('Target')
plt.legend()
plt.show()
这段代码创建了一个散点图,其中 x 轴代表测试集的索引,y 轴代表目标变量。实际值用蓝色绘制,预测值用红色绘制。这允许你直观地比较模型做出的预测与实际值。
[回复结束]
建议的代码似乎想要创建一个散点图,以便更好地比较我们的预测值与测试数据:
import matplotlib.pyplot as plt
# Plot the actual values
plt.scatter(X_test.index, y_test, color='blue', label='Actual')
# Plot the predicted values
plt.scatter(X_test.index, y_pred, color='red', label='Predicted')
plt.title('Actual vs Predicted')
plt.xlabel('Index')
plt.ylabel('Target')
plt.legend()
plt.show()
以上代码的输出如下:
图 18.3:实际值与预测值比较
我们可以看到预测数据与实际数据非常吻合。接下来,让我们尝试总结我们的学习成果。
作业
不使用回归来预测一个值,而是将相同的数据视为一个分类问题,并预测股价是否将在第二天上涨或下跌。
摘要
回归是机器学习中的一个基本概念,用于根据一个或多个预测变量预测一个连续的因变量。它涉及识别因变量(通常称为目标)与一个或多个自变量(特征)之间的关系。我们看到了,在我们的数据集中,我们能够找到某些变量的相关性。我们还发现,我们可以包括如日期这样的列,但要包括这些列,我们需要从这些列中提取重要的数值部分,即年份、月份和日期。
回归在医疗保健和市场营销等其他领域有许多应用。从提示的角度来看,尽早设置上下文并展示 Copilot 数据的形状是个好主意,这样可以帮助你询问 Copilot 下一步该做什么。
在下一章中,我们将使用相同的数据集,同时使用 GitHub Copilot 帮助我们编写一些代码。
加入我们的 Discord 社区
加入我们的社区 Discord 空间,与作者和其他读者进行讨论:
第十九章:基于 Copilot 建议的回归
简介
在上一章中,我们使用 GitHub Copilot Chat 构建了一个回归问题,并探讨了人工智能如何协助编程。在本章中,我们将采取不同的方法。我们将借助 GitHub Copilot 编写代码,让它引导我们进行编码并添加有用的注释。这将是一种交互式体验,结合我们的编码技能和 Copilot 的建议,有效地解决回归问题。让我们看看 GitHub Copilot 如何实时增强我们的编码过程。
在这个任务中,我们将使用苹果公司(AAPL)的数据集来预测股票价格,并帮助投资者决定是否买入。这是我们之前在第十八章,基于 Copilot Chat 的回归中使用的数据集,当时我们使用 Copilot Chat 来分析它。
数据集概述
这个数据集为我们提供了关于苹果公司(AAPL)过去十年股票(交易代码为 AAPL)的大量信息,始于 2010 年。这些数据极其宝贵,因为它可以帮助我们开发预测算法,预测苹果公司股票的未来价格,这对于投资决策至关重要。这个数据集中的数据是从 25 个不同的证券交易所收集和汇总的。
为了有效地使用这些数据来进行预测,我们需要理解关键要素:影响我们目标(预测股票价格)的特征。
数据集包括五个重要值,这些值表示股票价格在特定时间段内的变化情况,通常是整天,但也可能是一周或一个月。这些值包括:
-
开盘价:这是交易日开始时的股票价格。
-
收盘价:这是交易日结束时的股票价格。
-
高:此值表示股票在交易日达到的最高价格。
-
低:这表示股票在交易日达到的最低价格。
-
成交量:这是在市场收盘前一天内交易的总股数。
我们将重点关注使用历史价格数据,包括这五个记录的值,以及股票过去的业绩,来预测其未来的价格。
提示策略
在本章中,我们将使用第二章中描述的“探索性提示模式”。我们对想要采取的一般行动相当有信心,但很感兴趣 AI 助手在需要转向时会产生什么。
在 Copilot 的帮助下开始编码
安装了 GitHub Copilot 后,你就可以开始用 Python 编写你的回归问题了。在打开的文件中使用建议的方法与使用聊天窗口的方法略有不同。主要区别在于,我们将依赖输入注释并使用Tab键让 Copilot 提供建议。这种技术在 Jupyter Notebook 和普通文本文件中都同样有效。以下是具体操作方法:
# generate import statements for libraries to use with a Regression problem
在这里,我们有一个打开的文本文件。我们已经添加了注释来生成import语句。为了使 Copilot 生成响应,我们需要使用回车键后跟Tab键来接受建议。上面的文本文件可能如下所示:
# generate import statements for libraries to use with a Regression problem
import pandas
import numpy
import scikit-learn
当按下Tab键后跟回车键时,import语句是由 Copilot 生成的。
人工智能助手通过提供代码补全来帮助,但请记住在接受每个建议之前进行审查和理解。
第 1 步:在 Copilot 的帮助下导入库
我们可以开始用一个描述问题的提示建议注释,包括数据集以及更多内容,就像我们在本书的其他章节中使用 Copilot Chat 一样。然后,提示可能看起来像这样:
# generate the steps I need to follow for performing a Regression problem, here's my dataset and its columns
然而,我们将尝试一种方法,即请求我们所需的一切。
让我们开始吧。让我们创建我们的第一个评论(这相当于在聊天窗口中输入):
[提示]
import pandas
[提示结束]
使用Tab键接受建议。你应该看到以下加粗代码:
[提示响应]
# import pandas
import pandas as pd
[响应结束]
太好了!我们已经导入了所需的库。接下来,让我们加载数据集并探索。
第 2 步:加载数据集并探索
在下一步中,我们想要加载数据集并探索数据特征。继续在同一个文件上工作,并添加以下提示:
[提示]
# Load the dataset into a pandas DataFrame
[提示结束]
在这一点上,Copilot 理解我们试图做什么,所以我们不需要输入比上面的提示评论更多的内容。因此,我们只需要按下回车键,然后多次按下Tab键,我们应该会得到以下内容:
[提示响应]
# Load the dataset into a pandas DataFrame
df = pd.read_csv('enter-your-file-path')
# Print the first 5 rows of the DataFrame
print(df.head())
[响应结束]
确保您已从 Kaggle 下载了数据集(www.kaggle.com/datasets/varpit94/apple-stock-data-updated-till-22jun2021)并且您已将read_csv中的路径替换为您系统中的文件位置。
如果您运行建议的代码,您应该看到类似以下输出:
Date Close Volume Open High Low
0 02/28/2020 $273.36 106721200 $257.26 $278.41 $256.37
1 02/27/2020 $273.52 80151380 $281.1 $286 $272.96
2 02/26/2020 $292.65 49678430 $286.53 $297.88 $286.5
3 02/25/2020 $288.08 57668360 $300.95 $302.53 $286.13
4 02/24/2020 $298.18 55548830 $297.26 $304.18 $289.23
如果您看到上述内容,这意味着数据已成功加载。
获取类型和列
太好了!现在我们已经成功加载数据,让我们更多地了解加载数据集,例如它有哪些列和列类型。像往常一样,让我们继续在同一个文件上工作,并添加如下提示的注释:
[提示]
# Get the data types of the columns in the dataset
[提示结束]
你应该看到以下结果:
[提示响应]
# Get the data types of the columns in the dataset
print(df.dtypes)
[响应结束]
现在,让我们运行代码。它应该显示我们的列及其数据类型:
Date object
Close object
Volume int64
Open object
High object
Low object
dtype: object
太好了!我们看到列,但许多列的类型是object。这不太好;它们需要是数值型才能用于机器学习训练。让我们看看我们是否能很快解决这个问题,但首先,让我们更多地了解数据集的形状。
数据集形状
让我们更多地了解我们的数据集在结构方面的信息,比如它由多少列和多少行组成。这将帮助我们评估其复杂性,了解我们有多少数据,以及是否足够训练一个可靠的模型。让我们写下我们的下一个提示注释:
[提示]
# Get the shape of the dataset
[提示结束]
你应该看到一个以下的建议:
[提示响应]
# Get the shape of the dataset
print(df.shape)
[响应结束]
运行上面的代码应该提供以下的响应:
(2518, 6)
这个响应告诉我们我们有 2518 行和 6 列。
处理列类型
在这一点上,我们知道我们需要更多的数值列,所以让我们处理那些非数值列。首先,让我们确定这些非数值列:
[提示]
# print the columns in the dataset
[提示结束]
你应该会看到一个类似以下的建议:
[提示响应]
# print the columns in the dataset
print(df.columns)
Index(['Date', 'Close', 'Volume', 'Open', 'High', 'Low'], dtype='object')
[响应结束]
虽然我们刚刚要求打印列,但 Copilot 决定只显示object类型的列。这并不令人惊讶,因为 Copilot 接受了机器学习的训练,能够推断出接下来会发生什么,在这种情况下是转换列以用于模型训练。
接下来,让我们更加具体地要求将列转换为数值版本,以下为提示注释:
[提示]
# Replace the $ symbol with an empty string and convert the column to float data type
[提示结束]
你应该会看到以下代码,它将多个列转换为数值版本。
[快速响应]
# Replace the $ symbol with an empty string and convert the column to float data type
df['Open'] = df['Open'].replace({'\$': ''}, regex=True).astype(float)
df['Close'] = df['Close'].replace({'\$': ''}, regex=True).astype(float)
df['High'] = df['High'].replace({'\$': ''}, regex=True).astype(float)
df['Low'] = df['Low'].replace({'\$': ''}, regex=True).astype(float)
[响应结束]
太好了!接下来,让我们检查旁边的列,以确保转换已经正确执行。
[提示]
# Print the first 5 rows of the DataFrame to confirm the changes
[提示结束]
你应该会看到一个类似的响应:
[提示响应]
# Print the first 5 rows of the DataFrame to confirm the changes
print(df.head())
[响应结束]
如果你运行上面的代码,你应该会看到以下的响应:
Date Close Volume Open High Low
0 02/28/2020 273.36 106721200 257.26 278.41 256.37
1 02/27/2020 273.52 80151380 281.10 286.00 272.96
2 02/26/2020 292.65 49678430 286.53 297.88 286.50
3 02/25/2020 288.08 57668360 300.95 302.53 286.13
4 02/24/2020 298.18 55548830 297.26 304.18 289.23
我们可以清楚地看到美元符号已被移除,列现在是数值的,除了日期列,我们稍后再处理。
统计摘要
接下来,让我们通过请求一个统计摘要来更多地了解数据集。我们预计会看到以下值:
-
计数:非空条目数量
-
平均值 (mean):平均值
-
标准差 (std):数据的分散程度
-
最小值 (min):最小值
-
25% 分位数 (25%):25% 的数据值低于此值
-
中位数 (50%):中间值,也称为第 50 百分位数
-
75% 分位数 (75%):75% 的数据值低于此值
-
最大值 (max):最大值
考虑到这一点,让我们编写一个提示注释:
[提示]
# get the statistical summary of the dataset
[提示结束]
你应该会看到类似以下的输出:
[快速响应]
# get the statistical summary of the dataset
print(df.describe())
[响应结束]
如果运行代码,你会看到类似以下的数据:
Close Volume Open High Low
count 2518.000000 2.518000e+03 2518.000000 2518.000000 2518.000000
mean 114.769522 7.258009e+07 114.728443 115.766415 113.690582
std 60.662405 5.663113e+07 60.546893 61.134456 60.085105
min 29.835700 1.136205e+07 29.392800 29.928600 28.464300
25% 66.822475 3.053026e+07 66.877150 67.475300 66.372950
50% 101.090000 5.295469e+07 101.115000 102.085000 100.350000
75%
检查缺失值
识别缺失值以评估数据集的质量至关重要。大量空值可能表明数据收集或输入存在问题,并可能影响我们的模型,因此我们需要一种处理它们的方法:
[提示]
检查缺失值
[提示结束]
你应该会看到一个类似的响应:
[提示响应]
# check for missing values
print(df.isnull().sum())
[响应结束]
太好了!那么,代码做了什么?好吧,让我们来解释。假设你有一个以下的数据集:
data = {'A': [7, 99, None, 3, None],
'B': [5, None, 6, 8, 9],
'C': [10, 15, 12, None, 11]}
运行建议的代码将总结每列的缺失值数量,你会看到类似以下的响应:
A: 2
B: 1
C: 1
你可以做的就是在不影响整体分数的情况下替换缺失值。一种方法是将平均值添加到缺失值中,并用它替换None。
检查重复项
另一种清理数据的方法是删除重复数据,因为你不希望这些数据对模型产生强化作用。让我们为这一点添加一个注释,看看 Copilot 能否帮助我们:
[提示]
print(df.duplicated().sum())
[提示结束]
到目前为止,Copilot 理解我们想要做什么,那就是识别和删除重复项。所以,你应该会看到以下两个操作的代码建议:
[提示响应]
# check for duplicates
print(df.duplicated().sum())
# drop duplicates
df.drop_duplicates(inplace=True)
[响应结束]
缩放数值特征
接下来,我们将对值进行缩放,使它们落入特定的范围,0–1。这种预处理将对许多事情产生有益的影响,例如算法性能、收敛速度、可解释性和防止一组值主导。让我们创建一个缩放特征的提示:
[提示]
# Scale numerical features
[提示结束]
注意,当响应中有多于一行时,你可能需要反复按Return和Tab键。你应该看到类似以下的输出:
[提示响应]
# Scale numerical features
# import StandardScaler
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
df[['Open', 'Close', 'High', 'Low', 'Volume']] = scaler.fit_transform(df[['Open', 'Close', 'High', 'Low', 'Volume']])
# Print the first 5 rows of the DataFrame to confirm the changes
print(df.head())
[响应结束]
运行建议的代码应该得到以下输出:
Date Close Volume Open High Low
0 02/28/2020 2.614832 0.602988 2.354536 2.660953 2.375094
1 02/27/2020 2.617470 0.133721 2.748359 2.785130 2.651257
2 02/26/2020 2.932884 -0.404481 2.838059 2.979494 2.876649
3 02/25/2020 2.857534 -0.263366 3.076269 3.055571 2.870490
4 02/24/2020 3.024063 -0.300800 3.015313 3.082566 2.922093
可视化
接下来,我们想要可视化我们的数据。我们可以给出一些模糊的指令来说明如何进行,但在这个案例中,散点图是一个很好的工具,所以让我们在提示中反映这一点:
[提示]
# Create a scatter plot of the Open and Close columns
[提示结束]
你应该看到类似以下的响应:
[提示响应]
import matplotlib.pyplot as plt
# Create a scatter plot of the Open and Close columns
plt.scatter(df['Open'], df['Close'])
plt.xlabel('Open')
plt.ylabel('Close')
plt.title('Relationship between Open and Close')
plt.show()
[响应结束]
运行上面的代码应该会得到一个类似这样的散点图:
图 19.1:显示开盘价和收盘价之间关系的散点图
第 3 步:将数据分为训练集和测试集
在我们能够训练模型之前,我们需要将数据分为训练数据和测试数据。让我们创建一个提示来帮助完成这项工作:
[提示]
“使用 scikit-learn 中的 train_test_split 来分割数据集”
[提示结束]
你应该看到类似以下的输出:
[提示响应]
# Use train_test_split from scikit-learn to split the dataset
from sklearn.model_selection import train_test_split
# Drop the Date column from the DataFrame
df = df.drop('Date', axis=1)
# Split the dataset into training and testing sets
X = df.drop('Close', axis=1)
y = df['Close']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
[响应结束]
# Print the shapes of the training and testing sets
print('X_train shape:', X_train.shape)
print('y_train shape:', y_train.shape)
print('X_test shape:', X_test.shape)
print('y_test shape:', y_test.shape)
如果你运行上面的代码,你应该看到类似以下的响应:
X_train shape: (2014, 4)
y_train shape: (2014,)
X_test shape: (504, 4)
y_test shape: (504,)
提问
就像在 Copilot 的聊天体验中一样,可以在特定主题上提问。如果你在问题前加上“Q:”,Copilot 就会理解它是一个问题。让我们试一试,找出我们的下一步:
[提示]
问题:在将数据分为训练集和测试集之后下一步是什么?
[提示结束]
你应该看到类似以下的响应:
[提示响应]
# Q: what is the next step after splitting the data into training and testing sets?
# A: train the model using the training set and test the model using the tesing set
[响应结束]
第 4 步:构建回归问题
现在是训练模型的时候了。你可以相当模糊地询问 Copilot 进行训练。然而,建议你提出你想要的训练类型。在这种情况下,我们想要线性回归,所以让我们创建一个包含该内容的提示:
[提示]
“初始化一个线性回归模型”。
[结束提示]
你应该看到类似以下的响应:
[提示响应]
# initialize a LinearRegression model
# import LinearRegression
from sklearn.linear_model import LinearRegression
# Instantiate LinearRegression as lr
lr = LinearRegression()
[结束建议响应]
太好了!我们有一些代码确保我们使用线性回归。尽管如此,我们还没有进行任何训练,所以这是下一步。
第 5 步:训练模型
根据指定的训练类型,接下来让我们训练模型:
[提示]
“拟合模型”
[结束提示]
你应该看到类似以下的响应:
[提示响应]
# Fit lr to the training data
lr.fit(X_train, y_train)
# Predict the labels of the test set
y_pred = lr.predict(X_test)
[结束响应]
第 6 步:评估模型性能
太好了!我们已经训练了模型,但我们不知道它的表现如何,这是我们接下来应该解决的问题:
[提示]
评估性能指标,如 MSE 或 R 平方。
[结束提示]
你应该看到类似的输出:
[提示响应]
#evaluate the performance metrics like MSE or R-squared
from sklearn.metrics import mean_squared_error
# Calculate the Mean Squared Error (MSE) of the model on the testing set
mean_squared_error = mean_squared_error(y_test, y_pred)
print('Mean squared error:', mean_squared_error)
# Calculate the Root Mean Squared Error (RMSE) of the model on the testing set
root_mean_squared_error = np.sqrt(mean_squared_error)
print('Root mean squared error:', root_mean_squared_error)
[结束响应]
如果你运行上述代码,你应该看到如下响应:
MSE: 0.00011569609998631774
RMSE: 0.010756212157926123
我们得到的输出代表两种不同的误差:均方误差和均方根误差。
较低的 MSE 表明模型与数据的拟合度更好。在这种情况下,MSE 相当低,表明模型的预测非常接近实际值。
RMSE 值也非常低,这进一步证实了模型的预测非常准确。太好了!让我们回顾本章的作业,然后总结一下我们关于使用 Copilot 帮助机器学习的所学内容。
作业
尝试使用提示方法解决这个问题,你需要在开始时提供大量信息。我们建议构建一个如下所示的提示:
-
“在以下形状的数据集上执行回归:
-
开盘价:这是交易日开始的股票价格。
-
收盘价:这代表了交易日结束时的股票价格。
-
高:这个值显示了股票在交易日内达到的最高价格。
-
低:这表示股票在交易日内达到的最低价格。
-
成交量:这是在市场收盘前一天内交易的总股数。
建议从加载数据和预处理到训练和评估模型的全部步骤。你必须为每个步骤展示代码。”
然后查看响应,并尝试为每个步骤运行建议的代码片段。如果你遇到任何问题,可以用如下问题提示向 Copilot 报告错误:
- “问题:以下/以上代码不工作,请修复”
不要忘记按Enter和Tab键接受完成。
摘要
在本章中,我们想使用 GitHub Copilot 的建议功能,这意味着我们会输入注释并使用 回车 和 Tab 键来接收 Copilot 的建议。这里有点技巧,因为有时你需要反复按 回车 和 Tab 键才能获得完整的响应。它也是一种非常适合你在积极编写代码时的 AI 体验。GitHub Copilot Chat 也有其位置。实际上,这两种不同的体验是互补的;选择你想要使用多少每种方法。此外,始终测试 Copilot 提出的代码,并在需要时让 Copilot 修复代码输出。
加入我们的 Discord 社区
加入我们社区的 Discord 空间,与作者和其他读者进行讨论: