用自己的图片集做随机森林、逻辑回归分类

版权声明:本文为博主原创文章,转载请注明作者和出处。https://blog.csdn.net/xq920831/article/details/84390468

参考文章地址:https://blog.csdn.net/qq_42379006/article/details/80929670

 

决策树与随机森林的基础知识:https://www.cnblogs.com/fionacai/p/5894142.html

首先制作好自己的图片集:文件夹——各类别小文件夹——各类图片。

下面就是代码部分:

# -*- coding:utf-8 -*-
# Author: Agent Xu

# 导入模块
import numpy as np
import cv2
import os
import glob
from skimage import io,transform
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import confusion_matrix,precision_recall_fscore_support
import pandas as pd
import pickle

#将所有的图片resize成100*100
w = 100
h = 100

# 创建模型输出文件夹
output_dir='output'
if not os.path.exists(output_dir):
    os.mkdir(output_dir)
# 数据准备 - 读取图片并贴标签
img_dir = 'D:/GJAI_data/gongjingai_pre/tupian/'
#读取图片
def read_img(path):
    cate = [path+x for x in os.listdir(path) if os.path.isdir(path+x)]
    imgs = []
    labels = []
    for idx,folder in enumerate(cate):
        for im in glob.glob(folder+'/*.jpg'):
            print('reading the images:%s'%(im))
            img = cv2.imread(im,cv2.IMREAD_COLOR)
            # img = transform.resize(img,(w,h))
            imgs.append(img)
            labels.append(idx)
    # return np.asarray(imgs,np.float32),np.asarray(labels,np.int32)
    return imgs,labels
# for fname in os.listdir(img_dir):
#     '''跳过不是目标图片的文件'''
#     if not fname.startswith('image'):continue
#     '''
#     合并目录:os.path.join
#     import os
#     os.path.join('/hello/','good/boy/','doiido')
#     >>> '/hello/good/boy/doiido'
#     '''
#     fpath = os.path.join(img_dir,fname)
#     '''根据文件名,提取图片分类'''
#     lab = fpath.split('_')[1]
#     '''RGB模式读取图片,读入的图片得到的是ndarray对象,0~255的整数'''
#     img = cv2.imread(fpath,cv2.IMREAD_COLOR)
#     images.append(img)
#     labels.append(lab)

'''定义特征转化函数'''
def transform1(img):
    '''每个通道等分为8组后计算直方图'''
    hist = cv2.calcHist([img],[0,1,2],None,[8,8,8],[0,256,0,256,0,256])
    '''将8*8*8的多维数组拉平'''
    return hist.ravel()

'''
保存模型:
通常情况下在一个地方训练的模型都会在另外一个地方被使用,因此每次训练的模型都需要保存成一个可调用的对象
本例中采用pickle.dump()方法将训练的模型保存,然后可以实现在其他地方调用,以此方便模型的使用
'''
def save_model(model,label_encoder,output_file):
    try:
        with open(output_file,'wb') as outfile:
            pickle.dump({
                'model':model,
                'label_encoder':label_encoder
            },outfile)
        return True
    except:
        return False

'''计算各项评价指标'''
def eval_model(y_true,y_pred,labels):
    '''计算每个分类器的Precision,Recall,f1,support'''
    P,r,f1,s =precision_recall_fscore_support(y_true,y_pred)
    '''计算总体平均的Precision,Recall,f1,support'''
    tot_P = np.average(P,weights =s)
    tot_r = np.average(r,weights =s)
    tot_f1 = np.average(f1,weights =s)
    tot_s = np.sum(s)
    res1 = pd.DataFrame({
        'Label':labels,
        'Precision':P,
        'Reacll':r,
        'F1':f1,
        'Support':s
    })
    res2 = pd.DataFrame({
        'Label':['总体'],
        'Precision':[tot_P],
        'Recall':[tot_r],
        'F1':[tot_f1],
        'Support':[tot_s]
    })
    res2.index=[999]
    res = pd.concat([res1,res2])
    '''计算混淆矩阵'''
    conf_mat = pd.DataFrame(confusion_matrix(y_true,y_pred),columns=labels,index=labels)
    return conf_mat,res[['Label','Precision','Recall','F1','Support']]


images,labels = read_img(img_dir)
'''将图片标签ID化,输出可由计算机处理的数据,四种花,四种标签,此处相当于多分类问题'''
label_encoder = LabelEncoder()
y = label_encoder.fit_transform(labels)
'''训练集、测试集划分,stratify = y,表示根据图片类别进行分类,确保每个类别图片的均衡性'''
train_idx,test_idx = train_test_split(range(len(y)),test_size=0.2,stratify = y, random_state = 1234)    # 返回拆分后的索引
train_y = y[train_idx]
test_y = y[test_idx]

# 计算RGB颜色直方图
'''提取每个图像的直方图特征,按行合并成一个大的矩阵,每一行即一张图片的长度为512特征'''
x_rgb = np.row_stack([transform1(img) for img in images])
'''
根据索引取得处理后的图片分别存入训练集和测试集
x[[],:]:取得对应行数的所有列数据
'''
train_x = x_rgb[train_idx,:]
test_x = x_rgb[test_idx,:]

#使用随机森林分类器
model_rgb_rf = RandomForestClassifier(n_estimators =50, max_depth =7, random_state=None) # 1234随机初始化的种子
model_rgb_rf.fit(train_x,train_y) # 训练数据集

# 保存模型
save_model(model_rgb_rf,label_encoder,os.path.join(output_dir,'model_rgb_rf.pkl'))

#随机森林模型评估
'''在测试集上计算每个图片的预测分类'''
y_pred_rgb_rf = model_rgb_rf.predict(test_x)
'''评估模型'''
conf_mat_lab_rf,evalues_rf = eval_model(test_y,y_pred_rgb_rf,label_encoder.classes_)


#使用逻辑回归训练分类器
'''l2正则惩罚项,惩罚力度为1'''
model_rgb_lr = LogisticRegression(penalty ='l2',C=1,random_state=1234)
model_rgb_lr.fit(train_x,train_y)
# 保存模型
save_model(model_rgb_lr,label_encoder,os.path.join(output_dir,'model_rgb_lr.pkl'))

#逻辑回归模型评估
'''在测试集上计算每个图片的预测分类'''
y_pred_rgb_lr = model_rgb_lr.predict(test_x)
'''评估模型'''
conf_mat_rgb_lr,evalues_rgb_lr = eval_model(test_y,y_pred_rgb_lr,label_encoder.classes_)

重点是调参部分

随机森林:RandomForestClassifier函数

根据自身数据集调节n_estimators和max_depth参数,其次min_samples_split和min_samples_leaf调参(可加可不加)

逻辑回归:LogisticRegression函数

调节penalty和C两个参数

  • 6
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值