Machine Learning-Ex6(吴恩达课后习题)Support Vector Machines

目录

1. Support Vector Machines

1.1 Example Dataset 1

1.2 SVM with Gaussian Kernels

1.2.1 Gaussian Kernel

1.2.2 Example Dataset 2

1.2.3 Example Dataset 3

2. Spam Classification

2.1 Preprocessing Emails

2.1.1 Vocabulary List

2.2 Extracting Features from Emails

2.3 Training SVM for Spam Classification

2.4 Top Predictors for Spam 


1. Support Vector Machines

内容:前半部分使用SVM对2D数据集进行应用,后半部分使用SVM来构建垃圾邮件分类器。

1.1 Example Dataset 1

内容:使用线性内核函数的SVM,调整参数C(=1/λ)的大小,并进行观察。

main.py

from scipy.io import loadmat  # 读取.mat文件
import pandas as pd  # 数据分析

res = loadmat('ex6data1.mat')
data = pd.DataFrame(res['X'], columns=['x1', 'x2'])
data['y'] = res['y']
print(data.head())

            x1        x2   y
0  1.9643  4.5957  1
1  2.2753  3.8589  1
2  2.9781  4.5651  1
3  2.9320  3.5519  1
4  3.5772  2.8560  1

A. 可视化数据

plot.py

import matplotlib.pyplot as plt

def plotData(data):
    filter_pos = data['y'].isin([1])
    filter_neg = data['y'].isin([0])
    positive = data[filter_pos]
    negative = data[filter_neg]
    fig, ax = plt.subplots(figsize=(8, 6))
    ax.scatter(positive['x1'], positive['x2'], marker='x', c='r', label='Positive')
    ax.scatter(negative['x1'], negative['x2'], marker='o', c='b', label='Negative')
    ax.set_xlabel('x1')
    ax.set_ylabel('x2')
    ax.legend()
    plt.show()
    return fig, ax

main.py

from scipy.io import loadmat  # 读取.mat文件
import pandas as pd  # 数据分析
from plot import *  # 数据可视化

res = loadmat('ex6data1.mat')
data = pd.DataFrame(res['X'], columns=['x1', 'x2'])
data['y'] = res['y']
plotData(data)

B. 训练线性SVM(带线性内核函数)

linearSVM.py

from sklearn import svm  # 机器学习

def linearSVM(data, C_number):
    # LinearSVC(C,max_iter, loss)
    # C:惩罚参数(1/λ),max_iter:最大迭代次数
    # loss:指定损失函数,“hinge”是标准的SVM损失
    svc = svm.LinearSVC(C=C_number, loss='hinge', max_iter=10000)
    # svc.fit(X,y) 根据给定的训练数据拟合SVM模型
    # svc.score(X,y) 返回给定测试数据和标签的平均精确度
    svc.fit(data[['x1', 'x2']], data['y'])
    print(svc.score(data[['x1', 'x2']], data['y']))  # 0.9803921568627451

main.py

from scipy.io import loadmat  # 读取.mat文件
import pandas as pd  # 数据分析
from linearSVM import *  # 线性SVM

res = loadmat('ex6data1.mat')
data = pd.DataFrame(res['X'], columns=['x1', 'x2'])
data['y'] = res['y']
C = 1  # 惩罚项
linearSVM(data, C)

C. 可视化决策边界

linearSVM.py

from sklearn import svm  # 机器学习
import numpy as np
import pandas as pd
from plot import *  # 绘制决策边界

def linearSVM(data, C_number):
    # LinearSVC(C,max_iter, loss)
    # C:惩罚参数(1/λ),max_iter:最大迭代次数
    # loss:指定损失函数,“hinge”是标准的SVM损失
    svc = svm.LinearSVC(C=C_number, loss='hinge', max_iter=10000)
    # svc.fit(X,y) 根据给定的训练数据拟合SVM模型
    # svc.score(X,y) 返回给定测试数据和标签的平均精确度
    svc.fit(data[['x1', 'x2']], data['y'])
    x1, x2 = findDecisionBoundary(svc, 0, 4, 1.5, 5, 2 * 10 ** -3)  # 寻找决策边界
    plotDecisionBoundary(data, x1, x2)

def findDecisionBoundary(svc, x1min, x1max, x2min, x2max, dis):
    x1 = np.linspace(x1min, x1max, 1000)
    x2 = np.linspace(x2min, x2max, 1000)
    coordinates = [(x, y) for x in x1 for y in x2]
    # print(len(coordinates))  # 1000*1000=1,000,000
    x_cord, y_cord = zip(*coordinates)  # 解压
    # print(len(x_cord)) #1,000,000
    points = pd.DataFrame({'x1': x_cord, 'x2': y_cord})
    # svc.decision_function(X) 样本X到分离超平面的距离
    points['val'] = svc.decision_function(points[['x1', 'x2']])
    decision = points[np.abs(points['val']) < dis]  # 这些点可以构成一个决策边界(想法:近乎贴近超平面)
    return decision.x1, decision.x2

plot.py

import matplotlib.pyplot as plt

# 数据可视化
def plotData(data):
    filter_pos = data['y'].isin([1])
    filter_neg = data['y'].isin([0])
    positive = data[filter_pos]
    negative = data[filter_neg]
    fig, ax = plt.subplots(figsize=(8, 6))
    ax.scatter(positive['x1'], positive['x2'], marker='x', c='r', label='Positive')
    ax.scatter(negative['x1'], negative['x2'], marker='o', c='b', label='Negative')
    ax.set_xlabel('x1')
    ax.set_ylabel('x2')
    return fig, ax

# 绘制决策边界
def plotDecisionBoundary(data, x1, x2):
    fig, ax = plotData(data)
    ax.scatter(x1, x2, c='g', s=10, label='Boundary')
    ax.set_title('SVM Decision Boundary with C=1')
    ax.legend()
    plt.show()

调整参数C(=1/λ)的值:C=100

main.py

C = 100  # 惩罚项

linearSVM.py(部分修改)

def linearSVM(data, C_number):
    svc = svm.LinearSVC(C=C_number, loss='hinge', max_iter=1000)
    svc.fit(data[['x1', 'x2']], data['y'])
    print(svc.score(data[['x1', 'x2']], data['y']))  # 0.9803921568627451
    x1, x2 = findDecisionBoundary(svc, 0, 4, 1.5, 5, 2 * 10 ** -3)  # 寻找决策边界
    plotDecisionBoundary(data, x1, x2)

观察:随着C的增大,可以得到一个完美的分类结果,但是创建了一个不再适合数据的决策边界。

1.2 SVM with Gaussian Kernels

内容:我们会使用带有高斯内核函数的SVM来处理非线性分类。

1.2.1 Gaussian Kernel

内容:高斯核函数是一个表示数据间“距离”的相似度函数,参数σ可以决定相似度下降到0的快慢程度。

gaussianKernel.py

import numpy as np

def gaussianKernel(x1, x2, sigma):
    return np.exp(-np.sum((x1 - x2) ** 2) / (2 * sigma ** 2))

x1 = np.array([1, 2, 1])
x2 = np.array([0, 4, -1])
sigma = 2
print(gaussianKernel(x1, x2, sigma))

 0.32465246735834974

1.2.2 Example Dataset 2

内容:在数据集2上使用带高斯核函数的SVM找到决策边界。

main.py

from scipy.io import loadmat
import pandas as pd

raw_data = loadmat('ex6data2.mat')
data = pd.DataFrame(raw_data['X'], columns=['x1', 'x2'])
data['y'] = raw_data['y']
print(data.head())

               x1              x2  y
0  0.107143  0.603070  1
1  0.093318  0.649854  1
2  0.097926  0.705409  1
3  0.155530  0.784357  1
4  0.210829  0.866228  1

数据可视化

plot.py

import matplotlib.pyplot as plt

def plotData(data, ax):
    filter_pos = data['y'].isin([1])
    filter_neg = data['y'].isin([0])
    positive = data[filter_pos]
    negative = data[filter_neg]
    ax.scatter(positive['x1'], positive['x2'], c='r', s=15, marker='x', label='Positive')
    ax.scatter(negative['x1'], negative['x2'], c='y', s=15, label='Negative')
    ax.set_xlabel('x1')
    ax.set_ylabel('x2')
    ax.legend()

main.py

from scipy.io import loadmat
import pandas as pd
import matplotlib.pyplot as plt
from plot import *  # 绘制数据

raw_data = loadmat('ex6data2.mat')
data = pd.DataFrame(raw_data['X'], columns=['x1', 'x2'])
data['y'] = raw_data['y']
fig, ax = plt.subplots(figsize=(8, 6))
plotData(data, ax)
plt.show()

使用高斯核函数

main.py

from scipy.io import loadmat
import pandas as pd
import matplotlib.pyplot as plt
from sklearn import svm
from plot import *  # 绘制数据

raw_data = loadmat('ex6data2.mat')
data = pd.DataFrame(raw_data['X'], columns=['x1', 'x2'])
data['y'] = raw_data['y']
# gamma:核函数系数
# probability:是否启用概率估计
svc = svm.SVC(C=100, gamma=10, probability=True)
svc.fit(data[['x1', 'x2']], data['y'])
print(svc.score(data[['x1', 'x2']], data['y']))

0.9698725376593279

foundDecisionBoundary.py

import numpy as np
import pandas as pd

def findDecisionBoundary(svc, x1_min, x1_max, x2_min, x2_max, dist):
    x1 = np.linspace(x1_min, x1_max, 1000)
    x2 = np.linspace(x2_min, x2_max, 1000)
    cordinates = [(x, y) for x in x1 for y in x2]
    x_cord, y_cord = zip(*cordinates)
    points = pd.DataFrame({'x1': x_cord, 'x2': y_cord})
    points['val'] = svc.decision_function(points[['x1', 'x2']])
    decision = points[np.abs(points['val']) < dist]
    return decision.x1, decision.x2

main.py

from scipy.io import loadmat
import pandas as pd
import matplotlib.pyplot as plt
from sklearn import svm
from plot import *  # 绘制数据
from foundDecisionBoundary import *  # 决策边界

raw_data = loadmat('ex6data2.mat')
data = pd.DataFrame(raw_data['X'], columns=['x1', 'x2'])
data['y'] = raw_data['y']
# gamma:核函数系数
# probability:是否启用概率估计
svc = svm.SVC(C=100, gamma=10, probability=True)
svc.fit(data[['x1', 'x2']], data['y'])
x1, x2 = findDecisionBoundary(svc, 0, 1, 0.4, 1, 2 * 10 ** -3)
fig, ax = plt.subplots(figsize=(8, 6))
plotData(data, ax)
ax.scatter(x1, x2, s=10)
ax.set_title('SVM (Gaussian Kernel) Decision Boundary')
plt.show()

1.2.3 Example Dataset 3

内容:根据验证集,我们可以为SVM找到最优的C和σ参数,候选值为[0.01,0.03,0.1,0.3,1,3,10,30,100]。

main.py

from scipy.io import loadmat
import pandas as pd
import matplotlib.pyplot as plt
from plot import *  # 绘制数据

raw_data = loadmat('ex6data3.mat')
X, y, Xval, yval = raw_data['X'], raw_data['y'].ravel(), raw_data['Xval'], raw_data['yval'].ravel()
data = pd.DataFrame(X, columns=['x1', 'x2'])
data['y'] = y
print(data.head())
fig, ax = plt.subplots(figsize=(8, 6))
plotData(data, ax)
plt.show()

                x1             x2  y
0 -0.158986  0.423977  1
1 -0.347926  0.470760  1
2 -0.504608  0.353801  1
3 -0.596774  0.114035  1
4 -0.518433 -0.172515  1

 

A. 找到最优的参数C和σ

fitParam.py

from sklearn import svm

def fitParam(X, y, Xval, yval):
    C_values = [0.01, 0.03, 0.1, 0.3, 1, 3, 10, 30, 100]
    gamma_values = [0.01, 0.03, 0.1, 0.3, 1, 3, 10, 30, 100]
    best_score = 0
    best_params = {'C': None, 'gamma': None}
    for C in C_values:
        for gamma in gamma_values:
            svc = svm.SVC(C=C, gamma=gamma)
            svc.fit(X, y)
            score = svc.score(Xval, yval)
            if score > best_score:
                best_score = score
                best_params['C'] = C
                best_params['gamma'] = gamma
    return best_score, best_params

main.py

from scipy.io import loadmat
import pandas as pd
from fitParam import *  # 找到最优参数

raw_data = loadmat('ex6data3.mat')
X, y, Xval, yval = raw_data['X'], raw_data['y'].ravel(), raw_data['Xval'], raw_data['yval'].ravel()
data = pd.DataFrame(X, columns=['x1', 'x2'])
data['y'] = y
best_score, best_params = fitParam(X, y, Xval, yval)
print(best_score, best_params)

0.965 {'C': 0.3, 'gamma': 100}

main.py

from scipy.io import loadmat
import pandas as pd
from sklearn import svm  # 支持向量机
import matplotlib.pyplot as plt
from plot import *  # 绘制数据
from fitParam import *  # 找到最优参数
from foundDecisionBoundary import *  # 决策边界

raw_data = loadmat('ex6data3.mat')
X, y, Xval, yval = raw_data['X'], raw_data['y'].ravel(), raw_data['Xval'], raw_data['yval'].ravel()
data = pd.DataFrame(X, columns=['x1', 'x2'])
data['y'] = y
best_score, best_params = fitParam(X, y, Xval, yval)
svc = svm.SVC(C=best_params['C'], gamma=best_params['gamma'])
svc.fit(X, y)
x1, x2 = findDecisionBoundary(svc, -0.6, 0.3, -0.7, 0.6, 2 * 10 ** -3)
fig, ax = plt.subplots(figsize=(8, 6))
plotData(data, ax)
ax.scatter(x1, x2, s=10)
ax.set_title('SVM (Gaussian Kernel) Decision Boundary')
plt.show()

2. Spam Classification

内容:使用SVM来构建垃圾邮件过滤器。

2.1 Preprocessing Emails

内容:完成预处理邮件信息,使其更好为SVM所应用。比如:全部小写化、移除HTML标签、将所有URL统称为httpaddr、将所有邮件地址统称为emailaddr、将所有数字统称为number、将所有钱数统称为dollar、词干提取、移除标点符号以及非文字,将制表符、换行,多个空格统一为一个空格符等。

2.1.1 Vocabulary List

内容:

  • 预处理好的邮件。
  • 词汇列表:可以选择在垃圾语料库中至少出现过100次的这些单词,因为如果出现的次数较少,则可能会出现过拟合的情况。每个单词在词汇列表中都有对应的索引。
  • 映射:将预处理好的邮件中的单词与词汇列表中的单词进行对比,如果是一样的,则返回相应索引值,如果未在索引表中出现,则跳过。

2.2 Extracting Features from Emails

内容: 将邮件转化成特征向量,特征向量的维度n即为词汇列表的长度。Xi∈{0,1},Xi=0表示词汇表中的第 i 个单词在邮件中未出现,Xi=1表示词汇表中的第 i 个单词在邮件中出现。此例中特征向量长为1899,有45个非零项。

2.3 Training SVM for Spam Classification

内容:处理好的训练集有4000个邮件(含垃圾和非垃圾邮件),处理好的测试集有1000个邮件。使用SVM对其进行分类,垃圾邮件为y=1,非垃圾邮件为y=0。

main.py

from scipy.io import loadmat

rawTrainData = loadmat('spamTrain.mat')
rawTestData = loadmat('spamTest.mat')
X, y, Xtest, ytest = rawTrainData['X'], rawTrainData['y'].ravel(), rawTestData['Xtest'], rawTestData['ytest'].ravel()
print(X.shape, y.shape, Xtest.shape, ytest.shape)
# (4000, 1899) (4000,) (1000, 1899) (1000,)

说明:1899表示这封邮件的单词在词汇表(1899个词)中有无出现,出现则为1,未出现则为0。

main.py

from scipy.io import loadmat
from sklearn import svm
import numpy as np

rawTrainData = loadmat('spamTrain.mat')
rawTestData = loadmat('spamTest.mat')
X, y, Xtest, ytest = rawTrainData['X'], rawTrainData['y'].ravel(), rawTestData['Xtest'], rawTestData['ytest'].ravel()
svc = svm.SVC()
svc.fit(X, y)
# round()设置保留几位小数
print('Training accuracy={0}%'.format(np.round(svc.score(X, y) * 100, 2)))
print('Test accuracy={0}%'.format(np.round(svc.score(Xtest, ytest) * 100, 2)))

Training accuracy=99.32%
Test accuracy=98.7%

2.4 Top Predictors for Spam 

内容:垃圾邮件的主要预测因素。

main.py

from scipy.io import loadmat
from sklearn import svm
import numpy as np
import pandas as pd

rawTrainData = loadmat('spamTrain.mat')
rawTestData = loadmat('spamTest.mat')
X, y, Xtest, ytest = rawTrainData['X'], rawTrainData['y'].ravel(), rawTestData['Xtest'], rawTestData['ytest'].ravel()
svc = svm.SVC()
svc.fit(X, y)
# 创建单位矩阵
kw = np.eye(1899)
spam_val = pd.DataFrame({'idx': range(1899)})
spam_val['isspam'] = svc.decision_function(kw)
# pd.describe()返回统计变量
print(spam_val['isspam'].describe())
# count:数量统计 mean:均值 std:标准差 min:最小值

count    1899.000000
mean       -0.110039
std         0.049094
min        -0.428396
25%        -0.131213
50%        -0.111985
75%        -0.091973
max         0.396286
Name: isspam, dtype: float64

main.py

from scipy.io import loadmat
from sklearn import svm
import numpy as np
import pandas as pd

rawTrainData = loadmat('spamTrain.mat')
rawTestData = loadmat('spamTest.mat')
X, y, Xtest, ytest = rawTrainData['X'], rawTrainData['y'].ravel(), rawTestData['Xtest'], rawTestData['ytest'].ravel()
svc = svm.SVC()
svc.fit(X, y)
# 创建单位矩阵
kw = np.eye(1899)
spam_val = pd.DataFrame({'idx': range(1899)})
spam_val['isspam'] = svc.decision_function(kw)
decision = spam_val[spam_val['isspam'] > 0]
print(decision)

            idx    isspam
155    155  0.095529
173    173  0.066666
297    297  0.396286
351    351  0.023785
382    382  0.030317
476    476  0.042474
478    478  0.057344
529    529  0.060692
537    537  0.008558
680    680  0.109643
697    697  0.003269
738    738  0.092561
774    774  0.181496
791    791  0.040396
1008  1008  0.012187
1088  1088  0.132633
1101  1101  0.002832
1120  1120  0.003076
1163  1163  0.072045
1178  1178  0.012122
1182  1182  0.015656
1190  1190  0.232788
1263  1263  0.160806
1298  1298  0.044018
1372  1372  0.019640
1397  1397  0.218337
1399  1399  0.018762
1460  1460  0.001859
1467  1467  0.002822
1519  1519  0.001654
1661  1661  0.003775
1721  1721  0.057241
1740  1740  0.034107
1795  1795  0.125143
1823  1823  0.002071
1829  1829  0.002630
1851  1851  0.030662
1892  1892  0.052786
1894  1894  0.101613

main.py (词汇列表)

import pandas as pd

# sep正则
voc = pd.read_csv('vocab.txt', header=None, names=['idx', 'voc'], sep='\t')
print(voc.head())

    idx    voc
0    1     aa
1    2     ab
2    3   abil
3    4    abl
4    5  about

输出敏感(容易在垃圾邮件中出现的)词汇

main.py

from scipy.io import loadmat
from sklearn import svm
import numpy as np
import pandas as pd

rawTrainData = loadmat('spamTrain.mat')
rawTestData = loadmat('spamTest.mat')
X, y, Xtest, ytest = rawTrainData['X'], rawTrainData['y'].ravel(), rawTestData['Xtest'], rawTestData['ytest'].ravel()
svc = svm.SVC()
svc.fit(X, y)
# 创建单位矩阵
kw = np.eye(1899)
spam_val = pd.DataFrame({'idx': range(1899)})
spam_val['isspam'] = svc.decision_function(kw)
decision = spam_val[spam_val['isspam'] > 0]
# sep正则
voc = pd.read_csv('vocab.txt', header=None, names=['idx', 'voc'], sep='\t')
spamvoc = voc.loc[decision['idx']]
print(spamvoc)

           idx         voc
155    156    basenumb
173    174       below
297    298       click
351    352     contact
382    383      credit
476    477      dollar
478    479  dollarnumb
529    530       email
537    538       encod
680    681        free
697    698       futur
738    739    guarante
774    775        here
791    792        hour
1008  1009      market
1088  1089        nbsp
1101  1102    nextpart
1120  1121     numbera
1163  1164       offer
1178  1179         opt
1182  1183       order
1190  1191         our
1263  1264       pleas
1298  1299       price
1372  1373      receiv
1397  1398       remov
1399  1400       repli
1460  1461          se
1467  1468         see
1519  1520      sincer
1661  1662        text
1721  1722    transfer
1740  1741        type
1795  1796       visit
1823  1824      websit
1829  1830      welcom
1851  1852        will
1892  1893         you
1894  1895        your

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

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

相关文章

安卓GB28181-2022 RTP over TCP

使用TCP传输RTP包&#xff0c;GB28181-2016和GB28181-2022 都是按IETF RFC4571来的。使用TCP发送RTP包&#xff0c;前面加个16位无符号长度字段就好(网络字节序)。具体定义格式如下&#xff1a; 需要注意的是LENGTH值可以是0&#xff0c;0的话表示空包; 另外UDP传输RTP包&#…

第二届易派客工业品展圆满落幕 3天超7万人次观展

4月15日&#xff0c;第二届易派客工业品展览会在苏州国际博览中心成功闭幕&#xff0c;展会期间共7.4万人次观展。展会以“绿色•智造•融通•赋能”为主题&#xff0c;为参展企业衔接供需、共享商机、共促发展提供平台&#xff0c;推动工业企业数字化转型、致力供应链优化升级…

blast的-max_target_seqs?

Shah, N., Nute, M.G., Warnow, T., and Pop, M. (2018). Misunderstood parameter of NCBI BLAST impacts the correctness of bioinformatics workflows. Bioinformatics. 杂志Bioinformatics以letter to the editor的形式刊发了来自美国马里兰大学计算机系的Nidhi Shah等人…

powershell搞定烦人的Windows Defender

0x00 Windows Defender真烦 最近装了不少虚拟机&#xff0c;发现目前较新版本的windows Defender是真的烦&#xff0c;关了一段时间后&#xff0c;自己又打开。特别是装了域控后的winserver 2016&#xff0c;半都关不掉&#xff0c;做个实验是真烦。 顺手去查了下如何使用pow…

ThinkPHP模型操作上

ThinkPHP模型操作上 前言模型一、创建模型二、模型操作 总结 前言 在mvc架构中&#xff0c;模型的解释是写逻辑代码的地方&#xff0c;其实还可以这样理解&#xff0c;就是一串操作写在一个模型类中&#xff0c;就是你要完成某一项功能&#xff0c;将这个功能的代码写在一个mod…

2023年产业基金研究报告

第一章 行业概况 1.1 概述 产业基金&#xff0c;又称为产业投资基金&#xff0c;是一种由政府、企业、金融机构等出资设立的&#xff0c;专门用于支持和促进特定产业发展的投资基金。产业基金通常以股权投资和长期投资为主&#xff0c;旨在推动产业结构升级、促进科技创新、提…

基于ResNet-attention的负荷预测

一、attention机制 注意力模型最近几年在深度学习各个领域被广泛使用&#xff0c;无论是图像处理、语音识别还是自然语言处理的各种不同类型的任务中&#xff0c;都很容易遇到注意力模型的身影。从注意力模型的命名方式看&#xff0c;很明显其借鉴了人类的注意力机制。我们来看…

融云 CTO 岑裕:出海技术前沿探索和排「坑」实践

在本文中&#xff0c;你将看到以下内容&#xff1a; 全球通信网络在接入点、链路加速、服务商、协议等层面的动态演进&#xff1b; 进入到具体市场&#xff0c;禁运国、跨国拦截、区域一致性差等细节“坑点”如何应对&#xff1b; 融云如何从技术侧帮助开发者应对本地化用户体…

Hive与HBase的区别及应用场景

目录&#xff1a; 零、前言一、定义二、区别三、应用场景 零、前言 在学大数据分析的过程中&#xff0c;Hive和HBase是两个非常重要的内容&#xff0c;对于初学者而言容易混淆。所以比较两者区别&#xff0c;能够帮助我们对这两个组件有一个清晰的认识和定位。那么&#xff0c;…

一篇文章看懂MySQL的多表连接(包含左/右/全外连接)

MySQL的多表查询 这是第二次学习多表查询&#xff0c;关于左右连接还是不是很熟悉&#xff0c;因此重新看一下。小目标&#xff1a;一篇文章看懂多表查询&#xff01;&#xff01; 这篇博客是跟着宋红康老师学习的&#xff0c;点击此处查看视频&#xff0c;关于数据库我放在了…

大神们分享STM32的学习方法

单片机用处这么广&#xff0c;尤其是STM32生态这么火&#xff01;如何快速上手学习呢&#xff1f; 第一&#xff1a;你要考虑的是&#xff0c;要用STM32实现什么 为什么使用STM32而不是8051? 是因为51的频率太低&#xff0c;无法满足计算需求?是51的管脚太少&#xff0c;无法…

云HIS(二级医院,乡镇医院,民营医院,标准化HIS医院信息管理系统源码)

传统 HIS&#xff08;基于医院信息系统&#xff09; 和云 HIS&#xff08;基于云计算的医院信息系统&#xff09;各有优缺点&#xff0c;选择哪种系统需要根据具体情况进行权衡。 传统 HIS 系统通常由医院自行开发和维护&#xff0c;适用于医院内部信息化程度较高、数据安全性…

【软件测试】第1章 软件测试概述

系列文章目录 文章目录 系列文章目录前言第1章 软件测试概述1.1 软件、软件危机和软件工程1.1.1 基本概念1.1.2 软件工程的目标及其一般开发过程1.1.3 软件过程模型 1.2 软件缺陷与软件故障1.2.1 基本概念1.2.2 典型案例 1.3 软件测试的概念1.3.1 软件测试的定义1.3.2 软件测试…

计算机程序安装及使用须知_kaic

安装及使用须知 1 数据库建模程序的使用 本文件夹中的“PowerDesigner建模”目录下包含三个可运行文件TMS1.cdm&#xff0c;TMS.cdm&#xff0c;TMS.pdm分别为TMS系统的实体关系简图、实体关系图和数据库模型&#xff0c;使用PowerDesigner集成开发环境打开任意一个文件即可运…

Linux系统与shell编程第一节课

目录 1.1 Linux发展历史 1.2 什么是linux&#xff1f; 1.3 Linux的发行版 Host-Only&#xff08;仅主机模式&#xff09; windows开发 linux服务 区块链&#xff0c; 特点&#xff1a;稳定&#xff0c;安全&#xff0c;可移植性&#xff0c;低资源消耗&#xff0c;开源软…

2023年第十二届数据技术嘉年华(DTC)资料分享

第十二届数据技术嘉年华&#xff08;DTC 2023&#xff09;已于4月8日在北京圆满落幕&#xff0c;大会围绕“开源融合数智化——引领数据技术发展&#xff0c;释放数据要素价值”这一主题&#xff0c;共设置有1场主论坛&#xff0c;12场专题论坛&#xff0c;68场主题演讲&#x…

【基础】Kafka -- 日志存储

Kafka -- 日志存储 日志文件目录日志索引偏移量索引时间戳索引 日志清理日志删除基于时间基于日志大小基于日志起始偏移量 日志压缩 日志文件目录 Kafka 中的消息以主题为单位进行基本归类&#xff0c;而每个主题又可以划分为一个或者多个分区。在不考虑多副本的情况下&#x…

【MySQL】插入文件路径,反斜杠消失

系列文章 C#底层库–MySQL脚本自动构建类&#xff08;insert、update语句生成&#xff09; 本文链接&#xff1a;https://blog.csdn.net/youcheng_ge/article/details/129179216 C#底层库–MySQL数据库访问操作辅助类&#xff08;推荐阅读&#xff09; 本文链接&#xff1a;h…

如何优雅的写个try catch的方式!

软件开发过程中&#xff0c;不可避免的是需要处理各种异常&#xff0c;就我自己来说&#xff0c;至少有一半以上的时间都是在处理各种异常情况&#xff0c;所以代码中就会出现大量的try {...} catch {...} finally {...} 代码块&#xff0c;不仅有大量的冗余代码&#xff0c;而…

07 【Sass语法介绍-控制指令】

1.前言 Sass 为我们提供了很多控制指令&#xff0c;使得我们可以更高效的来控制样式的输出&#xff0c;或者在函数中进行逻辑控制。本节内容我们就来讲解什么是 Sass 控制指令&#xff1f;它能用来做什么&#xff1f;它将使你更方便的编写 Sass 。 2.什么是 Sass 控制指令 控…