SVM 支持向量机

news2024/11/19 5:31:57

SVM 支持向量机

    • SVM 原理
    • 最优化问题
    • 线性不可分
    • sklearn 调用 SVM
    • 核函数

 


SVM 原理

前置知识:用迭代策略来划分样本,请猛击《神经元的计算》。

SVM 也是用一条迭代的直线来划分不同数据之间的边界:

.- 是一条直线(线性函数)

  • 能将苹果和橘子分为两个部分(具有分类功能,是一种二值分类)


这样的线性函数,极端情况(直线逼近某一样本时),会把添加在附近的新样本误分在另外一侧,比如下图所示:

新添加的元素,按照距离来看,本应是属于红色样本。

结果因为直线过于逼近红色区域,导致被划分成蓝色样本了。

这个直线泛化能力不够好的问题,要么是在数据预处理部分做处理,要么是做正则化。

  • 正则化的本质是一个概念,不同算法中的使用方式可能不同,但它们的目的都是一样的,都是在机器学习算法层面增加模型的泛化能力。

SVM 是在算法里面解决泛化问题,不同于线性函数的地方在于:

  • 这条直线,一定位于苹果和橘子的正中间,尽可能的离俩个样本最远,如同男女课桌的军事分解线,处于正中间,不偏向任何一方(注重公平原则,才能保证双方利益最大化)。

SVM 尝试寻找一条最优的决策边界,距离俩个类别最近的样本最远。

  • 俩个类别最近的样本(被直线划中的蓝点、红点),叫支持向量,就是支持向量机 SVM 取名的由来

我们会用一个 margin 来描述这个距离:


公平,就是要让 margin 最大化。

  • 这种思维,也被称为 Hard Margin SVM,解决线性可分问题,找到一个决策边界,没有错误的将所有决策点进行划分。

  • 但真实情况下,很多数据是线性不可分的,我们需要改进了 Hard Margin SVM,实现 Soft Margin SVM 解决线性不可分。

  • 参数学习算法的固定套路:我们把算法思想(支持向量机的思想)转化为最优化问题、最优化目标函数。

 


最优化问题

因为 margin = 2dmargin 最大化也就是最大化 d

还记得高中数学吗,点 (x, y) 到直线的距离公式:

  • 点: ( x , y ) (x, y) (x,y)
  • 直线方程: A x + B y + C = 0 Ax+By+C=0 Ax+By+C=0
  • 点 (x, y) 到直线 A x + B y + C = 0 Ax+By+C=0 Ax+By+C=0 的距离公式: ∣ A x + B y + C ∣ A 2 + B 2 \frac{|Ax+By+C|}{\sqrt{A^{2}+B^{2}}} A2+B2 Ax+By+C

这只是基于二维平面情况,我们再把这个公式,拓展到 N 维。

N 维点到直线的距离(推导过程不清楚可搜索一下):

  • 点: [ x 1 , x 2 , x 3 , ⋅ ⋅ ⋅ , x n ] T = X [x_{1},x_{2},x_{3},···,x^{n}]^{T}=X [x1,x2,x3,⋅⋅⋅,xn]T=X,这里的点就是支持向量
  • 直线方程: W T X + b = 0 , W T = [ w 1 , w 2 , w 3 , ⋅ ⋅ ⋅ , w n ] W^{T}X+b=0,W^{T}=[w_{1},w_{2},w_{3},···,w_{n}] WTX+b=0WT=[w1,w2,w3,⋅⋅⋅,wn]
  • 点到直线的距离公式: ∣ W T x + b ∣ ∣ ∣ w ∣ ∣ , ∣ ∣ w ∣ ∣ = w 1 2 + w 2 2 + w 3 2 + ⋅ ⋅ ⋅ + w n 2 \frac{|W^{T}x+b|}{||w||},||w||=\sqrt{w_{1}^{2}+w_{2}^{2}+w_{3}^{2}+···+w_{n}^{2}} ∣∣w∣∣WTx+b∣∣w∣∣=w12+w22+w32+⋅⋅⋅+wn2

分子 ∣ A x + B y + C ∣ |Ax + By + C| Ax+By+C 就是 ∣ W T x + b ∣ |W^{T}x + b| WTx+b,分母 ( A 2 + B 2 ) \sqrt(A^2 + B^2) ( A2+B2) 就是 ∣ ∣ w ∣ ∣ ||w|| ∣∣w∣∣

把这个公式代入 SVM 中:

假设中间的直线方程是: W T x + b = 0 W^{T}x+b=0 WTx+b=0

那上下俩条直线就可以这样表示了:

  • 上: W T x i + b ∣ ∣ w ∣ ∣ > = d , y i = 1 \frac{W^{T}x^{i}+b}{||w||}>=d,y^{i}=1 ∣∣w∣∣WTxi+b>=dyi=1
  • 下: W T x i + b ∣ ∣ w ∣ ∣ < = − d , y i = − 1 \frac{W^{T}x^{i}+b}{||w||}<=-d,y^{i}=-1 ∣∣w∣∣WTxi+b<=dyi=1

格式俩边都除以 d:

  • 上: W T x i + b ∣ ∣ w ∣ ∣ d > = 1 , y i = 1 \frac{W^{T}x^{i}+b}{||w||d}>=1,y^{i}=1 ∣∣w∣∣dWTxi+b>=1yi=1
  • 下: W T x i + b ∣ ∣ w ∣ ∣ d < = − 1 , y i = − 1 \frac{W^{T}x^{i}+b}{||w||d}<=-1,y^{i}=-1 ∣∣w∣∣dWTxi+b<=1yi=1

因为 w 、 d w、d wd 都是一个具体的数,我们可以约分。

分子、分母都除以 ∣ ∣ w ∣ ∣ d ||w||d ∣∣w∣∣d

  • 上: W d T x i + b d > = 1 , y i = 1 W^{T}_{d}x^{i}+b_{d}>=1,y^{i}=1 WdTxi+bd>=1yi=1
  • 下: W d T x i + b d < = − 1 , y i = − 1 W^{T}_{d}x^{i}+b_{d}<=-1,y^{i}=-1 WdTxi+bd<=1yi=1
  • 上: W d T x i + b d = 1 W^{T}_{d}x^{i}+b_{d}=1 WdTxi+bd=1
  • 下: W d T x i + b d = − 1 W^{T}_{d}x^{i}+b_{d}=-1 WdTxi+bd=1

我们把中间的直线,也除以 ∣ ∣ w ∣ ∣ d ||w||d ∣∣w∣∣d

  • 中: W d T x i + b d = 0 W^{T}_{d}x^{i}+b_{d}=0 WdTxi+bd=0

既然所有直线都是 W d T 、 b d W^{T}_{d}、b_{d} WdTbd,那我们用 W T 、 b W^{T}、b WTb 来简写。

将式子中的 W d 、 b d W_{d}、b_{d} Wdbd 重新命名成了 W 、 d W、d Wd,实际还是 W d 、 b d W_{d}、b_{d} Wdbd

  • 上: W T x i + b = 1 W^{T}x^{i}+b=1 WTxi+b=1
  • 中: W T x i + b = 0 W^{T}x^{i}+b=0 WTxi+b=0
  • 下: W T x i + b = − 1 W^{T}x^{i}+b=-1 WTxi+b=1

【细节扩展】(可跳过)
.
我们为什么能够把 w d w_{d} wd b d b_{d} bd 的那个 d d d 去掉,不是说去掉以后, w d = w w_{d}=w wd=w b d = b b_{d}=b bd=b,而是,由于 d d d 是一个常数,所以,如果 d d d 不等于 1 1 1 的话,我们总能找到另外一组 w w w b b b,和原假设是等价的,这组 w w w b b b 就是 w d w_{d} wd b d b_{d} bd
.
或者说,虽然我们最初假设两条线是 w x + b = d wx+b =d wx+b=d w x + b = − d wx+b=-d wx+b=d,但我们总能找到另外一组 w w w b b b,使得这两条同样的直线方程,改写成 w x + b = 1 wx+b=1 wx+b=1 w x + b = − 1 wx+b=-1 wx+b=1 的形式。
.
我们后续推导,用这组让等式右侧等于 1 1 1 − 1 -1 1 w w w b b b
.
用这组让等式右侧等于 1 1 1 − 1 -1 1 的,并不会改变我们之前推导的 SVM 的优化的内容。所以,在这里,可以带进去。

话分俩头,我们再把上、下直线变成一个:

  • 上: W T x i + b > = 1 , y i = 1 W^{T}x^{i}+b>=1,y^{i}=1 WTxi+b>=1yi=1
  • 下: W T x i + b < = − 1 , y i = − 1 W^{T}x^{i}+b<=-1,y^{i}=-1 WTxi+b<=1yi=1

组合式子:

  • 限定条件: y i ( W T x i + b ) > = 1 y^{i}(W^{T}x^{i}+b)>=1 yi(WTxi+b)>=1,所有数据点都必须在上、下直线之上或者之外

这个式子是限定条件,对于任意支持向量,都满足这个不等式关系。

我们现在就是在这个限定条件下,最优化这个问题。

回到开头提出的问题:

因为 margin = 2dmargin 最大化也就是最大化 d

那么,d 是什么?

d:支持向量到决策边界的距离。

  • SVM 不是求 d 的最大值,SVM 求的是:在 d 最大的情况下,w 是什么。
  • w 是我们关注的一切,因为 SVM 的解,就是一条直线,我们要求的是这个直线方程,即 w。
  • 让 d 最大是这条直线要满足的条件。

因为支持向量就是一个点,决策边界就是一条线,SVM 的公平划分思想,就变成了点到直线的距离。

  • 支持向量: ( x , y ) (x,y) (x,y)
  • 直线方程: w x + b = 0 wx+b = 0 wx+b=0
  • 对于任意一个点 ( x , y ) (x,y) (x,y),到直线 w x + b = 0 wx+b = 0 wx+b=0 的距离公式: d = ∣ W T ∗ x + b ∣ ∣ ∣ w ∣ ∣ d=\frac{|W^{T}*x+b|}{||w||} d=∣∣w∣∣WTx+b

最大化 d: m a x ∣ W T ∗ x + b ∣ ∣ ∣ w ∣ ∣ max\frac{|W^{T}*x+b|}{||w||} max∣∣w∣∣WTx+b

  • 代入这个式子中的支持向量的结果,要么等于 1(红色),要么等于 -1(蓝色)

所以,最大化 d: m a x 1 ∣ ∣ w ∣ ∣ max\frac{1}{||w||} max∣∣w∣∣1

也就是,最小化模: m i n ∣ ∣ w ∣ ∣ min||w|| min∣∣w∣∣

  • 为了方便求导,我们会改成: m i n 1 2 ∣ ∣ w ∣ ∣ 2 min\frac{1}{2}||w||^{2} min21∣∣w2

综上所述,SVM 就变成了一个最优化问题:

  • 限定条件: y i ( W T x i + b ) > = 1 y^{i}(W^{T}x^{i}+b)>=1 yi(WTxi+b)>=1,所有数据点都必须在上、下直线之上或者之外
  • 最优化: m i n 1 2 ∣ ∣ w ∣ ∣ 2 min\frac{1}{2}||w||^{2} min21∣∣w2

SVM:在满足限定条件下,最优化。

  • 和全局最优化问题不同,有条件的最优化问题计算难度很大,这个数学推导是最复杂了,超过本科数学范畴,我也不会······
     

线性不可分

可能会有极少个数据样本很偏,如下图:

有一个蓝色节点远离其他蓝色节点,更靠近红色节点。

线性分类器为了分类正确,虽然正确的把俩种数据分开了,但泛化能力有点差,为了一个预测点过拟合了。

  • 线性不可分:更极端的情况,这个蓝色节点出现在红色节点内部,那线性分类器会因为这样一个特殊点的存在,导致无法划分的情况。

在商业项目中,往往会有这种极端数据,如果不解决这种问题,就无法应用。

我们要追求泛化能力,我们希望有一定的容错能力,可以把一些点预测错误,提高泛化能力。

  • 这种可以解决线性不可分的 SVM,也叫 Soft Margin SVM

SVM 是一个限定条件下的最优化问题:

  • 限定条件: y i ( W T x i + b ) > = 1 y^{i}(W^{T}x^{i}+b)>=1 yi(WTxi+b)>=1
  • 最优化: m i n 1 2 ∣ ∣ w ∣ ∣ 2 min\frac{1}{2}||w||^{2} min21∣∣w2

限定的条件是,所有数据点都必须在上、下直线之上或者之外。

我们宽松这个限定条件:让所有数据点不止在直线之上或者之外。

  • 引入宽松 ζ > = 0 \zeta>=0 ζ>=0 后的限定条件: y i ( W T x i + b ) > = 1 − ζ i y^{i}(W^{T}x^{i}+b)>=1-\zeta_{i} yi(WTxi+b)>=1ζi
     
  • ζ i \zeta_{i} ζi 不是一个固定值,每个数据点都有一个 ζ i \zeta_{i} ζi
  • 为什么对于每一个样本来说,都有一个不同的 ζ i \zeta_{i} ζi,简单来说,是因为不是所有的错误都是相等的。
  • 这个 ζ i \zeta_{i} ζi 不是超参数,而是模型参数,所以不需要我们设置。他就像线性回归中的 theta 一样,是在 fit 的过程中根据数据求出来的。
  • ζ > = 0 \zeta>=0 ζ>=0 才会宽松,反之更严格。

宽松后的限定条件,在图上是一条虚线:

宽松后,允许数据点:

  • 在上直线和上虚线之间
  • 在下直线和下虚线之间

当然,仅仅设置 ζ > = 0 \zeta>=0 ζ>=0 是不够的。

  • ζ = + ∞ \zeta=+∞ ζ=+ 时,上虚线会在上直线,下面无限远的地方,那红色方所有数据都可以满足了,太松

那怎么设置限定容错空间呢?加上 ∑ i = 1 m ζ i \sum^{m}_{i=1}\zeta_{i} i=1mζi

  • 最优化: m i n 1 2 ∣ ∣ w ∣ ∣ 2 + ∑ i = 1 m ζ i min\frac{1}{2}||w||^{2}+\sum^{m}_{i=1}\zeta_{i} min21∣∣w2+i=1mζi

这俩者之间也需要设置比例关系,添加一个变量 C:

  • 最优化: m i n 1 2 ∣ ∣ w ∣ ∣ 2 + C ∑ i = 1 m ζ i min\frac{1}{2}||w||^{2}+C\sum^{m}_{i=1}\zeta_{i} min21∣∣w2+Ci=1mζi

如果 C 数值小,最优化公式大部分都在前面部分。

如果 C 数值大,最优化公式大部分都在后面部分。

 
宽松后的 SVM:

  • 限定条件: y i ( W T x i + b ) > = 1 − ζ i y^{i}(W^{T}x^{i}+b)>=1-\zeta_{i} yi(WTxi+b)>=1ζi

  • 最优化: m i n 1 2 ∣ ∣ w ∣ ∣ 2 + C ∑ i = 1 m ζ i min\frac{1}{2}||w||^{2}+C\sum^{m}_{i=1}\zeta_{i} min21∣∣w2+Ci=1mζi

 
【拓展】
Hard SVM:每个数据点都在决策边界的一侧,且 margin 内没有数据点。

Soft SVM,数据点没有这个限制,但对于错误分类的数据点,或者 margin 内的数据点,很显然离正确的那个 margin 边界越近越好,也就是错误越小。

  • ζ i \zeta_{i} ζi 在衡量每个数据点的这个错误。
  • 我们的正则化项是看所有数据点的这个错误总和(或者平方和),來最小化ta。

 


sklearn 调用 SVM

from sklearn import datasets
from sklearn import model_selection
from sklearn import svm

# 加载数据集,sklearn提供的乳腺癌数据集load-barest-cancer(),这是一个简单经典的用于二分类任务的数据集。该数据集有539个样本,每个样本有30个特征。
cancer = datasets.load_breast_cancer()
X = cancer.data  # 样本
y = cancer.target  # 类别

# 将数据集进行划分,分成训练集和测试集
X_trainer, X_test, Y_trainer, Y_test = model_selection.train_test_split(X, y, test_size=0.2)

# 分类器
clf = svm.SVC(kernel="linear")               # 调用 SVM,参数kernel为线性核函数
clf.fit(X_trainer, Y_trainer)                # 训练分类器
print("Support Vector:\n", clf.n_support_)  # 每一类中属于支持向量的点数目
print("Predict:\n", clf.predict(X_test))    # 对测试集的预测结果
score = clf.score(X_test, Y_test)            # 模型得分
print("Score:", score)

输出:

Support Vector:
 [25 26]
Predict:
 [1 0 1 1 1 1 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 1 1 1 1 1 1 0 0 1 0 1
 0 0 0 1 1 1 0 1 1 0 1 1 1 1 1 0 0 1 1 0 1 0 1 1 1 1 1 1 1 0 1 0 1 1 0 1 0
 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 0 1 1 1 0 0 0 1 0 1 1 1 1 0 0 1 0 1 1 1 1
 0 1 1]
 
Score: 0.956140350877193(咋样,我是不是炒鸡棒(๑•̀ㅂ•́)و✧)

 


核函数

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

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

相关文章

数据结构c语言版第二版(严蔚敏)第五章笔记

目录 树和二叉树的定义 树的定义 树的基本术语 二叉树的定义 二叉树的性质和存储结构 二叉树的性质 二叉树的存储结构 顺序存储结构 链式存储结构 遍历二叉树和线索二叉树 遍历二叉树 先序遍历 中序遍历 后序遍历 前序遍历的递归算法 中序遍历的递归算法 后序…

SARScape中用sentinel-1数据做SBAS-InSAR完整流程(2/2)

书接上回&#xff1a;SARScape中用sentinel-1数据做SBAS-InSAR完整流程&#xff08;1/2&#xff09; SARScape中用sentinel-1数据做SBAS-InSAR完整流程&#xff08;2/2&#xff09;7 反演第一步Inversion&#xff1a;First Step7.1 导入设置7.2 optional file7.3 parameters参数…

齐博x1用户登录接口

用户的登录主要涉及到小程序登录、APP的帐号密码登录、APP的微信开发平台帐号登录。 相应的地址是&#xff1a;http://qb.net/index.php/index/wxapp.login/index.html 涉及到的方法如下 上面的地址&#xff0c;默认是小程序的登录与注册。 http://qb.net/index.php/index/wxa…

matlab/simulink电力电子仿真傅里叶变换模块(fourier)测幅值相角的设置与使用

matlab/simulink电力电子仿真傅里叶变换模块&#xff08;fourier&#xff09;测幅值相角的设置与使用 今天要说的是一个可以测量信号的幅值和相角的模块&#xff0c;fourier&#xff0c;长下面这样&#xff1a; 有时候我们需要求某个信号的幅值或者相位&#xff0c;或求两个…

用文字描述给黑白照上色,这个免费网站火了!网友:比其他同类都好用

金磊 Alex 发自 凹非寺量子位 | 公众号 QbitAI这是清朝末代皇后婉容广为流传的一张老照片&#xff1a;如果让照片变成彩色的&#xff0c;会是什么样子&#xff1f;竟然没有什么违和感&#xff0c;百年前的老照片似乎在此刻变得鲜活了起来。而这张图上色的背后&#xff0c;并没有…

BUUCTF NewStarCTF 公开赛赛道Week5 Writeup

文章目录WEBGive me your photo PLZBabySSTI_ThreeUnsafe ApacheSo Baby RCE AgainFinal roundMISC最后的流量分析奇怪的PDF 2奇怪的文本Yesec no drumsticks 5qsdzs girlfriend 5WEB Give me your photo PLZ 可上传.htaccess AddType application/x-httpd-php .jpg然后上传…

干货!手把手教你穿透内网

干货&#xff01;手把手教你穿透内网干货&#xff01;手把手教你穿透内网cpolar内网穿透使用场景如何使用cpolar内网穿透&#xff1f; ↓↓1. 注册cpolar账号2. 安装cpolar内网穿透2.1 Windows系统2.2 Linux系统2.2.1 安装2.2.2 向系统添加服务2.2.3 启动服务2.2.4 查看服务状态…

生成二维码或条形码JavaScript脚本库

二维码或条形码在日常生活中现在应用已经非常普遍了&#xff0c;文章分享生成条形码和二维码的JavaScript库。 条形码 条形码是日常生活中比较常见的&#xff0c;主要用于商品。通俗的理解就是一串字符串的集合&#xff08;含字母、数字及其它ASCII字符的集合应用&#xff09…

【机器学习基础】 线性回归

线性回归1、线性回归定义2、线性回归题目示例3、推导公式4、误差5、似然函数6、线性回归评价指标7、梯度下降1、线性回归定义 经典统计学习技术中的线性回归和softmax回归可以视为 线性神经⽹络。给定训练数据特征 X 和对应的已知标签 y &#xff0c;线性回归的⽬标是找到⼀组权…

Seata安装启动

一、下载 https://github.com/seata/seata/releases/download/v1.4.2/seata-server-1.4.2.zip 二、启动 在安装路径下cmd seata-server.bat -h 127.0.0.1 -m file 三、作用 Seata是分布事务解决方案&#xff0c;seata保证微服务远程调用业务的原子性 Seata将为用户提供了 …

Spring Cloud LoadBalancer--负载均衡的原理(源码分析)

原文网址&#xff1a;Spring Cloud LoadBalancer--负载均衡的原理&#xff08;源码分析&#xff09;_IT利刃出鞘的博客-CSDN博客 简介 说明 本文介绍Spring Cloud LoadBalancer负载均衡的原理。 SpringCloud从2020版本开始移除了对Ribbon的依赖&#xff0c;官方使用Spring Cl…

VsCode中一些可以让工作“事半功倍”的插件

1.GitLens — Git supercharged 这个插件可以查看代码修改的消息&#xff0c;比如是谁修改的以及修改时间 2.Chinese (Simplified) (简体中文) 简体中文&#xff0c;这个可以说是装的最多的一款插件了 3.Auto Close Tag 标签自动补全 4.Auto Rename Tag&#xff1a;自动完…

2021第7届中国大学生程序设计竞赛CCPC广州站, 签到题4题

文章目录I.Pudding StoreH.Three IntegersC.NecklaceF.Cactus补题链接&#xff1a;https://codeforces.com/gym/103415 I.Pudding Store I. Pudding Store time limit per test2.0 s memory limit per test512 megabytes inputstandard input outputstandard output 159 is a…

快速排序图解(两种思想)

七大排序之快速排序 文章目录七大排序之快速排序前言一、《算法导论》中的分区思想1.1 算法思想1.2 代码实现二、Hoare挖坑法2.1 算法思想2.2 代码实现三、算法分析四、注意事项总结前言 博主个人社区&#xff1a;开发与算法学习社区 博主个人主页&#xff1a;Killing Vibe的博…

【每天学习一点新知识】网络安全--截获攻击

截获攻击原理和后果 原理 若正常传输路径为终端A到终端B&#xff0c;黑客首先改变传输路径为终端A—黑客终端—终端B&#xff0c;使得传输信息必须经过黑客终端&#xff0c;黑客终端就可以截获终端A传输给终端B的消息。 后果 目前很多访问过程采用明码方式传输登录的用户名和密…

C++入门基础(下)

目录 引用 引用概念 引用特性 1.引用在定义时必须初始化 2.一个变量可以有多个引用 3.引用一旦引用一个实体&#xff0c;再不能引用其他实体. 常引用 使用场景 1.作为参数使用 2.作为返回值使用 引用和指针的区别 内联函数 内联函数的概念 内联函数特性 宏的优缺点 auto关键字 …

scala spark dataframe 时间加减

参考Adding 12 hours to datetime column in Spark 只针对标准化时间戳 yyyy-MM-dd HH:mm:ss 如果是 yyyy-MM-dd HH:mm 转换后会自动补到 HH:mm:ss ss位补0 时间英文简写查询 HOUR 代表小时 MINUTE 代表分钟 SECOND 代表秒 DAY MONTH YEAR 正数代表向后 负数代表向前 …

AI绘画突然爆火?快速体验二次元画师NovelAI(diffusion)

目录0 写在前面1 diffusion vs GAN2 NovelAI3 AI绘画环境搭建4 体验AI创作0 写在前面 机器学习强基计划聚焦深度和广度&#xff0c;加深对机器学习模型的理解与应用。“深”在详细推导算法模型背后的数学原理&#xff1b;“广”在分析多个机器学习模型&#xff1a;决策树、支持…

到了30岁,我才有了深刻的感悟:千万不要一辈子靠技术生存

千万不要一辈子靠技术生存&#xff0c;这句话&#xff0c;我也是到了快30岁才有了深刻认知。 当我20多岁&#xff0c;年收入2-3W的时候&#xff0c;我会认为说这话的人都是自身技术不咋地&#xff0c;想靠技术吃饭吃不了。 然而&#xff0c;快30岁了&#xff0c;虽然技术小有…

【Java】之IO流

个人主页&#xff1a;天寒雨落的博客_CSDN博客-C,CSDN竞赛,python领域博主 特别标注&#xff1a;仅为自己的学习记录笔记&#xff0c;方便复习和加深记忆&#xff0c;仅供借鉴参考&#xff01; 目录 IO流概述 IO流分类 按数据的流向 按数据类型 字符流 字节流 字节流写数…