引言
这是一篇将之前所学的机器学习的内容汇总复习的文章。
一、机器学习是什么?
机器学习本质上就是让机器从数据中自动的找出规律来,用来预测新的数据。就比如:你有1000张猫狗照片(带标签),计算机学完后,看到新照片能自动判断是猫还是狗。你有1000条房屋信息(面积、价格、地段),计算机学完后,看到新房屋信息能预测价格。
二、机器学习的两大类型
1、监督学习
监督学习就是:数据有标签,让计算器学习"输入-答案"的规律,例如:
预测房价:输入是"面积、地段",输出是"价格"(已知历史房价)。
识别垃圾邮件:输入是"邮件内容",输出是"垃圾/正常"(已知历史邮件分类)。
其中的关键在于要有标签数据(必须有答案),基本分为两类:回归(预测数字,如房价)和分类(预测类别,如垃圾邮件)。
2、无监督学习
无监督学习就是:数据没有"答案",让计算机自己找规律。例如:
客户分群:把顾客分成"高消费/低消费"群体(没有事先标签)。
电影推荐:发现"喜欢科幻的人也喜欢动作片"(没告诉计算机规则)。
三、监督学习核心:回归 vs 分类
现在我们假设有一个这样的场景:预测房价(回归) vs 识别垃圾邮件(分类)
其中:
| 任务 | 输入特征(数据) | 输出(标签) | 算法选择 | 为什么选这个? |
|---------------|-----------------------|--------------|----------------|----------------|
| 预测房价 | 房屋面积、卧室数、地段 | 价格(数字) | 线性回归 | 输出是数字 |
| 识别垃圾邮件 | 邮件内容、发件人 | 垃圾/正常 | 逻辑回归 | 输出是类别 |
我们只要记住其中的关键信息:输出是数字 → 用回归;输出是类别 → 用分类。
四、基础算法详解
1 、线性回归
线性回归一般是用来预测数字类的问题,就比如房价类,因为线性回归是最简单、最常用的,并且结果好解释。就如:房子面积越大,价格越高(线性关系)。
# 安装必备库
# pip install pandas scikit-learn
# 导入库
import pandas as pd
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
# 加载数据
# 模拟100个房屋数据:面积(平方米)和价格(万元)
data = {
'面积': [60, 75, 80, 90, 100, 120, 150, 200, 250, 300],
'价格': [50, 65, 70, 80, 90, 105, 130, 160, 190, 220] # 价格 = 面积 × 0.8 + 10(模拟真实关系)
}
df = pd.DataFrame(data) # 转成表格
# 拆分数据(训练集 vs 测试集)
# 训练集:计算机学习用(80%数据)
# 测试集:验证计算机学得对不对(20%数据)
X = df[['面积']] # 输入特征(面积)
y = df['价格'] # 输出标签(价格)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 创建模型(线性回归)
model = LinearRegression() # 初始化模型
# 训练模型(计算机学习规律)
model.fit(X_train, y_train) # 关键!让计算机学
# 预测新数据(用学的规律预测)
new_house = # 新房子面积180平方米
predicted_price = model.predict(new_house) # 预测价格
print(f"预测价格: {predicted_price[0]:.2f} 万元") # 输出: 154.00
# 验证模型(看学得好不好)
score = model.score(X_test, y_test) # 0~1,越接近1越好
print(f"模型准确度: {score:.2f}") # 输出: 0.98(98%准确)
# 可视化(看规律是否合理)
import matplotlib.pyplot as plt
plt.scatter(X, y, color='blue') # 原始数据点
plt.plot(X, model.predict(X), color='red') # 模型拟合线
plt.xlabel('房屋面积(平方米)')
plt.ylabel('价格(万元)')
plt.title('房价预测模型')
plt.show()
其中random_state=42:保证每次拆分数据一样,避免结果随机,model.score():不是"准确率",是R²值(0~1),代表模型能解释数据的比例(0.98=98%)。如果拟合线是弯的(不是直线),说明数据不是线性关系,这时我们需要换算法(如决策树)。
2、逻辑回归:预测类别
虽然名字有逻辑二字但用于分类(输出是类别)。例如垃圾邮件识别:邮件包含"免费""中奖" → 判定为垃圾邮件。
# 导入库
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
# 加载数据
# 模拟100条邮件:包含"免费"次数、发件人是否陌生、是否垃圾邮件
data = {
'免费次数': [2, 0, 1, 3, 5, 0, 4, 1, 2, 6],
'陌生发件人': [1, 0, 0, 1, 1, 0, 1, 0, 1, 1], # 1=陌生, 0=熟悉
'垃圾邮件': [1, 0, 0, 1, 1, 0, 1, 0, 1, 1] # 1=垃圾, 0=正常
}
df = pd.DataFrame(data)
# 拆分数据
X = df[['免费次数', '陌生发件人']] # 输入特征
y = df['垃圾邮件'] # 输出标签
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 创建并训练模型
model = LogisticRegression(max_iter=1000) # max_iter=1000避免训练失败
model.fit(X_train, y_train)
# 预测新邮件
new_email = [[3, 1]] # 包含3次"免费",陌生发件人
is_spam = model.predict(new_email) # 1=垃圾, 0=正常
print(f"是否垃圾邮件: {'是' if is_spam[0] == 1 else '否'}") # 输出: 是
# 评估模型(重点!)
y_pred = model.predict(X_test) # 用测试集预测
print(classification_report(y_test, y_pred)) # 打印详细报告
其中max_iter=1000:逻辑回归可能不收敛,必须加(否则报错)。precision(精确率):预测为垃圾邮件的邮件中,真正垃圾的比例(1.00=100%)。recall(召回率):所有垃圾邮件中,被正确识别的比例(1.00=100%)。f1-score:平衡精确率和召回率(1.00=最好)。如果精确率低(如0.5),说明模型把很多正常邮件误判为垃圾(代表用户体验差)。
3、决策树:像查字典一样分类
决策树的结果可解释(像查流程图),适合业务人员理解。举个例子:判断是否贷款(根据收入、信用记录)。
# 导入库
import pandas as pd
from sklearn.tree import DecisionTreeClassifier, plot_tree
import matplotlib.pyplot as plt
# 加载数据(模拟贷款数据)
data = {
'收入': [30, 45, 60, 75, 90, 100, 120],
'信用记录': [0, 1, 0, 1, 0, 1, 1], # 0=差, 1=好
'贷款': [0, 0, 1, 1, 0, 1, 1] # 0=不批, 1=批
}
df = pd.DataFrame(data)
# 拆分数据
X = df[['收入', '信用记录']]
y = df['贷款']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 创建并训练模型
model = DecisionTreeClassifier(max_depth=2, random_state=42) # max_depth=2限制树深度
model.fit(X_train, y_train)
# 可视化决策树
plt.figure(figsize=(10, 8))
plot_tree(model,
feature_names=['收入', '信用记录'],
class_names=['不批', '批'],
filled=True)
plt.show()
# 预测新申请
new_loan = [[50, 0]] # 收入50万,信用记录差
approved = model.predict(new_loan) # 0=不批, 1=批
print(f"是否批准贷款: {'是' if approved[0] == 1 else '否'}")
其中max_depth=2:必须加! 避免树太深导致过拟合。从上到下:先看"信用记录" → 差则直接不批(叶子节点0);好则看"收入" → >60万才批。因为决策树结果十分直观,所以用途很广。
五、数据预处理
数据的预处理是最重要的一步,严重的说,不处理数据等于模型全废。
1、处理缺失值
数据有空值时我们要如何处理呢,首先我们需要了解数值的类型,最基本的处理为:数值型缺失(面积、价格):用中位数填充(避免均值受极端值影响)。类别型缺失(如"地段"):用最常见值填充(如"市中心"出现最多)。例如:
# 模拟有缺失值的数据
data = {
'面积': [60, 75, None, 90, 100], # None表示缺失
'地段': ['市中心', '郊区', None, '市中心', '郊区']
}
df = pd.DataFrame(data)
# 处理数值型缺失(面积)
df['面积'].fillna(df['面积'].median(), inplace=True) # 中位数填充
# 处理类别型缺失(地段)
df['地段'].fillna(df['地段'].mode()[0], inplace=True) # 最常见值填充
print(df)
如果面积有1个极端值(如1000平方米),均值会偏高(800),导致填充错误。
2、处理分类数据(如"地段")
因为计算机不能直接处理文字,我们需要将其转化为数字。
# 模拟分类数据
data = {
'地段': ['市中心', '郊区', '市中心', '新区', '郊区']
}
df = pd.DataFrame(data)
# 转换分类数据
df_encoded = pd.get_dummies(df, columns=['地段'], prefix='地段')
print(df_encoded)
get_dummies:自动把"市中心"转成列,出现时为1,否则为0。
3、特征缩放
因为特征尺度的不同,模型学习困难,尤其像SVM、神经网络对尺度敏感。所以我们这里需要标准化数据让模型更快更准。
from sklearn.preprocessing import StandardScaler
# 模拟数据(面积和价格)
data = {
'面积': [60, 75, 80, 90, 100],
'价格': [50, 65, 70, 80, 90]
}
df = pd.DataFrame(data)
# 缩放
scaler = StandardScaler()
df_scaled = scaler.fit_transform(df) # 转成数值矩阵
# 转回DataFrame方便看
df_scaled = pd.DataFrame(df_scaled, columns=['面积', '价格'])
print(df_scaled)
六、模型评估(别只看准确率)
1、准确率的陷阱
# 模拟数据(99%正常邮件,1%垃圾邮件)
y_true = [0, 0, 0, 0, 0, 0, 0, 0, 0, 1] # 9个正常,1个垃圾
y_pred = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] # 全判为正常
accuracy = (y_true == y_pred).mean() # 90%准确率
print(f"准确率: {accuracy:.2f}")
其中准确率90%,但漏掉了100%的垃圾邮件(召回率=0),因为准确率在不平衡数据中无效。
2、正确评估指标
用classification_report:
from sklearn.metrics import classification_report
y_true = [0, 0, 0, 0, 0, 0, 0, 0, 0, 1] # 真实标签
y_pred = [0, 0, 0, 0, 0, 0, 0, 0, 0, 1] # 预测结果
print(classification_report(y_true, y_pred))
# 输出:
# precision recall f1-score support
# 0 1.00 0.90 0.95 9
# 1 0.00 1.00 0.00 1
# accuracy 0.90 10
# macro avg 0.50 0.95 0.47 10
# weighted avg 0.90 0.90 0.86 10
其中精确率(precision):预测为垃圾邮件的邮件中,真正垃圾的比例(0.00=0%)。召回率(recall):所有垃圾邮件中,被正确识别的比例(1.00=100%)。f1-score:精确率和召回率的平衡(0.00=最差)。
七、防止过拟合
1、为什么过拟合?
模型太复杂,记住了训练数据的噪音(如"某张照片的背景是蓝色")。例子:决策树深度太深,把"面积=80.5平方米"也作为判断条件。
2、解决办法
使用正则化操作,例如:(其中max_depth=3:必须设置(否则树会无限长)。cross_val_score避免数据划分随机性。)
# 创建决策树时限制深度
model = DecisionTreeClassifier(max_depth=3) # 限制深度为3
# 或者用正则化(逻辑回归)
model = LogisticRegression(C=1.0) # C越小,正则化越强(防止过拟合)
# 交叉验证(关键!)
from sklearn.model_selection import cross_val_score
scores = cross_val_score(model, X, y, cv=5) # 5折交叉验证
print(f"平均准确度: {scores.mean():.2f}") # 用平均值代替单次结果
机器学习的基本框架内容大概就有这些,还有要注意的是当我们入手一个完整的项目时,我们需要了解一个项目基本的流程:首先要加载训练所需的数据,千万别忘了数据的预处理,之后将数据拆分成训练集与测试集,紧接着就要开始训练我们的模型,训练完后要评估一下模型的训练效果以及模拟一个新用户去使用来确保最终的实现效果。