Supervised Learning
Supervised Learning
在 监督学习 中,目标是学习从输入(X)到输出(Y)的映射。数学上表示为:
X \rightarrow Y
其中:
- ( X ) 表示输入数据,
- ( Y ) 表示带有标签的输出数据,或称为“真实值”。
模型通过在训练期间被提供每个输入的 正确答案 来进行学习。这个过程使模型能够基于新数据中的相似模式进行预测。
简而言之,监督学习:
- 从带标签的数据中学习,利用输入及其对应的标签。
- 旨在推广 ( X ) 到 ( Y ) 的映射,以便在新数据上做出准确的预测。
或者用英文更好表达:learns from being given ’ right answers’
Regression(回归)
import matplotlib.pyplot as plt
import numpy as np
# Generate example data points
x = np.linspace(100, 2500, 20)
y = 200 * (1 - np.exp(-0.001 * (x - 500))) + 150 + np.random.normal(0, 15, len(x))
# Define polynomial lines (approximating fit lines)
x_fit = np.linspace(100, 2500, 100)
y_fit_1 = 200 * (1 - np.exp(-0.001 * (x_fit - 500))) + 150 # Curve line
y_fit_2 = 50 + (300 / 2500) * x_fit # Adjust linear line to fit between 50 and 350
# Plotting
plt.figure(figsize=(10, 6))
plt.scatter(x, y, color='red', s=100, label='Data points') # data points
plt.plot(x_fit, y_fit_1, color='blue', linewidth=2, label='Curved fit line') # curved fit line
plt.plot(x_fit, y_fit_2, color='blue', linewidth=2, linestyle='--', label='Adjusted Linear fit line') # adjusted linear fit line
# Annotate example points
plt.annotate('200K', xy=(500, 200), xytext=(250, 220),
textcoords='offset points', ha='center', va='bottom', color='purple',
arrowprops=dict(arrowstyle='->', color='purple'))
plt.annotate('150K', xy=(500, 150), xytext=(250, 180),
textcoords='offset points', ha='center', va='bottom', color='purple',
arrowprops=dict(arrowstyle='->', color='purple'))
# Add example lines and circles
plt.plot([500, 500], [0, 200], color='orange', linestyle='--') # vertical guide line
plt.scatter([500], [150], color='orange', s=100, edgecolor='black') # circle at 150K
plt.scatter([500], [200], color='orange', s=100, edgecolor='black') # circle at 200K
# Labels and title
plt.title('Price Prediction Example')
plt.xlabel('House Size (sq ft)')
plt.ylabel('Price in $1000\'s')
plt.ylim(0, 400)
plt.xlim(0, 2500)
plt.legend()
plt.grid(True)
plt.show()
在监督学习中,我们通过收集的数据(红色的点)进行学习,这些数据包含了输入的特征(例如房屋面积)以及对应的输出标签(例如房价)。通过监督学习,我们可以得到一个拟合数据的函数,可以是直线(Adjusted Linear fit line)或者拟合曲线(如 Curved fit line),用以表示数据之间的关系。
这种拟合方式不是固定不变的,也可以选择更复杂的函数来更好地拟合数据。
这种特殊的监督学习类型称为 Regression(回归),其主要目的是 预测数值型的输出。通过回归分析,模型能够学习输入特征与输出之间的数值关系,以在未来进行更精准的数值预测。
从英文上来说:By Regression , I mean we’re trying to predict a number from infinitely many possible numbers
从大量的数据中的预测结果 , 从无线多可能的数字中预测其中的任意一个
监督学习的实质:
- Supervised Learning input output , or x to y mappings
Classification(分类)
术语:
- classes(输出类)
- category(输出类别)
category 和 classes 被作为输出的时候含义一样
下面举例一个实际的列子:学习什么size下的的肿瘤是良性和恶性的
import numpy as np
import matplotlib.pyplot as plt
# 生成更加分散的良性和恶性肿瘤尺寸数据
np.random.seed(42) # 设置随机种子以确保结果可重复
# 良性肿瘤尺寸随机分布在1.0到3.0之间
tumor_sizes_benign = np.random.uniform(1.0, 4.0, 20)
# 恶性肿瘤尺寸随机分布在3.5到7.0之间
tumor_sizes_malignant = np.random.uniform(3.5, 7.0, 20)
# 绘图
plt.figure(figsize=(10, 6))
# 绘制良性肿瘤数据点
plt.scatter(tumor_sizes_benign, [0] * len(tumor_sizes_benign), color='blue', s=100, edgecolor='black', label='benign (0)', alpha=0.7)
# 绘制恶性肿瘤数据点
plt.scatter(tumor_sizes_malignant, [1] * len(tumor_sizes_malignant), color='red', s=100, edgecolor='black', label='malignant (1)', alpha=0.7)
# 标签和标题
plt.xlabel('Tumor Size (diameter in cm)', fontsize=12)
plt.ylabel('Diagnosis', fontsize=12)
plt.title('Tumor Size vs Diagnosis (with More Spread Out Data)', fontsize=14)
# 添加图例
plt.legend(loc='upper left')
# 轴设置
plt.ylim(-0.5, 1.5)
plt.xlim(0, 8)
plt.xticks(range(0, 9))
plt.yticks([0, 1], ['benign', 'malignant'])
plt.grid(True, linestyle='--', alpha=0.7)
# 显示图表
plt.show()
在对图中:
- 横轴代表:
- 肿瘤的大小
- 纵轴代表:
- 肿瘤是否是恶性或者良性
在纵轴上我们可以将恶性或者良性映射到0,1这两个方便表达的数字上
import matplotlib.pyplot as plt
import random
# Create a new plot similar to the provided image
plt.figure(figsize=(10, 4))
# Plot benign and malignant points
benign_diameters = [1, 2, 3, 6, 7.5]
malignant_diameters = [5, 7, 8, 9, 10]
# Plot benign points
for diameter in benign_diameters:
plt.scatter(diameter, 0, color='blue', edgecolor='blue', marker='o', s=100, facecolors='none', label='benign' if diameter == 1 else "")
# Plot malignant points
for diameter in malignant_diameters:
plt.scatter(diameter, 0, color='red', marker='x', s=100, label='malignant' if diameter == 7 else "")
# Add horizontal line
plt.axhline(y=0, color='black', linestyle='-', linewidth=2)
# Add axis arrows and labels
plt.xlim(0, 11)
plt.ylim(-1, 1)
plt.xticks([0, 5, 10], ['0cm', '5 (cm)', '10cm'])
plt.yticks([])
plt.legend()
plt.title('Benign and Malignant Tumor Types by Diameter')
# Randomly select a point and mark it with a question mark
all_diameters = benign_diameters + malignant_diameters
random_point = random.choice(all_diameters)
plt.scatter(random_point, 0, color='green', marker='o', s=150, label='unknown', edgecolor='green')
plt.text(random_point, 0.1, '?', fontsize=15, ha='center', va='bottom', color='green')
# Show the plot
plt.show()
你可以将数据集绘制成一条线,以便更好地观察分类结果。对于未被标记为0或1的数据,Classification模型的目标是将这些数据最终分类为0或1。
如上图一样:我们最终能在学习后的模型中得到?是0或1,即使结果不是这个size下的的事实情况
import matplotlib.pyplot as plt
import numpy as np
# 示例数据 (扩展范围以便于更好地分开)
np.random.seed(42) # 设置随机种子以确保结果可重复
# 良性肿瘤直径数据在 1.0 到 3.0 之间
diameters_benign = np.random.uniform(1.0, 3.0, 10)
# 恶性肿瘤类型 1 在 3.5 到 5.0 之间
diameters_malignant_type_1 = np.random.uniform(3.5, 5.0, 5)
# 恶性肿瘤类型 2 在 5.5 到 7.5 之间
diameters_malignant_type_2 = np.random.uniform(5.5, 7.5, 5)
# 将所有数据合并
diameters = np.concatenate((diameters_benign, diameters_malignant_type_1, diameters_malignant_type_2))
types = ['benign'] * len(diameters_benign) + ['malignant type 1'] * len(diameters_malignant_type_1) + ['malignant type 2'] * len(diameters_malignant_type_2)
# 创建绘图
plt.figure(figsize=(10, 4))
# 绘制数据点,不同类型使用不同的标记
for i, diameter in enumerate(diameters):
if types[i] == 'benign':
plt.scatter(diameter, 0, color='blue', marker='o', s=100, label='benign' if i == 0 else "")
elif types[i] == 'malignant type 1':
plt.scatter(diameter, 0, color='red', marker='x', s=100, label='malignant type 1' if i == len(diameters_benign) else "")
elif types[i] == 'malignant type 2':
plt.scatter(diameter, 0, color='orange', marker='^', s=100, label='malignant type 2' if i == len(diameters_benign) + len(diameters_malignant_type_1) else "")
# 添加水平线 y=0
plt.axhline(y=0, color='black', linestyle='-', linewidth=1)
# 设置图表细节
plt.xlim(0, 10)
plt.ylim(-1, 1)
plt.xlabel('Diameter (cm)')
plt.yticks([])
plt.legend()
plt.title('Benign and Malignant Tumor Types by Diameter (Separated Data)')
# 显示图表
plt.show()
当然并不只有benigin 和 malignant 俩种分类 还存在肿瘤中期、后期的说法,你可以多加上几个类型(classes)
如上图:将malignant分为了type1 和 type2
用英语表达就是:Classification is
- Definition: Classification algorithms predict categories.
- Predict Categories: The predicted categories can be non-numeric. For example, a classification model can predict whether a picture is of a cat or a dog.
- Finite Set of Possible Outputs: The categories are chosen from a small, finite set, such as 0 or 1. Intermediate values like 0.5 or 1.7 are not possible as predictions.
# To fit the curve through the given points, we will use numpy's polynomial fitting.
import numpy as np
import matplotlib.pyplot as plt
# Given points through which the curve should pass
x_points = [45, 40, 35, 30, 20]
y_points = [0, 2.0, 2.5, 3.0, 3.5]
# Fit a polynomial of degree 4 (since we have 5 points, degree should be 4)
coefficients = np.polyfit(x_points, y_points, 4)
polynomial = np.poly1d(coefficients)
# Generate x values for plotting the curve
x_boundary = np.linspace(20, 55, 100)
y_boundary_curve = polynomial(x_boundary)
# Improved Plotting with Adjusted Pink Decision Boundary and Additional Points
# Adding new points: 'x' in the benign region and 'o' in the malignant region
new_malignant_point = (28, 1.7) # Blue region, adding an 'x'
new_benign_point = (42, 2.9) # Red region, adding an 'o'
plt.figure(figsize=(10, 6))
# Scatter plot for benign and malignant data points
benign_age = [25, 30, 28, 32, 34, 26, 29, 31, 33, 30, 35, 27, 28, 29, 26]
benign_size = [1.5, 2.0, 1.8, 1.7, 1.6, 1.2, 1.4, 1.9, 1.3, 1.8, 2.1, 1.4, 1.5, 1.3, 1.7]
malignant_age = [40, 42, 43, 45, 44, 47, 48, 46, 49, 41, 44, 50, 42, 43, 45]
malignant_size = [2.5, 2.8, 2.7, 3.0, 3.1, 2.9, 3.2, 3.1, 3.3, 2.6, 2.9, 3.4, 2.7, 2.8, 3.0]
plt.scatter(benign_age, benign_size, color='blue', marker='o', s=70, edgecolors='k', label='Benign')
plt.scatter(malignant_age, malignant_size, color='red', marker='x', s=70, edgecolors='k', label='Malignant')
# Plot the additional points with swapped markers
plt.scatter(*new_malignant_point, color='red', marker='x', s=100, edgecolors='k', zorder=5)
plt.scatter(*new_benign_point, color='blue', marker='o', s=100, edgecolors='k', zorder=5)
# Plot the fitted decision boundary curve
plt.plot(x_boundary, y_boundary_curve, color='magenta', linestyle='-', linewidth=2, label='Decision Boundary')
# Vertical and horizontal orange lines with modified limits for clarity
plt.plot([30, 30], [1.0, 1.8], color='orange', linestyle='--', linewidth=2) # Vertical line with dashed style
plt.plot([20, 30], [1.8, 1.8], color='orange', linestyle='--', linewidth=2) # Horizontal line with dashed style
# Intersection point in pink, making it visually distinct
plt.scatter([30], [1.8], color='pink', s=150, edgecolors='k', zorder=5)
# Adding labels and title with improved text size for better readability
plt.xlabel('Age', fontsize=14, color='darkorange')
plt.ylabel('Tumor Size', fontsize=14, color='darkorange')
plt.title('Tumor Classification based on Age and Size', fontsize=16, fontweight='bold')
# Grid and legend
plt.grid(True, linestyle='--', alpha=0.7)
plt.legend(fontsize=12)
# Improving x and y axis limits for better visual balance
plt.xlim(20, 55)
plt.ylim(1.0, 3.5)
# Show plot
plt.show()
/tmp/ipykernel_23380/2092796540.py:31: UserWarning: You passed a edgecolor/edgecolors ('k') for an unfilled marker ('x'). Matplotlib is ignoring the edgecolor in favor of the facecolor. This behavior may change in the future.
plt.scatter(malignant_age, malignant_size, color='red', marker='x', s=70, edgecolors='k', label='Malignant')
/tmp/ipykernel_23380/2092796540.py:34: UserWarning: You passed a edgecolor/edgecolors ('k') for an unfilled marker ('x'). Matplotlib is ignoring the edgecolor in favor of the facecolor. This behavior may change in the future.
plt.scatter(*new_malignant_point, color='red', marker='x', s=100, edgecolors='k', zorder=5)
在我们增加维度后,一个病人的肿瘤是良性还是恶性的
- 如何预测:学习算法可能需要在数据中找到一些边界来区分,算法最终必须决定将边界线拟合到这些数据上。
- 区分边界:学习算法会通过分析已有的数据,找到能够区分良性和恶性肿瘤的边界。这些边界可以是直线、曲线,或者在高维情况下,是更复杂的超平面。
- 拟合边界线:算法最终的任务是将这条边界线合理地拟合到数据上,使得分类尽可能准确。
Classification和Regression的区别
分类算法
- 目标: 分类算法的目标是将输入数据点分配到某个类别中。
- 类别的性质: 预测的类别是有限且可数的集合,这意味着类别的数量是固定的,并且类别之间是离散的。
- 例如:
- 预测图片中的动物是狗、猫或鸟。
- 判断一个肿瘤是良性还是恶性。
- 分类某个邮件是垃圾邮件(Spam)还是正常邮件(Not Spam)。
- 类别可以用数字表示,比如0/1或0/1/2,但这些数字仅表示类别之间的标识,而不具备数值上的意义。
- 例如:
- 类别特性: 分类问题通常使用准确率、召回率、F1分数等来衡量模型的好坏。
回归算法
- 目标: 回归算法的目标是预测一个连续值,通常是某个数值。
- 预测的值的性质: 预测的结果是无限大且不可数的集合,即预测结果是一个在某个范围内的连续值。
- 例如:
- 预测房价,如某房屋的价格是50万美元。
- 预测股票的未来价格。
- 预测某人未来的年收入。
- 预测的结果是一个数值,通常可以为任何实数,并且不同值之间是连续的。
- 例如:
- 结果特性: 回归问题通常用均方误差(MSE)、均方根误差(RMSE)等来评估模型的好坏。
特点 | 分类 | 回归 |
---|---|---|
目标 | 预测类别 | 预测连续值 |
输出类型 | 有限的、离散的类别集合 | 无限的、连续的数值集合 |
示例 | 图片分类(猫、狗) | 房价预测 |
常见评估指标 | 准确率、F1分数 | 均方误差(MSE) |
分类和回归虽然都属于监督学习范畴,但由于它们的输出目标不同,在数据建模、评估方式和实际应用场景上也存在显著差异。