MATLAB实现基于BP网络的个人信贷信用评估

问题背景

image

神经网络建模

image

image

本实例采用一种简单的个人客户信贷信用评估方法,对所有客户做二分类,只区分好和差两种情况。数据采用德国信用数据库。德国信用数据库由Hans Hofmann教授整理,包含1000份客户资料,每位客户包含20条属性,并给出了信用的好或差的标注。数据库可从以下网址下载得到:

image

除了原始数据,该数据库还给出了数据的说明。原始数据保存在german.data文件中,包含7个数值属性,13个类别属性,以及一个分类标签,以下给出粗略的介绍:

image

image

部分样本如下表所示:

image

其中的数值属性可以直接使用,类别属性经过整数编码后可以使用。观察上文给出的20中个人用户属性,可以发现不少信息发生了部分重叠,然而,在神经网络中,用户可以忽略这些细节,由网络来完成映射关系。

此外,该数据库还给出了另一个处理过的文件german.data-numeric,将原始文件的类别属性进行了整数编码,形成了24个数值属性,可以直接使用。本实例将主要使用原始数据进行评估,最后也会给出结果。

使用MATLAB实现一个三层的BP神经网络。由于每个个人用户拥有24个属性,因此输入层包含24个神经元节点。该问题为针对信用好/差的二分类问题,因此输出层只包含一个神经元。隐含层的神经元个数与网络性能有关,需要通过实验确定,建立的神经网络结果如图:

image

个人信贷信用评估的实现

使用文件german.data提供的1000×20属性及分类标签作为数据构建BP神经网络,完成个人信贷的信用评估。具体流程如下图所示:

image

(1)读入数据。由于数据保存在二进制文件german.data中,需要使用MATLAB的读入函数textcsan。调用方法如下:

C = textscan(fileID,formatSpec)

其中FID为打开的文件句柄,字符串formatSpec表示读取时的格式。读取数据的代码如下:

%% 读入数据
% 打开文件
fid = fopen('german.data', 'r');

% 按格式读取每一行
% 每行包括21项,包括字符串和数字
C = textscan(fid, '%s %d %s %s %d %s %s %d %s %s %d %s %d %s %s %d %s %d %s %s %d\n');

% 关闭文件
fclose(fid);

执行上述代码,二进制文件中是数据就被读到变量C中。C是一个1×21的细胞数组,对应20个属性和信用状况。细胞数组的每一个元素均包含了1000个样本数据,如果该属性为数值属性,则该元素为1000×1列向量,否则元素本身又是一个包含1000个字符串的细胞数组:

C = 

  1 至 9 列

    {1000x1 cell}    [1000x1 int32]    {1000x1 cell}    {1000x1 cell}    [1000x1 int32]    {1000x1 cell}    {1000x1 cell}    [1000x1 int32]    {1000x1 cell}

  10 至 18 列

    {1000x1 cell}    [1000x1 int32]    {1000x1 cell}    [1000x1 int32]    {1000x1 cell}    {1000x1 cell}    [1000x1 int32]    {1000x1 cell}    [1000x1 int32]

  19 至 21 列

    {1000x1 cell}    {1000x1 cell}    [1000x1 int32]

为了便于计算,必须使用数值来表示数据中的类别属性。最简单的方式就是使用整数进行编码,如第一个属性的类别字符串为“A12”,“A1”表示该属性为第一个属性,“2”表示属性值为第二个类别。因此,采用数字“2”编码字符串“A12”,具体实现如下:

% 将字符串转换为整数
N = 20;
% 存放整数编码后的数值矩阵
C1=zeros(N+1,1000);
for i=1:N+1
    % 类别属性
    if iscell(C{i}) % Determine whether input is cell array
        for j=1:1000
            % eg: 'A12' -> 2
            if i<10
                d = textscan(C{i}{j}, '%c%c%d');
            % eg: 'A103'  -> 3
            else
                d = textscan(C{i}{j}, '%c%c%c%d');
            end
            C1(i,j) = d{end};
        end
    % 数值属性
    else
        C1(i,:) = C{i};
    end
end

得到的矩阵C1位21×1000数组矩阵。

(2)划分训练样本与测试样本。在全部1000份样本中,共有700份正例(信誉好)300份负例(信誉差)。划分时取前350份正例和前150负例作为训练样本,后350正例和后150份负例作为测试样本:

%% 划分训练样本与测试样本

% 输入向量
x = C1(1:N, :);
% 目标输出
y = C1(N+1, :);

% 正例
posx = x(:,y==1);
% 负例
negx = x(:,y==2);

% 训练样本
trainx = [ posx(:,1:350), negx(:,1:150)];
trainy = [ones(1,350), ones(1,150)*2];

% 测试样本
testx = [ posx(:,351:700), negx(:,151:300)];
testy = trainy;

(3)样本归一化。使用mapminmax函数对输入样本进行归一化,由于输出样本只取1和2两个值,因此目标输出不做归一化。

%% 样本归一化
% 训练样本归一化
[trainx, s1] = mapminmax(trainx);

% 测试样本归一化
testx = mapminmax('apply', testx, s1);

(4)创建BP神经网络,并完成训练:

%% 创建网络,训练

% 创建BP网络
net = newff(trainx, trainy);
% 设置最大训练次数
net.trainParam.epochs = 1500;
% 目标误差
net.trainParam.goal = 1e-13;
% 显示级别
net.trainParam.show = 1;

% 训练
net = train(net,trainx, trainy);

在这里,采用newff函数创建一个BP神经网络,隐含层节点个数及传递函数均采用默认值,训练函数采用默认的trainlm函数,设定最大迭代次数为1500次,然后调用train函数进行训练。

(5)测试。BP网络输出值并不限定为1或2,而是一个实数,因此还需要将输出转换为整数。取1.5为阈值,小于该阈值的输出判为1(信用好),否则判为2(信用差)。

%% 测试
y0 = net(testx);

% y0为浮点数输出。将y0量化为1或2。
y00 = y0;
% 以1.5为临界点,小于1.5为1,大于1.5为2
y00(y00<1.5)=1;
y00(y00>1.5)=2;

% 显示正确率
fprintf('正确率: \n');
disp(sum(y00==testy)/length(y00));

BP神经网络取得了较为理想的正确率,测试的输出结果为:

正确率:
    0.7500

(6)显示结果。为了抵消随机因素的影响。取相同的训练和测试样本运算20次,统计正确率与迭代次数。将第(4)和第(5)步的代码改为:

%% 训练.测试
M = 20;
rat = zeros(1, M);
trr = rat;
for i=1 : M
    % 创建网络,训练
    net = newff(trainx, trainy);
    % 设置最大训练次数
    net.trainParam.epochs = 1500;
    % 目标误差
    net.trainParam.goal = 1e-13;
    % 显示级别
    net.trainParam.show=1;
    
    % 训练
    [net tr] = train(net, trainx, trainy);
    % 测试
    y0 = net(testx);
    
    % y0为浮点数,将y0量化为1或2
    y00 = y0;
    y00(y00<1.5) =1;
    y00(y00>1.5) =2;
    rat(i) = sum(y00==testy)/length(y00);
    trr(i) = length(tr.epoch);
end

% 显示正确率
fprintf('正确率:\n');
disp(rat);
fprintf('平均正确率:\n');
disp(mean(rat));
fprintf('最低正确率:\n');
disp(min(rat));

% 显示训练次数
fprintf('迭代次数:\n');
disp(trr);

% 绘制双坐标图
[AX, H1, H2] = plotyy(1:M, rat, 1:M, trr, 'plot', 'plot');

% 设置y轴的范围
set(AX(1), 'YLim', [0.70, 0.80]);
set(AX(2), 'YLim', [0, 5]);

% 设置线型
set(H1, 'LineStyle', '--')
set(H2, 'LineStyle', ':')

% 设置Y轴标签
set(get(AX(1), 'Ylabel'), 'String', '正确率')
set(get(AX(2), 'Ylabel'), 'String', '训练次数')
title('BP网络的正确率与训练次数')

运算20次,可得到每一次测试的正确率及迭代次数:

正确率:
  1 至 8 列

    0.7560    0.7460    0.7620    0.7640    0.7580    0.7480    0.7560    0.7460

  9 至 16 列

    0.7600    0.7500    0.7520    0.7500    0.7480    0.7620    0.7500    0.7600

  17 至 20 列

    0.7680    0.7620    0.7440    0.7380

平均正确率:
    0.7540

最低正确率:
    0.7380

迭代次数:
  1 至 13 列

     4     4     4     4     4     4     4     4     4     4     4     4     4

  14 至 20 列

     4     4     4     4     4     4     4

测试20次的平均正确率为75.4%,最低正确率为73.8%,迭代次数均为4。绘制的双坐标图如下:

image

如上图所示,正确率曲线大致稳定在0.74~0.76之间,迭代次数则稳定在4次。使用BP神经网络对实际信用数据实现了较好的预测。在采用350份正例和150份负例作为训练样本的情况下,以75%的正确率成功预测了新客户的信贷信用情况。

  • 4
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
以下是一个简单的基于BP神经网络的印刷体汉字识别的MATLAB代码: 1. 数据准备 首先,需要准备好用于训练和测试的汉字图像数据。可以使用公开数据集,如CASIA-OLHWDB1.1等。将图像转换为灰度图像,并将其调整为相同的大小。然后将汉字图像转换为一维向量,并将其归一化为0到1之间的值。 2. 神经网络模型 使用MATLAB的Neural Network Toolbox创建一个BP神经网络模型。该模型包括输入层、一个或多个隐藏层和输出层。在本例中,输入层有784个神经元(28x28),一个隐藏层有100个神经元,输出层有汉字的总数目个神经元。 3. 训练神经网络 使用神经网络工具箱的train函数训练BP神经网络。可以设置训练参数,如学习速率、训练轮数等。在训练过程中,可以使用交叉验证来评估模型的性能,并选择最佳的训练参数。 4. 测试神经网络 使用测试数据集对训练好的神经网络进行测试。将测试图像转换为一维向量,并将其输入到神经网络中。神经网络将输出一个向量,其中每个元素表示对应的汉字的概率。通过比较概率值,可以确定神经网络识别的汉字。 以下是一个简单的示例代码: ``` % Load data load('chinese_characters.mat'); % Create neural network model net = patternnet(100); % Train neural network [net,tr] = train(net,X,T); % Test neural network Y = net(X_test); [~,I] = max(Y); accuracy = sum(I == y_test) / numel(y_test); fprintf('Accuracy: %.2f%%\n', accuracy * 100); ``` 其中,chinese_characters.mat是一个包含训练和测试数据的MATLAB数据文件。X和T分别是训练数据和训练标签,X_test和y_test是测试数据和测试标签。在这个例子中,我们使用了一个包含100个神经元的隐藏层,训练数据使用了默认的训练参数,测试数据使用了训练好的神经网络进行测试,并计算了识别精度。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值