Python实现机器学习的流程(pipeline)--分类和回归问题

  • 实现了常用的机器学习算法
    • 分类方法:朴素贝叶斯、K近邻、逻辑回归、决策树、支持向量机
    • 回归问题:线性回归、岭回归

数据和代码源


本文主要是介绍了Python进行机器学习的分析流程,其中包括常用模块的准备、数据的预处理、模型训练、模型预测、模型评估、分析可视化以及模型的改进。


在分析流程中,分类问题和回归问题的主要区别在于模型的评估标准

模块准备

1. 常用的数据处理和绘图包

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import pylab as pl

2. 用于机器学习的包

  1. 数据集的格式化

    from sklearn.preprocessing import StandardScaler
    
  2. 数据集拆分成训练集和测试集

    from sklearn.model_selection import train_test_split
    
  3. 常用的机器学习模型

    # 分类问题
    from sklearn.naive_bayes import GaussianNB          # 朴素贝叶斯
    from sklearn.tree import DecisionTreeClassifier     # 决策树
    from sklearn.neighbors import KNeighborsClassifier  # k近邻
    from sklearn.linear_model import LogisticRegression # Logistics回归
    from sklearn import svm                             # 支持向量机
    # 回归问题
    from sklearn.linear_model import Ridge              # 岭回归
    from sklearn.linear_model import LinearRegression   # 线性回归
    
  4. 模型的评估和报告

    # 分类问题
    from sklearn.metrics import accuracy_score,\
    classification_report, confusion_matrix
    # 回归问题
    from sklearn.metrics import mean_absolute_error,\
          mean_squared_error, r2_score
    
  5. k折交叉验证

    from sklearn.model_selection import cross_val_score
    

一、数据准备

1. 数据导入

# 从csv导入文件、并格式化成array方便调用
data = pd.read_csv('nbayes_data.csv',header=None)
print(data.iloc[:,2].value_counts())
X = data.iloc[:,:-1].to_numpy()
y = data.iloc[:,-1].to_numpy()

注:提一下张量tensor的概念,通常以array的方式存储,

tensor.shape -> (samples,features)

tensor.ndim -> nD,

形象地理解,张量像是均衡的树结构,树的深度表示ndim,从上到下的每一层的单个节点分支数表示shape.

2. 数据标准化

  • 标准化、归一化、正态化
# 均值为0,方差为1
scaler = StandardScaler()
scaler.fit(X)
X = scaler.transform(X)

3. 数据切分

# 80:20的比例随机切分数据集,可固定随机种子
X_train, X_test, y_train, y_test =\
    train_test_split(X, y, test_size=0.20, random_state=53)

二、模型训练

训练分类器classifier的两步:

1. 实例化

# 分类模型
clf = GaussianNB()       # 朴素贝叶斯实例化
#clf = DecisionTreeClassifier(criterion='gini',random_state=53)  # 决策树实例化
#clf = KNeighborsClassifier(n_neighbors=7)  # k近邻实例化
#clf = LogisticRegression(C=1)  # logistic回归, C为正则化系数
'''生成多个学习模型
C = 0.3 # SVM regularization parameter
models = (svm.SVC(kernel='linear', C=C),
          svm.LinearSVC(C=C, max_iter=10000),
          svm.SVC(kernel='rbf', gamma=0.7, C=C),
          svm.SVC(kernel='poly', degree=7, gamma='auto', C=C))
'''
# 线性模型
#clf = Ridge()               # 岭回归
#clf = LinearRegression()    # 线性回归

2. 调用fit函数训练该实例

clf.fit(X_train,y_train) # 训练单个实例clf
#models = (clf.fit(X, y) for clf in models)  # 训练多个模型,以svm为例

三、模型预测

对测试集进行预测

y_pred = clf.predict(X_test)

四、模型评估

1. 分类问题

  • 三个矩阵:准确率、误判率矩阵、分类情况报告

猜正T、负F 真实正P、负N

准确率(accuracy):(TP+FN)/(TP+TN+FP+FN) 猜准确的比例

精确率(precision): TP/(TP+FP) 样本中真实为正,被猜正的比例

召回率(recall):TP/(TP+FN) 猜准确中,猜正的比例

F1值():精确率和召回率的几何平均数

print('Accuracy: %.2f' % accuracy_score(y_test, y_pred))
clf.score(X_test, y_test) # 2nd way to calculate accuracy
print(confusion_matrix(y_test, y_pred))
print(classification_report(y_test, y_pred))
  • 两个曲线:ROC Curve 和 PR Curve 、AUC

2. 回归问题

print("coefficients =",clf.coef_)     # 回归参数
print("intercept b =",clf.intercept_) # 回归截距
print('Mean Absolute Error =', mean_absolute_error(y_test, y_pred))
print('Mean Squared Error =', mean_squared_error(y_test, y_pred))
print('Root Mean Squared Error =', np.sqrt(mean_squared_error(y_test, y_pred)))
print('R2 Score:', r2_score(y_test, y_pred))

五、可视化

1. 分类问题

两步走:1. 绘制训练的分类边界;2. 绘制预测点的散点图

'''visualization'''
def visual(X,y):
    '''通过训练的模型,代入测试集,绘制边界;再绘制'''
    # Plot the decision boundary. For that, we will asign a color
    # to each point in the mesh [x_min, x_max] x [y_min, y_max].
    x_min, x_max = X[:,0].min() - 0.1, X[:,0].max() + 0.1
    y_min, y_max = X[:,1].min() - 0.1, X[:,1].max() + 0.1
    h = 0.02 # step size in the mesh
    xx, yy = np.meshgrid(np.arange(x_min, x_max, h),\
                         np.arange(y_min, y_max, h))
    Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
    Z = Z.reshape(xx.shape)
    # Put the result into a color plot
    pl.figure(2)
    pl.set_cmap(pl.cm.Paired)
    pl.pcolormesh(xx, yy, Z)
    # Plot the testing points
    for i in range(len(X)):
        if y[i] == 0:
            _ = pl.scatter(X[i,0], X[i,1], c='red', marker='x')
        elif y[i] == 1:
            _ = pl.scatter(X[i,0], X[i,1], c='blue', marker='+')
        elif y[i] == 2:
            _ = pl.scatter(X[i,0], X[i,1], c='green', marker='o')
        else:
            _ = pl.scatter(X[i,0], X[i,1], c='c', marker='^')
    pl.xlim()
    pl.ylim()
    pl.title('naive bayes classifier model boundaries')

visual(X_test,y_test)
plt.show()

2. 回归问题

splt.plot(data.iloc[:,0],data.iloc[:,1],'ro')
plt.xlim()
plt.ylim()
xmin, xmax = data.iloc[:,0].min(), data.iloc[:,1].max()
xx = np.linspace(xmin, xmax, 101)
yy = clf.coef_ * xx + clf.intercept_
plt.plot(xx, yy, linestyle='-',color='green')
plt.legend(['data points','regression'])
plt.show()

六、模型改进

  1. K折交叉验证:通过分割数据集为K份,每次保留其中1份,使用其余K-1份进行训练模型,训练K次取其指标的平均值作为最终的值,因此K折交叉验证又称为留一交叉验证。
'''S-fold cross validation''' 
def cross_valid(classifier):
    num_folds = 3   # 3折
    accuracy_values = cross_val_score(classifier,\
            X, y, scoring='accuracy', cv=num_folds)
    print("Accuracy: " + str(round(100*accuracy_values.mean(), 2)) + "%")

    precision_values = cross_val_score(classifier,\
            X, y, scoring='precision_weighted', cv=num_folds)
    print("Precision: " + str(round(100*precision_values.mean(), 2)) + "%")

    recall_values = cross_val_score(classifier,\
            X, y, scoring='recall_weighted', cv=num_folds)
    print("Recall: " + str(round(100*recall_values.mean(), 2)) + "%")

    f1_values = cross_val_score(classifier,\
            X, y, scoring='f1_weighted', cv=num_folds)
    print("F1: " + str(round(100*f1_values.mean(), 2)) + "%")

cross_valid(clf)
  1. 调节超参数

    通过拟合不同超参数时的模型,选出最优的模型

    # 对k近邻的 邻近参数的调节
    '''Error plot against K values '''
    error = []
    # Calculating error for K values between 1 and 40
    for i in range(1, 41):
        knn = KNeighborsClassifier(n_neighbors=i)
        _ = knn.fit(X_train, y_train)
        y_pred_i = knn.predict(X_test)
        error.append(np.mean(y_pred_i != y_test))
    
    def plot_k(error):
        plt.figure(1)
        plt.plot(range(1, 41), error, color='red',
            linestyle='dashed', marker='o',
            markerfacecolor='blue', markersize=10)
        plt.title('Error Rate vs K Value')
        plt.xlabel('K Value')
        plt.ylabel('Mean Error')
    plot_k(error)
    

猜你喜欢

转载自blog.csdn.net/weixin_43899514/article/details/110671882