【机器学习】李宏毅-判断年收入

news2024/12/26 20:54:26

李宏毅-判断年收入

在这里插入图片描述


1 实验目的

本次作业的数据是加州大学尔湾分校机器学习作业中下载得到,使用Classification中的生成模型generative model以及logistic regression解决二分类问题。

根据已有数据,判断该人年收入是否大于5万美元,最终得到预测结果输出到结果文件中比较准确率。


2 实验要求

  • 不可以使用 tensorflow 或者 pytorch 库

  • 请用概率生成模型generative model(分类第一节课)解决本问题

  • 请用logistic regression(分类第二节课)解决本问题

  • 上传格式为csv, 第一行必须为id,label,第二行开始为预测结果,每行分别为id以及预测的label,请以逗号分隔


3 实验环境

3.1 硬件环境

笔记本电脑、Intel Core i5

3.2 软件环境

windows10操作系统、Python 3.8 64-bit、Visual Studio Code


4 数据处理

4.1 数据文件描述

关于train.csv, test.csv:

age, workclass, fnlwgt (总人数), education, education num, marital-status, occupation, relationship, race, sex, capital-gain, capital-loss, hours-per-week, native-country, make over 50K a year or not

关于X_train, Y_train, X_test :

  1. discrete features in train.csv => one-hot encoding in X_train (work_class,education…)
  2. continuous features in train.csv => remain the same in X_train (age,capital_gain…)
  3. X_train, X_test : each row contains one 106-dim feature represents a sample
  4. Y_train: label = 0 means “<= 50K”label = 1 means “ >50K ”

4.2 读取数据

在data_manager()类中定义了读取数据的函数read():

#读取数据
def read(self,name,path):
    with open(path,newline = '') as csvfile:
        #注意去掉首行读取
        rows = np.array(list(csv.reader(csvfile))[1:] ,dtype = float) 

通过调用该函数读取X_train, Y_train, X_test 三个数据文件:

#读取文件
dm.read('X_train','data/X_train')
dm.read('Y_train','data/Y_train')
dm.read('X_test','data/X_test')

4.3 z-score特征标准化

σ = 1   N ∑ i = 1 N ( x i − μ ) 2 z i = x i − μ σ \sigma=\sqrt{\frac{1}{\mathrm{~N}} \sum_{i=1}^{\mathrm{N}}\left(\mathrm{x}_{\mathrm{i}}-\mu\right)^{2}}\\ \mathrm{z}_{\mathrm{i}}=\frac{\mathrm{x}_{\mathrm{i}}-\mu}{\sigma} σ= N1i=1N(xiμ)2 zi=σxiμ

z-score通过(x-μ)/σ将两组或多组数据转化为无单位的Z-Score分值,使得数据标准统一化,提高了数据可比性,削弱了数据解释性:

        if name == 'X_train':
                #求均值并转为1行,div=1*106
                self.mean = np.mean(rows,axis = 0).reshape(1,-1)
                #求方差并转为1行,div=1*106
                self.std = np.std(rows,axis = 0).reshape(1,-1)
                self.theta = np.ones((rows.shape[1] + 1,1),dtype = float)
                #对每一行数据进行标准化
                for i in range(rows.shape[0]):
                    rows[i,:] = (rows[i,:]-self.mean)/self.std
            elif name == 'X_test': 
                for i in range(rows.shape[0]):
                    rows[i,:] = (rows[i,:]-self.mean)/self.std
            #保存数据处理结果到类内字典索引里
            self.data[name] = rows

4.4 划分训练集和验证集

data_manager()类内函数partition()负责训练集和验证集的划分,其中num代表设定验证集里有多少笔验证数据,在此暂时设为3000:

#分割数据集为训练集和验证集
def partition(self):
    num=3000
    self.data['X_verify']=self.data['X_train'][:num]
    self.data['X_train']=self.data['X_train'][num:]
    self.data['Y_verify']=self.data['Y_train'][:num]
    self.data['Y_train']=self.data['Y_train'][num:]

由此可见训练集在self.data字典里的索引为X_train、Y_train,验证集在self.data字典里的索引为X_verify、Y_verify,测试集在self.data字典里的索引为X_test。


5 概率生成模型generative model

概率生成模型,简称生成模型(Generative Model),是概率统计和机器学习中的一类重要模型,指一系列用于随机生成可观测数据的模型。生成模型可以和贝叶斯概率公式进行结合,用于分类问题。

5.1 对训练数据二分类

由于概率生成模型需要计算样本选择的概率,所以需要先对训练数据进行二分类:

#记录分类的元素索引
class_0_id = []
class_1_id = []
#通过Y_train分类索引
for i in range(self.data['Y_train'].shape[0]):
    if self.data['Y_train'][i][0] == 0:
        class_0_id.append(i)
    else:
        class_1_id.append(i)
#按照索引去X_train找到对应元素
class_0 = self.data['X_train'][class_0_id]
class_1 = self.data['X_train'][class_1_id] 

5.2 计算均值和协方差

参考均值的计算公式:
μ 0 ∗ = 1 n 0 ∑ i = 0 n 0 x i , Σ 0 ∗ = 1 n 0 ∑ i = 0 n 0 ( x i − μ 0 ∗ ) ( x i − μ 0 ∗ ) T μ 1 ∗ = 1 n 1 ∑ i = 0 n 1 x i , Σ 1 ∗ = 1 n 1 ∑ i = 0 n 1 ( x i − μ 1 ∗ ) ( x i − μ 1 ∗ ) T \mu_{0}^{*}=\frac{1}{\mathrm{n}_{0}} \sum_{\mathrm{i}=0}^{\mathrm{n}_{0}} \mathrm{x}^{\mathrm{i}}, \quad \Sigma_{0}^{*}=\frac{1}{\mathrm{n}_{0}} \sum_{\mathrm{i}=0}^{\mathrm{n}_{0}}\left(\mathrm{x}^{\mathrm{i}}-\mu_{0}^{*}\right)\left(\mathrm{x}^{\mathrm{i}}-\mu_{0}^{*}\right)^{\mathrm{T}}\\ \mu_{1}^{*}=\frac{1}{n_{1}} \sum_{\mathrm{i}=0}^{\mathrm{n}_{1}} \mathrm{x}^{\mathrm{i}}, \quad \Sigma_{1}^{*}=\frac{1}{\mathrm{n}_{1}} \sum_{\mathrm{i}=0}^{\mathrm{n}_{1}}\left(\mathrm{x}^{\mathrm{i}}-\mu_{1}^{*}\right)\left(\mathrm{x}^{\mathrm{i}}-\mu_{1}^{*}\right)^{\mathrm{T}}\\ μ0=n01i=0n0xi,Σ0=n01i=0n0(xiμ0)(xiμ0)Tμ1=n11i=0n1xi,Σ1=n11i=0n1(xiμ1)(xiμ1)T
在代码中实现:

#分别求出两类均值
mean_0 = np.mean(class_0,axis = 0)
mean_1 = np.mean(class_1,axis = 0) 

不同的类别共享协方差矩阵,因为协方差的规模是和特征数量的平方成正比的,如果特征数量很大,协方差的尺寸也大,由于不同的高斯分布有不同的协方差矩阵,这样模型的参数就会很多,就会过拟合。计算协方差的公式为:
Σ ∗ = n 0 n 0 + n 1 Σ 0 ∗ + n 1 n 0 + n 1 Σ 1 ∗ \Sigma^{*}=\frac{\mathrm{n}_{0}}{\mathrm{n}_{0}+\mathrm{n}_{1}} \Sigma_{0}^{*}+\frac{\mathrm{n}_{1}}{\mathrm{n}_{0}+\mathrm{n}_{1}} \Sigma_{1}^{*} Σ=n0+n1n0Σ0+n0+n1n1Σ1
在代码中实现:

n = class_0.shape[1]
#两类的协方差,div=106*106
cov_0 = np.zeros((n,n))
cov_1 = np.zeros((n,n))
#计算类1的协方差
for i in range(class_0.shape[0]):
    #需要进行矩阵转置,div从1*106转置为106*1
    cov_0 += np.dot(np.transpose([class_0[i]-mean_0]),[class_0[i]-mean_0])
#计算类2的协方差
    for i in range(class_1.shape[0]):
    #需要进行矩阵转置,div从1*106转置为106*1
    cov_1 += np.dot((class_1[i]-mean_1).transpose(),class_1[i]-mean_1)
#类中的行数
n_0 = class_0.shape[0]
n_1 = class_1.shape[0]
#两个类共享一个协方差
cov = (cov_0+cov_1)/(n_0+n_1)

5.3 计算参数w和b

参考计算参数w和b的公式:
w T = ( μ 0 − μ 1 ) T Σ − 1   b = − 1 2 ( μ 0 ) T Σ − 1 μ 0 + 1 2 ( μ 1 ) T Σ − 1 μ 1 + ln ⁡ n 0 n 1 \begin{array}{c} \mathrm{w}^{\mathrm{T}}=\left(\mu^{0}-\mu^{1}\right)^{\mathrm{T}} \Sigma^{-1} \\ \mathrm{~b}=-\frac{1}{2}\left(\mu^{0}\right)^{\mathrm{T}} \Sigma^{-1} \mu^{0}+\frac{1}{2}\left(\mu^{1}\right)^{\mathrm{T}} \Sigma^{-1} \mu^{1}+\ln \frac{\mathrm{n}_{0}}{\mathrm{n}_{1}} \end{array} wT=(μ0μ1)TΣ1 b=21(μ0)TΣ1μ0+21(μ1)TΣ1μ1+lnn1n0
从公式中可以看出,我们不光需要刚才计算出的均值和协方差,还需要协方差的逆,代码实现如下:

#协方差的逆
cov_inv = inv(cov)
#根据公式求w和b
self.w = np.dot((mean_0-mean_1).transpose(),cov_inv).transpose()
self.b = (-0.5)*np.dot(np.dot(mean_0.transpose(),cov_inv),mean_0)+0.5*np.dot(np.dot(mean_1.transpose(),cov_inv),mean_1)+np.log(float(n_0)/n_1)

5.4 后验概率函数sigmoid

后验概率参考公式:
P ( C 1 ∣ x ) = P ( x ∣ C 1 ) P ( C 1 ) P ( x ∣ C 1 ) P ( C 1 ) + P ( x ∣ C 2 ) P ( C 2 ) = 1 1 + P ( x ∣ C 2 ) P ( C 2 ) P ( x ∣ C 1 ) P ( C 1 ) = 1 1 + exp ⁡ ( − z )   ,   z = ln ⁡ P ( x ∣ C 1 ) P ( C 1 ) P ( x ∣ C 2 ) P ( C 2 ) P\left(C_{1} \mid x\right)=\frac{P\left(x \mid C_{1}\right) P\left(C_{1}\right)}{P\left(x \mid C_{1}\right) P\left(C_{1}\right)+P\left(x \mid C_{2}\right) P\left(C_{2}\right)}=\frac{1}{1+\frac{P\left(x \mid C_{2}\right) P\left(C_{2}\right)}{P\left(x \mid C_{1}\right) P\left(C_{1}\right)}}\\=\frac{1}{1+\exp (-z)}\ ,\ z=\ln \frac{P\left(x \mid C_{1}\right) P\left(C_{1}\right)}{P\left(x \mid C_{2}\right) P\left(C_{2}\right)} P(C1x)=P(xC1)P(C1)+P(xC2)P(C2)P(xC1)P(C1)=1+P(xC1)P(C1)P(xC2)P(C2)1=1+exp(z)1 , z=lnP(xC2)P(C2)P(xC1)P(C1)
代码实现如下,注意这里的np.exp()会存在溢出风险,所以使用了拆分运算(在逻辑回归模型中改进了更好的办法):

#后验概率函数sigmoid
def func(self,x):
    arr = np.empty([x.shape[0],1],dtype=float)
    ##拆分运算,防止exp溢出
    for i in range(x.shape[0]):
        z = x[i,:].dot(self.w) + self.b
        z *= (-1)
        arr[i][0] = 1 / (1 + np.exp(z))
    #避免由于数值太小,通过numpy的clip函数,将其转换为了界于1e-8和1-(1e-8)的数字
    return np.clip(arr, 1e-8, 1-(1e-8))

5.5 分类模型输出

通过5.4中后验概率的计算结果,我们需要对模型进行输出,后验概率值>0.5则输出1,后验概率值<0.5则输出0,定义类内函数predict()来完成这一过程:

#函数输出
def predict(self,x):
    ans = np.ones([x.shape[0],1],dtype=int)
    for i in range(x.shape[0]):
        if x[i] > 0.5:
            ans[i] = 0
    return ans

5.6 训练集和验证集上的准确率

计算出w和b之后就可以直接计算出训练的生成模型在训练集上的准确率:

#用求得的w和b计算sigmoid()函数结果
result = self.func(self.data['X_train'])
#经过0-1函数处理得到预测值
answer = self.predict(result)
#计算训练集上的准确率
accuracy=1-np.mean(np.abs(self.data['Y_train']-answer))
print("accuracy on train set = ",accuracy)

另外我们用类内函数verify()计算在验证集上的准确率,验证集来自于4.4环节划分得到:

#验证集验证
def verify(self):
    #用求得的w和b计算sigmoid()函数结果
    result = self.func(self.data['X_verify'])
    #经过0-1函数处理得到预测值
    answer = self.predict(result)
    #计算验证集上的准确率
    accuracy=1-np.mean(np.abs(self.data['Y_verify']-answer))
    print("accuracy on verify set = ",accuracy)

运行程序得到训练的生成模型在训练集和验证集上各自的准确率:

5.7 模型预测结果

类内函数wirte_file()可以把模型的预测结果导出到格式为csv的文件里, 第一行为id,label,第二行开始为预测结果,每行分别为id以及预测的label,以逗号分隔:

#预测结果并输出到目标文件中
def write_file(self,path):
    result = self.func(self.data['X_test'])
    answer = self.predict(result)
    with open(path, 'w', newline='') as csvfile:
        writer = csv.writer(csvfile) 
        writer.writerow(['id','label']) 
        for i in range(answer.shape[0]):
            writer.writerow([i+1,answer[i][0]])

运行程序得到预测结果,详见结果文件generative_model_output.csv。


6 逻辑回归模型logistic regression

逻辑回归假设数据服从伯努利分布(即数据的标签为0或者1),通过极大化似然函数的方法,运用梯度下降来求解参数,来达到将数据二分类的目的。

使用的基础模型为:
P w , b ( C 1 ∣ x ) = σ ( z ) = 1 1 + e − z z = w ⋅ x + b = ∑ i w i x i + b \begin{array}{c} P_{w, b}\left(C_{1} \mid x\right)=\sigma(z)=\frac{1}{1+e^{-z}} \\ z=w \cdot x+b=\sum_{i} w_{i} x_{i}+b \end{array} Pw,b(C1x)=σ(z)=1+ez1z=wx+b=iwixi+b

6.1 参数设定

在梯度下降的过程中,我们需要诸多参数,在此预先定义好:

#学习率
learning_rate = 1
#迭代次数
iter_time = 1000
#初始化权重w和偏移b
self.w = np.zeros([len(self.data['X_train'][0]),1])
self.b = 0
#初始化adagrad参数
w_adagrad = np.ones([len(self.data['X_train'][0]),1])
b_adagrad = 1

6.2 梯度下降迭代过程

迭代过程类似上一次线性回归的实验,但是使用的偏微分公式发生了变化:
∂ ( − ln ⁡ L ( w , b ) ) ∂ w i = − ∑ n ( y ^ n − f w , b ( x n ) ) x i n ∂ ( − ln ⁡ L ( w , b ) ) ∂ b = − ∑ n ( y ^ n − f w , b ( x n ) ) \begin{array}{l} \frac{\partial(-\ln \mathrm{L}(\mathrm{w}, \mathrm{b}))}{\partial \mathrm{w}_{\mathrm{i}}}=-\sum_{\mathrm{n}}\left(\hat{\mathrm{y}}^{\mathrm{n}}-\mathrm{fw}, \mathrm{b}\left(\mathrm{x}^{\mathrm{n}}\right)\right) \mathrm{x}_{\mathrm{i}}^{\mathrm{n}} \\ \frac{\partial(-\ln \mathrm{L}(\mathrm{w}, \mathrm{b}))}{\partial \mathrm{b}}=-\sum_{\mathrm{n}}\left(\hat{\mathrm{y}}^{\mathrm{n}}-\mathrm{fw}, \mathrm{b}\left(\mathrm{x}^{\mathrm{n}}\right)\right) \end{array} wi(lnL(w,b))=n(y^nfw,b(xn))xinb(lnL(w,b))=n(y^nfw,b(xn))
因此参数更新的公式变为:
w i = w i − η ( − ∑ n ( y ^ n − f w , b ( x n ) ) x i n ) b i = b i − η ( − ∑ n ( y ^ n − f w , b ( x n ) ) ) \begin{aligned} \mathrm{w}_{\mathrm{i}} &=\mathrm{w}_{\mathrm{i}}-\eta\left(-\sum_{\mathrm{n}}\left(\hat{\mathrm{y}}^{\mathrm{n}}-\mathrm{fw}, \mathrm{b}\left(\mathrm{x}^{\mathrm{n}}\right)\right) \mathrm{x}_{\mathrm{i}}^{\mathrm{n}}\right) \\ \mathrm{b}_{\mathrm{i}} &=\mathrm{b}_{\mathrm{i}}-\eta\left(-\sum_{\mathrm{n}}\left(\hat{\mathrm{y}}^{\mathrm{n}}-\mathrm{fw}, \mathrm{b}\left(\mathrm{x}^{\mathrm{n}}\right)\right)\right) \end{aligned} wibi=wiη(n(y^nfw,b(xn))xin)=biη(n(y^nfw,b(xn)))
另外为了更好地训练模型,使用Adagrad方法更新学习率:
η n = η ∑ i = 1 n − 1 g i 2 \eta_{n}=\frac{\eta}{\sqrt{\sum_{i=1}^{n-1} g^{\mathrm{i}^{2}}}} ηn=i=1n1gi2 η
代码实现如下:

#进度条对象
p=progressbar.ProgressBar()
#梯度下降法迭代
for i in p(range(iter_time)):
     result = self.func(self.data['X_train'])
     #求w梯度
     w_gradient = -np.dot(self.data['X_train'].transpose(),self.data['Y_train']-result)
     w_adagrad += (w_gradient/self.data['X_train'].shape[0]) ** 2
     #求b梯度
     b_gradient = -np.sum(self.data['Y_train']-result)
     b_adagrad += (b_gradient/self.data['X_train'].shape[0]) ** 2
     #更新w
     self.w = self.w - learning_rate * w_gradient / np.sqrt(w_adagrad)
     #更新b
     self.b = self.b - learning_rate * b_gradient / np.sqrt(b_adagrad)

6.3 后验概率函数sigmoid

在概率生成模型中,由于运算规模较小,并且使用了拆分运算,所以没有出现exp的overflow问题,在逻辑回归模型的最开始的调试过程中我们发现了这个问题,引用scipy.special模块中的expit函数解决了溢出的问题:

from scipy.special import expit

#sigmoid函数
def func(self,x):
    arr = np.empty([x.shape[0],1],dtype=float)
    #拆分运算,防止exp溢出
    for i in range(x.shape[0]):
        z = x[i,:].dot(self.w) + self.b
        z *= (-1)
        arr[i][0] = 1 / (1 + expit(z))
    #避免由于数值太小,通过numpy的clip函数,将其转换为了界于1e-8和1-(1e-8)的数字
    return np.clip(arr, 1e-8, 1-(1e-8))

6.4 训练集和验证集上的准确率

计算出w和b之后就可以直接计算出训练的逻辑回归模型在训练集上的准确率:

#用求得的w和b计算sigmoid()函数结果
result = self.func(self.data['X_train'])
#经过0-1函数处理得到预测值
answer = self.predict(result)
#计算训练集上的准确率
accuracy=1-np.mean(np.abs(self.data['Y_train']-answer))
print("accuracy on train set = ",accuracy)

另外我们用类内函数verify()计算在验证集上的准确率,验证集来自于4.4环节划分得到:

#验证集验证
def verify(self):
    #用求得的w和b计算sigmoid()函数结果
    result = self.func(self.data['X_verify'])
    #经过0-1函数处理得到预测值
    answer = self.predict(result)
    #计算验证集上的准确率
    accuracy=1-np.mean(np.abs(self.data['Y_verify']-answer))
    print("accuracy on verify set = ",accuracy)

运行程序得到训练的逻辑回归模型在训练集和验证集上各自的准确率:

在这里插入图片描述

6.5 正则化regularization

正则化的思想是在损失函数中加入限制项,公式如下:
L = 1 2 m [ ∑ i = 1 m ( h w ( x ( i ) ) − y ( i ) ) 2 + λ ∑ j = 1 n w j 2 ] L=\frac{1}{2 m}\left[\sum_{i=1}^{m}\left(h_{w}\left(x^{(i)}\right)-y^{(i)}\right)^{2}+\lambda \sum_{j=1}^{n} w_{j}^{2}\right] L=2m1[i=1m(hw(x(i))y(i))2+λj=1nwj2]
定义正则化系数λ:

regularization_lambda=1

修改梯度下降迭代过程,考虑正则项的微分:

#梯度下降法迭代过程
for i in p(range(iter_time)):
     result = self.func(self.data['X_train'])
     #求w梯度
     w_gradient = -np.dot(self.data['X_train'].transpose(),self.data['Y_train']-result)
     w_gradient += regularization_lambda*w_gradient
     w_adagrad += (w_gradient/self.data['X_train'].shape[0]) ** 2
     #求b梯度
     b_gradient = -np.sum(self.data['Y_train']-result)
     b_adagrad += (b_gradient/self.data['X_train'].shape[0]) ** 2
     #更新w
     self.w = self.w - learning_rate * w_gradient / np.sqrt(w_adagrad)
     #更新b
     self.b = self.b - learning_rate * b_gradient / np.sqrt(b_adagrad)

运行程序得到新的结果(对于正则化的分析评估将在7.3展开):

在这里插入图片描述

6.6 模型预测结果

类内函数wirte_file()可以把模型的预测结果导出到格式为csv的文件里, 第一行为id,label,第二行开始为预测结果,每行分别为id以及预测的label,以逗号分隔。

代码相较于生成模型作出了适当修改:

#预测结果并输出到目标文件中
def write_file(self,path):
    result = self.func(self.data['X_test'])
    answer = np.around(result)
    with open(path, 'w', newline='') as csvfile:
        writer = csv.writer(csvfile) 
        writer.writerow(['id','label']) 
        for i in range(answer.shape[0]):
            writer.writerow([i+1,int(answer[i][0])])

运行程序得到预测结果,详见结果文件logistic_regression_output.csv。


7 分析评估

7.1 不同分类模型的影响

用逻辑回归的方法生成的模型叫做判别模型,用高斯公式描述后验概率称为生成模型。逻辑回归和生成模型用的一样的模型。前者直接在训练数据的特征空间进行学习,直接找出w,b,后者会考虑数据的生成情况,即每个类别下的数据分布规律,用概率分布算出w和b。

虽然是同一个函数,但是用两种方法得到的w和b结果是不同的。因为在生成式模型中,我们对概率分布是有假设的,假设是高斯分布或伯努利分布。

下面是不同模型在不同数据集上的的准确率的汇总:

模型类别训练集上的准确率验证集上的准确率
generative model0.79324109468556550.7933333333333333
logistic regression0.82372044247488240.8226666666666667

可以看到逻辑回归模型相较于概率生成模型的拟合效果更好,在训练集和验证集上的表现也更出色。

但是逻辑回归模型的表现依赖于其一系列参数的选取,例如学习率大小和正则化系数等等,其次样本量也对测试结果有一定影响,因此并不能保证说逻辑回归模型优于概率生成模型。

7.2 特征标准化feature scaling对模型准确率的影响

z-score通过(x-μ)/σ将两组或多组数据转化为无单位的Z-Score分值,使得数据标准统一化,提高了数据可比性,削弱了数据解释性。

7.3 正则化regularization对模型准确率的影响

加入正则化的目的就是让模型的参数变小,使模型对数据敏感度下降,所以正则项的加入就是降低模型变化率的过程,变化率降低直观表现为模型更加平滑,使模型更加集中且增大了与真实模型之间的距离,也就是增大了偏移量bias,从而增强了高阶过拟合模型的泛化能力。

下面是引入正则项前后逻辑回归模型在不同数据集上的准确率的汇总:

逻辑回归模型训练集上的准确率验证集上的准确率
未使用正则化0.82372044247488240.8226666666666667
使用正则化0.83501911302053380.8326666666666667

可以看到,正则化对模型在数据集上的准确率都有略微提升,但是提升的效果并不是非常明显。

究其原因依然是正则化对高次项的过拟合现象有较好的改良效果,在本次实验中的逻辑回归模型并没有使用高次项作为参数,因此使用正则化之后对结果的影响并不是特别明显。

7.4 猜测对结果影响最大的特征

在逻辑回归模型得到的结果中,找到权重w里绝对值最大的一项,该w对应的特征可能就是对结果影响最大的特征。定义类内函数find_max()来完成这一过程:

#猜测影响最大的特征
def find_max(self):
    max=np.max(dm.w)
    for i in range(len(self.w)):   
        if self.w[i]==max:
            print("The most important feature is No.",i)
            break

得到函数输出:
在这里插入图片描述

可以看到第三个特征对结果的影响最大,对应的特征是capital_gain。


8 References

[1] python.org

[2] kaggle.com

[3] 百度百科

[4] CSDN专业开发者技术社区

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/138524.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

leetcode 23[python3]几种方法的思考与总结

题目 给你一个链表数组&#xff0c;每个链表都已经按升序排列。 请你将所有链表合并到一个升序链表中&#xff0c;返回合并后的链表。 示例 输入&#xff1a; lists [[1,4,5],[1,3,4],[2,6]]输出&#xff1a;[1,1,2,3,4,4,5,6]解释&#xff1a;链表数组如下&#xff1a;[ 1…

⚡️【linux】linux编辑器-VIM的高频使用,快快收藏起来!

⚡️目录 1️⃣VIM最小集 2️⃣VIM指令集 3️⃣VIM的配置 &#x1f332;前言&#xff1a;VIM和VI的区别简单点来讲&#xff0c;他们都是多模式编辑器&#xff0c;不同的是VIM是VI的升级版本&#xff0c;它不仅兼容VI的所有指令&#xff0c;而且还有一些新的特征在里面。例如语…

录屏软件哪个好?试试这6款录屏软件,小编亲测(2023已更新)

对于很多小伙伴来说&#xff0c;电脑录屏是经常需要使用的技能。面对网络上眼花缭乱的录屏软件&#xff0c;究竟哪个录屏软件好用呢&#xff1f;录屏软件哪个好&#xff1f;今天&#xff0c;小编分享亲自测试的这6款录屏软件给你&#xff0c;一起来看看吧。 录屏软件1&#xff…

DevSecOps“内置安全保护”,让软件研发“天生健康”

前言 随着DevOps的发展&#xff0c;DevOps大幅提升了企业应用迭代的速度。但同时&#xff0c;安全如果不能跟上步伐&#xff0c;不仅会抵消DevOps变革带来的提升&#xff0c;拖慢企业数字化转型进程&#xff0c;还会导致漏洞与风险不约而至。所以安全能力在全球范围内受到的重…

4款宝藏国产软件,装了就舍不得卸载,白嫖必备

提到国产软件&#xff0c;许多人想到“流氓、捆绑、广告多”&#xff0c;事实上国产良心软件非常多&#xff0c;如下面几款&#xff0c;每一个都功能强大&#xff0c;最重要还免费使用。 1、原本&#xff08;图片处理神器&#xff09; 日常生活与工作中&#xff0c;经常需要拍摄…

C++单例模式 : 懒汉模式 与 饿汉模式

单例模式&#xff1a; 只能有一个实例&#xff0c;有懒汉和饿汉区分&#xff0c;实现核心思想&#xff1a; 1.构造函数私有化 2.使用静态函数作为接口来获取类对象 1、懒汉模式&#xff1a; 由调用者实例&#xff0c;多线程情况下会存在线程安全问题&#xff0c;需要加互斥锁进…

寒冬已过,2023抓住IT复苏新机会

随着疫情防控进入新的阶段&#xff0c;2023年经济将逐渐回暖&#xff0c;许多行业也将迎来IT需求复苏的新机会。本期&#xff0c;我们就以互联网&#xff0c;金融和房地产这3个支柱行业近期的实际案例&#xff0c;来说明在在线文档领域的新机会。案例1:某互联网集团A公司&#…

数据结构---二叉树路径问题

二叉树路径问题二叉树所有路径分析JAVA实现力扣提交找到一个和为sum的到达叶子节点的路径分析JAVA实现力扣提交求路径&#xff08;中间一段&#xff09;C实现打印根节点到任意节点的路径JAVA实现二叉树所有路径 257二叉树所有路径 分析 前序遍历二叉树递归实现回溯 深度优先搜…

容器化——Centos下部署最后一版支持Docker的k8s集群

部署版本 首先要确定部署的版本 查询Kubernetes对Docker支持的情况 kubernetes/dependencies.yaml at master kubernetes/kubernetes (github.com) 查询Kubernetes Dashboard对Kubernetes支持的情况 Releases kubernetes/dashboard (github.com) 名称版本kubernetes1.23Doc…

如何对CentOS7配置静态IP

CentOS配置静态IP一、检测配置成功的方法1.虚拟机能访问互联网2.虚拟机和物理机可以相互ping通二、配置步骤1.查看物理机IP2.配置虚拟机网络模式3.设置NAT模式网段4.编辑修改配置文件5.测试三、报错解决方案1.网络重启失败2.ping不通一、检测配置成功的方法 1.虚拟机能访问互联…

MyBatis的五种批量查询

一.直接循环插入 RestController RequestMapping("/mybatis3/user") RequiredArgsConstructor public class UserController {private final IUserService iUserService;GetMapping("/one")public Long one(){return iUserService.add();} }Long add();Se…

intel更新13代桌面处理器产品线,更多核心更贵价格

intel 13代酷睿产品线更新带来了更多低于125w TDP的处理器。intel确认了10个65wTDP的SKU和6个35wTDP的SKU。13代酷睿包含新的Raptor Lake和旧的Alder Lake(Refresh)处理器。因为桌面处理器型号序列比较乱&#xff0c;这是SKU命名方式的列表&#xff1a;1XX00KS – 特别(灰烬)版…

【回答问题】ChatGPT上线了!给我推荐比较流行的音频处理算法模型

给我推荐比较流行的音频处理算法模型 音频处理算法模型有很多种&#xff0c;我给你列举一些比较流行的&#xff1a; 声音分类&#xff1a;用于将声音信号分成不同的类别&#xff0c;比如人声、自然声、机器声等。 声音分离&#xff1a;用于从混合的声音信号中分离出单独的声…

PDF可以转Word吗?3种方法建议收藏

PDF文件是很常见的文件传输格式&#xff0c;大部分的时候我们会将常见的办公文件格式转换成PDF。PDF文件占存较小&#xff0c;传输的速度比较快&#xff0c;而且文件的固定性强&#xff0c;不会轻易发生改动让排版和文本错乱&#xff0c;是很好用的文件格式。但常常对于我们所需…

乐维监控keycloak单点登录实操(上篇)

Keycloak为Web应用和Restful服务提供了一站式的单点登录解决方案&#xff0c;为登录、注册、用户管理提供了可视化管理界面&#xff0c;用户可以借助于该界面来配置符合自身需要的安全策略和进行用户管理。下面让我们来看看乐维监控如何实现keycloak单点登录&#xff0c;乐维ke…

反编译Method(反编译类中的方法)

package com.javase.reflect;import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.ResourceBundle;/*** 反编译Method 这里我们暂时还不能获取方法体中的内容* 通过读取属性配置文件来对不同的类进行反编译*/ public class ReflectMethodTe…

【机器学习】李宏毅-预测PM2.5

李宏毅-预测PM2.51 实验目的 巩固课堂所学知识&#xff0c;学习使用Linear Regression中梯度下降预测模型&#xff0c;并将所学运用至实践&#xff0c;根据从空气质量监测网下载的观测数据&#xff0c;使用Linear Regression 预测出空气污染指数(即PM2.5) 的数值。 2 实验要求…

【算法】超详细哈夫曼编码JAVA解释

综合实验报告格式 综合实验题目 一、人员和分工 LenckCuak 二、问题描述和基本要求 1、 用哈夫曼编码设计一个压缩软件&#xff1b; 2、 能对输入的任何类型的文件进行哈夫曼编码&#xff0c;产生编码后的文件——压缩文件&#xff1b; 3、 能对输入的压缩文件进行译码&…

【机器学习】李宏毅-食物图像分类器

李宏毅-食物图像分类器1 实验目的 掌握使用Pytorch的使用方法&#xff1a; Pytorch的安装以及环境搭建Pytorch处理数据Pytorch计算梯度以及搭建神经网络Pytorch训练模型 并使用Pytorch来训练CNN模型&#xff0c;实作一个食物的图像分类器。 2 实验要求 可以使用tensorflow或…

print()函数的使用

一、print()函数共三种类型的使用方法二、代码展示