监督学习中的分类与回归
立即解锁
发布时间: 2025-09-08 00:37:35 阅读量: 4 订阅数: 10 AIGC 


Python人工智能实战指南
### 监督学习中的分类与回归
在机器学习领域,监督学习是一种重要的方法,它利用带有标签的数据来训练模型,以实现分类和回归任务。本文将详细介绍几种常见的监督学习分类器,包括逻辑回归分类器、朴素贝叶斯分类器、混淆矩阵以及支持向量机,并给出相应的代码实现和解释。
#### 1. 解码随机数字集
首先,我们来看一个简单的解码示例。以下代码展示了如何使用编码器对一组值进行解码:
```python
# Decode a set of values using the encoder
encoded_values = [3, 0, 4, 1]
decoded_list = encoder.inverse_transform(encoded_values)
print("\nEncoded values =", encoded_values)
print("Decoded labels =", list(decoded_list))
```
运行这段代码,你可以通过检查映射关系来验证编码和解码步骤是否正确。此部分代码位于`label_encoder.py`文件中。
#### 2. 逻辑回归分类器
逻辑回归是一种用于解释输入变量和输出变量之间关系的技术。输入变量被假定为相互独立,而输出变量被称为因变量,它只能取一组固定的值,这些值对应于分类问题的类别。
我们的目标是通过使用逻辑函数估计概率来确定自变量和因变量之间的关系。逻辑函数是一个S形曲线,用于构建具有各种参数的函数。它与广义线性模型分析密切相关,在广义线性模型分析中,我们试图拟合一条直线到一组点上以最小化误差。与线性回归不同,我们使用逻辑回归。逻辑回归本身实际上不是一种分类技术,但我们以这种方式使用它来促进分类。由于其简单性,它在机器学习中非常常用。
下面是使用逻辑回归构建分类器的步骤:
1. **导入必要的包**:
```python
import numpy as np
from sklearn import linear_model
import matplotlib.pyplot as plt
from utilities import visualize_classifier
```
2. **定义样本输入数据**:
```python
# Define sample input data
X = np.array([[3.1, 7.2], [4, 6.7], [2.9, 8], [5.1, 4.5], [6, 5], [5.6, 5],
[3.3, 0.4], [3.9, 0.9], [2.8, 1], [0.5, 3.4], [1, 4], [0.6, 4.9]])
y = np.array([0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3])
```
3. **创建逻辑回归分类器对象**:
```python
# Create the logistic regression classifier
classifier = linear_model.LogisticRegression(solver='liblinear', C=1)
```
4. **训练分类器**:
```python
# Train the classifier
classifier.fit(X, y)
```
5. **可视化分类器的性能**:
```python
# Visualize the performance of the classifier
visualize_classifier(classifier, X, y)
```
其中,`visualize_classifier`函数的定义如下:
```python
import numpy as np
import matplotlib.pyplot as plt
def visualize_classifier(classifier, X, y):
# Define the minimum and maximum values for X and Y
# that will be used in the mesh grid
min_x, max_x = X[:, 0].min() - 1.0, X[:, 0].max() + 1.0
min_y, max_y = X[:, 1].min() - 1.0, X[:, 1].max() + 1.0
# Define the step size to use in plotting the mesh grid
mesh_step_size = 0.01
# Define the mesh grid of X and Y values
x_vals, y_vals = np.meshgrid(np.arange(min_x, max_x, mesh_step_size),
np.arange(min_y, max_y, mesh_step_size))
# Run the classifier on the mesh grid
output = classifier.predict(np.c_[x_vals.ravel(), y_vals.ravel()])
# Reshape the output array
output = output.reshape(x_vals.shape)
# Create a plot
plt.figure()
# Choose a color scheme for the plot
plt.pcolormesh(x_vals, y_vals, output, cmap=plt.cm.gray)
# Overlay the training points on the plot
plt.scatter(X[:, 0], X[:, 1], c=y, s=75, edgecolors='black',
linewidth=1, cmap=plt.cm.Paired)
# Specify the boundaries of the plot
plt.xlim(x_vals.min(), x_vals.max())
plt.ylim(y_vals.min(), y_vals.max())
# Specify the ticks on the X and Y axes
plt.xticks((np.arange(int(X[:, 0].min() - 1), int(X[:, 0].max() + 1),
1.0)))
plt.yticks((np.arange(int(X[:, 1].min() - 1), int(X[:, 1].max() + 1),
1.0)))
plt.show()
```
如果将`C`的值改为100,即:
```python
classifier = linear_model.LogisticRegression(solver='liblinear', C=100)
```
你会发现分类边界变得更加准确。这是因为`C`对错误分类施加了一定的惩罚,使得算法更贴合训练数据。但需要注意的是,如果过度增大`C`的值,模型会过拟合训练数据,导致泛化能力变差。此部分代码位于`logistic_regression.py`文件中。
#### 3. 朴素贝叶斯分类器
朴素贝叶斯是一种使用贝叶斯定理构建分类器的技术。贝叶斯定理描述了基于与事件相关的不同条件下事件发生的概率。我们通过为问题实例分配类别标签来构建朴素贝叶斯分类器,这些问题实例用特征值向量表示。这里的假设是任何给定特征的值与其他任何特征的值相互独立,这就是朴素贝叶斯分类器中“朴素”的部分。
下面是构建朴素贝叶斯分类器的步骤:
1. **导入必要的包**:
```python
import numpy as np
import matplotlib.pyplot as plt
from sklearn.naive_bayes import GaussianNB
from sklearn import cross_validation
from utilities import visualize_classifier
```
2. **加载数据**:
```python
# Input file containing data
input_file = 'data_multivar_nb.txt'
# Load data from input file
data = np.loadtxt(input_file, delimiter=',')
X, y = data[:, :-1], data[:, -1]
```
3. **创建朴素贝叶斯分类器**:
```python
# Create Naïve Bayes classifier
classifier = GaussianNB()
```
4. **训练分类器**:
```python
# Train the classifier
classifier.fit(X, y)
```
5. **预测训练数据的输出**:
```python
# Predict the values for training data
y_pred = classifier.predict(X)
```
6. **计算分类器的准确率并可视化性能**:
```python
# Compute accuracy
accuracy = 100.0 * (y == y_pred).sum() / X.shape[0]
print("Accuracy of Naïve Bayes classifier =", round(accuracy, 2), "%")
# Visualize the performance of the classifier
visualize_classifier(classifier, X, y)
```
上述计算分类器准确率的方法不够稳健,我们需要进行交叉验证,以避免在测试时使用相同的训练数据。以下是进行交叉验证的步骤:
```python
# Split data into training and test data
X_train, X_test, y_train, y_test = cross_validation.train_test_split(X, y,
test_size=0.2, random_state=3)
classifier_new = GaussianNB()
classifier_new.fit(X_train, y_train)
y_test_pred = classifier_new.predict(X_test)
# compute accuracy of the classifier
accuracy = 100.0 * (y_test == y_test_pred).sum() / X_test.shape[0]
print("Accuracy of the new classifier =", round(accuracy, 2), "%")
# Visualize the performance of the classifier
visualize_classifier(classifier_new, X_test, y_test)
```
我们还可以使用内置函数基于三重交叉验证计算准确率、精确率、召回率和F1值:
```python
num_folds = 3
accuracy_values = cross_validation.cross_val_score(classifier,
X, y, scoring='accuracy', cv=num_folds)
print("Accuracy: " + str(round(100*accuracy_values.mean(), 2)) + "%")
precision_values = cross_validation.cross_val_score(classifier,
X, y, scoring='precision_weighted', cv=num_folds)
print("Precision: " + str(round(100*precision_values.mean(), 2)) + "%")
recall_values = cross_validation.cross_val_score(classifier,
X, y, scoring='recall_weighted', cv=num_folds)
print("Recall: " + str(round(100*recall_values.mean(), 2)) + "%")
f1_values = cross_validation.cross_val_score(classifier,
X, y, scoring='f1_weighted', cv=num_folds)
print("F1: " + str(round(100*f1_values.mean(), 2)) + "%")
```
此部分代码位于`naive_bayes.py`文件中。
#### 4. 混淆矩阵
混淆矩阵是一个用于描述分类器性能的表格或图形,通常从已知真实标签的测试数据集中提取。通过比较每个类别与其他类别的样本,我们可以了解有多少样本被错误分类。在构建混淆矩阵的过程中,会涉及到几个在机器学习领域非常重要的关键指标。
以二分类问题为例,输出为0或1时,有以下几种情况:
| 指标 | 含义 |
| ---- | ---- |
| 真正例(True positives) | 预测输出为1,真实标签也为1的样本 |
| 真负例(True negatives) | 预测输出为0,真实标签也为0的样本 |
| 假正例(False positives) | 预测输出为1,但真实标签为0的样本,也称为I型错误 |
| 假负例(False negatives) | 预测输出为0,但真实标签为1的样本,也称为II型错误 |
根据具体问题,我们可能需要优化算法以降低假正例或假负例的比率。例如,在生物识别系统中,避免假正例非常重要,因为错误的人可能会获取敏感信息。
下面是创建混淆矩阵的步骤:
1. **导入必要的包**:
```python
import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import confusion_matrix
from sklearn.metrics import classification_report
```
2. **定义样本标签**:
```python
# Define sample labels
true_labels = [2, 0, 0, 2, 4, 4, 1, 0, 3, 3, 3]
pred_labels = [2, 1, 0, 2, 4, 3, 1, 0, 1, 3, 3]
```
3. **创建混淆矩阵**:
```python
# Create confusion matrix
confusion_mat = confusion_matrix(true_labels, pred_labels)
```
4. **可视化混淆矩阵**:
```python
# Visualize confusion matrix
plt.imshow(confusion_mat, interpolation='nearest', cmap=plt.cm.gray)
plt.title('Confusion matrix')
plt.colorbar()
ticks = np.arange(5)
plt.xticks(ticks, ticks)
plt.yticks(ticks, ticks)
plt.ylabel('True labels')
plt.xlabel('Predicted labels')
plt.show()
```
5. **打印分类报告**:
```python
# Classification report
targets = ['Class-0', 'Class-1', 'Class-2', 'Class-3', 'Class-4']
print('\n', classification_report(true_labels, pred_labels,
target_names=targets))
```
在上述可视化代码中,`ticks`变量表示不同类别的数量。在我们的例子中,有五个不同的标签。运行代码后,你可以看到混淆矩阵的可视化结果,白色表示较高的值,黑色表示较低的值。在理想情况下,对角线上的方块都是白色,其他部分都是黑色,这表示100%的准确率。此部分代码位于`confusion_matrix.py`文件中。
#### 5. 支持向量机
支持向量机(SVM)是一种使用类别之间的分隔超平面定义的分类器,这个超平面是线在N维空间的扩展。给定有标签的训练数据和一个二分类问题,SVM会找到将训练数据分为两类的最优超平面,并且可以很容易地扩展到多分类问题。
为了便于理解,我们先考虑二维平面上的两类点的情况。在二维平面中,我们只需要处理点和线,这比在高维空间中处理向量和超平面更容易可视化。
下面是使用支持向量机对收入数据进行分类的步骤:
1. **导入必要的包**:
```python
import numpy as np
import matplotlib.pyplot as plt
from sklearn import preprocessing
from sklearn.svm import LinearSVC
from sklearn.multiclass import OneVsOneClassifier
from sklearn import cross_validation
```
2. **加载数据**:
```python
# Input file containing data
input_file = 'income_data.txt'
# Read the data
X = []
y = []
count_class1 = 0
count_class2 = 0
max_datapoints = 25000
with open(input_file, 'r') as f:
for line in f.readlines():
if count_class1 >= max_datapoints and count_class2 >= max_datapoints:
break
if '?' in line:
continue
data = line[:-1].split(', ')
if data[-1] == '<=50K' and count_class1 < max_datapoints:
X.append(data)
count_class1 += 1
if data[-1] == '>50K' and count_class2 < max_datapoints:
X.append(data)
count_class2 += 1
# Convert to numpy array
X = np.array(X)
```
3. **将字符串数据转换为数值数据**:
```python
# Convert string data to numerical data
label_encoder = []
X_encoded = np.empty(X.shape)
for i,item in enumerate(X[0]):
if item.isdigit():
X_encoded[:, i] = X[:, i]
else:
label_encoder.append(preprocessing.LabelEncoder())
X_encoded[:, i] = label_encoder[-1].fit_transform(X[:, i])
X = X_encoded[:, :-1].astype(int)
y = X_encoded[:, -1].astype(int)
```
4. **创建SVM分类器**:
```python
# Create SVM classifier
classifier = OneVsOneClassifier(LinearSVC(random_state=0))
```
5. **训练分类器**:
```python
# Train the classifier
classifier.fit(X, y)
```
6. **进行交叉验证**:
```python
# Cross validation
X_train, X_test, y_train, y_test = cross_validation.train_test_split(X, y,
test_size=0.2, random_state=5)
classifier = OneVsOneClassifier(LinearSVC(random_state=0))
classifier.fit(X_train, y_train)
y_test_pred = classifier.predict(X_test)
```
7. **计算分类器的F1分数**:
```python
# Compute the F1 score of the SVM classifier
f1 = cross_validation.cross_val_score(classifier, X, y,
scoring='f1_weighted', cv=3)
print("F1 score: " + str(round(100*f1.mean(), 2)) + "%")
```
8. **预测测试数据点的输出**:
```python
# Predict output for a test datapoint
input_data = ['37', 'Private', '215646', 'HS-grad', '9', 'Never-married',
'Handlers-cleaners', 'Not-in-family', 'White', 'Male', '0', '0', '40',
'United-States']
# Encode test datapoint
input_data_encoded = [-1] * len(input_data)
count = 0
for i, item in enumerate(input_data):
if item.isdigit():
input_data_encoded[i] = int(input_data[i])
else:
input_data_encoded[i] = int(label_encoder[count].transform(input_data[i]))
count += 1
```
此部分代码位于相关文件中,通过上述步骤,我们可以使用支持向量机对收入数据进行分类,并评估模型的性能。
综上所述,逻辑回归、朴素贝叶斯、混淆矩阵和支持向量机都是监督学习中非常有用的工具,它们在不同的场景下都有各自的优势。通过合理选择和使用这些方法,我们可以构建出高效准确的分类模型。
### 监督学习中的分类与回归
#### 6. 总结与对比
在前面的内容中,我们详细介绍了逻辑回归、朴素贝叶斯、混淆矩阵和支持向量机这几种常见的监督学习方法。下面我们对它们进行一个总结和对比,以便在实际应用中能更好地选择合适的方法。
| 方法 | 优点 | 缺点 | 适用场景 |
| ---- | ---- | ---- | ---- |
| 逻辑回归 | 简单易懂,计算效率高,可解释性强,能输出概率 | 对非线性关系处理能力有限 | 数据线性可分,需要输出概率的场景,如信用风险评估 |
| 朴素贝叶斯 | 计算速度快,对缺失数据不敏感,在小规模数据上表现良好 | 假设特征之间相互独立,在实际应用中可能不成立 | 文本分类、垃圾邮件过滤等 |
| 支持向量机 | 能处理高维数据,在非线性问题上表现出色,有较好的泛化能力 | 计算复杂度高,对参数和核函数的选择敏感 | 图像识别、生物信息学等 |
#### 7. 应用建议
在实际应用中,我们可以按照以下流程选择合适的分类方法:
```mermaid
graph TD;
A[明确问题类型] --> B{数据规模};
B -->|小规模数据| C{特征独立性};
C -->|特征独立| D(朴素贝叶斯);
C -->|特征不独立| E{数据线性可分};
E -->|线性可分| F(逻辑回归);
E -->|非线性可分| G(支持向量机);
B -->|大规模数据| H{数据复杂度};
H -->|低复杂度| I(逻辑回归);
H -->|高复杂度| J(支持向量机);
```
具体步骤如下:
1. **明确问题类型**:确定是分类问题还是回归问题,本文主要讨论分类问题。
2. **评估数据规模**:如果数据规模较小,考虑朴素贝叶斯或逻辑回归;如果数据规模较大,可以考虑支持向量机。
3. **分析特征独立性**:如果特征之间相互独立,朴素贝叶斯是一个不错的选择;否则,需要进一步判断数据的线性可分性。
4. **判断数据线性可分性**:如果数据线性可分,逻辑回归是一个简单有效的方法;如果数据非线性可分,支持向量机可能更合适。
#### 8. 代码优化与扩展
在实际应用中,我们可能需要对代码进行优化和扩展,以提高模型的性能和适用性。以下是一些常见的优化和扩展方法:
##### 8.1 特征工程
特征工程是提高模型性能的关键步骤。我们可以通过以下方法进行特征工程:
- **特征选择**:选择与目标变量相关性高的特征,去除冗余和无关的特征,减少模型的复杂度。
- **特征提取**:从原始特征中提取更有代表性的特征,如主成分分析(PCA)、线性判别分析(LDA)等。
- **特征变换**:对特征进行变换,如标准化、归一化、对数变换等,以提高模型的稳定性和收敛速度。
以下是一个简单的特征标准化示例:
```python
from sklearn.preprocessing import StandardScaler
# 假设X是输入数据
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
```
##### 8.2 参数调优
不同的模型有不同的参数,通过调整这些参数可以提高模型的性能。常见的参数调优方法有网格搜索、随机搜索等。
以下是一个使用网格搜索调优逻辑回归参数的示例:
```python
from sklearn.model_selection import GridSearchCV
from sklearn.linear_model import LogisticRegression
# 定义参数网格
param_grid = {'C': [0.1, 1, 10], 'solver': ['liblinear', 'lbfgs']}
# 创建逻辑回归分类器
classifier = LogisticRegression()
# 创建网格搜索对象
grid_search = GridSearchCV(classifier, param_grid, cv=5)
# 进行网格搜索
grid_search.fit(X, y)
# 输出最佳参数
print("Best parameters:", grid_search.best_params_)
```
##### 8.3 模型融合
模型融合是将多个模型的预测结果进行组合,以提高模型的性能和稳定性。常见的模型融合方法有投票法、堆叠法等。
以下是一个简单的投票法示例:
```python
from sklearn.ensemble import VotingClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.naive_bayes import GaussianNB
from sklearn.svm import SVC
# 创建不同的分类器
clf1 = LogisticRegression(solver='liblinear', C=1)
clf2 = GaussianNB()
clf3 = SVC(kernel='linear', probability=True)
# 创建投票分类器
voting_clf = VotingClassifier(estimators=[('lr', clf1), ('nb', clf2), ('svc', clf3)], voting='soft')
# 训练投票分类器
voting_clf.fit(X, y)
# 预测结果
y_pred = voting_clf.predict(X)
```
#### 9. 注意事项
在使用这些分类方法时,还需要注意以下几点:
- **数据质量**:数据的质量直接影响模型的性能,需要对数据进行清洗和预处理,去除噪声和异常值。
- **过拟合和欠拟合**:过拟合会导致模型在训练数据上表现良好,但在测试数据上表现不佳;欠拟合则相反。需要通过调整模型参数、增加数据量等方法来避免过拟合和欠拟合。
- **参数选择**:不同的模型有不同的参数,需要根据具体情况进行选择和调优。
总之,监督学习中的分类方法有很多种,每种方法都有其优缺点和适用场景。在实际应用中,我们需要根据问题的特点和数据的情况选择合适的方法,并进行适当的优化和扩展,以提高模型的性能和稳定性。通过不断地实践和探索,我们可以更好地掌握这些方法,解决各种实际问题。
0
0
复制全文
相关推荐









