金融领域机器学习的实现与优化
在金融数据分析中,机器学习技术能够帮助我们识别潜在的欺诈行为、预测风险等。本文将详细介绍如何在金融领域应用机器学习,包括数据预处理、模型选择、参数调优以及特征选择等关键步骤。
1. 数据预处理
在开始构建机器学习模型之前,我们需要对原始数据进行预处理,以确保数据的质量和可用性。
首先,我们要删除一些无用的特征,例如
Payment Date
、
Invoice ID
、
Invoice Date
和
Unnamed: 0
等。这些特征对于模型的构建没有太大的帮助,因此可以将它们从数据集中移除。
features_raw = features_raw.drop('Payment Date', axis=1)
features_raw = features_raw.drop('Invoice ID', axis=1)
features_raw = features_raw.drop('Invoice Date', axis=1)
features_raw = features_raw.drop('Unnamed: 0', axis=1)
接下来,我们要对数据进行可视化,查看
Amount
、
Month
和
Fiscal Year
这三个数值列的分布情况。通过可视化可以发现,这些列的分布都呈现出高度偏斜的状态,需要进行转换。
# Visualize skewed continuous features of original data
distribution(data)
为了处理数据的偏斜问题,我们可以使用对数变换(Log Transformation)。对数变换可以将数据的分布变得更加接近正态分布,从而提高模型的性能。
import warnings
warnings.filterwarnings("ignore")
skewed = ['Amount', 'Month', 'Fiscal Year']
features_raw[skewed] = data[skewed].apply(lambda x: np.log(x + 1))
features_raw.isnull().sum()
features_raw.fillna(0, inplace=True)
features_raw.dtypes
# Visualize the new log distributions
distribution(features_raw, transformed = True)
在进行对数变换之后,我们还需要对数据进行归一化处理,以消除不同特征之间的尺度差异。这里我们使用
MinMaxScaler
来对数值特征进行归一化。
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
numerical = ['Amount', 'Month', 'Fiscal Year']
features_raw[numerical] = scaler.fit_transform(data[numerical])
此外,由于Python的
scikit-learn
库需要对分类变量进行数值编码,我们还需要对
Payment Status
列进行热编码(Hot Encoding)。
d = {"Paid-Reconciled": 0, "Paid-Unreconciled": 1}
features_raw['Payment Status'] = features_raw['Payment Status'].map(d)
encoded = list(features_raw.columns)
print("{} total features after one-hot encoding.".format(len(encoded)))
2. 数据划分
完成数据预处理之后,我们需要将数据划分为训练集和测试集,以便评估模型的性能。这里我们使用
train_test_split
函数来进行划分。
from sklearn.cross_validation import train_test_split
X_train, X_test, y_train, y_test = train_test_split(features_raw, payment_raw, test_size = 0.2, random_state = 0)
print("Training set has {} samples.".format(X_train.shape[0]))
print("Testing set has {} samples.".format(X_test.shape[0]))
3. 模型评估
在选择合适的模型之前,我们需要先确定一个基准模型,以便评估其他模型的性能。这里我们使用朴素贝叶斯(Naive Bayes)作为基准模型,并计算其准确率、F1分数、精确率和召回率等指标。
from sklearn.naive_bayes import GaussianNB
from sklearn.metrics import accuracy_score, f1_score, precision_score, recall_score, classification_report, confusion_matrix
NB = GaussianNB()
NB.fit(X_train, y_train)
pred = NB.predict(X_test)
print(f1_score(y_test, pred, average="macro"))
print(precision_score(y_test, pred, average="macro"))
print(recall_score(y_test, pred, average="macro"))
接下来,我们将引入其他几种分类器,包括决策树(Decision Tree)、逻辑回归(Logistic Regression)、随机梯度下降(SGD)、ExtraTrees分类器和随机森林分类器(Random Forest Classifier),并比较它们的性能。
from sklearn.naive_bayes import GaussianNB
from sklearn.tree import DecisionTreeClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.linear_model import SGDClassifier
from sklearn.ensemble import ExtraTreesClassifier
from sklearn.ensemble import RandomForestClassifier
clf_A = GaussianNB()
clf_B = DecisionTreeClassifier(max_features=0.2, max_depth=2, min_samples_split=2, random_state=0)
clf_C = LogisticRegression(random_state=0)
clf_D = SGDClassifier(loss="hinge", penalty="l2")
clf_E = ExtraTreesClassifier(n_estimators=2, max_depth=2, min_samples_split=2, random_state=0)
clf_F = RandomForestClassifier(max_depth=2)
learners = ["Naive Bayes", "Decision Tree", "Logistic Regression", "SGD Classifier", "ExtraTrees Classifier", "RandomForest Classifier"]
cnt = 0
columns = ['learner', 'train_time', 'pred_time', 'acc_train', 'acc_test', 'f1_score']
learningresults = pd.DataFrame(columns=columns)
results = {}
for learner in [clf_A, clf_B, clf_C, clf_D, clf_E, clf_F]:
results['learner'] = learners[cnt]
start = time()
learner.fit(X_train, y_train)
end = time()
results['train_time'] = end - start
start = time()
predictions_test = learner.predict(X_test)
predictions_train = learner.predict(X_train)
end = time()
results['pred_time'] = end - start
results['acc_train'] = accuracy_score(y_train, predictions_train)
results['acc_test'] = accuracy_score(y_test, predictions_test)
beta = 0.5
results['f1_score'] = f1_score(y_test, pred, average="macro")
print(results)
learningresults.loc[cnt] = results
cnt = cnt + 1
print(learningresults)
learningresults.columns
learningresults.plot(kind='bar', x='learner', legend='reverse', title='Classifier Algorithms Compared - Accounts Payment Dataset', figsize=(10, 10), fontsize=20)
以下是各个分类器的性能比较表格:
| Learner | train_time | pred_time | acc_train | acc_test | f1_score |
| — | — | — | — | — | — |
| Decision Tree | 0.001 | 0.001 | 0.857045 | 0.880055 | 0.806468 |
| Naïve-Bayes | 0.002 | 0.002 | 0.910525 | 0.910898 | 0.806468 |
| SGD Classifier | 0.009 | 0 | 0.947377 | 0.946539 | 0.806468 |
| ExtraTrees Classifier | 0.01 | 0.002 | 0.858759 | 0.867032 | 0.806468 |
| Logistic Regression | 0.028 | 0.001 | 0.96349 | 0.971213 | 0.806468 |
| RandomForest Classifier | 0.146 | 0.011 | 0.948234 | 0.956134 | 0.806468 |
从表格中可以看出,各个分类器的F1分数相同,因此不能仅仅根据F1分数来选择模型。在考虑训练时间和测试准确率的情况下,逻辑回归是一个较好的选择。
4. 模型调优
选择了逻辑回归作为最佳分类器之后,我们可以使用网格搜索(Grid Search)和交叉验证(Cross Validation)来对模型进行超参数调优,以进一步提高模型的性能。
from sklearn.metrics import make_scorer
from sklearn.model_selection import GridSearchCV
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import fbeta_score
def getscore(y_true, y_predict):
return fbeta_score(y_true, y_predict, beta)
best_clf = None
beta = 0.5
clf_C = LogisticRegression(random_state=0)
parameters = {'solver': ['newton-cg', 'lbfgs', 'liblinear', 'sag', 'saga'], 'C': range(1, 10), 'max_iter': range(50, 100)}
scorer = make_scorer(getscore)
grid_obj = GridSearchCV(clf_C, parameters)
startTime = datetime.now()
grid_fit = grid_obj.fit(X_train, y_train)
CV_lr = GridSearchCV(estimator=clf_C, param_grid=parameters, cv= 5)
CV_lr.fit(X_train, y_train)
print(datetime.now() - startTime)
best_clf = grid_fit.best_estimator_
predictions = (clf_C.fit(X_train, y_train)).predict(X_test)
best_predictions = best_clf.predict(X_test)
print("Unoptimized model\n------")
print("Accuracy score on testing data: {:.4f}".format(accuracy_score(y_test, predictions)))
print("F-score on testing data: {:.4f}".format(fbeta_score(y_test, predictions, beta = 0.5, average='micro')))
print("\nOptimized Model\n------")
print("Final accuracy score on the testing data: {:.4f}".format(accuracy_score(y_test, best_predictions)))
print("Final F-score on the testing data: {:.4f}".format(fbeta_score(y_test, best_predictions, beta = 0.5, average='micro')))
通过网格搜索和交叉验证,我们可以找到最优的模型参数,从而提高模型的准确率和F分数。
5. 特征选择
最后,我们需要确定哪些特征对模型的预测最为重要,以便选择最相关的特征来构建最终的模型。这里我们使用
ExtraTreesClassifier
来计算特征的重要性,并选择前五个最重要的特征。
from sklearn.ensemble import ExtraTreesClassifier
from sklearn.feature_selection import SelectFromModel
from sklearn.metrics import fbeta_score
model = ExtraTreesClassifier()
model.fit(X_train, y_train)
importances = model.feature_importances_
feature_plot(importances, X_train, y_train)
从特征重要性的可视化结果中可以看出,
Amount
和
Payment Status
是最重要的两个特征,而
Fiscal Year
和
Month
对模型的预测影响较小。
接下来,我们可以根据特征的重要性对特征空间进行缩减,并使用缩减后的特征集来训练模型,比较使用完整特征集和缩减特征集的模型性能。
from sklearn.base import clone
best_clf = clf_F
X_train_reduced = X_train[X_train.columns.values[(np.argsort(importances)[::-1])[:5]]]
X_test_reduced = X_test[X_test.columns.values[(np.argsort(importances)[::-1])[:5]]]
clf = (clone(best_clf)).fit(X_train_reduced, y_train)
best_predictions = best_clf.predict(X_test)
reduced_predictions = clf.predict(X_test_reduced)
print("Final Model trained on full data\n------")
print("Accuracy on testing data: {:.4f}".format(accuracy_score(y_test, best_predictions)))
print("F-score on testing data: {:.4f}".format(fbeta_score(y_test, best_predictions, average="macro", beta = 0.5)))
print("\nFinal Model trained on reduced data\n------")
print("Accuracy on testing data: {:.4f}".format(accuracy_score(y_test, reduced_predictions)))
print("F-score on testing data: {:.4f}".format(fbeta_score(y_test, reduced_predictions, beta = 0.5, average='macro')))
通过比较可以发现,使用完整特征集和缩减特征集的模型性能差异不大,因此我们可以保留完整的数据集,而不需要丢弃其他特征。
综上所述,通过数据预处理、模型选择、参数调优和特征选择等步骤,我们可以构建一个性能良好的机器学习模型,用于金融领域的欺诈检测和风险预测等任务。
下面是整个流程的mermaid流程图:
graph LR
A[数据预处理] --> B[删除无用特征]
B --> C[可视化数据分布]
C --> D[对数变换]
D --> E[归一化处理]
E --> F[热编码]
F --> G[数据划分]
G --> H[模型评估]
H --> I[选择最佳模型]
I --> J[模型调优]
J --> K[特征选择]
K --> L[构建最终模型]
通过以上步骤,我们可以在金融领域有效地应用机器学习技术,提高数据分析的效率和准确性。
金融领域机器学习的实现与优化(续)
6. 关键步骤总结与深入分析
为了更清晰地理解整个机器学习在金融领域应用的过程,我们对前面的关键步骤进行详细总结,并深入分析每个步骤的重要性和作用。
-
数据预处理
-
删除无用特征
:去除如
Payment Date、Invoice ID等对模型构建无帮助的特征,减少数据的冗余,提高模型训练的效率。 -
对数变换
:针对
Amount、Month和Fiscal Year等高度偏斜的特征,通过对数变换使其分布更接近正态分布,有助于提高模型的性能。 -
归一化处理
:使用
MinMaxScaler对数值特征进行归一化,消除不同特征之间的尺度差异,避免因特征尺度不同而影响模型的训练效果。 -
热编码
:将分类变量
Payment Status进行热编码,将其转换为数值形式,以满足scikit-learn库的要求。
-
删除无用特征
:去除如
-
数据划分 :将数据划分为训练集和测试集,比例为8:2。训练集用于模型的训练,测试集用于评估模型的性能,确保模型具有良好的泛化能力。
-
模型评估
- 基准模型 :使用朴素贝叶斯作为基准模型,计算其准确率、F1分数、精确率和召回率等指标,为后续模型的评估提供参考。
- 多模型比较 :引入决策树、逻辑回归、SGD、ExtraTrees分类器和随机森林分类器等多种模型,比较它们的训练时间、预测时间、训练准确率、测试准确率和F1分数等指标,选择最适合的模型。
-
模型调优 :使用网格搜索和交叉验证对逻辑回归模型进行超参数调优,找到最优的模型参数,进一步提高模型的性能。
-
特征选择 :使用
ExtraTreesClassifier计算特征的重要性,选择前五个最重要的特征,构建缩减后的特征集,并比较使用完整特征集和缩减特征集的模型性能。
7. 操作步骤回顾
以下是整个流程的详细操作步骤列表:
1.
数据预处理
1. 删除无用特征:
features_raw = features_raw.drop('Payment Date', axis=1)
features_raw = features_raw.drop('Invoice ID', axis=1)
features_raw = features_raw.drop('Invoice Date', axis=1)
features_raw = features_raw.drop('Unnamed: 0', axis=1)
2. 可视化数据分布:
distribution(data)
3. 对数变换:
import warnings
warnings.filterwarnings("ignore")
skewed = ['Amount', 'Month', 'Fiscal Year']
features_raw[skewed] = data[skewed].apply(lambda x: np.log(x + 1))
features_raw.isnull().sum()
features_raw.fillna(0, inplace=True)
features_raw.dtypes
distribution(features_raw, transformed = True)
4. 归一化处理:
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
numerical = ['Amount', 'Month', 'Fiscal Year']
features_raw[numerical] = scaler.fit_transform(data[numerical])
5. 热编码:
d = {"Paid-Reconciled": 0, "Paid-Unreconciled": 1}
features_raw['Payment Status'] = features_raw['Payment Status'].map(d)
encoded = list(features_raw.columns)
print("{} total features after one-hot encoding.".format(len(encoded)))
- 数据划分 :
from sklearn.cross_validation import train_test_split
X_train, X_test, y_train, y_test = train_test_split(features_raw, payment_raw, test_size = 0.2, random_state = 0)
print("Training set has {} samples.".format(X_train.shape[0]))
print("Testing set has {} samples.".format(X_test.shape[0]))
-
模型评估
- 基准模型(朴素贝叶斯):
from sklearn.naive_bayes import GaussianNB
from sklearn.metrics import accuracy_score, f1_score, precision_score, recall_score, classification_report, confusion_matrix
NB = GaussianNB()
NB.fit(X_train, y_train)
pred = NB.predict(X_test)
print(f1_score(y_test, pred, average="macro"))
print(precision_score(y_test, pred, average="macro"))
print(recall_score(y_test, pred, average="macro"))
2. 多模型比较:
from sklearn.naive_bayes import GaussianNB
from sklearn.tree import DecisionTreeClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.linear_model import SGDClassifier
from sklearn.ensemble import ExtraTreesClassifier
from sklearn.ensemble import RandomForestClassifier
clf_A = GaussianNB()
clf_B = DecisionTreeClassifier(max_features=0.2, max_depth=2, min_samples_split=2, random_state=0)
clf_C = LogisticRegression(random_state=0)
clf_D = SGDClassifier(loss="hinge", penalty="l2")
clf_E = ExtraTreesClassifier(n_estimators=2, max_depth=2, min_samples_split=2, random_state=0)
clf_F = RandomForestClassifier(max_depth=2)
learners = ["Naive Bayes", "Decision Tree", "Logistic Regression", "SGD Classifier", "ExtraTrees Classifier", "RandomForest Classifier"]
cnt = 0
columns = ['learner', 'train_time', 'pred_time', 'acc_train', 'acc_test', 'f1_score']
learningresults = pd.DataFrame(columns=columns)
results = {}
for learner in [clf_A, clf_B, clf_C, clf_D, clf_E, clf_F]:
results['learner'] = learners[cnt]
start = time()
learner.fit(X_train, y_train)
end = time()
results['train_time'] = end - start
start = time()
predictions_test = learner.predict(X_test)
predictions_train = learner.predict(X_train)
end = time()
results['pred_time'] = end - start
results['acc_train'] = accuracy_score(y_train, predictions_train)
results['acc_test'] = accuracy_score(y_test, predictions_test)
beta = 0.5
results['f1_score'] = f1_score(y_test, pred, average="macro")
print(results)
learningresults.loc[cnt] = results
cnt = cnt + 1
print(learningresults)
learningresults.columns
learningresults.plot(kind='bar', x='learner', legend='reverse', title='Classifier Algorithms Compared - Accounts Payment Dataset', figsize=(10, 10), fontsize=20)
- 模型调优 :
from sklearn.metrics import make_scorer
from sklearn.model_selection import GridSearchCV
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import fbeta_score
def getscore(y_true, y_predict):
return fbeta_score(y_true, y_predict, beta)
best_clf = None
beta = 0.5
clf_C = LogisticRegression(random_state=0)
parameters = {'solver': ['newton-cg', 'lbfgs', 'liblinear', 'sag', 'saga'], 'C': range(1, 10), 'max_iter': range(50, 100)}
scorer = make_scorer(getscore)
grid_obj = GridSearchCV(clf_C, parameters)
startTime = datetime.now()
grid_fit = grid_obj.fit(X_train, y_train)
CV_lr = GridSearchCV(estimator=clf_C, param_grid=parameters, cv= 5)
CV_lr.fit(X_train, y_train)
print(datetime.now() - startTime)
best_clf = grid_fit.best_estimator_
predictions = (clf_C.fit(X_train, y_train)).predict(X_test)
best_predictions = best_clf.predict(X_test)
print("Unoptimized model\n------")
print("Accuracy score on testing data: {:.4f}".format(accuracy_score(y_test, predictions)))
print("F-score on testing data: {:.4f}".format(fbeta_score(y_test, predictions, beta = 0.5, average='micro')))
print("\nOptimized Model\n------")
print("Final accuracy score on the testing data: {:.4f}".format(accuracy_score(y_test, best_predictions)))
print("Final F-score on the testing data: {:.4f}".format(fbeta_score(y_test, best_predictions, beta = 0.5, average='micro')))
- 特征选择 :
from sklearn.ensemble import ExtraTreesClassifier
from sklearn.feature_selection import SelectFromModel
from sklearn.metrics import fbeta_score
model = ExtraTreesClassifier()
model.fit(X_train, y_train)
importances = model.feature_importances_
feature_plot(importances, X_train, y_train)
from sklearn.base import clone
best_clf = clf_F
X_train_reduced = X_train[X_train.columns.values[(np.argsort(importances)[::-1])[:5]]]
X_test_reduced = X_test[X_test.columns.values[(np.argsort(importances)[::-1])[:5]]]
clf = (clone(best_clf)).fit(X_train_reduced, y_train)
best_predictions = best_clf.predict(X_test)
reduced_predictions = clf.predict(X_test_reduced)
print("Final Model trained on full data\n------")
print("Accuracy on testing data: {:.4f}".format(accuracy_score(y_test, best_predictions)))
print("F-score on testing data: {:.4f}".format(fbeta_score(y_test, best_predictions, average="macro", beta = 0.5)))
print("\nFinal Model trained on reduced data\n------")
print("Accuracy on testing data: {:.4f}".format(accuracy_score(y_test, reduced_predictions)))
print("F-score on testing data: {:.4f}".format(fbeta_score(y_test, reduced_predictions, beta = 0.5, average='macro')))
8. 不同步骤的作用和影响
-
数据预处理的作用
- 提高数据质量:去除无用特征和处理缺失值,使数据更加干净、准确。
- 改善特征分布:对数变换使数据分布更接近正态分布,有助于模型更好地学习数据的特征。
- 统一特征尺度:归一化处理消除了特征尺度的差异,避免某些特征对模型的影响过大。
-
支持模型输入:热编码将分类变量转换为数值形式,满足了
scikit-learn库对输入数据的要求。
-
数据划分的影响 :合理的数据划分可以确保模型在训练过程中不会过拟合,同时能够准确评估模型的泛化能力。如果划分不合理,可能会导致模型在训练集上表现良好,但在测试集上表现不佳。
-
模型评估的意义 :通过多模型比较和基准模型的设置,可以全面了解不同模型的性能特点,选择最适合当前数据和任务的模型。同时,评估指标可以帮助我们客观地衡量模型的优劣。
-
模型调优的效果 :网格搜索和交叉验证可以找到最优的模型参数,进一步提高模型的性能。通过调优,模型的准确率和F分数等指标得到了显著提升。
-
特征选择的价值 :确定特征的重要性,选择最相关的特征构建模型,可以减少模型的复杂度,提高模型的训练效率和泛化能力。同时,避免了无关特征对模型的干扰。
9. 实际应用建议
在实际应用中,我们可以根据具体的业务需求和数据特点,灵活调整上述步骤和参数。例如:
- 当数据量较大时,可以考虑使用更高效的特征选择方法,如主成分分析(PCA),进一步减少特征的维度。
- 如果对模型的实时性要求较高,可以选择训练时间和预测时间较短的模型,如SGD分类器。
- 在进行模型调优时,可以尝试不同的超参数范围和搜索方法,以找到更优的模型参数。
通过以上的分析和建议,我们可以在金融领域更加有效地应用机器学习技术,实现欺诈检测、风险预测等目标,提高金融业务的安全性和效率。
总之,机器学习在金融领域的应用是一个复杂而又有价值的过程,需要我们认真对待每个步骤,不断优化和改进,以达到最佳的效果。
超级会员免费看

被折叠的 条评论
为什么被折叠?



