逻辑斯蒂回归

逻辑斯蒂回归简介

  逻辑斯蒂回归(Logistic Regression)是一个非常经典的算法,虽然被称为回归,但其实际上是分类模型,并常用于二分类。因为通过逻辑回归模型,我们得到的计算结果是0-1之间的连续数字,可以把它称为“可能性”(概率),然后,给这个可能性加一个阈值,就成了分类。逻辑回归因其简单、可并行化、可解释强深受工业界喜爱。
  Logistic 回归的本质是:假设数据服从这个分布,然后使用极大似然估计做参数的估计。

逻辑回归拟合函数

  逻辑回归算法的拟合函数,叫做Sigmoid函数,是一个单调可导的函数,通过设置阈值0.5,就可以分为两类
y ^ = { 1 , σ ( x ) > 0.5 0 , σ ( x ) ≤ 0.5 \hat{y} = \begin{cases} 1, & \sigma(x) > 0.5 \\ 0, & \sigma(x) \leq 0.5 \\ \end{cases} y^={1,0,σ(x)>0.5σ(x)0.5
请添加图片描述

从图形上看,sigmoid曲线就像是被掰弯捋平后的线性回归直线,将取值范围(−∞,+∞)映射到(0,1) 之间,更适宜表示预测的概率,即事件发生的“可能性” 。

Sigmoid函数的输入记为 z z z,多元场景下的公式为: z = w 0 x 0 + w 1 x 1 + w 2 x 2 + . . . + w n x n z = w_0x_0 + w_1x_1 + w_2x_2 + ... + w_nx_n z=w0x0+w1x1+w2x2+...+wnxn,采用向量的写法 z = x w z = xw z=xw,其中 w 0 w_0 w0是多元函数常数项,而 x 0 x_0 x0的值置为1,便于与 w w w矩阵相乘。
f ( x ) = 1 1 + e − x w f(x)=\frac{1}{1+e^{-xw}} f(x)=1+exw1

最大似然函数估计

在二分类问题中,y只取0或1,可以组合起来表示y的概率:
P ( y ) = P ( y = 1 ) y P ( y = 0 ) 1 − y P(y) = P(y=1)^yP(y=0)^{1-y} P(y)=P(y=1)yP(y=0)1y

加上特征 x x x和参数 w w w后,表示为:
P ( y ∣ x , w ) = P ( y = 1 ∣ x , w ) y [ 1 − P ( y = 1 ∣ x , w ) ] 1 − y P(y|x,w) = P(y=1|x,w)^y[1 - P(y=1|x,w)]^{1-y} P(yx,w)=P(y=1∣x,w)y[1P(y=1∣x,w)]1y

P ( y = 1 ∣ x , w ) = 1 1 + e − x w P(y=1|x,w)=\frac{1}{1+e^{-xw}} P(y=1∣x,w)=1+exw1代入上式得:
P ( y ∣ x , w ) = ( 1 1 + e − x w ) y ( 1 − 1 1 + e − x w ) 1 − y P(y|x,w) = (\frac{1}{1+e^{-xw}})^y(1 - \frac{1}{1+e^{-xw}})^{1-y} P(yx,w)=(1+exw1)y(11+exw1)1y

( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . , ( x n , y n ) (x_1,y_1),(x_2,y_2),...,(x_n,y_n) (x1,y1),(x2,y2),...,(xn,yn)是实际观测的数据,而不同事件是相互独立的,那么它们同时发生的概率为 ∏ i = 1 n P ( y i ∣ x i , w ) \prod_{i=1}^nP(y_i|x_i,w) i=1nP(yixi,w)。即似然函数为:
L ( w ) = ∏ i = 1 n P ( y i ∣ x i , w ) = ∏ i = 1 n ( 1 1 + e − x i w ) y i ( 1 − 1 1 + e − x i w ) 1 − y i L(w) = \prod_{i=1}^nP(y_i|x_i,w)=\prod_{i=1}^n(\frac{1}{1+e^{-x_iw}})^{y_i}(1 - \frac{1}{1+e^{-x_iw}})^{1-y_i} L(w)=i=1nP(yixi,w)=i=1n(1+exiw1)yi(11+exiw1)1yi
如此,问题变为了参数 w w w在取什么值时, L ( w ) L(w) L(w)取得极大值。
w ^ = a r g   m a x w   L ( w ) \hat{w}=arg\ \underset{w}{max} \ L(w) w^=arg wmax L(w)

交叉熵损失函数

  损失函数是用于衡量预测值与实际值的偏离程度,即模型预测的错误程度。也就是说,这个值越小,认为模型效果越好,举个极端例子,如果预测完全精确,则损失函数值为0。
  我们要做的是 L ( w ) L(w) L(w)取得极大值,反过来 − L ( w ) -L(w) L(w)取得极小值,与损失函数的要求相同。因连乘不易取极值,需对 L ( w ) L(w) L(w)取对数后,在取相反数,这样就成为了交叉熵损失函数:
J ( w ) = − log ⁡ L ( w ) = − ∑ i = 1 n [ y i log ⁡ P ( y i ) + ( 1 − y i ) log ⁡ ( 1 − P ( y i ) ) ] J(w)=-\log L(w)=-\sum_{i=1}^n[y_i\log{P(y_i)}+(1-y_i)\log (1-P(y_i))] J(w)=logL(w)=i=1n[yilogP(yi)+(1yi)log(1P(yi))]
其中:
y i y_i yi : 表示样本 i i i的标记(label),正类为1,负类为0
P ( y i ) P(y_i) P(yi):表示样本 i i i预测为正类的概率

梯度下降法求解

对于Sigmoid函数 f ( z ) = 1 1 + e − z f(z)=\frac{1}{1+e^{-z}} f(z)=1+ez1,求导得:
f ′ ( z ) = ( 1 1 + e − z ) ′ = − ( e − z ) ′ ( 1 + e − z ) 2 = e − z ( 1 + e − z ) 2 f^\prime(z) = (\frac{1}{1+e^{-z}})^\prime=-\frac{(e^{-z})^\prime}{(1+e^{-z})^2}=\frac{e^{-z}}{(1+e^{-z})^2} f(z)=(1+ez1)=(1+ez)2(ez)=(1+ez)2ez

这还不算完,我们发现 1 − f ( z ) = e − z 1 + e − z 1-f(z)=\frac{e^{-z}}{1+e^{-z}} 1f(z)=1+ezez,而 f ′ ( z ) f^\prime(z) f(z)正好可以拆分为 e − z 1 + e − z ⋅ 1 1 + e − z \frac{e^{-z}}{1+e^{-z}} \cdot \frac{1}{1+e^{-z}} 1+ezez1+ez1,也就是说:
f ′ ( z ) = f ( z ) ⋅ ( 1 − f ( z ) ) f^\prime(z)=f(z)\cdot(1-f(z)) f(z)=f(z)(1f(z))

已知 z = x w z=xw z=xw,而 x x x是实际观测数据,未知的是 w w w,所以后面是对 w w w求导,记:
∂ J ( w ) ∂ w = ∂ J ( w ) ∂ f ( z ) ∗ ∂ f ( z ) ∂ z ∗ ∂ z ∂ w \frac{\partial J(w)}{\partial w}=\frac{\partial J(w)}{\partial f(z)} * \frac{\partial f(z)}{\partial z} * \frac{\partial z}{\partial w} wJ(w)=f(z)J(w)zf(z)wz

其中:
∂ J ( w ) ∂ f ( z ) = − [ y log ⁡ f ( z ) + ( 1 − y ) log ⁡ ( 1 − f ( z ) ) ] ′ = − ( y f ( z ) + ( 1 − y ) − 1 1 − f ( z ) ) = − ( y f ( z ) + y − 1 1 − f ( z ) ) \begin{aligned}\frac{\partial J(w)}{\partial f(z)} &= -[y \log f(z) + (1-y)\log (1-f(z))]^\prime \\ &= -( \frac{y} {f(z)} + (1-y) \frac{-1} {1-f(z)}) \\ &= -( \frac{y} {f(z)} + \frac{y-1} {1-f(z)}) \\ \end{aligned} f(z)J(w)=[ylogf(z)+(1y)log(1f(z))]=(f(z)y+(1y)1f(z)1)=(f(z)y+1f(z)y1)

∂ f ( z ) ∂ z = f ( z ) ( 1 − f ( z ) ) \begin{aligned}\frac{\partial f(z)}{\partial z}&=f(z)(1-f(z)) \end{aligned} zf(z)=f(z)(1f(z))

∂ z ∂ w = x \begin{aligned} \frac{\partial z}{\partial w} &= x\end{aligned} wz=x

综上所得:
∂ J ( w ) ∂ w = − ( y f ( z ) + y − 1 1 − f ( z ) ) ∗ f ( z ) ( 1 − f ( z ) ) ∗ x = − ( y − f ( z ) ) ∗ x = − ( y − 1 1 + e − x w ) ∗ x \begin{aligned}\frac{\partial J(w)}{\partial w} &=-( \frac{y} {f(z)} + \frac{y-1} {1-f(z)}) *f(z)(1-f(z)) * x \\ &=-(y-f(z))*x \\ &= - (y-\frac{1}{1+e^{-xw}}) * x \end{aligned} wJ(w)=(f(z)y+1f(z)y1)f(z)(1f(z))x=(yf(z))x=(y1+exw1)x

因此,梯度上升迭代公式为:
w : = w + α ( y − 1 1 + e − x w ) ∗ x w:= w +\alpha(y-\frac{1}{1+e^{-xw}})*x w:=w+α(y1+exw1)x

梯度下降算法过程:

  1. 初始化 w w w向量的值,即 Θ 0 \Theta_{0} Θ0,将其代入G得到当前位置的梯度;
  2. 用步长α乘以当前梯度,得到从当前位置下降的距离;
  3. 更新 Θ 1 \Theta_1 Θ1,其更新表达式为 Θ 1 = Θ 0 − α G \Theta_1=\Theta_0-\alpha G Θ1=Θ0αG
  4. 重复以上步骤,直到更新到某个 Θ k \Theta_k Θk,达到停止条件,这个 Θ k \Theta_k Θk就是我们求解的参数向量。

逻辑斯蒂回归分布

定义:设X是连续随机变量,X服从逻辑斯蒂分布是指X具有下列分布函数和密度函数:
F ( x ) = P ( X ≤ x ) = 1 1 + e − ( x − μ ) / γ F(x)=P(X \leq x)=\frac{1}{1+e^{-(x-\mu)/\gamma}} F(x)=P(Xx)=1+e(xμ)/γ1

f ( x ) = F ′ ( x ) = e − ( x − μ ) / γ γ ( 1 + e − ( x − μ ) / γ ) 2 f(x)=F'(x)=\frac{e^{-(x-\mu)/\gamma}}{\gamma(1+e^{-(x-\mu)/\gamma})^2} f(x)=F(x)=γ(1+e(xμ)/γ)2e(xμ)/γ

式中, μ \mu μ为位置参数, γ > 0 \gamma>0 γ>0为形状参数。

Logistic 分布是由其位置和尺度参数定义的连续分布。Logistic 分布的形状与正态分布的形状相似,但是 Logistic 分布的尾部更长,所以我们可以使用 Logistic 分布来建模比正态分布具有更长尾部和更高波峰的数据分布。在深度学习中常用到的 S i g m o i d Sigmoid Sigmoid函数就是 Logistic 的分布函数在 μ = 0 , γ = 1 \mu=0,\gamma=1 μ=0,γ=1的特殊形式。

逻辑斯蒂回归实战

首先,下载数据集 testSet.txt,数据集链接:https://pan.baidu.com/s/1rJm0Ok_9OfrsEktVqhGoCQ?pwd=47db ,提取码:47db

from numpy import *

# 加载数据集
def loadDataSet():
    datas = []; classLabels = []
    fr = open('testSet.txt')
    for line in fr.readlines():
        lineArr = line.strip().split()
        datas.append([1.0, float(lineArr[0]), float(lineArr[1])])
        classLabels.append(int(lineArr[2]))
    return datas,classLabels

def sigmoid(inX):
    return 1.0/(1+exp(-inX))
    # return 0.5 * (1 + tanh(0.5 * inX))


# 梯度上升算法
def gradAscent(datas, classLabels):
    dataMat = mat(datas)             #convert to NumPy matrix
    labelMat = mat(classLabels).transpose() #convert to NumPy matrix
    m,n = shape(dataMat)
    alpha = 0.001  # 步长
    maxCycles = 500  # 迭代次数
    weights = ones((n,1))
    for k in range(maxCycles):       #heavy on matrix operations
        h = sigmoid(dataMat*weights) #matrix mult,h为列向量,元素数为n
        error = (labelMat - h)       #vector subtraction
        weights = weights + alpha * dataMat.transpose()* error #matrix mult
    return weights

# 画出数据集和逻辑回归最佳拟合直线
def plotBestFit(weights):
    import matplotlib.pyplot as plt
    dataMat,labelMat=loadDataSet()
    dataArr = array(dataMat)
    n = shape(dataArr)[0] 
    xcord1 = []; ycord1 = []
    xcord2 = []; ycord2 = []
    for i in range(n):
        if int(labelMat[i])== 1:
            xcord1.append(dataArr[i,1]); ycord1.append(dataArr[i,2])
        else:
            xcord2.append(dataArr[i,1]); ycord2.append(dataArr[i,2])
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.scatter(xcord1, ycord1, s=30, c='red', marker='s')
    ax.scatter(xcord2, ycord2, s=30, c='green')
    x = arange(-3.0, 3.0, 0.1)
    y = (-weights[0]-weights[1]*x)/weights[2]
    ax.plot(x, y.T)
    plt.xlabel('X1'); plt.ylabel('X2')
    plt.show()

# 训练梯度下降算法并画出最佳拟合直线
datas,classLabels = loadDataSet()
weights = gradAscent(datas, classLabels)
plotBestFit(weights)

请添加图片描述

从疝气病症预测病马的死亡率

疝病是描述马胃肠痛的术语,数据集中包含368个样本和28个特征。使用Logistic回归估计马疝病的死亡率步骤如下:

  1. 收集数据:给定数据文件。
  2. 准备数据:用Python解析文本文件并填充缺失值。
  3. 分析数据:可视化并观察数据。
  4. 训练算法:使用优化算法,找到最佳的系数。
  5. 测试算法:为了量化回归的效果,需要观察错误率。根据错误率决定是否回退到训练阶段,通过改变迭代的次数和步长等参数来得到更好的回归系数。
  6. 使用算法:实现一个简单的命令行程序来收集马的症状并输出预测结果。

需要说明的是,除了部分指标主观和难以测量外,该数据存在的另一个问题是大约30%的值是缺失的。一些可选的处理缺失值的做法有:

  • 使用可用特征的均值来填补缺失值
  • 使用特殊值来填补缺失值,如-1
  • 忽略有缺失值的样本
  • 使用相似样本的均值填补缺失值
  • 使用另外的机器学习算法预测缺失值

这里,选择实数0来替换所有缺失值,这样在更新系数时,0值不会有影响,而且对结果的预测不具有任何倾向性。若类别标签缺失则直接丢弃。原始数据集经过预处理后保存成两个文件:horseColicTest.txt 和 horseColicTraining.txt。

from numpy import *

def sigmoid(inX):
    return 0.5 * (1 + tanh(0.5 * inX))

# 随机梯度上升算法
def stocGradAscent0(datas, classLabels):
    m,n = shape(datas)
    alpha = 0.01
    weights = ones(n)   #initialize to all ones
    for i in range(m):
        h = sigmoid(sum(datas[i]*weights))
        error = classLabels[i] - h
        weights = weights + alpha * error * datas[i]
    return weights

# 改进的随机梯度上升算法
def stocGradAscent1(datas, classLabels, numIter=150):
    m,n = shape(datas)
    weights = ones(n)   #initialize to all ones
    for j in range(numIter):
        dataIndex = list(range(m))
        for i in range(m):
            alpha = 4/(1.0+j+i)+0.0001    #apha decreases with iteration, does not 
            randIndex = int(random.uniform(0,len(dataIndex)))#go to 0 because of the constant
            h = sigmoid(sum(datas[randIndex]*weights))
            error = classLabels[randIndex] - h
            weights = weights + alpha * error * datas[randIndex]
            del(dataIndex[randIndex])
    return weights

# 逻辑回归分类函数
def classifyVector(inX, weights):
    prob = sigmoid(sum(inX*weights))
    if prob > 0.5: return 1.0
    else: return 0.0

def colicTest():
    frTrain = open('horseColicTraining.txt'); frTest = open('horseColicTest.txt')
    trainingSet = []; trainingLabels = []
    for line in frTrain.readlines():
        currLine = line.strip().split('\t')
        lineArr =[]
        for i in range(21):
            lineArr.append(float(currLine[i]))
        trainingSet.append(lineArr)
        trainingLabels.append(float(currLine[21]))
    trainWeights = stocGradAscent1(array(trainingSet), trainingLabels, 1000)
    errorCount = 0; numTestVec = 0.0
    for line in frTest.readlines():
        numTestVec += 1.0
        currLine = line.strip().split('\t')
        lineArr =[]
        for i in range(21):
            lineArr.append(float(currLine[i]))
        if int(classifyVector(array(lineArr), trainWeights))!= int(currLine[21]):
            errorCount += 1
    errorRate = (float(errorCount)/numTestVec)
    print ("the error rate of this test is: %f" % errorRate)
    return errorRate


def multiTest():
    numTests = 10; errorSum=0.0
    for k in range(numTests):
        errorSum += colicTest()
    print ("after %d iterations the average error rate is: %f" % (numTests, errorSum/float(numTests)))

# 训练并检验
multiTest()

the error rate of this test is: 0.358209
the error rate of this test is: 0.328358
the error rate of this test is: 0.283582
the error rate of this test is: 0.388060
the error rate of this test is: 0.313433
the error rate of this test is: 0.268657
the error rate of this test is: 0.283582
the error rate of this test is: 0.358209
the error rate of this test is: 0.388060
the error rate of this test is: 0.283582
after 10 iterations the average error rate is: 0.325373

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

FreeRTOS 实时操作系统第九讲 - 链表 (数据结构)

一、链表简述 链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列节点(链表中每一个元素称为节点)组成,节点可以在运行时动态生成。每个节点包括两个部分&…

虾皮、Lazada店铺流量怎么提升?自养号优势及测评系统如何搭建?

虾皮、Lazada是东南亚地区最大的购物平台之一,吸引了大量的买家和卖家。在竞争激烈的虾皮市场上,如何提升店铺的流量成为许多卖家关注的问题。以下是关于如何提升虾皮、Lazada店铺流量的一些建议。 一、店铺流量怎么提升? 首先,进行优质的…

C#编程-使用集合

使用集合 您学习了如何使用数组来有效地存储和操作相似类型额数据。但是,以下限制于数组的使用相关联: 您必须在声明时定义数组的大小。您必须编写代码以对数组执行标准操作,如排序。让我们思考一个示例。假设您想要存储在组织工作的五个雇员的姓名。您可以使用以下语句来声…

java基于ssm的线上选课系统的设计与实现论文

摘 要 在如今社会上,关于信息上面的处理,没有任何一个企业或者个人会忽视,如何让信息急速传递,并且归档储存查询,采用之前的纸张记录模式已经不符合当前使用要求了。所以,对学生选课信息管理的提升&#x…

无人直播源码/技术源头开发/直播贴片技术源头

无人直播源码/技术源头开发/直播贴片,无人直播,无人实景直播。动态切片功能,自动回复功能,压低打断主播音,支持短视频各大主流平台开播。 搭建无人直播源码需要以下步骤: 1. 确定直播平台和工具&#xff1…

基于孔雀优化算法的航线规划

MATLAB2020a下正常运行 上传明细-CSDN创作中心

XSKY SDS 产品率先获得 OceanBase V4 新版本认证

近日,北京奥星贝斯科技有限公司(简称:OceanBase)与北京星辰天合科技股份有限公司(简称:XSKY 星辰天合)顺利完成产品兼容性认证。 XSKY 的高性能全闪存储以及混闪存储,与 OceanBase V…

大数据平台Bug Bash大扫除最佳实践

一、背景 随着越来越多的"新人"在日常工作以及大促备战中担当大任,我们发现仅了解自身系统业务已不能满足日常系统开发运维需求。为此,大数据平台部门组织了一次Bug Bash活动,既能提升自己对兄弟产品的理解和使用,又能…

【IPC通信--信号】

信号处理函数 • 信号发送函数 – kill(), sigqueue(), raise(), alarm(), setitimer(), pause() , abort() • 信号安装函数 – signal(), sigaction() • 信号集操作函数 – sigemptyset(), sigfillset(), sigaddset(), sigdelset(), sigismember() 信号发送函数—…

xgboost对密西西比数据集csv文件进行预测

代码: # 导入需要的库 from sklearn.preprocessing import LabelEncoder import matplotlib.pyplot as plt import pandas as pd import xgboost as xgb from sklearn.model_selection import train_test_split from sklearn.metrics import confusion_matrix, cla…

自定义事件总线

文章目录 什么是自定义事件总线具体实现思路分析定义结构实现 on实现 emit实现 off 源码 什么是自定义事件总线 自定义事件总线属于一种观察着模式,其中包括三个角色发布者(Publisher):发出事件(Event)订阅…

[SwiftUI]工程最低适配iOS13

问题: 新建工程,选择最低支持iOS13报错: main() is only available in iOS 14.0 or newer Scene is only available in iOS 14.0 or newer WindowGroup is only available in iOS 14.0 or newer 解决: 注释掉上面代码&#x…

短剧分销系统搭建:其成为普通人创业的新选择?短剧的红利有多高?

去年,短剧进入到了爆发期,成为了年轻人闲暇时间的娱乐方式。短剧每集只有几分钟时间,非常适合当下大众的碎片化时间。根据当下短剧的发展趋势,短剧的市场规模将逐渐赶超电影票房。 目前短剧还进行了多元化发展,逐渐走…

两数之和 ? 三数之和? 四数之和? 统统搞定

🎈个人主页:🎈 :✨✨✨初阶牛✨✨✨ 🐻推荐专栏1: 🍔🍟🌯C语言初阶 🐻推荐专栏2: 🍔🍟🌯C语言进阶 🔑个人信条: 🌵知行合一 前言 声明…

高性价比LDR6028Type-C转3.5mm音频和PD快充转接器

随着市面上的大部分手机逐渐取消了3.5mm音频耳机接口,仅保留一个Type-C接口,追求音质和零延迟的用户面临着一大痛点。对于这些用户,Type-C转3.5mm接口线的出现无疑是一大福音。这款线材在刚推出时就受到了手机配件市场的热烈欢迎,…

Python武器库开发-武器库篇之子域名扫描器开发(四十一)

Python武器库开发-武器库篇之子域名扫描器开发(四十一) 在我们做红队攻防或者渗透测试的过程中,信息收集往往都是第一步的,有人说:渗透的本质就是信息收集,前期好的信息收集很大程度上决定了渗透的质量和攻击面,本文将…

AI数字人国内人工智能产业发展趋势

随着科技的不断进步,人工智能(Artificial Intelligence,简称AI)已成为当今社会的热门话题。作为一种复杂而高级的技术,人工智能在国内发展势头迅猛。本文将探讨AI数字人国内人工智能产业的发展趋势。 首先&#xff0c…

科锐16位汇编学习笔记01汇编基础和debug使用

为什么学习16位汇编? 16位操作指令最多能够操作两个字节,且更能够体现出与硬件的交互。16位下的指令和32位汇编的指令差不多。16位汇编的指令在32位一样使用.要学好汇编必须要了解一点点硬件知识,16汇编是直接操作硬件,32位汇编指令跟硬件隔离了 硬件运…

simulink代码生成(六)——中断向量模块的配置

假如系统中存在多个中断,需要合理的配置中断的优先级与中断向量表;在代码生成中,要与中断向量表对应;中断相关的知识参照博客: DSP28335学习——中断向量表的初始化_中断向量表什么时候初始化-CSDN博客 F28335中断系…

目标检测-One Stage-YOLOv2

文章目录 前言一、YOLOv2的网络结构和流程二、YOLOv2的创新点预处理网络结构训练 总结 前言 根据前文目标检测-One Stage-YOLOv1可以看出YOLOv1的主要缺点是: 和Fast-CNN相比,速度快,但精度下降。(边框回归不加限制)…