-
Notifications
You must be signed in to change notification settings - Fork 0
/
rss.xml
1031 lines (1031 loc) · 440 KB
/
rss.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0"?>
<rss version="2.0">
<channel>
<title>幽化猫の博客</title>
<subtitle>生活朗朗,万物可爱</subtitle>
<icon>https://love.youhuamao.xyz/images/favicon.ico</icon>
<link>https://love.youhuamao.xyz</link>
<author>
<name>youhuamao</name>
</author>
<description>这是一个人的博客</description>
<language>zh-CN</language>
<pubDate>Tue, 29 Nov 2022 00:00:00 +0800</pubDate>
<lastBuildDate>Tue, 29 Nov 2022 00:00:00 +0800</lastBuildDate>
<item>
<guid isPermalink="true">https://love.youhuamao.xyz/2022/11/29/ai/Andrew%20Ng%20Lesson/%E5%9B%BE%E7%89%87%E6%96%87%E5%AD%97%E8%AF%86%E5%88%AB/</guid>
<title>大规模机器学习</title>
<link>https://love.youhuamao.xyz/2022/11/29/ai/Andrew%20Ng%20Lesson/%E5%9B%BE%E7%89%87%E6%96%87%E5%AD%97%E8%AF%86%E5%88%AB/</link>
<category term="ai" scheme="https://love.youhuamao.xyz/categories/ai/" />
<category term="Andrew Ng Lesson" scheme="https://love.youhuamao.xyz/categories/ai/Andrew-Ng-Lesson/" />
<category term="ai lesson" scheme="https://love.youhuamao.xyz/tags/ai-lesson/" />
<pubDate>Tue, 29 Nov 2022 00:00:00 +0800</pubDate>
<description><![CDATA[ <h1 id="问题描述和流程图-problem-description-and-pipeline"><a class="anchor" href="#问题描述和流程图-problem-description-and-pipeline">#</a> 问题描述和流程图 Problem Description and Pipeline</h1>
<p>图像文字识别需要如下步骤:<br />
<img data-src="/pic/wuenda/daguimojiqixuexi-01.png" alt="img.png" /><br />
1. 文字侦测 (Text detection)—— 将图片上的文字与其他环境对象分离开来<br />
2. 字符切分 (Character segmentation)—— 将文字分割成一个个单一的字符<br />
3. 字符分类 (Character classification)—— 确定每一个字符是什么</p>
<p>如果用任务流程图来表达这个问题,每一项任务可以由一个单独的小队来负责:<br />
<img data-src="/pic/wuenda/daguimojiqixuexi-02.png" alt="img.png" /></p>
<h1 id="滑动窗口-sliding-windows"><a class="anchor" href="#滑动窗口-sliding-windows">#</a> 滑动窗口 Sliding Windows</h1>
<p>滑动窗口是一项用来从图像中抽取对象的技术。<br />
<img data-src="/pic/wuenda/daguimojiqixuexi-03.png" alt="img.png" /><br />
假使需要在图片中识别行人,首先用许多固定尺寸的图片来训练一个能够准确识别行人的模型。<br />
<img data-src="/pic/wuenda/daguimojiqixuexi-04.png" alt="img.png" /><br />
之后使用训练模型时用的图片尺寸对预测图片进行剪裁,将切片交给模型判断其是否为行人,然后滑动剪裁区域,剪裁切片后再交给模型判断,直至将图片全部检测完。<br />
然后按比例放大剪裁的区域,以新的尺寸对图片进行剪裁,将新剪裁的切片按比例缩小至模型采纳的尺寸,交给模型判断,如此循环。<br />
<img data-src="/pic/wuenda/daguimojiqixuexi-05.png" alt="img.png" /><br />
<img data-src="/pic/wuenda/daguimojiqixuexi-06.png" alt="img.png" /><br />
<img data-src="/pic/wuenda/daguimojiqixuexi-07.png" alt="img.png" /><br />
滑动窗口技术也被用于文字识别,首先训练模型使其能够区分字符与非字符,然后,运用滑动窗口技术识别字符。一旦完成了识别,将识别得出的区域进行一些扩展,然后将重叠的区域进行合并。<br />
<img data-src="/pic/wuenda/daguimojiqixuexi-08.png" alt="img.png" /><br />
接着以宽高比作为过滤条件,过滤高度比宽度更大的区域 (因为单词的长度通常比高度要大)。下图中绿色区域是识别出的文字区域,红色区域是被忽略的。<br />
<img data-src="/pic/wuenda/daguimojiqixuexi-09.png" alt="img.png" /><br />
下一步是训练模型分割字符,需要的训练集为单个字符的图和两个相连字符之间的图。模型训练完后,仍然使用滑动窗口技术来进行字符识别。<br />
<img data-src="/pic/wuenda/daguimojiqixuexi-10.png" alt="img.png" /><br />
最后是字符分类阶段,利用神经网络、支持向量机或者逻辑回归算法训练一个分类器即可。</p>
<h1 id="获取大量数据和人工数据-getting-lots-of-data-and-artificial-data"><a class="anchor" href="#获取大量数据和人工数据-getting-lots-of-data-and-artificial-data">#</a> 获取大量数据和人工数据 Getting Lots of Data and Artificial Data</h1>
<p>以文字识别应用为例,一种方法是从网站下载各种字体,利用不同的字体配上各种不同的随机背景,创造出一些用于训练的实例,能够获得一个无限大的训练集。这属于从零开始创造实例。<br />
<img data-src="/pic/wuenda/daguimojiqixuexi-11.png" alt="img.png" /><br />
<img data-src="/pic/wuenda/daguimojiqixuexi-12.png" alt="img.png" /><br />
另一种方法是,对已有的数据进行修改,例如将其进行扭曲、旋转、模糊处理。只要认为实际数据有可能和处理后的数据类似,便可以用这样的方法来创造大量的数据。<br />
<img data-src="/pic/wuenda/daguimojiqixuexi-13.png" alt="img.png" /><br />
某些处理起不到增加数据集的作用,例如加入高斯噪声、将单个图片复制多份等<br />
<img data-src="/pic/wuenda/daguimojiqixuexi-14.png" alt="img.png" /><br />
在增大数据集之前,必须确保当前训练的已经是一个低偏差的模型。不然增大数据集也没有用</p>
<p>有关获得更多数据的几种方法: 1. 人工数据合成;2. 手动收集、标记数据;3. 众包<br />
<img data-src="/pic/wuenda/daguimojiqixuexi-15.png" alt="img.png" /></p>
<h1 id="上限分析-what-part-of-the-pipeline-to-work-on-next"><a class="anchor" href="#上限分析-what-part-of-the-pipeline-to-work-on-next">#</a> 上限分析 What Part of the Pipeline to Work on Next</h1>
<p>如何知道哪一部分最值得花时间和精力去改善呢?可以使用流程图进行上限分析,流程图中每一部分的输出都是下一部分的输入。</p>
<p>在上限分析中,我们选取一部分,手工提供 100% 正确的输出结果,然后看应用的整体效果提升了多少。假使当前总体效果为 72% 的正确率:</p>
<ol>
<li>如果让文字检测部分 100% 正确,系统的总体效果从 72% 提高到了 89%。这意味着很值得投入时间精力来提高我们的文字检测的准确度</li>
<li>接着让字符切分结果 100% 正确,系统总体效果只提升了 1%,这意味着字符切分部分可能已经足够好了</li>
<li>最后让字符分类 100% 正确,系统总体效果又提升了 10%,这意味着我们可能也会应该投入更多的时间和精力到分类这部分<br />
<img data-src="/pic/wuenda/daguimojiqixuexi-16.png" alt="img.png" /><br />
另一个上限分析的例子,人脸识别:<br />
<img data-src="/pic/wuenda/daguimojiqixuexi-17.png" alt="img.png" /><br />
其中最值得优化的是:脸部检测 Face detection,眼部分割 Eyes segmentation 和 逻辑回归 Logistic regression 三个部分。</li>
</ol>
<p>建议不要根据直觉,而是使用上限分析判断应该改进哪个模块。当把精力花在最值得优化的那个模块上,会让整个系统的表现有显著的提高。</p>
]]></description>
</item>
<item>
<guid isPermalink="true">https://love.youhuamao.xyz/2022/11/29/ai/Andrew%20Ng%20Lesson/%E5%A4%A7%E8%A7%84%E6%A8%A1%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0/</guid>
<title>大规模机器学习</title>
<link>https://love.youhuamao.xyz/2022/11/29/ai/Andrew%20Ng%20Lesson/%E5%A4%A7%E8%A7%84%E6%A8%A1%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0/</link>
<category term="ai" scheme="https://love.youhuamao.xyz/categories/ai/" />
<category term="Andrew Ng Lesson" scheme="https://love.youhuamao.xyz/categories/ai/Andrew-Ng-Lesson/" />
<category term="ai lesson" scheme="https://love.youhuamao.xyz/tags/ai-lesson/" />
<pubDate>Tue, 29 Nov 2022 00:00:00 +0800</pubDate>
<description><![CDATA[ <h1 id="大型数据集的学习-learning-with-large-datasets"><a class="anchor" href="#大型数据集的学习-learning-with-large-datasets">#</a> 大型数据集的学习 Learning With Large Datasets</h1>
<p>如果有一个低方差的模型, 通常通过增加数据集的规模,可以获得更好的结果。<br />
<img data-src="/pic/wuenda/daguimojiqixuexi-01.png" alt="img.png" /><br />
但是如果数据集特别大,则首先应该检查这么大规模是否真的必要,也许只用 1000 个训练集也能获得较好的效果,可以绘制学习曲线来帮助判断。<br />
<img data-src="/pic/wuenda/daguimojiqixuexi-02.png" alt="img.png" /></p>
<h1 id="随机梯度下降法-stochastic-gradient-descent"><a class="anchor" href="#随机梯度下降法-stochastic-gradient-descent">#</a> 随机梯度下降法 Stochastic Gradient Descent</h1>
<p>如果必须使用一个大规模的训练集,则可以尝试使用随机梯度下降法 (SGD) 来代替批量梯度下降法。<br />
<img data-src="/pic/wuenda/daguimojiqixuexi-03.png" alt="img.png" /><br />
随机梯度下降算法 则首先对训练集随机 “洗牌”,然后在每一次计算之后便更新参数 θ<br />
<img data-src="/pic/wuenda/daguimojiqixuexi-04.png" alt="img.png" /><br />
在批量梯度下降算法还没有完成一次迭代时,随机梯度下降算法便已经走出了很远。但 SGD 不是每一步都是朝着” 正确” 的方向迈出的。因此虽然会逐渐走向全局最小值的位置,但可能无法到达最小值点,而是在附近徘徊。不过很多时候这已经足够了。<br />
<img data-src="/pic/wuenda/daguimojiqixuexi-05.png" alt="img.png" /></p>
<h1 id="小批量梯度下降-mini-batch-gradient-descent"><a class="anchor" href="#小批量梯度下降-mini-batch-gradient-descent">#</a> 小批量梯度下降 Mini-Batch Gradient Descent</h1>
<p>小批量梯度下降算法,介于批量梯度下降算法和随机梯度下降算法之间,每计算常数 b 次训练实例,更新一次参数 θ 。<br />
<img data-src="/pic/wuenda/daguimojiqixuexi-06.png" alt="img.png" /><br />
通常会令 b 在 2-100 之间。小批量梯度下降的好处在于可以用向量化的方式来循环 b 个训练实例,如果用的线性代数函数库能支持平行处理,那算法的总体表现将与随机梯度下降近似。<br />
<img data-src="/pic/wuenda/daguimojiqixuexi-07.png" alt="img.png" /></p>
<h1 id="随机梯度下降算法的收敛-stochastic-gradient-descent-convergence"><a class="anchor" href="#随机梯度下降算法的收敛-stochastic-gradient-descent-convergence">#</a> 随机梯度下降算法的收敛 Stochastic Gradient Descent Convergence</h1>
<p>在批量梯度下降中,可以令代价函数 J 为迭代次数的函数,绘制图表判断梯度下降是否收敛。但是,在大规模的训练集下不现实,因为计算代价太大。<br />
当数据集很大时使用随机梯度下降算法,这时为了检查随机梯度下降的收敛性,我们在每 1000 次迭代运算后,对最后 1000 个样本的 cost 值求一次平均,将这个平均值画到图中。<br />
<img data-src="/pic/wuenda/daguimojiqixuexi-08.png" alt="img.png" /><br />
下面是可能得到的几种图像:<br />
<img data-src="/pic/wuenda/daguimojiqixuexi-09.png" alt="img.png" /><br />
图 1:红色线的学习率比蓝色线要小,因此收敛的慢,最后收敛的更好一些。<br />
图 2:红线通过对 5000 次迭代求平均,而不是 1000 个,得到更加平滑的曲线。<br />
图 3:蓝线颠簸不平而且没有明显减少。可以增大 α 来使得函数更加平缓,也许能使其像红线一样下降;或者可能仍像粉线一样颠簸不平且不下降,说明模型本身可能存在一些错误。<br />
图 4:如果曲线正在上升,说明算法发散。应该把学习速率 α 的值减小。</p>
<p>还可以令学习率随着迭代次数的增加而减小,例如令:<br />
<img data-src="/pic/wuenda/daguimojiqixuexi-10.png" alt="img.png" /><br />
这样,随着不断地靠近全局最小值,学习率会越来越小,迫使算法收敛而非在最小值附近徘徊。<br />
<img data-src="/pic/wuenda/daguimojiqixuexi-11.png" alt="img.png" /><br />
但是通常不需要这样做便能有非常好的效果,对 α 进行调整所耗费的计算通常不值得。</p>
<h1 id="在线学习-online-learning"><a class="anchor" href="#在线学习-online-learning">#</a> 在线学习 Online Learning</h1>
<p>有一种大规模的机器学习机制,叫做在线学习机制。让我们可以模型化问题。它指的是针对数据流,而非针对离线静态数据集进行学习。例如,许多在线网站都有持续不断的用户流,对于每一个用户,网站希望能不将数据存储到数据库中,便顺利地进行算法学习。</p>
<p>在线学习的算法与随机梯度下降算法有些类似,只对单一的实例进行学习,而非对一个提前定义的训练集进行循环:<br />
Repeat forever (as long as the website is running) {<br />
Get (x, y) corresponding to the current user<br />
θ: = θj − α(hθ(x) − y)xj<br />
(for j = 0: n)<br />
}<br />
一旦对一个数据的学习完成,便可以丢弃它,不需要再存储。这样的好处在于可以针对用户当前行为,不断更新模型以适应该用户。慢慢地调试学习到的假设,将其调节更新到最新的用户行为。<br />
<img data-src="/pic/wuenda/daguimojiqixuexi-12.png" alt="img.png" /></p>
<h1 id="映射化简和数据并行-map-reduce-and-data-parallelism"><a class="anchor" href="#映射化简和数据并行-map-reduce-and-data-parallelism">#</a> 映射化简和数据并行 Map Reduce and Data Parallelism</h1>
<p>映射化简和数据并行对于大规模机器学习问题而言非常重要。之前提到,批量梯度下降算法计算代价非常大。如果能将数据集分配给多台计算机,让每一台计算机处理数据集的一个子集,然后将结果汇总求和,这样的方法叫做映射简化。</p>
<p>例如有 400 个训练实例,可以将批量梯度下降的求和任务分配给 4 台计算机进行处理:<br />
<img data-src="/pic/wuenda/daguimojiqixuexi-13.png" alt="img.png" /><br />
<img data-src="/pic/wuenda/daguimojiqixuexi-14.png" alt="img.png" /><br />
如果任何学习算法能够表达为对训练集函数的求和,那么便能将这个任务分配给多台计算机 (或者同一台计算机的不同 CPU 核心),以达到加速处理的目的。例如逻辑回归:<br />
<img data-src="/pic/wuenda/daguimojiqixuexi-15.png" alt="img.png" /><br />
很多高级的线性代数函数库能够利用多核 CPU 的来并行地处理矩阵运算,这也是算法的向量化实现如此重要的缘故 (比调用循环快)。<br />
<img data-src="/pic/wuenda/daguimojiqixuexi-16.png" alt="img.png" /></p>
]]></description>
</item>
<item>
<guid isPermalink="true">https://love.youhuamao.xyz/2022/11/28/ai/Andrew%20Ng%20Lesson/%E6%8E%A8%E8%8D%90%E7%B3%BB%E7%BB%9F/</guid>
<title>推荐系统</title>
<link>https://love.youhuamao.xyz/2022/11/28/ai/Andrew%20Ng%20Lesson/%E6%8E%A8%E8%8D%90%E7%B3%BB%E7%BB%9F/</link>
<category term="ai" scheme="https://love.youhuamao.xyz/categories/ai/" />
<category term="Andrew Ng Lesson" scheme="https://love.youhuamao.xyz/categories/ai/Andrew-Ng-Lesson/" />
<category term="ai lesson" scheme="https://love.youhuamao.xyz/tags/ai-lesson/" />
<pubDate>Mon, 28 Nov 2022 00:00:00 +0800</pubDate>
<description><![CDATA[ <h1 id="问题形式化-problem-formulation"><a class="anchor" href="#问题形式化-problem-formulation">#</a> 问题形式化 Problem Formulation</h1>
<p>在机器学习领域,对于一些问题存在一些算法, 能试图自动地替你学习到一组优良的特征。通过推荐系统 (recommender systems),将领略一小部分特征学习的思想。</p>
<p>假使有 5 部电影,3 部爱情片、2 部动作片。 4 个用户为其中的部分电影打了分。现在希望构建一个算法,预测每个人可能给没看过的电影打多少分,以此作为推荐的依据。<br />
<img data-src="/pic/wuenda/tuijianxitong-01.png" alt="img.png" /><br />
下面引入一些标记:<br />
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>n</mi><mi>u</mi></msub></mrow><annotation encoding="application/x-tex">n_{u}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">u</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> 代表用户的数量<br />
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>n</mi><mi>m</mi></msub></mrow><annotation encoding="application/x-tex">n_{m}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">m</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> 代表电影的数量<br />
r (i,j) 如果用户 j 给电影 i 评过分则 r (i, j) = 1<br />
y (i,j) 代表用户 j 给电影 i 的评分 (注:这里 i 和 j 不要搞反)<br />
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>m</mi><mi>j</mi></msub></mrow><annotation encoding="application/x-tex">m_{j}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.716668em;vertical-align:-0.286108em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.311664em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span></span></span></span> 代表用户 j 评过分的电影的总数</p>
<h1 id="基于内容的推荐系统-content-based-recommendations"><a class="anchor" href="#基于内容的推荐系统-content-based-recommendations">#</a> 基于内容的推荐系统 Content Based Recommendations</h1>
<h2 id="定义"><a class="anchor" href="#定义">#</a> 定义</h2>
<p (i)="">在一个基于内容的推荐系统算法中,假设对于我们希望推荐的东西有一些数据,是这些东西的特征。现在假设每部电影都有两个特征, x1 代表电影的浪漫程度,x2 代表电影的动作程度。<br />
<img data-src="/pic/wuenda/tuijianxitong-02.png" alt="img.png" /><br />
则每部电影都有一个特征向量,如 x (1) 是第一部电影的特征向量,为 [0.9 0]。<br />
下面我们采用线性回归模型,针对每一个用户都训练一个线性回归模型,如 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>θ</mi><mrow><mo stretchy="false">(</mo><mn>1</mn><mo stretchy="false">)</mo></mrow></msup></mrow><annotation encoding="application/x-tex">θ^{(1)}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8879999999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.02778em;">θ</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mtight">1</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span></span> 是第一个用户的模型的参数。 于是有:<br />
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>θ</mi><mrow><mo stretchy="false">(</mo><mi>j</mi><mo stretchy="false">)</mo></mrow></msup></mrow><annotation encoding="application/x-tex">θ^{(j)}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8879999999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.02778em;">θ</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span></span> 用户 j 的参数向量<br />
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup></mrow><annotation encoding="application/x-tex">x^{(i)}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8879999999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span></span> 电影 i 的特征向量<br />
对于用户 j 和电影 i,我们预测其评分为:(θ^{(j)})^{T}x^</p>
<h2 id="代价函数"><a class="anchor" href="#代价函数">#</a> 代价函数</h2>
<p>针对用户 j,该线性回归模型的代价为预测误差的平方和,加上正则化项:<br />
<img data-src="/pic/wuenda/tuijianxitong-03.png" alt="img.png" /><br />
其中 i: r (i, j) 表示我们只计算那些用户 j 评过分的电影。在一般的线性回归模型中,误差项和正则项应该都是乘以 1/2m,在这里我们将 m 去掉,且不对方差项 θ0 进行正则化处理。<br />
上面的代价函数只是针对一个用户的,为了学习所有用户,我们将所有用户的代价函数求和:<br />
<img data-src="/pic/wuenda/tuijianxitong-04.png" alt="img.png" /><br />
如果我们要用梯度下降法来求解最优解,我们计算代价函数的偏导数后得到梯度下降的更新公式为:<br />
<img data-src="/pic/wuenda/tuijianxitong-05.png" alt="img.png" /></p>
<h1 id="协同过滤-collaborative-filtering"><a class="anchor" href="#协同过滤-collaborative-filtering">#</a> 协同过滤 Collaborative Filtering</h1>
<p>在之前的基于内容的推荐系统中,使用电影的特征,训练出了每一个用户的参数。相反地,如果拥有用户的参数,可以学习得出电影的特征。<br />
<img data-src="/pic/wuenda/tuijianxitong-06.png" alt="img.png" /><br />
但是如果既没有用户的参数,也没有电影的特征,这两种方法都不可行了。可以使用协同过滤算法,同时学习这两者。<br />
<img data-src="/pic/wuenda/tuijianxitong-07.png" alt="img.png" /><br />
优化目标便改为同时针对 x 和 θ 进行。是一个:预测 θ,再反过来预测 x, 再预测 θ,再预测 x 的迭代过程。</p>
<h1 id="协同过滤算法-collaborative-filtering-algorithm"><a class="anchor" href="#协同过滤算法-collaborative-filtering-algorithm">#</a> 协同过滤算法 Collaborative Filtering Algorithm</h1>
<p>协同过滤的代价函数定义为:<br />
<img data-src="/pic/wuenda/tuijianxitong-08.png" alt="img.png" /><br />
对代价函数求偏导数:<br />
<img data-src="/pic/wuenda/tuijianxitong-09.png" alt="img.png" /><br />
(注:在协同过滤从算法中,通常不使用方差项,如果需要的话,算法会自动学得。)<br />
协同过滤算法使用步骤如下:<br />
<img data-src="/pic/wuenda/tuijianxitong-10.png" alt="img.png" /></p>
<ol>
<li>初始 x 和 θ 为一些随机小值</li>
<li>使用梯度下降算法最小化代价函数 J</li>
<li>在训练完算法后,通过计算 θTx 预测用户 j 给电影 i 的评分<br />
通过这个学习过程获得的特征矩阵包含了有关电影的重要数据,这些数据不总是人能读懂的,但是可以用这些数据作为给用户推荐电影的依据。</li>
</ol>
<p>总结:<br />
<img data-src="/pic/wuenda/tuijianxitong-11.png" alt="img.png" /></p>
<h1 id="向量化低秩矩阵分解-vectorization_-low-rank-matrix-factorization"><a class="anchor" href="#向量化低秩矩阵分解-vectorization_-low-rank-matrix-factorization">#</a> 向量化:低秩矩阵分解 Vectorization_ Low Rank Matrix Factorization</h1>
<p>协同过滤算法的向量化实现<br />
举例:<br />
1)给出一件产品,能否找到与之相关的其它产品。<br />
2)一位用户最近看上一件产品,有没有其它相关的产品可以推荐给他。</p>
<p>现在有 5 部电影,4 位用户,矩阵 Y 就是一个 5 行 4 列的矩阵,存储每个用户对每个电影的评分数据:<br />
<img data-src="/pic/wuenda/tuijianxitong-12.png" alt="img.png" /><br />
通过使用 θ 和 x 计算,可以预测出每个用户对每个电影打的分数:<br />
<img data-src="/pic/wuenda/tuijianxitong-13.png" alt="img.png" /><br />
现在将所有 x 都集中在一个大的矩阵 X 中,每一部电影是一行;</p>
<p>将所有 θ 集中在一个大的 Θ 中,每个用户是一行。<br />
<img data-src="/pic/wuenda/tuijianxitong-14.png" alt="img.png" /><br />
则有:<br />
<img data-src="/pic/wuenda/tuijianxitong-15.png" alt="img.png" /><br />
因为矩阵 X 乘 Θ 的转置,在数学上具有低秩属性。因此这个算法也被称为低秩矩阵分解 low rank matrix factorization。</p>
<p>现在已经学习到了特征参数向量,那么可以使用这些向量做一些别的事情,比如度量两部电影之间的相似性。例如,如果一位用户正在观看电影 x (i) ,可以根据两部电影的特征向量之间的距离 ∥x^(i) − x^(j)∥,寻找另一部相似电影 x^(j):<br />
<img data-src="/pic/wuenda/tuijianxitong-16.png" alt="img.png" /></p>
<h1 id="推行工作上的细节均值归一化-mean-normalization"><a class="anchor" href="#推行工作上的细节均值归一化-mean-normalization">#</a> 推行工作上的细节:均值归一化 Mean Normalization</h1>
<p>现在新增一个用户 Eve,她没有为任何电影评分,那么我们以什么为依据为 Eve 推荐电影呢?</p>
<p>如果根据之前的模型,因为她没有打分,代价函数第一项为 0。算法目标变为最小化最后一项,最后得到 θ(5) 中的元素都是 0。现在拿着 θ(5) 预测出的瓶分都是 0。这没有什么意义,因此需要做一些处理。<br />
<img data-src="/pic/wuenda/tuijianxitong-17.png" alt="img.png" /><br />
首先需要对结果 Y 矩阵进行均值归一化处理,将每一个用户对某一部电影的评分减去所有用户对该电影评分的平均值:<br />
<img data-src="/pic/wuenda/tuijianxitong-18.png" alt="img.png" /><br />
然后利用这个新的 Y 矩阵来训练算法。 最后在预测评分时,需要在预测值的基础上加回平均值,即预测值等于 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><msup><mi>θ</mi><mrow><mo stretchy="false">(</mo><mi>j</mi><mo stretchy="false">)</mo></mrow></msup><msup><mo stretchy="false">)</mo><mi>T</mi></msup><msup><mi>x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><mo>+</mo><msub><mi>μ</mi><mi>i</mi></msub></mrow><annotation encoding="application/x-tex">(θ^{(j)})^{T}x^{(i)} + μ_{i}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.138em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.02778em;">θ</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal">μ</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> 。因此对于 Eve,新模型预测出的她的打分都是该电影的平均分。</p>
]]></description>
</item>
<item>
<guid isPermalink="true">https://love.youhuamao.xyz/2022/11/26/ai/Andrew%20Ng%20Lesson/%E5%BC%82%E5%B8%B8%E6%A3%80%E6%B5%8B/</guid>
<title>异常检测</title>
<link>https://love.youhuamao.xyz/2022/11/26/ai/Andrew%20Ng%20Lesson/%E5%BC%82%E5%B8%B8%E6%A3%80%E6%B5%8B/</link>
<category term="ai" scheme="https://love.youhuamao.xyz/categories/ai/" />
<category term="Andrew Ng Lesson" scheme="https://love.youhuamao.xyz/categories/ai/Andrew-Ng-Lesson/" />
<category term="ai lesson" scheme="https://love.youhuamao.xyz/tags/ai-lesson/" />
<pubDate>Sat, 26 Nov 2022 00:00:00 +0800</pubDate>
<description><![CDATA[ <h1 id="异常检测问题的动机-problem-motivation"><a class="anchor" href="#异常检测问题的动机-problem-motivation">#</a> 异常检测问题的动机 Problem Motivation</h1>
<p>异常检测 (Anomaly detection) 问题是机器学习算法的一个常见应用。这种算法虽然主要用于无监督学习问题,但从某些角度看,它又类似于一些监督学习问题。<br />
举例: 当飞机引擎从生产线上流出时需要进行 QA (质量控制测试),数据集包含引擎的一些特征变量,比如运转时产生的热量,或者振动等。当有一个新的飞机引擎从生产线上流出,它具有特征变量 xtest 。异常检测问题就是:希望知道这个新的飞机引擎是否有某种异常。如下图:<br />
<img data-src="/pic/wuenda/yichangjiance-01.png" alt="img.png" /><br />
训练出的模型,需要能够根据 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>x</mi><mrow><mi>t</mi><mi>e</mi><mi>s</mi><mi>t</mi></mrow></msub></mrow><annotation encoding="application/x-tex">x_{test}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.2805559999999999em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">t</span><span class="mord mathnormal mtight">e</span><span class="mord mathnormal mtight">s</span><span class="mord mathnormal mtight">t</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> 的位置告诉我们其属于一组数据的可能性 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>p</mi><mrow><mo stretchy="false">(</mo><mi>x</mi><mi>t</mi><mi>e</mi><mi>s</mi><mi>t</mi><mo stretchy="false">)</mo></mrow></msub></mrow><annotation encoding="application/x-tex">p_{(xtest)}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7857599999999999em;vertical-align:-0.3551999999999999em;"></span><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.34480000000000005em;"><span style="top:-2.5198em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">x</span><span class="mord mathnormal mtight">t</span><span class="mord mathnormal mtight">e</span><span class="mord mathnormal mtight">s</span><span class="mord mathnormal mtight">t</span><span class="mclose mtight">)</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.3551999999999999em;"><span></span></span></span></span></span></span></span></span></span>。<br />
<img data-src="/pic/wuenda/yichangjiance-02.png" alt="img.png" /><br />
在上图中,蓝色圈内的数据属于该组数据的可能性较高;而越偏远,属于该组数据的可能性就越低。 这种方法称为密度估计,表达如下:<br />
<img data-src="/pic/wuenda/yichangjiance-03.png" alt="img.png" /></p>
<p>常见的异常检测问题如下:<br />
例 1:欺诈检测,通过 p (x) &lt; ε 检测非正常用户。例如在线采集而来的有关用户的数据,一个特征向量中可能会包含如:用户多久登录一次,访问过的页面,在论坛发布的帖子数量,甚至是打字速度等。根据这些特征构建一个模型,可以用来识别不符合该模式的用户。<br />
例 2:检测一个数据中心,特征可能包含:内存使用情况,被访问的磁盘数量,CPU 的负载,网络的通信量等。根据这些特征构建模型,用来判断某些计算机是否可能出错了。<br />
<img data-src="/pic/wuenda/yichangjiance-04.png" alt="img.png" /></p>
<h1 id="高斯分布-gaussian-distribution"><a class="anchor" href="#高斯分布-gaussian-distribution">#</a> 高斯分布 Gaussian Distribution</h1>
<p>高斯分布,也称为正态分布。<br />
<img data-src="/pic/wuenda/yichangjiance-05.png" alt="img.png" /><br />
通常如果变量 x 符合高斯分布 x∼N (μ, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>σ</mi><mn>2</mn></msup></mrow><annotation encoding="application/x-tex">σ^{2}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141079999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">σ</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span></span> ) 则其概率密度函数为 :<br />
<img data-src="/pic/wuenda/yichangjiance-06.png" alt="img.png" /><br />
高斯分布样例如下图(其中 μ 决定中心点的位置, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>σ</mi><mn>2</mn></msup></mrow><annotation encoding="application/x-tex">σ^{2}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141079999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">σ</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span></span> 决定曲线的高度):<br />
<img data-src="/pic/wuenda/yichangjiance-07.png" alt="img.png" /></p>
<p>通过已有数据集 x ,可以预测总体的均值 μ 和方差 σ2 ,计算方法如下:<br />
<img data-src="/pic/wuenda/yichangjiance-08.png" alt="img.png" /><br />
<img data-src="/pic/wuenda/yichangjiance-09.png" alt="img.png" /></p>
<p>注:机器学习中对于方差通常除以 m,而统计学中会除以 (m − 1)。这两个公式在理论和数学特性上稍有不同,但在实际使用中的区别几乎可以忽略不计。</p>
<h1 id="异常检测算法-algorithm"><a class="anchor" href="#异常检测算法-algorithm">#</a> 异常检测算法 Algorithm</h1>
<h2 id="密度估计"><a class="anchor" href="#密度估计">#</a> 密度估计</h2>
<p>现在我们应用高斯分布开发异常检测算法。 对于给定的数据集 x ,针对每一个特征计算均值 μ 和方差 σ2 的估计值。然后,当出现一个新的训练实例,可以根据模型计算其对应的 p (x),这个过程也叫做密度估计 (Density estimation),公式如下:<br />
<img data-src="/pic/wuenda/yichangjiance-10.png" alt="img.png" /><br />
(注:每个特征 xi 都对应不同的高斯分布)<br />
<img data-src="/pic/wuenda/yichangjiance-11.png" alt="img.png" /><br />
当 p (x) &lt; ε 时,判断为异常。</p>
<h2 id="异常检测算法"><a class="anchor" href="#异常检测算法">#</a> 异常检测算法</h2>
<p><img data-src="/pic/wuenda/yichangjiance-12.png" alt="img.png" /></p>
<h2 id="举例"><a class="anchor" href="#举例">#</a> 举例</h2>
<p>下图中的 2D 图形是一个具有两个特征的训练集及其两个特征的分布情况,3D 图形表示密度估计函数,z 轴为根据两个特征对 xtest 估计出的 p (x) 值。<br />
<img data-src="/pic/wuenda/yichangjiance-13.png" alt="img.png" /></p>
<h1 id="开发和评价一个异常检测系统"><a class="anchor" href="#开发和评价一个异常检测系统">#</a> 开发和评价一个异常检测系统</h1>
<h2 id="划分数据"><a class="anchor" href="#划分数据">#</a> 划分数据</h2>
<p>异常检测算法是一个无监督学习算法。但事实上,如果我们拥有一些带标记的数据,为了检验算法是否有效。可以在最开始将其看作一个监督学习算法。将已有数据分开,从中选择一部分正常数据作为训练集,剩下的正常数据和异常数据混合构成交叉检验集和测试集。<br />
<img data-src="/pic/wuenda/yichangjiance-14.png" alt="img.png" /></p>
<h2 id="举例-2"><a class="anchor" href="#举例-2">#</a> 举例</h2>
<p>有 10000 台正常引擎的数据,有 20 台异常引擎的数据。 我们这样分配数据:</p>
<p>6000 台正常引擎的数据作为 Training set;<br />
2000 台正常引擎和 10 台异常引擎的数据作为 CV set<br />
2000 台正常引擎和 10 台异常引擎的数据作为 Test set<br />
<img data-src="/pic/wuenda/yichangjiance-15.png" alt="img.png" /><br />
还有一些人把同样一组数据既用作 CV 集,也用作 Test 集。Andrew 不推荐这样做。</p>
<h2 id="具体的算法评估方法"><a class="anchor" href="#具体的算法评估方法">#</a> 具体的算法评估方法</h2>
<p>1) 根据测试集数据,估计特征的平均值和方差并构建 p (x) 函数<br />
2) 对 CV set,尝试使用不同的 ε 值作为阈值,并预测数据是否异常,根据 F1 值或者查准率与查全率的比例来选择 ε<br />
3) 选出 ε 后,针对 Test 集进行预测,计算异常检验系统的 F1 值,或者查准率与查全率之比<br />
<img data-src="/pic/wuenda/yichangjiance-16.png" alt="img.png" /></p>
<h1 id="异常检测与监督学习对比-anomaly-detection-vs-supervised-learning"><a class="anchor" href="#异常检测与监督学习对比-anomaly-detection-vs-supervised-learning">#</a> 异常检测与监督学习对比 Anomaly Detection vs. Supervised Learning</h1>
<p>之前构建的异常检测系统也使用了带标记的数据,与监督学习有些相似。下面对异常检测和监督学习进行对比:<br />
<img data-src="/pic/wuenda/yichangjiance-17.png" alt="img.png" /></p>
<h1 id="选择特征-choosing-what-features-to-use"><a class="anchor" href="#选择特征-choosing-what-features-to-use">#</a> 选择特征 Choosing What Features to Use</h1>
<h2 id="特征转换"><a class="anchor" href="#特征转换">#</a> 特征转换</h2>
<p>特征的选择对异常检测算法至关重要。假设特征不符合高斯分布,算法也能够工作,但最好还是将数据转换成高斯分布,例如: 使用对数函数 x = log (x + c),其中 c 为非负常数;或者 x = xc ,c 为 0-1 之间的一个分数。<br />
(注:在 python 中,通常用 np.log1p () 函数,即 log (x + 1),可以避免出现负数结果,反向函数就是 np.expm1 ())<br />
<img data-src="/pic/wuenda/yichangjiance-18.png" alt="img.png" /></p>
<h2 id="误差分析"><a class="anchor" href="#误差分析">#</a> 误差分析</h2>
<p>一些异常的数据可能也会有较高的 p (x) 值,因而被算法认为是正常的。 可以使用误差分析帮我们分析是否存在问题。也许从问题中发现需要增加一些新的特征,增加这些新特征后获得的新算法能够帮助我们更好地进行异常检测。<br />
<img data-src="/pic/wuenda/yichangjiance-19.png" alt="img.png" /></p>
<p>通常可以通过将一些相关的特征进行组合,来获得一些新的更好的特征 (异常数据的该特征值异常地大或小)。例如增加两个特征值的比例。</p>
<p>例如,在检测计算机状况的例子中,可以用 CPU 负载与网络通信量的比例作为一个新的特征,如果该值异常地大,便有可能意味着该服务器是陷入了一些问题中。如下图:<br />
<img data-src="/pic/wuenda/yichangjiance-20.png" alt="img.png" /></p>
<h1 id="多元高斯分布-multivariate-gaussian-distribution-optional"><a class="anchor" href="#多元高斯分布-multivariate-gaussian-distribution-optional">#</a> 多元高斯分布 Multivariate Gaussian Distribution (Optional)</h1>
<h2 id="多元高斯分布的定义"><a class="anchor" href="#多元高斯分布的定义">#</a> 多元高斯分布的定义</h2>
<p>假如我们有两个相关的特征,其值域范围比较宽。一般的高斯分布模型可能不能很好地识别异常数据。其原因在于,一般的高斯分布模型尝试的是去同时抓住两个特征的偏差,得到的判定边界范围比较大。<br />
例如下图中是两个相关特征,粉色的线 (根据 ε 的不同其范围可大可小) 是原始高斯分布模型获得的判定边界,绿色的 X 点很可能是异常值,但其 p (x) 值却仍然在正常范围内。</p>
<p>如果使用多元高斯分布,获得蓝色曲线所示的判定边界,范围更小,判定结果会更准确。<br />
<img data-src="/pic/wuenda/yichangjiance-21.png" alt="img.png" /></p>
<p>回顾下一般的高斯分布模型,通过分别计算每个特征对应的几率,将其累乘起来,得到 p (x)。</p>
<p>而多元高斯分布模型将构建特征的协方差矩阵,使用所有的特征一次性计算出 p (x)。 首先,计算所有特征的平均值,然后再计算协方差矩阵:<br />
<img data-src="/pic/wuenda/yichangjiance-22.png" alt="img.png" /></p>
<p>其中: μ 是一个向量,其每一个单元都是原特征矩阵中一行数据的均值。<br />
最后我们计算多元高斯分布的 p (x):<br />
<img data-src="/pic/wuenda/yichangjiance-23.png" alt="img.png" /><br />
其中: |Σ| 是矩阵的行列式,在 Matlab 中用 det (sigma) 计算; Σ-1 是逆矩阵。</p>
<h2 id="协方差矩阵对模型的影响"><a class="anchor" href="#协方差矩阵对模型的影响">#</a> 协方差矩阵对模型的影响</h2>
<p>协方差对角线上的值影响图像的平缓程度,逆对角线上的值影响图像的角度(正值为顺时针旋转 45 度,负值为逆时针 45 度)。<br />
<img data-src="/pic/wuenda/yichangjiance-24.png" alt="img.png" /></p>
<p>图像从左往右:<br />
a. 一般的高斯分布模型<br />
b. 令特征 1 拥有较小的偏差,同时保持特征 2 的偏差<br />
c. 令特征 2 拥有较大的偏差,同时保持特征 1 的偏差<br />
d. 在不改变两个特征的原有偏差的基础上,增加两者之间的正相关性<br />
e. 在不改变两个特征的原有偏差的基础上,增加两者之间的负相关性</p>
<h2 id="均值-μ-对中心点的影响"><a class="anchor" href="#均值-μ-对中心点的影响">#</a> 均值 µ 对中心点的影响</h2>
<p><img data-src="/pic/wuenda/yichangjiance-25.png" alt="img.png" /></p>
<h1 id="使用多元高斯分布进行异常检测"><a class="anchor" href="#使用多元高斯分布进行异常检测">#</a> 使用多元高斯分布进行异常检测</h1>
<h2 id="使用多元高斯分布来进行异常检测"><a class="anchor" href="#使用多元高斯分布来进行异常检测">#</a> 使用多元高斯分布来进行异常检测</h2>
<p>步骤:<br />
1) 计算出均值 µ 和协方差矩阵 Σ<br />
2)对新实例 x, 根据公式计算其 p (x) 的值,如果小于 ε 则异常。<br />
<img data-src="/pic/wuenda/yichangjiance-26.png" alt="img.png" /></p>
<h2 id="原始高斯分布模型-和-多元高斯分布模型"><a class="anchor" href="#原始高斯分布模型-和-多元高斯分布模型">#</a> 原始高斯分布模型 和 多元高斯分布模型</h2>
<p><img data-src="/pic/wuenda/yichangjiance-27.png" alt="img.png" /><br />
可以看出:对于一个多元高斯分布模型,如果其协方差矩阵只有正对角线上元素非零,则退化为原始高斯分布模型。<br />
<img data-src="/pic/wuenda/yichangjiance-28.png" alt="img.png" /><br />
<img data-src="/pic/wuenda/yichangjiance-29.png" alt="img.png" /><br />
原高斯分布模型被广泛使用,如果特征之间在某种程度上相互关联,可以通过构造新特征的方法来捕捉这些相关性。<br />
如果训练集不是太大,并且没有太多的特征,可以使用多元高斯分布模型。</p>
]]></description>
</item>
<item>
<guid isPermalink="true">https://love.youhuamao.xyz/2022/11/22/Java/SSM/Spring/AOP/</guid>
<title>AOP</title>
<link>https://love.youhuamao.xyz/2022/11/22/Java/SSM/Spring/AOP/</link>
<category term="学习Java" scheme="https://love.youhuamao.xyz/categories/Java/" />
<category term="Java基础" scheme="https://love.youhuamao.xyz/categories/Java/Java%E5%9F%BA%E7%A1%80/" />
<category term="java" scheme="https://love.youhuamao.xyz/tags/java/" />
<pubDate>Tue, 22 Nov 2022 00:00:00 +0800</pubDate>
<description><![CDATA[ <h1 id="什么是aop"><a class="anchor" href="#什么是aop">#</a> 什么是 AOP</h1>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>AOP <span class="token punctuation">(</span>Aspect Oriented Programming<span class="token punctuation">)</span>意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能</pre></td></tr><tr><td data-num="2"></td><td><pre>的统- -维护的一 种技术。AOP是OOP的延续,是软件开发中的一一个热点,也是Spring框架中的一一个重要内容,是</pre></td></tr><tr><td data-num="3"></td><td><pre>函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合</pre></td></tr><tr><td data-num="4"></td><td><pre>度降低,提高程序的可重用性,同时提高了开发的效率。</pre></td></tr></table></figure><h1 id="aop在spring中的作用"><a class="anchor" href="#aop在spring中的作用">#</a> Aop 在 Spring 中的作用</h1>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>横切关注点:跨越应用程序多个模块的方法或功能。即是,与我们业务逻辑无关的,但是我们需要关注的部分,就是横切关注点。如日志,安全,缓存,事务等等<span class="token punctuation">..</span>.</pre></td></tr><tr><td data-num="2"></td><td><pre>切面<span class="token punctuation">(</span>ASPECT<span class="token punctuation">)</span> :横切关注点被模块化的特殊对象。即,它是一-个类。</pre></td></tr><tr><td data-num="3"></td><td><pre>通知<span class="token punctuation">(</span>Advice<span class="token punctuation">)</span> :切面必须要完成的工作。即,它是类中的一-个方法。</pre></td></tr><tr><td data-num="4"></td><td><pre>目标<span class="token punctuation">(</span>Target<span class="token punctuation">)</span> :被通知对象。</pre></td></tr><tr><td data-num="5"></td><td><pre>代理<span class="token punctuation">(</span>Proxy<span class="token punctuation">)</span> :向目标对象应用通知之后创建的对象。</pre></td></tr><tr><td data-num="6"></td><td><pre>切入点<span class="token punctuation">(</span>PointCut<span class="token punctuation">)</span> :切面通知执行的“地点”的定义。</pre></td></tr><tr><td data-num="7"></td><td><pre>连接点<span class="token punctuation">(</span>JointPoint<span class="token punctuation">)</span> :与切入点匹配的执行点。</pre></td></tr><tr><td data-num="8"></td><td><pre></pre></td></tr><tr><td data-num="9"></td><td><pre></pre></td></tr><tr><td data-num="10"></td><td><pre>SpringAOP中,通过Advice定义横切逻辑,Spring中支持5种类型的Advice:</pre></td></tr><tr><td data-num="11"></td><td><pre>通知类型 连接点 实现接口</pre></td></tr><tr><td data-num="12"></td><td><pre>前置通知 方法方法前 org.springframework.aop.MethodBeforeAdvice</pre></td></tr><tr><td data-num="13"></td><td><pre>后置通知 方法后 org.springframework.aop.AfterReturningAdvice</pre></td></tr><tr><td data-num="14"></td><td><pre>环绕通知 方法前后 org.aopalliance.intercept.MethodInterceptor</pre></td></tr><tr><td data-num="15"></td><td><pre>异常抛出通知 方法抛出异常 org.springframework.aop.ThrowsAdvice</pre></td></tr><tr><td data-num="16"></td><td><pre>引介通知 类中增加新的方 org.springframework.aop.IntroductionInterceptor</pre></td></tr><tr><td data-num="17"></td><td><pre> 法属性</pre></td></tr></table></figure><h1 id="使用spring实现aop"><a class="anchor" href="#使用spring实现aop">#</a> 使用 Spring 实现 AOP</h1>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token punctuation">[</span>重点<span class="token punctuation">]</span>使用AOP织入,需要导入一个依赖包<span class="token operator">!</span> </pre></td></tr><tr><td data-num="2"></td><td><pre></pre></td></tr><tr><td data-num="3"></td><td><pre><span class="token operator">&lt;</span><span class="token operator">!</span>-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver --<span class="token operator">></span></pre></td></tr><tr><td data-num="4"></td><td><pre><span class="token operator">&lt;</span>dependency<span class="token operator">></span></pre></td></tr><tr><td data-num="5"></td><td><pre> <span class="token operator">&lt;</span>groupId<span class="token operator">></span>org.aspectj<span class="token operator">&lt;</span>/groupId<span class="token operator">></span></pre></td></tr><tr><td data-num="6"></td><td><pre> <span class="token operator">&lt;</span>artifactId<span class="token operator">></span>aspectjweaver<span class="token operator">&lt;</span>/artifactId<span class="token operator">></span></pre></td></tr><tr><td data-num="7"></td><td><pre> <span class="token operator">&lt;</span>version<span class="token operator">></span><span class="token number">1.9</span>.<span class="token operator"><span class="token file-descriptor important">4</span>&lt;</span>/version<span class="token operator">></span></pre></td></tr><tr><td data-num="8"></td><td><pre><span class="token operator">&lt;</span>/dependency<span class="token operator">></span></pre></td></tr></table></figure><ul>
<li>方式一:使用 Spring 的 API 接口</li>
</ul>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token operator">&lt;</span>?xml <span class="token assign-left variable">version</span><span class="token operator">=</span><span class="token string">"1.0"</span> <span class="token assign-left variable">encoding</span><span class="token operator">=</span> <span class="token string">"UTF-8"</span>?<span class="token operator">></span></pre></td></tr><tr><td data-num="2"></td><td><pre><span class="token operator">&lt;</span>beans <span class="token assign-left variable">xmlns</span><span class="token operator">=</span><span class="token string">"http://www.springframework.org/schema/beans"</span></pre></td></tr><tr><td data-num="3"></td><td><pre> xmlns:xsi<span class="token operator">=</span><span class="token string">"http://www.w3.org/2001/XMLSchema-instance"</span></pre></td></tr><tr><td data-num="4"></td><td><pre> xmlns:aop<span class="token operator">=</span><span class="token string">"http://www.springframework.org/schema/aop"</span></pre></td></tr><tr><td data-num="5"></td><td><pre> xsi:schemaLocation<span class="token operator">=</span> <span class="token string">"http://www.springframework.org/schema/beans</pre></td></tr><tr><td data-num="6"></td><td><pre> https://www.springframework.org/schema/beans/spring-beans.xsd</pre></td></tr><tr><td data-num="7"></td><td><pre> http://www.springframework.org/schema/aop</pre></td></tr><tr><td data-num="8"></td><td><pre> http://www.springframework.org/schema/aop/spring-aop.xsd"</span><span class="token operator">></span></pre></td></tr><tr><td data-num="9"></td><td><pre></pre></td></tr><tr><td data-num="10"></td><td><pre> <span class="token operator">&lt;</span><span class="token operator">!</span>--注fbean--<span class="token operator">></span></pre></td></tr><tr><td data-num="11"></td><td><pre> <span class="token operator">&lt;</span>bean <span class="token assign-left variable">id</span><span class="token operator">=</span><span class="token string">"userService"</span> <span class="token assign-left variable">class</span><span class="token operator">=</span><span class="token string">"com.kuang.service.UserServiceImpl"</span>/<span class="token operator">></span></pre></td></tr><tr><td data-num="12"></td><td><pre> <span class="token operator">&lt;</span>bean <span class="token assign-left variable">id</span><span class="token operator">=</span><span class="token string">"log"</span> <span class="token assign-left variable">class</span><span class="token operator">=</span><span class="token string">" com.kuang.log.Log"</span>/<span class="token operator">></span></pre></td></tr><tr><td data-num="13"></td><td><pre> <span class="token operator">&lt;</span>bean <span class="token assign-left variable">id</span><span class="token operator">=</span><span class="token string">"afterLog"</span> <span class="token assign-left variable">class</span><span class="token operator">=</span><span class="token string">"com.kuang.log.AfterLog"</span>/<span class="token operator">></span></pre></td></tr><tr><td data-num="14"></td><td><pre> <span class="token operator">&lt;</span><span class="token operator">!</span>--方式一: 使用原生Spring API接口--<span class="token operator">></span></pre></td></tr><tr><td data-num="15"></td><td><pre> <span class="token operator">&lt;</span><span class="token operator">!</span>--配置aop:需要导入aop的约束--<span class="token operator">></span></pre></td></tr><tr><td data-num="16"></td><td><pre> <span class="token operator">&lt;</span>aop:config<span class="token operator">></span></pre></td></tr><tr><td data-num="17"></td><td><pre> <span class="token operator">&lt;</span><span class="token operator">!</span>--切入点: expression: 表达式,execution<span class="token punctuation">(</span> 要执行的位置<span class="token operator">!</span> * ****<span class="token punctuation">)</span> --<span class="token operator">></span></pre></td></tr><tr><td data-num="18"></td><td><pre> <span class="token operator">&lt;</span>aop:pointcut <span class="token assign-left variable">id</span><span class="token operator">=</span> <span class="token string">"pointcut"</span> <span class="token assign-left variable">expression</span><span class="token operator">=</span><span class="token string">"execution(* com.kuang.service.UserServiceImpl.*(..))"</span>/<span class="token operator">></span></pre></td></tr><tr><td data-num="19"></td><td><pre> <span class="token operator">&lt;</span><span class="token operator">!</span>--执行环绕增加<span class="token operator">!</span> --<span class="token operator">></span></pre></td></tr><tr><td data-num="20"></td><td><pre> <span class="token operator">&lt;</span>aop:advisor advice-ref<span class="token operator">=</span><span class="token string">"log"</span> pointcut-ref<span class="token operator">=</span><span class="token string">"pointcut"</span>/<span class="token operator">></span></pre></td></tr><tr><td data-num="21"></td><td><pre> <span class="token operator">&lt;</span>aop:advisor advice-ref<span class="token operator">=</span><span class="token string">"afterLog"</span> pointcut-ref<span class="token operator">=</span><span class="token string">"pointcut"</span>/<span class="token operator">></span></pre></td></tr><tr><td data-num="22"></td><td><pre> <span class="token operator">&lt;</span>/aop:config<span class="token operator">></span></pre></td></tr><tr><td data-num="23"></td><td><pre></pre></td></tr><tr><td data-num="24"></td><td><pre></pre></td></tr><tr><td data-num="25"></td><td><pre><span class="token operator">&lt;</span>/beans<span class="token operator">></span></pre></td></tr><tr><td data-num="26"></td><td><pre></pre></td></tr><tr><td data-num="27"></td><td><pre></pre></td></tr><tr><td data-num="28"></td><td><pre></pre></td></tr><tr><td data-num="29"></td><td><pre>package com.kuang.log<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="30"></td><td><pre></pre></td></tr><tr><td data-num="31"></td><td><pre><span class="token function">import</span> org.springframework.aop.AfterReturningAdvice<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="32"></td><td><pre></pre></td></tr><tr><td data-num="33"></td><td><pre><span class="token function">import</span> java.lang.reflect.Method<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="34"></td><td><pre></pre></td></tr><tr><td data-num="35"></td><td><pre>public class AfterLog implements AfterReturningAdvice <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="36"></td><td><pre> //returnValue:返回值</pre></td></tr><tr><td data-num="37"></td><td><pre> @Override</pre></td></tr><tr><td data-num="38"></td><td><pre> public void afterReturning<span class="token punctuation">(</span>Object returnValue, Method method, Object<span class="token punctuation">[</span><span class="token punctuation">]</span> objects, Object target<span class="token punctuation">)</span> throws Throwable <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="39"></td><td><pre> System.out.println<span class="token punctuation">(</span><span class="token string">"执行了"</span>+method.getName<span class="token punctuation">(</span><span class="token punctuation">)</span>+<span class="token string">"方法,返回结果为"</span>+returnValue<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="40"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="41"></td><td><pre><span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="42"></td><td><pre></pre></td></tr><tr><td data-num="43"></td><td><pre></pre></td></tr><tr><td data-num="44"></td><td><pre></pre></td></tr><tr><td data-num="45"></td><td><pre>package com.kuang.log<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="46"></td><td><pre></pre></td></tr><tr><td data-num="47"></td><td><pre><span class="token function">import</span> org.springframework.aop.MethodBeforeAdvice<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="48"></td><td><pre></pre></td></tr><tr><td data-num="49"></td><td><pre><span class="token function">import</span> java.lang.reflect.Method<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="50"></td><td><pre></pre></td></tr><tr><td data-num="51"></td><td><pre>public class Log implements MethodBeforeAdvice <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="52"></td><td><pre> //method:要执 行的目标对象的方法</pre></td></tr><tr><td data-num="53"></td><td><pre> //args:参数</pre></td></tr><tr><td data-num="54"></td><td><pre> //target:目标对象</pre></td></tr><tr><td data-num="55"></td><td><pre></pre></td></tr><tr><td data-num="56"></td><td><pre> @Override</pre></td></tr><tr><td data-num="57"></td><td><pre> public void before<span class="token punctuation">(</span>Method method, Object<span class="token punctuation">[</span><span class="token punctuation">]</span> objects, Object targrt<span class="token punctuation">)</span> throws Throwable <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="58"></td><td><pre> System.out.println<span class="token punctuation">(</span>targrt.getClass<span class="token punctuation">(</span><span class="token punctuation">)</span>.getName<span class="token punctuation">(</span><span class="token punctuation">)</span>+<span class="token string">"的"</span>+method.getName<span class="token punctuation">(</span><span class="token punctuation">)</span>+<span class="token string">"被执行了"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="59"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="60"></td><td><pre><span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="61"></td><td><pre></pre></td></tr><tr><td data-num="62"></td><td><pre></pre></td></tr><tr><td data-num="63"></td><td><pre>package com.kuang.service<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="64"></td><td><pre></pre></td></tr><tr><td data-num="65"></td><td><pre>public interface UserService <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="66"></td><td><pre> public void add<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="67"></td><td><pre> public void delete<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="68"></td><td><pre> public void update<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="69"></td><td><pre> public void select<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="70"></td><td><pre><span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="71"></td><td><pre></pre></td></tr><tr><td data-num="72"></td><td><pre></pre></td></tr><tr><td data-num="73"></td><td><pre></pre></td></tr><tr><td data-num="74"></td><td><pre>package com.kuang.service<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="75"></td><td><pre></pre></td></tr><tr><td data-num="76"></td><td><pre>public class UserServiceImpl implements UserService<span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="77"></td><td><pre> @Override</pre></td></tr><tr><td data-num="78"></td><td><pre> public void <span class="token function-name function">add</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="79"></td><td><pre> System.out.println<span class="token punctuation">(</span><span class="token string">"增加了一个用户"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="80"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="81"></td><td><pre></pre></td></tr><tr><td data-num="82"></td><td><pre> @Override</pre></td></tr><tr><td data-num="83"></td><td><pre> public void <span class="token function-name function">delete</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="84"></td><td><pre> System.out.println<span class="token punctuation">(</span><span class="token string">"删除了一个用户"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="85"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="86"></td><td><pre></pre></td></tr><tr><td data-num="87"></td><td><pre> @Override</pre></td></tr><tr><td data-num="88"></td><td><pre> public void <span class="token function-name function">update</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="89"></td><td><pre> System.out.println<span class="token punctuation">(</span><span class="token string">"更新了一个用户"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="90"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="91"></td><td><pre></pre></td></tr><tr><td data-num="92"></td><td><pre> @Override</pre></td></tr><tr><td data-num="93"></td><td><pre> public void <span class="token function-name function">select</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="94"></td><td><pre> System.out.println<span class="token punctuation">(</span><span class="token string">"查询了一个用户"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="95"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="96"></td><td><pre><span class="token punctuation">&#125;</span></pre></td></tr></table></figure><ul>
<li>方式二:自定义来实现 AOP</li>
</ul>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token operator">&lt;</span><span class="token operator">!</span>--方式二:自定义类--<span class="token operator">></span></pre></td></tr><tr><td data-num="2"></td><td><pre> <span class="token operator">&lt;</span>bean <span class="token assign-left variable">id</span><span class="token operator">=</span><span class="token string">"diy"</span> <span class="token assign-left variable">class</span><span class="token operator">=</span><span class="token string">"com.kuang.diy.DiyPointCut"</span>/<span class="token operator">></span></pre></td></tr><tr><td data-num="3"></td><td><pre> <span class="token operator">&lt;</span>aop:config<span class="token operator">></span></pre></td></tr><tr><td data-num="4"></td><td><pre> <span class="token operator">&lt;</span><span class="token operator">!</span>--自定义切面, ref 要引用的类--<span class="token operator">></span></pre></td></tr><tr><td data-num="5"></td><td><pre> <span class="token operator">&lt;</span>aop:aspect <span class="token assign-left variable">ref</span><span class="token operator">=</span><span class="token string">"diy"</span><span class="token operator">></span></pre></td></tr><tr><td data-num="6"></td><td><pre> <span class="token operator">&lt;</span><span class="token operator">!</span>--切入点--<span class="token operator">></span></pre></td></tr><tr><td data-num="7"></td><td><pre> <span class="token operator">&lt;</span>aop:pointcut <span class="token assign-left variable">id</span><span class="token operator">=</span><span class="token string">"point"</span> <span class="token assign-left variable">expression</span><span class="token operator">=</span><span class="token string">"execution(* com.kuang.service.UserServiceImpl.*(..))"</span>/<span class="token operator">></span></pre></td></tr><tr><td data-num="8"></td><td><pre> <span class="token operator">&lt;</span><span class="token operator">!</span>--通知--<span class="token operator">></span></pre></td></tr><tr><td data-num="9"></td><td><pre> <span class="token operator">&lt;</span>aop:before <span class="token assign-left variable">method</span><span class="token operator">=</span><span class="token string">"before"</span> pointcut-ref<span class="token operator">=</span><span class="token string">"point"</span>/<span class="token operator">></span></pre></td></tr><tr><td data-num="10"></td><td><pre> <span class="token operator">&lt;</span>aop:after <span class="token assign-left variable">method</span><span class="token operator">=</span><span class="token string">"after"</span> pointcut-ref<span class="token operator">=</span><span class="token string">"point"</span>/<span class="token operator">></span></pre></td></tr><tr><td data-num="11"></td><td><pre> <span class="token operator">&lt;</span>/aop:aspect<span class="token operator">></span></pre></td></tr><tr><td data-num="12"></td><td><pre><span class="token operator">&lt;</span>/aop:config<span class="token operator">></span></pre></td></tr><tr><td data-num="13"></td><td><pre></pre></td></tr><tr><td data-num="14"></td><td><pre></pre></td></tr><tr><td data-num="15"></td><td><pre>package com.kuang.diy<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="16"></td><td><pre></pre></td></tr><tr><td data-num="17"></td><td><pre>public class DiyPointCut <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="18"></td><td><pre></pre></td></tr><tr><td data-num="19"></td><td><pre> public void <span class="token function-name function">before</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="20"></td><td><pre> System.out.println<span class="token punctuation">(</span><span class="token string">"========方法执行前"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="21"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="22"></td><td><pre></pre></td></tr><tr><td data-num="23"></td><td><pre> public void <span class="token function-name function">after</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="24"></td><td><pre> System.out.println<span class="token punctuation">(</span><span class="token string">"========方法执行后"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="25"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="26"></td><td><pre><span class="token punctuation">&#125;</span></pre></td></tr></table></figure><ul>
<li>方式三:使用注解方式实现 AOP</li>
</ul>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token operator">&lt;</span><span class="token operator">!</span>--方式三--<span class="token operator">></span></pre></td></tr><tr><td data-num="2"></td><td><pre> <span class="token operator">&lt;</span>bean <span class="token assign-left variable">id</span><span class="token operator">=</span><span class="token string">"annotationPointCut"</span> <span class="token assign-left variable">class</span><span class="token operator">=</span><span class="token string">"com.kuang.diy.AnnotationPointCut"</span>/<span class="token operator">></span></pre></td></tr><tr><td data-num="3"></td><td><pre> <span class="token operator">&lt;</span><span class="token operator">!</span>--开启注解支持 JDK<span class="token punctuation">(</span>默认proxy- target-class<span class="token operator">=</span><span class="token string">"false"</span><span class="token punctuation">)</span> cglib <span class="token punctuation">(</span>proxy- target-class<span class="token operator">=</span><span class="token string">"true"</span><span class="token punctuation">)</span>--<span class="token operator">></span></pre></td></tr><tr><td data-num="4"></td><td><pre> <span class="token operator">&lt;</span>aop:aspectj-autoproxy/<span class="token operator">></span></pre></td></tr><tr><td data-num="5"></td><td><pre></pre></td></tr><tr><td data-num="6"></td><td><pre></pre></td></tr><tr><td data-num="7"></td><td><pre></pre></td></tr><tr><td data-num="8"></td><td><pre>package com.kuang.diy<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="9"></td><td><pre></pre></td></tr><tr><td data-num="10"></td><td><pre><span class="token function">import</span> org.aspectj.lang.ProceedingJoinPoint<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="11"></td><td><pre><span class="token function">import</span> org.aspectj.lang.Signature<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="12"></td><td><pre><span class="token function">import</span> org.aspectj.lang.annotation.After<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="13"></td><td><pre><span class="token function">import</span> org.aspectj.lang.annotation.Around<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="14"></td><td><pre><span class="token function">import</span> org.aspectj.lang.annotation.Aspect<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="15"></td><td><pre><span class="token function">import</span> org.aspectj.lang.annotation.Before<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="16"></td><td><pre></pre></td></tr><tr><td data-num="17"></td><td><pre>@Aspect//标注这个类是一个切面</pre></td></tr><tr><td data-num="18"></td><td><pre>public class AnnotationPointCut <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="19"></td><td><pre> @Before<span class="token punctuation">(</span><span class="token string">"execution(* com.kuang.service.UserServiceImpl.*(..))"</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="20"></td><td><pre> public void <span class="token function-name function">before</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="21"></td><td><pre> System.out.println<span class="token punctuation">(</span><span class="token string">"=====方法执行前===="</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="22"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="23"></td><td><pre></pre></td></tr><tr><td data-num="24"></td><td><pre> @After<span class="token punctuation">(</span><span class="token string">"execution(* com.kuang.service.UserServiceImpl.*(..))"</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="25"></td><td><pre> public void <span class="token function-name function">after</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="26"></td><td><pre> System.out.println<span class="token punctuation">(</span><span class="token string">"==方法执行后"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="27"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="28"></td><td><pre></pre></td></tr><tr><td data-num="29"></td><td><pre> @Around<span class="token punctuation">(</span><span class="token string">"execution(* com.kuang.service.UserServiceImpl.*(..))"</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="30"></td><td><pre> public void around<span class="token punctuation">(</span>ProceedingJoinPoint jp<span class="token punctuation">)</span> throws Throwable<span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="31"></td><td><pre> System.out.println<span class="token punctuation">(</span><span class="token string">"环绕前"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="32"></td><td><pre></pre></td></tr><tr><td data-num="33"></td><td><pre> Signature signature <span class="token operator">=</span> jp.getSignature<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>//获得签名</pre></td></tr><tr><td data-num="34"></td><td><pre> System.out.println<span class="token punctuation">(</span><span class="token string">"signature"</span>+signature<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="35"></td><td><pre> //执行方法</pre></td></tr><tr><td data-num="36"></td><td><pre></pre></td></tr><tr><td data-num="37"></td><td><pre> Object proceed <span class="token operator">=</span> jp.proceed<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="38"></td><td><pre></pre></td></tr><tr><td data-num="39"></td><td><pre> System.out.println<span class="token punctuation">(</span><span class="token string">"环绕后"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="40"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="41"></td><td><pre><span class="token punctuation">&#125;</span></pre></td></tr></table></figure> ]]></description>
</item>
<item>
<guid isPermalink="true">https://love.youhuamao.xyz/2022/11/22/Java/SSM/Spring/%E5%A3%B0%E5%90%8D%E5%BC%8F%E4%BA%8B%E5%8A%A1/</guid>
<title>声名式事务</title>
<link>https://love.youhuamao.xyz/2022/11/22/Java/SSM/Spring/%E5%A3%B0%E5%90%8D%E5%BC%8F%E4%BA%8B%E5%8A%A1/</link>
<category term="学习Java" scheme="https://love.youhuamao.xyz/categories/Java/" />
<category term="Java基础" scheme="https://love.youhuamao.xyz/categories/Java/Java%E5%9F%BA%E7%A1%80/" />
<category term="java" scheme="https://love.youhuamao.xyz/tags/java/" />
<pubDate>Tue, 22 Nov 2022 00:00:00 +0800</pubDate>
<description><![CDATA[ <h1 id="回顾事务"><a class="anchor" href="#回顾事务">#</a> 回顾事务</h1>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>●把一组业务当成一个业务来做<span class="token punctuation">;</span>要么都成功,要么都失败<span class="token operator">!</span></pre></td></tr><tr><td data-num="2"></td><td><pre>●事务在项目开发中,十分的重要,涉及到数据的一致性问题,不能马虎<span class="token operator">!</span></pre></td></tr><tr><td data-num="3"></td><td><pre>●确保完整性和一致性<span class="token punctuation">;</span></pre></td></tr></table></figure><ul>
<li>事务 ACID 原则:</li>
</ul>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>●原子性</pre></td></tr><tr><td data-num="2"></td><td><pre>●一致性</pre></td></tr><tr><td data-num="3"></td><td><pre>●隔离性</pre></td></tr><tr><td data-num="4"></td><td><pre>。多个业务可能操作同- -个资源,防止数据损坏</pre></td></tr><tr><td data-num="5"></td><td><pre>●持久性</pre></td></tr><tr><td data-num="6"></td><td><pre>。事务一旦提交,无论系统发生什么问题,结果都不会再被影响,被持久化的写到存储器中<span class="token operator">!</span></pre></td></tr></table></figure><h1 id="spring中的事务管理"><a class="anchor" href="#spring中的事务管理">#</a> spring 中的事务管理</h1>
<ul>
<li>
<p>声明式事务: AOP</p>
</li>
<li>
<p>编程式事务:需要再代码中,进行事务的管理</p>
</li>
<li>
<p>思考:<br />
为什么需要事务?<br />
●如果不配置事务,可能存在数据提交不一致的情况下;<br />
●如果我们不在 SPRING 中去配置声明式事务,我们就需要在代码中手动配置事务!<br />
●事务在项目的开发中十分重要,设计到数据的一致性和完整性问题,不容马虎!</p>
</li>
</ul>
]]></description>
</item>
<item>
<guid isPermalink="true">https://love.youhuamao.xyz/2022/11/22/Java/SSM/Spring/%E6%95%B4%E5%90%88mybatis/</guid>
<title>整合mybatis</title>
<link>https://love.youhuamao.xyz/2022/11/22/Java/SSM/Spring/%E6%95%B4%E5%90%88mybatis/</link>
<category term="学习Java" scheme="https://love.youhuamao.xyz/categories/Java/" />
<category term="Java基础" scheme="https://love.youhuamao.xyz/categories/Java/Java%E5%9F%BA%E7%A1%80/" />
<category term="java" scheme="https://love.youhuamao.xyz/tags/java/" />
<pubDate>Tue, 22 Nov 2022 00:00:00 +0800</pubDate>
<description><![CDATA[ <figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>步骤:</pre></td></tr><tr><td data-num="2"></td><td><pre>导入相关jar包</pre></td></tr><tr><td data-num="3"></td><td><pre>junit</pre></td></tr><tr><td data-num="4"></td><td><pre>mybatis</pre></td></tr><tr><td data-num="5"></td><td><pre>mysq<span class="token operator">|</span>数据库</pre></td></tr><tr><td data-num="6"></td><td><pre>spring相关的</pre></td></tr><tr><td data-num="7"></td><td><pre>aop织入</pre></td></tr><tr><td data-num="8"></td><td><pre>mybatis-spring <span class="token punctuation">[</span>new<span class="token punctuation">]</span></pre></td></tr><tr><td data-num="9"></td><td><pre><span class="token number">2</span>.编写配置文件</pre></td></tr><tr><td data-num="10"></td><td><pre><span class="token number">3</span>.测试</pre></td></tr></table></figure><h1 id="整合mybatis方式一"><a class="anchor" href="#整合mybatis方式一">#</a> 整合 mybatis 方式一</h1>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>package com.kuang.mapper<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="2"></td><td><pre></pre></td></tr><tr><td data-num="3"></td><td><pre><span class="token function">import</span> com.kuang.pojo.User<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="4"></td><td><pre></pre></td></tr><tr><td data-num="5"></td><td><pre><span class="token function">import</span> java.util.List<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="6"></td><td><pre></pre></td></tr><tr><td data-num="7"></td><td><pre>public interface UserMapper <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="8"></td><td><pre> public List<span class="token operator">&lt;</span>User<span class="token operator">></span> selectUser<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="9"></td><td><pre><span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="10"></td><td><pre></pre></td></tr><tr><td data-num="11"></td><td><pre></pre></td></tr><tr><td data-num="12"></td><td><pre></pre></td></tr><tr><td data-num="13"></td><td><pre></pre></td></tr><tr><td data-num="14"></td><td><pre><span class="token operator">&lt;</span>?xml <span class="token assign-left variable">version</span><span class="token operator">=</span><span class="token string">"1.0"</span> <span class="token assign-left variable">encoding</span><span class="token operator">=</span><span class="token string">"UTF-8"</span> ?<span class="token operator">></span></pre></td></tr><tr><td data-num="15"></td><td><pre><span class="token operator">&lt;</span><span class="token operator">!</span>DOCTYPE mapper</pre></td></tr><tr><td data-num="16"></td><td><pre> PUBLIC <span class="token string">"-//mybatis.org//DTD Config 3.0//EN"</span></pre></td></tr><tr><td data-num="17"></td><td><pre> <span class="token string">"https://mybatis.org/dtd/mybatis-3-mapper.dtd"</span><span class="token operator">></span></pre></td></tr><tr><td data-num="18"></td><td><pre><span class="token operator">&lt;</span>mapper <span class="token assign-left variable">namespace</span><span class="token operator">=</span><span class="token string">"com.kuang.mapper.UserMapper"</span><span class="token operator">></span></pre></td></tr><tr><td data-num="19"></td><td><pre> <span class="token operator">&lt;</span>select <span class="token assign-left variable">id</span><span class="token operator">=</span><span class="token string">"selectUser"</span> <span class="token assign-left variable">resultType</span><span class="token operator">=</span><span class="token string">"user"</span><span class="token operator">></span></pre></td></tr><tr><td data-num="20"></td><td><pre> <span class="token keyword">select</span> * from mybatis.user<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="21"></td><td><pre> <span class="token operator">&lt;</span>/select<span class="token operator">></span></pre></td></tr><tr><td data-num="22"></td><td><pre><span class="token operator">&lt;</span>/mapper<span class="token operator">></span></pre></td></tr><tr><td data-num="23"></td><td><pre></pre></td></tr><tr><td data-num="24"></td><td><pre></pre></td></tr><tr><td data-num="25"></td><td><pre></pre></td></tr><tr><td data-num="26"></td><td><pre>package com.kuang.pojo<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="27"></td><td><pre></pre></td></tr><tr><td data-num="28"></td><td><pre><span class="token function">import</span> lombok.Data<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="29"></td><td><pre></pre></td></tr><tr><td data-num="30"></td><td><pre>@Data</pre></td></tr><tr><td data-num="31"></td><td><pre>public class User <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="32"></td><td><pre> private int <span class="token function">id</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="33"></td><td><pre> private String name<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="34"></td><td><pre> private String <span class="token builtin class-name">pwd</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="35"></td><td><pre><span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="36"></td><td><pre></pre></td></tr><tr><td data-num="37"></td><td><pre></pre></td></tr><tr><td data-num="38"></td><td><pre></pre></td></tr><tr><td data-num="39"></td><td><pre>package com.kuang.mapper<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="40"></td><td><pre></pre></td></tr><tr><td data-num="41"></td><td><pre><span class="token function">import</span> com.kuang.pojo.User<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="42"></td><td><pre><span class="token function">import</span> org.mybatis.spring.SqlSessionTemplate<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="43"></td><td><pre></pre></td></tr><tr><td data-num="44"></td><td><pre><span class="token function">import</span> java.util.List<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="45"></td><td><pre></pre></td></tr><tr><td data-num="46"></td><td><pre>public class UserMapperImpl implements UserMapper<span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="47"></td><td><pre></pre></td></tr><tr><td data-num="48"></td><td><pre> private SqlSessionTemplate sqlSession<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="49"></td><td><pre></pre></td></tr><tr><td data-num="50"></td><td><pre> public List<span class="token operator">&lt;</span>User<span class="token operator">></span> <span class="token function-name function">selectUser</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="51"></td><td><pre> UserMapper mapper <span class="token operator">=</span> sqlSession.getMapper<span class="token punctuation">(</span>UserMapper.class<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="52"></td><td><pre> <span class="token builtin class-name">return</span> mapper.selectUser<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="53"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="54"></td><td><pre></pre></td></tr><tr><td data-num="55"></td><td><pre> public void setSqlSession<span class="token punctuation">(</span>SqlSessionTemplate sqlSession<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="56"></td><td><pre> this.sqlSession <span class="token operator">=</span> sqlSession<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="57"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="58"></td><td><pre><span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="59"></td><td><pre></pre></td></tr><tr><td data-num="60"></td><td><pre></pre></td></tr><tr><td data-num="61"></td><td><pre><span class="token operator">&lt;</span>?xml <span class="token assign-left variable">version</span><span class="token operator">=</span><span class="token string">"1.0"</span> <span class="token assign-left variable">encoding</span><span class="token operator">=</span> <span class="token string">"UTF-8"</span>?<span class="token operator">></span></pre></td></tr><tr><td data-num="62"></td><td><pre><span class="token operator">&lt;</span>beans <span class="token assign-left variable">xmlns</span><span class="token operator">=</span><span class="token string">"http://www.springframework.org/schema/beans"</span></pre></td></tr><tr><td data-num="63"></td><td><pre> xmlns:xsi<span class="token operator">=</span><span class="token string">"http://www.w3.org/2001/XMLSchema-instance"</span></pre></td></tr><tr><td data-num="64"></td><td><pre> xmlns:aop<span class="token operator">=</span><span class="token string">"http://www.springframework.org/schema/aop"</span></pre></td></tr><tr><td data-num="65"></td><td><pre> xsi:schemaLocation<span class="token operator">=</span> <span class="token string">"http://www.springframework.org/schema/beans</pre></td></tr><tr><td data-num="66"></td><td><pre> https://www.springframework.org/schema/beans/spring-beans.xsd</pre></td></tr><tr><td data-num="67"></td><td><pre> http://www.springframework.org/schema/aop</pre></td></tr><tr><td data-num="68"></td><td><pre> http://www.springframework.org/schema/aop/spring-aop.xsd"</span><span class="token operator">></span></pre></td></tr><tr><td data-num="69"></td><td><pre><span class="token operator">&lt;</span><span class="token operator">!</span>-- DataSource:使用Spring的数据源替换Mybatis的配置c3pθ dbcp druid--<span class="token operator">></span></pre></td></tr><tr><td data-num="70"></td><td><pre><span class="token operator">&lt;</span><span class="token operator">!</span>-- 我们这里使用Spring提供的JDBC <span class="token builtin class-name">:</span> org.springframework.jdbc.datasource--<span class="token operator">></span></pre></td></tr><tr><td data-num="71"></td><td><pre></pre></td></tr><tr><td data-num="72"></td><td><pre> <span class="token operator">&lt;</span>bean <span class="token assign-left variable">id</span><span class="token operator">=</span><span class="token string">"datasource"</span> <span class="token assign-left variable">class</span><span class="token operator">=</span><span class="token string">"org.springframework.jdbc.datasource.DriverManagerDataSource"</span><span class="token operator">></span></pre></td></tr><tr><td data-num="73"></td><td><pre> <span class="token operator">&lt;</span>property <span class="token assign-left variable">name</span><span class="token operator">=</span><span class="token string">"driverClassName"</span> <span class="token assign-left variable">value</span><span class="token operator">=</span><span class="token string">"com.mysql.jdbc.Driver"</span>/<span class="token operator">></span></pre></td></tr><tr><td data-num="74"></td><td><pre> <span class="token operator">&lt;</span>property <span class="token assign-left variable">name</span><span class="token operator">=</span><span class="token string">"url"</span> <span class="token assign-left variable">value</span><span class="token operator">=</span><span class="token string">"jdbc:mysql://localhost:3306/mybatis?useSSL=false&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF-8"</span>/<span class="token operator">></span></pre></td></tr><tr><td data-num="75"></td><td><pre> <span class="token operator">&lt;</span>property <span class="token assign-left variable">name</span><span class="token operator">=</span><span class="token string">"username"</span> <span class="token assign-left variable">value</span><span class="token operator">=</span><span class="token string">"root"</span>/<span class="token operator">></span></pre></td></tr><tr><td data-num="76"></td><td><pre> <span class="token operator">&lt;</span>property <span class="token assign-left variable">name</span><span class="token operator">=</span><span class="token string">"password"</span> <span class="token assign-left variable">value</span><span class="token operator">=</span><span class="token string">"g123698745"</span>/<span class="token operator">></span></pre></td></tr><tr><td data-num="77"></td><td><pre> <span class="token operator">&lt;</span>/bean<span class="token operator">></span></pre></td></tr><tr><td data-num="78"></td><td><pre></pre></td></tr><tr><td data-num="79"></td><td><pre> <span class="token operator">&lt;</span>bean <span class="token assign-left variable">id</span><span class="token operator">=</span><span class="token string">"sqlSessionFactory"</span> <span class="token assign-left variable">class</span><span class="token operator">=</span><span class="token string">"org.mybatis.spring.SqlSessionFactoryBean"</span><span class="token operator">></span></pre></td></tr><tr><td data-num="80"></td><td><pre> <span class="token operator">&lt;</span>property <span class="token assign-left variable">name</span><span class="token operator">=</span><span class="token string">"dataSource"</span> <span class="token assign-left variable">ref</span><span class="token operator">=</span><span class="token string">"datasource"</span> /<span class="token operator">></span></pre></td></tr><tr><td data-num="81"></td><td><pre><span class="token operator">&lt;</span><span class="token operator">!</span>-- 绑定mybatis配置文件--<span class="token operator">></span></pre></td></tr><tr><td data-num="82"></td><td><pre> <span class="token operator">&lt;</span>property <span class="token assign-left variable">name</span><span class="token operator">=</span><span class="token string">"configLocation"</span> <span class="token assign-left variable">value</span><span class="token operator">=</span><span class="token string">"classpath:mybatis-config.xml"</span>/<span class="token operator">></span></pre></td></tr><tr><td data-num="83"></td><td><pre> <span class="token operator">&lt;</span>property <span class="token assign-left variable">name</span><span class="token operator">=</span><span class="token string">"mapperLocations"</span> <span class="token assign-left variable">value</span><span class="token operator">=</span><span class="token string">"classpath:com/kuang/mapper/*.xml"</span>/<span class="token operator">></span></pre></td></tr><tr><td data-num="84"></td><td><pre> <span class="token operator">&lt;</span>/bean<span class="token operator">></span></pre></td></tr><tr><td data-num="85"></td><td><pre></pre></td></tr><tr><td data-num="86"></td><td><pre> <span class="token operator">&lt;</span><span class="token operator">!</span>--SqLSessionTemplate:就是我们使用的sqlSession--<span class="token operator">></span></pre></td></tr><tr><td data-num="87"></td><td><pre> <span class="token operator">&lt;</span>bean <span class="token assign-left variable">id</span><span class="token operator">=</span><span class="token string">"sqlSession"</span> <span class="token assign-left variable">class</span><span class="token operator">=</span><span class="token string">"org.mybatis.spring.SqlSessionTemplate"</span><span class="token operator">></span></pre></td></tr><tr><td data-num="88"></td><td><pre> <span class="token operator">&lt;</span>constructor-arg <span class="token assign-left variable">index</span><span class="token operator">=</span><span class="token string">"0"</span> <span class="token assign-left variable">ref</span><span class="token operator">=</span><span class="token string">"sqlSessionFactory"</span>/<span class="token operator">></span></pre></td></tr><tr><td data-num="89"></td><td><pre> <span class="token operator">&lt;</span>/bean<span class="token operator">></span></pre></td></tr><tr><td data-num="90"></td><td><pre></pre></td></tr><tr><td data-num="91"></td><td><pre> <span class="token operator">&lt;</span>bean <span class="token assign-left variable">id</span><span class="token operator">=</span><span class="token string">"userMapper"</span> <span class="token assign-left variable">class</span><span class="token operator">=</span><span class="token string">"com.kuang.mapper.UserMapperImpl"</span><span class="token operator">></span></pre></td></tr><tr><td data-num="92"></td><td><pre> <span class="token operator">&lt;</span>property <span class="token assign-left variable">name</span><span class="token operator">=</span><span class="token string">"sqlSession"</span> <span class="token assign-left variable">ref</span><span class="token operator">=</span><span class="token string">"sqlSession"</span>/<span class="token operator">></span></pre></td></tr><tr><td data-num="93"></td><td><pre> <span class="token operator">&lt;</span>/bean<span class="token operator">></span></pre></td></tr><tr><td data-num="94"></td><td><pre></pre></td></tr><tr><td data-num="95"></td><td><pre><span class="token operator">&lt;</span>/beans<span class="token operator">></span></pre></td></tr><tr><td data-num="96"></td><td><pre></pre></td></tr><tr><td data-num="97"></td><td><pre></pre></td></tr><tr><td data-num="98"></td><td><pre></pre></td></tr><tr><td data-num="99"></td><td><pre> <span class="token operator">&lt;</span>bean <span class="token assign-left variable">id</span><span class="token operator">=</span><span class="token string">"userMapper"</span> <span class="token assign-left variable">class</span><span class="token operator">=</span><span class="token string">"com.kuang.mapper.UserMapperImpl"</span><span class="token operator">></span></pre></td></tr><tr><td data-num="100"></td><td><pre> <span class="token operator">&lt;</span>property <span class="token assign-left variable">name</span><span class="token operator">=</span><span class="token string">"sqlSession"</span> <span class="token assign-left variable">ref</span><span class="token operator">=</span><span class="token string">"sqlSession"</span>/<span class="token operator">></span></pre></td></tr><tr><td data-num="101"></td><td><pre> <span class="token operator">&lt;</span>/bean<span class="token operator">></span></pre></td></tr></table></figure><h1 id="整合mybatis方式二"><a class="anchor" href="#整合mybatis方式二">#</a> 整合 mybatis 方式二</h1>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>package com.kuang.mapper<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="2"></td><td><pre></pre></td></tr><tr><td data-num="3"></td><td><pre><span class="token function">import</span> com.kuang.pojo.User<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="4"></td><td><pre><span class="token function">import</span> org.mybatis.spring.support.SqlSessionDaoSupport<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="5"></td><td><pre></pre></td></tr><tr><td data-num="6"></td><td><pre><span class="token function">import</span> java.util.List<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="7"></td><td><pre></pre></td></tr><tr><td data-num="8"></td><td><pre>public class UserMapperImpl2 extends SqlSessionDaoSupport implements UserMapper <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="9"></td><td><pre> @Override</pre></td></tr><tr><td data-num="10"></td><td><pre> public List<span class="token operator">&lt;</span>User<span class="token operator">></span> <span class="token function-name function">selectUser</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="11"></td><td><pre> <span class="token builtin class-name">return</span> getSqlSession<span class="token punctuation">(</span><span class="token punctuation">)</span>.getMapper<span class="token punctuation">(</span>UserMapper.class<span class="token punctuation">)</span>.selectUser<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="12"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="13"></td><td><pre><span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="14"></td><td><pre></pre></td></tr><tr><td data-num="15"></td><td><pre></pre></td></tr><tr><td data-num="16"></td><td><pre></pre></td></tr><tr><td data-num="17"></td><td><pre> <span class="token operator">&lt;</span>bean <span class="token assign-left variable">id</span><span class="token operator">=</span><span class="token string">"userMapper2"</span> <span class="token assign-left variable">class</span><span class="token operator">=</span><span class="token string">"com.kuang.mapper.UserMapperImpl2"</span><span class="token operator">></span></pre></td></tr><tr><td data-num="18"></td><td><pre> <span class="token operator">&lt;</span>property <span class="token assign-left variable">name</span><span class="token operator">=</span><span class="token string">"sqlSessionFactory"</span> <span class="token assign-left variable">ref</span><span class="token operator">=</span><span class="token string">"sqlSessionFactory"</span>/<span class="token operator">></span></pre></td></tr><tr><td data-num="19"></td><td><pre> <span class="token operator">&lt;</span>/bean<span class="token operator">></span></pre></td></tr></table></figure> ]]></description>
</item>
<item>
<guid isPermalink="true">https://love.youhuamao.xyz/2022/11/21/Java/SSM/Spring/Bean%E7%9A%84%E8%87%AA%E5%8A%A8%E8%A3%85%E9%85%8D/</guid>
<title>Bean的自动装配</title>
<link>https://love.youhuamao.xyz/2022/11/21/Java/SSM/Spring/Bean%E7%9A%84%E8%87%AA%E5%8A%A8%E8%A3%85%E9%85%8D/</link>
<category term="学习Java" scheme="https://love.youhuamao.xyz/categories/Java/" />
<category term="Java基础" scheme="https://love.youhuamao.xyz/categories/Java/Java%E5%9F%BA%E7%A1%80/" />
<category term="java" scheme="https://love.youhuamao.xyz/tags/java/" />
<pubDate>Mon, 21 Nov 2022 00:00:00 +0800</pubDate>
<description><![CDATA[ <ul>
<li>
<p>自动装配是 Spring 满足 bean 依赖一种方式!</p>
</li>
<li>
<p>Spring 会在上下文中自动寻找,并自动给 bean 装配属性!</p>
</li>
<li>
<p>在 Spring 中有三种装配的方式</p>
</li>
</ul>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token number">1</span>.在xmI中显示的配置</pre></td></tr><tr><td data-num="2"></td><td><pre><span class="token number">2</span>.在java中显示配置</pre></td></tr><tr><td data-num="3"></td><td><pre><span class="token number">3</span>.隐式的自动装配bean<span class="token punctuation">[</span>重要 <span class="token punctuation">]</span></pre></td></tr></table></figure><h1 id="byname自动装配"><a class="anchor" href="#byname自动装配">#</a> ByName 自动装配</h1>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token operator">&lt;</span>bean <span class="token assign-left variable">id</span><span class="token operator">=</span><span class="token string">"cat"</span> <span class="token assign-left variable">class</span><span class="token operator">=</span><span class="token string">" com.kuang.pojo.Cat"</span>/<span class="token operator">></span></pre></td></tr><tr><td data-num="2"></td><td><pre> <span class="token operator">&lt;</span>bean <span class="token assign-left variable">id</span><span class="token operator">=</span><span class="token string">"dog"</span> <span class="token assign-left variable">class</span><span class="token operator">=</span><span class="token string">"com.kuang.pojo.Dog"</span>/<span class="token operator">></span></pre></td></tr><tr><td data-num="3"></td><td><pre> <span class="token operator">&lt;</span><span class="token operator">!</span>--</pre></td></tr><tr><td data-num="4"></td><td><pre> byName:会自动在容器上下文中查找,和自己对象set方法后面的值对应的beanid<span class="token operator">!</span></pre></td></tr><tr><td data-num="5"></td><td><pre> byType:会自动在容器上下文中查找,和自己对象属性类型相同的bean<span class="token operator">!</span></pre></td></tr><tr><td data-num="6"></td><td><pre> --<span class="token operator">></span></pre></td></tr><tr><td data-num="7"></td><td><pre> <span class="token operator">&lt;</span>bean <span class="token assign-left variable">id</span><span class="token operator">=</span><span class="token string">"people"</span> <span class="token assign-left variable">class</span><span class="token operator">=</span><span class="token string">"com.kuang.pojo.People"</span> <span class="token assign-left variable">autowire</span><span class="token operator">=</span><span class="token string">"byName"</span><span class="token operator">></span></pre></td></tr><tr><td data-num="8"></td><td><pre> <span class="token operator">&lt;</span>property <span class="token assign-left variable">name</span><span class="token operator">=</span><span class="token string">"name"</span> <span class="token assign-left variable">value</span><span class="token operator">=</span><span class="token string">"小狂神呀"</span>/<span class="token operator">></span></pre></td></tr><tr><td data-num="9"></td><td><pre> <span class="token operator">&lt;</span>/bean<span class="token operator">></span></pre></td></tr></table></figure><h1 id="bytype自动装配"><a class="anchor" href="#bytype自动装配">#</a> ByType 自动装配</h1>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token operator">&lt;</span>bean <span class="token assign-left variable">id</span><span class="token operator">=</span><span class="token string">"cat"</span> <span class="token assign-left variable">class</span><span class="token operator">=</span><span class="token string">" com.kuang.pojo.Cat"</span>/<span class="token operator">></span></pre></td></tr><tr><td data-num="2"></td><td><pre> <span class="token operator">&lt;</span>bean <span class="token assign-left variable">id</span><span class="token operator">=</span><span class="token string">"dog"</span> <span class="token assign-left variable">class</span><span class="token operator">=</span><span class="token string">"com.kuang.pojo.Dog"</span>/<span class="token operator">></span>(可以删去id)</pre></td></tr><tr><td data-num="3"></td><td><pre> <span class="token operator">&lt;</span><span class="token operator">!</span>--</pre></td></tr><tr><td data-num="4"></td><td><pre> byName:会自动在容器上下文中查找,和自己对象set方法后面的值对应的beanid<span class="token operator">!</span></pre></td></tr><tr><td data-num="5"></td><td><pre> byType:会自动在容器上下文中查找,和自己对象属性类型相同的bean<span class="token operator">!</span></pre></td></tr><tr><td data-num="6"></td><td><pre> --<span class="token operator">></span></pre></td></tr><tr><td data-num="7"></td><td><pre> <span class="token operator">&lt;</span>bean <span class="token assign-left variable">id</span><span class="token operator">=</span><span class="token string">"people"</span> <span class="token assign-left variable">class</span><span class="token operator">=</span><span class="token string">"com.kuang.pojo.People"</span> <span class="token assign-left variable">autowire</span><span class="token operator">=</span><span class="token string">"byType"</span><span class="token operator">></span></pre></td></tr><tr><td data-num="8"></td><td><pre> <span class="token operator">&lt;</span>property <span class="token assign-left variable">name</span><span class="token operator">=</span><span class="token string">"name"</span> <span class="token assign-left variable">value</span><span class="token operator">=</span><span class="token string">"小狂神呀"</span>/<span class="token operator">></span></pre></td></tr><tr><td data-num="9"></td><td><pre> <span class="token operator">&lt;</span>/bean<span class="token operator">></span></pre></td></tr></table></figure><ul>
<li>byname 的时候,需要保证所有 bean 的 id 唯一,并 且这个 bean 需要和自动注入的属性的 set 方法的值一致!</li>
<li>bytype 的时候,需要保证所有 bean 的 class 唯一, 并且这个 bean 需要和自动注入的属性的类型一致!</li>
</ul>
<h1 id="使用注解实现自动装配"><a class="anchor" href="#使用注解实现自动装配">#</a> 使用注解实现自动装配</h1>
<ol>
<li>导入约束 context 约束</li>
<li>配置注解的支持</li>
</ol>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token operator">&lt;</span>?xml <span class="token assign-left variable">version</span><span class="token operator">=</span><span class="token string">"1.0"</span> <span class="token assign-left variable">encoding</span><span class="token operator">=</span> <span class="token string">"UTF-8"</span>?<span class="token operator">></span></pre></td></tr><tr><td data-num="2"></td><td><pre><span class="token operator">&lt;</span>beans <span class="token assign-left variable">xmlns</span><span class="token operator">=</span><span class="token string">"http://www.springframework.org/schema/beans"</span></pre></td></tr><tr><td data-num="3"></td><td><pre> xmlns:xsi<span class="token operator">=</span><span class="token string">"http://www.w3.org/2001/XMLSchema-instance"</span></pre></td></tr><tr><td data-num="4"></td><td><pre> xmlns:context<span class="token operator">=</span><span class="token string">"http://www.springframework.org/schema/context"</span></pre></td></tr><tr><td data-num="5"></td><td><pre> xsi:schemaLocation<span class="token operator">=</span> <span class="token string">"http://www.springframework.org/schema/beans</pre></td></tr><tr><td data-num="6"></td><td><pre> https://www.springframework.org/schema/beans/spring-beans.xsd</pre></td></tr><tr><td data-num="7"></td><td><pre> http://www.springframework.org/schema/context</pre></td></tr><tr><td data-num="8"></td><td><pre> http://www.springframework.org/schema/context/spring-context.xsd"</span><span class="token operator">></span></pre></td></tr><tr><td data-num="9"></td><td><pre></pre></td></tr><tr><td data-num="10"></td><td><pre> <span class="token operator">&lt;</span>context:annotation-config/<span class="token operator">></span></pre></td></tr><tr><td data-num="11"></td><td><pre></pre></td></tr><tr><td data-num="12"></td><td><pre><span class="token operator">&lt;</span>/beans<span class="token operator">></span></pre></td></tr></table></figure><ul>
<li>@Autowired</li>
</ul>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>直接在属性上使用即可<span class="token operator">!</span>也可以在set方式上使用<span class="token operator">!</span></pre></td></tr><tr><td data-num="2"></td><td><pre></pre></td></tr><tr><td data-num="3"></td><td><pre>使用Autowired我们可以不用编写Set方法了,前提是你这个自动装配的属性在I0C <span class="token punctuation">(</span>Spring<span class="token punctuation">)</span> 容器中存在,且符</pre></td></tr><tr><td data-num="4"></td><td><pre>合名字byname<span class="token operator">!</span></pre></td></tr></table></figure><ul>
<li>@Nullable</li>
</ul>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>@Nullable 字段标记 了这个注解,说明这个字段可以为nu11<span class="token punctuation">;</span></pre></td></tr></table></figure><ul>
<li>测试代码</li>
</ul>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>public class People <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="2"></td><td><pre> //如果显示定义了Autowired的required属性为false,说明这个对象可以为nu17,否则不允许为空</pre></td></tr><tr><td data-num="3"></td><td><pre> @Autowired<span class="token punctuation">(</span>required <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="4"></td><td><pre> private Cat <span class="token function">cat</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="5"></td><td><pre> @Autowired</pre></td></tr><tr><td data-num="6"></td><td><pre> private Dog dog<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="7"></td><td><pre> private string name<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="8"></td><td><pre><span class="token punctuation">&#125;</span></pre></td></tr></table></figure><ul>
<li>@Qualifier</li>
</ul>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>如果@Autowired自动装配的环境比较复杂,自动装配无法通过一个注解<span class="token punctuation">[</span>@Autowired<span class="token punctuation">]</span> 完成的时候、我们可以</pre></td></tr><tr><td data-num="2"></td><td><pre>使用@Qualifier<span class="token punctuation">(</span>value<span class="token operator">=</span><span class="token string">"xx"</span><span class="token punctuation">)</span>去配置@Autowired的使用,指定一个唯一的bean对象注入<span class="token operator">!</span> <span class="token builtin class-name">.</span></pre></td></tr><tr><td data-num="3"></td><td><pre></pre></td></tr><tr><td data-num="4"></td><td><pre>pub1ic class People <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="5"></td><td><pre> @Autowired</pre></td></tr><tr><td data-num="6"></td><td><pre> @Qualifier<span class="token punctuation">(</span>value<span class="token operator">=</span><span class="token string">"cat111"</span><span class="token punctuation">)</span> <span class="token comment">#value 就是指定 bean 中的 id</span></pre></td></tr><tr><td data-num="7"></td><td><pre> private Cat <span class="token function">cat</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="8"></td><td><pre> @Autowired</pre></td></tr><tr><td data-num="9"></td><td><pre> @Qualifier<span class="token punctuation">(</span>value<span class="token operator">=</span><span class="token string">"dog222"</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="10"></td><td><pre> private Dog dog<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="11"></td><td><pre> private String name<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="12"></td><td><pre><span class="token punctuation">&#125;</span></pre></td></tr></table></figure><ul>
<li>@Resource 注解</li>
</ul>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>public class People <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="2"></td><td><pre> @Resource <span class="token punctuation">(</span>name <span class="token operator">=</span><span class="token string">"cat2"</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="3"></td><td><pre> private Cat <span class="token function">cat</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="4"></td><td><pre> @Resource</pre></td></tr><tr><td data-num="5"></td><td><pre> private Dog dog<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="6"></td><td><pre><span class="token punctuation">&#125;</span></pre></td></tr></table></figure><ul>
<li>@Autowired 和 @Resource 的区别</li>
</ul>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>都是用来自动装配的,都可以放在属性字段上</pre></td></tr><tr><td data-num="2"></td><td><pre></pre></td></tr><tr><td data-num="3"></td><td><pre>@Autowired是默认通过byType的方式实现,而且必须要求这个对象存在</pre></td></tr><tr><td data-num="4"></td><td><pre></pre></td></tr><tr><td data-num="5"></td><td><pre>@Resource默认通过byname的方式实现,如果找不到名字,则通过byType实现<span class="token operator">!</span> 如果两个都找不到的情况下,就报错<span class="token operator">!</span></pre></td></tr><tr><td data-num="6"></td><td><pre></pre></td></tr><tr><td data-num="7"></td><td><pre>执行顺序不同: @ Autowired通过byType的方式实现。@Resource默认通过byname的方式实现</pre></td></tr></table></figure> ]]></description>
</item>
<item>
<guid isPermalink="true">https://love.youhuamao.xyz/2022/11/21/Java/SSM/Spring/%E4%BB%A3%E7%90%86%E6%A8%A1%E5%BC%8F/</guid>
<title>代理模式</title>
<link>https://love.youhuamao.xyz/2022/11/21/Java/SSM/Spring/%E4%BB%A3%E7%90%86%E6%A8%A1%E5%BC%8F/</link>
<category term="学习Java" scheme="https://love.youhuamao.xyz/categories/Java/" />
<category term="Java基础" scheme="https://love.youhuamao.xyz/categories/Java/Java%E5%9F%BA%E7%A1%80/" />
<category term="java" scheme="https://love.youhuamao.xyz/tags/java/" />
<pubDate>Mon, 21 Nov 2022 00:00:00 +0800</pubDate>
<description><![CDATA[ <h1 id="静态代理"><a class="anchor" href="#静态代理">#</a> 静态代理</h1>
<h2 id="角色分析"><a class="anchor" href="#角色分析">#</a> 角色分析</h2>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>●抽象角色:一般会使用接口或者抽象类来解决</pre></td></tr><tr><td data-num="2"></td><td><pre>●真实角色:被代理的角色</pre></td></tr><tr><td data-num="3"></td><td><pre>●代理角色:代理真实角色,代理真实角色后,我们一般会做一-些附属操作</pre></td></tr><tr><td data-num="4"></td><td><pre>●客户:访问代理对象的人<span class="token operator">!</span></pre></td></tr></table></figure><h2 id="代码步骤"><a class="anchor" href="#代码步骤">#</a> 代码步骤</h2>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token number">1</span>.接口</pre></td></tr><tr><td data-num="2"></td><td><pre><span class="token number">2</span>.真实角色</pre></td></tr><tr><td data-num="3"></td><td><pre><span class="token number">3</span>.代理角色</pre></td></tr><tr><td data-num="4"></td><td><pre><span class="token number">4</span>.客户端访问代理角色</pre></td></tr></table></figure><h2 id="代理模式的好处"><a class="anchor" href="#代理模式的好处">#</a> 代理模式的好处</h2>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>●可以使真实角色的操作更加纯粹<span class="token operator">!</span>不用去关注一些公共的业务</pre></td></tr><tr><td data-num="2"></td><td><pre>●公共也就就交给代理角色<span class="token operator">!</span>实现了业务的分工<span class="token operator">!</span></pre></td></tr><tr><td data-num="3"></td><td><pre>●公共业务发生扩展的时候,方便集中管理<span class="token operator">!</span></pre></td></tr></table></figure><h2 id="缺点"><a class="anchor" href="#缺点">#</a> 缺点</h2>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>一个真实角色就会产生一个代理角色<span class="token punctuation">;</span>代码量会翻倍~开发效率会变低~</pre></td></tr></table></figure><h1 id="动态代理"><a class="anchor" href="#动态代理">#</a> 动态代理</h1>
<ul>
<li>动态代理和静态代理角色 - - 样</li>
<li>动态代理的代理类是动态生成的,不是我们直接写好的!</li>
<li>动态代理分为两大类:基于接口的动态代理,基于类的动态代理</li>
</ul>
<ol>
<li>基于接口 --- JDK 动态代理 [我们在这里使用]</li>
<li>基于类: cglib</li>
<li>java 字节码实现: javasist</li>
</ol>
<ul>
<li>Proxy: 代理,InvocationHandler: 调用处理程序</li>
</ul>
<h1 id="动态代理的好处"><a class="anchor" href="#动态代理的好处">#</a> 动态代理的好处</h1>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>可以使真实角色的操作更加纯粹<span class="token operator">!</span>不用去关注一些公共的业务</pre></td></tr><tr><td data-num="2"></td><td><pre>公共也就就交给代理角色<span class="token operator">!</span>实现了业务的分工<span class="token operator">!</span></pre></td></tr><tr><td data-num="3"></td><td><pre>公共业务发生扩展的时候,方便集中管理<span class="token operator">!</span></pre></td></tr><tr><td data-num="4"></td><td><pre>一个动态代理类代理的是一个接口,一般就是对应的一类业务</pre></td></tr><tr><td data-num="5"></td><td><pre>个动态代理类可以代理多个类,只要是实现了同一个接口即可</pre></td></tr></table></figure> ]]></description>
</item>
<item>
<guid isPermalink="true">https://love.youhuamao.xyz/2022/11/21/Java/SSM/Spring/%E4%BD%BF%E7%94%A8java%E7%9A%84%E6%96%B9%E5%BC%8F%E9%85%8D%E7%BD%AESpring/</guid>
<title>使用java的方式配置Spring</title>
<link>https://love.youhuamao.xyz/2022/11/21/Java/SSM/Spring/%E4%BD%BF%E7%94%A8java%E7%9A%84%E6%96%B9%E5%BC%8F%E9%85%8D%E7%BD%AESpring/</link>
<category term="学习Java" scheme="https://love.youhuamao.xyz/categories/Java/" />
<category term="Java基础" scheme="https://love.youhuamao.xyz/categories/Java/Java%E5%9F%BA%E7%A1%80/" />
<category term="java" scheme="https://love.youhuamao.xyz/tags/java/" />
<pubDate>Mon, 21 Nov 2022 00:00:00 +0800</pubDate>
<description><![CDATA[ <ul>
<li>实体类</li>
</ul>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>//这里这个注解的意思,就是说明这个类被Spring接管了,注册到了容器中</pre></td></tr><tr><td data-num="2"></td><td><pre>@Component</pre></td></tr><tr><td data-num="3"></td><td><pre>public class User <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="4"></td><td><pre> private String name<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="5"></td><td><pre></pre></td></tr><tr><td data-num="6"></td><td><pre> public String <span class="token function-name function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="7"></td><td><pre> <span class="token builtin class-name">return</span> name<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="8"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="9"></td><td><pre></pre></td></tr><tr><td data-num="10"></td><td><pre> @Value<span class="token punctuation">(</span><span class="token string">"youhuamao"</span><span class="token punctuation">)</span>//属性注入值</pre></td></tr><tr><td data-num="11"></td><td><pre> public void setName<span class="token punctuation">(</span>String name<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="12"></td><td><pre> this.name <span class="token operator">=</span> name<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="13"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="14"></td><td><pre></pre></td></tr><tr><td data-num="15"></td><td><pre> @Override</pre></td></tr><tr><td data-num="16"></td><td><pre> public String <span class="token function-name function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="17"></td><td><pre> <span class="token builtin class-name">return</span> <span class="token string">"User&#123;"</span> +</pre></td></tr><tr><td data-num="18"></td><td><pre> <span class="token string">"name='"</span> + name + <span class="token string">'\'</span>' +</pre></td></tr><tr><td data-num="19"></td><td><pre> <span class="token string">'&#125;'</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="20"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="21"></td><td><pre><span class="token punctuation">&#125;</span></pre></td></tr></table></figure><ul>
<li>配置文件</li>
</ul>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>// @Configuration代表这是一个配置类,就和我们之前看的beans.xml</pre></td></tr><tr><td data-num="2"></td><td><pre>//这个也会Spring容器托管,注册到容器中,因为他本来就是一@Component,</pre></td></tr><tr><td data-num="3"></td><td><pre>@Configuration</pre></td></tr><tr><td data-num="4"></td><td><pre>@ComponentScan<span class="token punctuation">(</span><span class="token string">"com.kuang.pojo"</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="5"></td><td><pre>@Import<span class="token punctuation">(</span>KuangConfig2.class<span class="token punctuation">)</span></pre></td></tr><tr><td data-num="6"></td><td><pre>public class KuangConfig <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="7"></td><td><pre></pre></td></tr><tr><td data-num="8"></td><td><pre> //注册一个bean ,就相当 于我们之前写的一- 个bean标签</pre></td></tr><tr><td data-num="9"></td><td><pre> //这个方法的名字,就相当于bean标签中的id属性</pre></td></tr><tr><td data-num="10"></td><td><pre> //这个方法的返回值,就相当Fbean标签中的class属性</pre></td></tr><tr><td data-num="11"></td><td><pre> @Bean</pre></td></tr><tr><td data-num="12"></td><td><pre> public User <span class="token function-name function">getUser</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="13"></td><td><pre> <span class="token builtin class-name">return</span> new User<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>//就是返回要注入到bean的对象<span class="token operator">!</span></pre></td></tr><tr><td data-num="14"></td><td><pre></pre></td></tr><tr><td data-num="15"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="16"></td><td><pre><span class="token punctuation">&#125;</span></pre></td></tr></table></figure><ul>
<li>测试类</li>
</ul>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>public class MyTest <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="2"></td><td><pre> public static void main<span class="token punctuation">(</span>String<span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="3"></td><td><pre> //如果完全使用了配置类方式去做,我们就只能通过AnnotationConfig.上 下文来获取容器,通过配置类的class对象加载<span class="token operator">!</span></pre></td></tr><tr><td data-num="4"></td><td><pre> ApplicationContext context <span class="token operator">=</span> new AnnotationConfigApplicationContext<span class="token punctuation">(</span>KuangConfig.class<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="5"></td><td><pre> User getUser <span class="token operator">=</span> <span class="token punctuation">(</span>User<span class="token punctuation">)</span> context.getBean<span class="token punctuation">(</span><span class="token string">"getUser"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="6"></td><td><pre> System.out.println<span class="token punctuation">(</span>getUser.getName<span class="token punctuation">(</span><span class="token punctuation">))</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="7"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="8"></td><td><pre><span class="token punctuation">&#125;</span></pre></td></tr></table></figure> ]]></description>
</item>
<item>
<guid isPermalink="true">https://love.youhuamao.xyz/2022/11/21/Java/SSM/Spring/%E4%BD%BF%E7%94%A8%E6%B3%A8%E8%A7%A3%E5%BC%80%E5%8F%91/</guid>
<title>使用注解开发</title>
<link>https://love.youhuamao.xyz/2022/11/21/Java/SSM/Spring/%E4%BD%BF%E7%94%A8%E6%B3%A8%E8%A7%A3%E5%BC%80%E5%8F%91/</link>
<category term="学习Java" scheme="https://love.youhuamao.xyz/categories/Java/" />
<category term="Java基础" scheme="https://love.youhuamao.xyz/categories/Java/Java%E5%9F%BA%E7%A1%80/" />
<category term="java" scheme="https://love.youhuamao.xyz/tags/java/" />
<pubDate>Mon, 21 Nov 2022 00:00:00 +0800</pubDate>
<description><![CDATA[ <ul>
<li>添加注解支持</li>
</ul>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token operator">&lt;</span>?xml <span class="token assign-left variable">version</span><span class="token operator">=</span><span class="token string">"1.0"</span> <span class="token assign-left variable">encoding</span><span class="token operator">=</span> <span class="token string">"UTF-8"</span>?<span class="token operator">></span></pre></td></tr><tr><td data-num="2"></td><td><pre><span class="token operator">&lt;</span>beans <span class="token assign-left variable">xmlns</span><span class="token operator">=</span><span class="token string">"http://www.springframework.org/schema/beans"</span></pre></td></tr><tr><td data-num="3"></td><td><pre> xmlns:xsi<span class="token operator">=</span><span class="token string">"http://www.w3.org/2001/XMLSchema-instance"</span></pre></td></tr><tr><td data-num="4"></td><td><pre> xmlns:context<span class="token operator">=</span><span class="token string">"http://www.springframework.org/schema/context"</span></pre></td></tr><tr><td data-num="5"></td><td><pre> xsi:schemaLocation<span class="token operator">=</span> <span class="token string">"http://www.springframework.org/schema/beans</pre></td></tr><tr><td data-num="6"></td><td><pre> https://www.springframework.org/schema/beans/spring-beans.xsd</pre></td></tr><tr><td data-num="7"></td><td><pre> http://www.springframework.org/schema/context</pre></td></tr><tr><td data-num="8"></td><td><pre> http://www.springframework.org/schema/context/spring-context.xsd</pre></td></tr><tr><td data-num="9"></td><td><pre> http://www.springframework.org/schema/aop</pre></td></tr><tr><td data-num="10"></td><td><pre> http://www.springframework.org/schema/aop/spring-aop.xsd"</span><span class="token operator">></span></pre></td></tr><tr><td data-num="11"></td><td><pre></pre></td></tr><tr><td data-num="12"></td><td><pre> <span class="token operator">&lt;</span>context:annotation-config/<span class="token operator">></span></pre></td></tr><tr><td data-num="13"></td><td><pre> </pre></td></tr><tr><td data-num="14"></td><td><pre><span class="token operator">&lt;</span>/beans<span class="token operator">></span></pre></td></tr></table></figure><ul>
<li>属性如何注入</li>
</ul>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>//等价于<span class="token operator">&lt;</span>bean <span class="token assign-left variable">id</span><span class="token operator">=</span> <span class="token string">"user"</span> <span class="token assign-left variable">class</span><span class="token operator">=</span> <span class="token string">"com.kuang.pojo.User"</span>/<span class="token operator">></span></pre></td></tr><tr><td data-num="2"></td><td><pre>// @Component组件</pre></td></tr><tr><td data-num="3"></td><td><pre>@Component</pre></td></tr><tr><td data-num="4"></td><td><pre>public class User <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="5"></td><td><pre> public String name<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="6"></td><td><pre></pre></td></tr><tr><td data-num="7"></td><td><pre> //相当于<span class="token operator">&lt;</span>property <span class="token assign-left variable">name</span><span class="token operator">=</span> <span class="token string">"name"</span> <span class="token assign-left variable">value</span><span class="token operator">=</span> <span class="token string">"易知鱼"</span>/ <span class="token operator">></span></pre></td></tr><tr><td data-num="8"></td><td><pre></pre></td></tr><tr><td data-num="9"></td><td><pre> @Value<span class="token punctuation">(</span><span class="token string">"易知鱼"</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="10"></td><td><pre> public void setName<span class="token punctuation">(</span>String name<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="11"></td><td><pre> this.name <span class="token operator">=</span> name<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="12"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="13"></td><td><pre><span class="token punctuation">&#125;</span></pre></td></tr></table></figure><ul>
<li>衍生的注解</li>
</ul>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>@Component有几个衍生注解,我们在web开发中,会按照mvc三层架构分层<span class="token operator">!</span></pre></td></tr><tr><td data-num="2"></td><td><pre>。dao <span class="token punctuation">[</span>@Repository<span class="token punctuation">]</span></pre></td></tr><tr><td data-num="3"></td><td><pre>。service <span class="token punctuation">[</span> @Service<span class="token punctuation">]</span></pre></td></tr><tr><td data-num="4"></td><td><pre>。controller <span class="token punctuation">[</span> @Controller<span class="token punctuation">]</span></pre></td></tr><tr><td data-num="5"></td><td><pre>这四个注解功能都是一样的,都是代表将某个类注册到Spring中,装配Bean</pre></td></tr></table></figure><ul>
<li>自动装配置</li>
</ul>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>一@Autowired :自动装配通过类型。名字</pre></td></tr><tr><td data-num="2"></td><td><pre> 如果Autowi red不能唯一自 动装配上属性,则需要通过@Qualifier<span class="token punctuation">(</span>va1ue<span class="token operator">=</span><span class="token string">"xxx"</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="3"></td><td><pre>一@Nu11able 字段标记了这个注解,说明这个字段可以为nu11<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="4"></td><td><pre>一@Resource:自动装配通过名字。类型。</pre></td></tr></table></figure><ul>
<li>作用域</li>
</ul>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>@Component</pre></td></tr><tr><td data-num="2"></td><td><pre>@Scope<span class="token punctuation">(</span><span class="token string">"prototype"</span><span class="token punctuation">)</span> <span class="token comment">#给该类设置为原型模式,也可以设置成单例模式</span></pre></td></tr><tr><td data-num="3"></td><td><pre>public class User <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="4"></td><td><pre> public String name<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="5"></td><td><pre></pre></td></tr><tr><td data-num="6"></td><td><pre> //相当于<span class="token operator">&lt;</span>property <span class="token assign-left variable">name</span><span class="token operator">=</span> <span class="token string">"name"</span> <span class="token assign-left variable">value</span><span class="token operator">=</span> <span class="token string">"易知鱼"</span>/ <span class="token operator">></span></pre></td></tr><tr><td data-num="7"></td><td><pre></pre></td></tr><tr><td data-num="8"></td><td><pre> @Value<span class="token punctuation">(</span><span class="token string">"易知鱼"</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="9"></td><td><pre> public void setName<span class="token punctuation">(</span>String name<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="10"></td><td><pre> this.name <span class="token operator">=</span> name<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="11"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="12"></td><td><pre><span class="token punctuation">&#125;</span></pre></td></tr></table></figure><ul>
<li>小结</li>
</ul>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>xml与注解:</pre></td></tr><tr><td data-num="2"></td><td><pre>。xml更加万能,适用于任何场合<span class="token operator">!</span>维护简单方便</pre></td></tr><tr><td data-num="3"></td><td><pre>。注解不是自己类使用不了,维护相对复杂<span class="token operator">!</span></pre></td></tr><tr><td data-num="4"></td><td><pre>xm<span class="token operator">|</span>与注解最佳实践:</pre></td></tr><tr><td data-num="5"></td><td><pre>。xml用来管理bean<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="6"></td><td><pre>。注解只负责完成属性的注入<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="7"></td><td><pre>。我们在使用的过程中,只需要注意一个问题:必须让注解生效,就需要开启注解的支持</pre></td></tr><tr><td data-num="8"></td><td><pre></pre></td></tr><tr><td data-num="9"></td><td><pre> <span class="token operator">&lt;</span>context:component-scan base-package<span class="token operator">=</span><span class="token string">"com.kuang"</span>/<span class="token operator">></span></pre></td></tr><tr><td data-num="10"></td><td><pre> <span class="token operator">&lt;</span>context:annotation-config/<span class="token operator">></span></pre></td></tr></table></figure> ]]></description>
</item>
<item>
<guid isPermalink="true">https://love.youhuamao.xyz/2022/11/20/Java/SSM/Spring/IOC%E5%88%9B%E5%BB%BA%E5%AF%B9%E8%B1%A1%E7%9A%84%E6%96%B9%E5%BC%8F/</guid>
<title>IOC创建对象的方式</title>
<link>https://love.youhuamao.xyz/2022/11/20/Java/SSM/Spring/IOC%E5%88%9B%E5%BB%BA%E5%AF%B9%E8%B1%A1%E7%9A%84%E6%96%B9%E5%BC%8F/</link>
<category term="学习Java" scheme="https://love.youhuamao.xyz/categories/Java/" />
<category term="Java基础" scheme="https://love.youhuamao.xyz/categories/Java/Java%E5%9F%BA%E7%A1%80/" />
<category term="java" scheme="https://love.youhuamao.xyz/tags/java/" />
<pubDate>Sun, 20 Nov 2022 00:00:00 +0800</pubDate>
<description><![CDATA[ <h1 id="使用无参构造器"><a class="anchor" href="#使用无参构造器">#</a> 使用无参构造器</h1>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>package com.kuang.pojo<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="2"></td><td><pre></pre></td></tr><tr><td data-num="3"></td><td><pre>public class User <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="4"></td><td><pre> private String name<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="5"></td><td><pre></pre></td></tr><tr><td data-num="6"></td><td><pre> public <span class="token function-name function">User</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="7"></td><td><pre> System.out.println<span class="token punctuation">(</span><span class="token string">"User的无参构造"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="8"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="9"></td><td><pre></pre></td></tr><tr><td data-num="10"></td><td><pre> public String <span class="token function-name function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="11"></td><td><pre> <span class="token builtin class-name">return</span> name<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="12"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="13"></td><td><pre></pre></td></tr><tr><td data-num="14"></td><td><pre> public void setName<span class="token punctuation">(</span>String name<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="15"></td><td><pre> this.name <span class="token operator">=</span> name<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="16"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="17"></td><td><pre></pre></td></tr><tr><td data-num="18"></td><td><pre> public void <span class="token function-name function">show</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="19"></td><td><pre> System.out.println<span class="token punctuation">(</span><span class="token string">"name="</span> + name<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="20"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="21"></td><td><pre><span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="22"></td><td><pre></pre></td></tr><tr><td data-num="23"></td><td><pre></pre></td></tr><tr><td data-num="24"></td><td><pre></pre></td></tr><tr><td data-num="25"></td><td><pre><span class="token operator">&lt;</span>?xml <span class="token assign-left variable">version</span><span class="token operator">=</span><span class="token string">"1.0"</span> <span class="token assign-left variable">encoding</span><span class="token operator">=</span> <span class="token string">"UTF-8"</span>?<span class="token operator">></span></pre></td></tr><tr><td data-num="26"></td><td><pre><span class="token operator">&lt;</span>beans <span class="token assign-left variable">xmlns</span><span class="token operator">=</span><span class="token string">"http://www.springframework.org/schema/beans"</span></pre></td></tr><tr><td data-num="27"></td><td><pre> xmlns:xsi<span class="token operator">=</span><span class="token string">"http://www.w3.org/2001/XMLSchema-instance"</span></pre></td></tr><tr><td data-num="28"></td><td><pre> xsi:schemaLocation<span class="token operator">=</span> <span class="token string">"http://www.springframework.org/schema/beans</pre></td></tr><tr><td data-num="29"></td><td><pre> https://www.springframework.org/schema/beans/spring-beans.xsd"</span><span class="token operator">></span></pre></td></tr><tr><td data-num="30"></td><td><pre> <span class="token operator">&lt;</span><span class="token operator">!</span>--使用Spring来创建对象,在Spring这 些都称为Bean</pre></td></tr><tr><td data-num="31"></td><td><pre> 类型 变量名<span class="token operator">=</span> new类型<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="32"></td><td><pre> Hello hello <span class="token operator">=</span> new HeLlo<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="33"></td><td><pre> <span class="token function">id</span> <span class="token operator">=</span> 变量名</pre></td></tr><tr><td data-num="34"></td><td><pre> class <span class="token operator">=</span> new 的对象<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="35"></td><td><pre> property 相当于给对象中的属性设置一个值<span class="token operator">!</span></pre></td></tr><tr><td data-num="36"></td><td><pre> <span class="token operator">!</span>--<span class="token operator">></span></pre></td></tr><tr><td data-num="37"></td><td><pre> <span class="token operator">&lt;</span>bean <span class="token assign-left variable">id</span><span class="token operator">=</span><span class="token string">"user"</span> <span class="token assign-left variable">class</span><span class="token operator">=</span><span class="token string">"com.kuang.pojo.User"</span><span class="token operator">></span></pre></td></tr><tr><td data-num="38"></td><td><pre> <span class="token operator">&lt;</span>property <span class="token assign-left variable">name</span><span class="token operator">=</span><span class="token string">"name"</span> <span class="token assign-left variable">value</span><span class="token operator">=</span><span class="token string">"qinijiang"</span>/<span class="token operator">></span></pre></td></tr><tr><td data-num="39"></td><td><pre> <span class="token operator">&lt;</span>/bean<span class="token operator">></span></pre></td></tr><tr><td data-num="40"></td><td><pre></pre></td></tr><tr><td data-num="41"></td><td><pre><span class="token operator">&lt;</span>/beans<span class="token operator">></span></pre></td></tr><tr><td data-num="42"></td><td><pre></pre></td></tr><tr><td data-num="43"></td><td><pre></pre></td></tr><tr><td data-num="44"></td><td><pre> ApplicationContext context <span class="token operator">=</span> new ClassPathXmlApplicationContext<span class="token punctuation">(</span><span class="token string">"bean.xml"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="45"></td><td><pre></pre></td></tr><tr><td data-num="46"></td><td><pre> User user <span class="token operator">=</span> <span class="token punctuation">(</span>User<span class="token punctuation">)</span> context.getBean<span class="token punctuation">(</span><span class="token string">"user"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="47"></td><td><pre></pre></td></tr><tr><td data-num="48"></td><td><pre> user.show<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr></table></figure><h1 id="使用有参构造创建对象"><a class="anchor" href="#使用有参构造创建对象">#</a> 使用有参构造创建对象</h1>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token operator">&lt;</span><span class="token operator">!</span>--第一种,下标赋值<span class="token operator">!</span> --<span class="token operator">></span></pre></td></tr><tr><td data-num="2"></td><td><pre><span class="token operator">&lt;</span><span class="token operator">!</span>--<span class="token operator">&lt;</span>bean <span class="token assign-left variable">id</span><span class="token operator">=</span><span class="token string">"user"</span> <span class="token assign-left variable">cLass</span><span class="token operator">=</span> <span class="token string">"com.kuang.pojo.User"</span><span class="token operator">></span>--<span class="token operator">></span></pre></td></tr><tr><td data-num="3"></td><td><pre><span class="token operator">&lt;</span><span class="token operator">!</span>--<span class="token operator">&lt;</span>constructor-arg <span class="token assign-left variable">index</span><span class="token operator">=</span> <span class="token string">"0"</span> <span class="token assign-left variable">value</span><span class="token operator">=</span> <span class="token string">"狂神说Java"</span>/<span class="token operator">></span>--<span class="token operator">></span></pre></td></tr><tr><td data-num="4"></td><td><pre><span class="token operator">&lt;</span><span class="token operator">!</span>--<span class="token operator">&lt;</span>/bean<span class="token operator">></span>--<span class="token operator">></span></pre></td></tr><tr><td data-num="5"></td><td><pre></pre></td></tr><tr><td data-num="6"></td><td><pre><span class="token operator">&lt;</span><span class="token operator">!</span>--第二种方式:通过类型创建,不建议使用<span class="token operator">!</span> --<span class="token operator">></span></pre></td></tr><tr><td data-num="7"></td><td><pre><span class="token operator">&lt;</span><span class="token operator">!</span>--<span class="token operator">&lt;</span>bean <span class="token assign-left variable">id</span><span class="token operator">=</span> <span class="token string">"user"</span> <span class="token assign-left variable">class</span><span class="token operator">=</span> <span class="token string">"com.kuang.pojo.User"</span><span class="token operator">></span>--<span class="token operator">></span></pre></td></tr><tr><td data-num="8"></td><td><pre><span class="token operator">&lt;</span><span class="token operator">!</span>--<span class="token operator">&lt;</span>constructor-arg <span class="token assign-left variable">type</span><span class="token operator">=</span> <span class="token string">"java.lang.String"</span> <span class="token assign-left variable">value</span><span class="token operator">=</span><span class="token string">"qinjiang"</span>/<span class="token operator">></span>--<span class="token operator">></span></pre></td></tr><tr><td data-num="9"></td><td><pre><span class="token operator">&lt;</span><span class="token operator">!</span>--<span class="token operator">&lt;</span>/bean<span class="token operator">></span>--<span class="token operator">></span></pre></td></tr><tr><td data-num="10"></td><td><pre></pre></td></tr><tr><td data-num="11"></td><td><pre><span class="token operator">&lt;</span><span class="token operator">!</span>--第三种,直接通过参数名来设置--<span class="token operator">></span></pre></td></tr><tr><td data-num="12"></td><td><pre><span class="token operator">&lt;</span>bean <span class="token assign-left variable">id</span><span class="token operator">=</span><span class="token string">"user"</span> <span class="token assign-left variable">class</span><span class="token operator">=</span><span class="token string">"com.kuang.pojo.User"</span><span class="token operator">></span></pre></td></tr><tr><td data-num="13"></td><td><pre><span class="token operator">&lt;</span>constructor-arg <span class="token assign-left variable">name</span><span class="token operator">=</span><span class="token string">"name"</span> <span class="token assign-left variable">value</span><span class="token operator">=</span><span class="token string">"秦疆"</span>/<span class="token operator">></span></pre></td></tr><tr><td data-num="14"></td><td><pre><span class="token operator">&lt;</span>/bean<span class="token operator">></span></pre></td></tr></table></figure><ul>
<li>在配置文件加载的时候,容器中管理的对象就已经初始化了</li>
</ul>
]]></description>
</item>
<item>
<guid isPermalink="true">https://love.youhuamao.xyz/2022/11/20/Java/SSM/Spring/Spring%E9%85%8D%E7%BD%AE/</guid>
<title>Spring配置</title>
<link>https://love.youhuamao.xyz/2022/11/20/Java/SSM/Spring/Spring%E9%85%8D%E7%BD%AE/</link>
<category term="学习Java" scheme="https://love.youhuamao.xyz/categories/Java/" />
<category term="Java基础" scheme="https://love.youhuamao.xyz/categories/Java/Java%E5%9F%BA%E7%A1%80/" />
<category term="java" scheme="https://love.youhuamao.xyz/tags/java/" />
<pubDate>Sun, 20 Nov 2022 00:00:00 +0800</pubDate>
<description><![CDATA[ <h1 id="别名"><a class="anchor" href="#别名">#</a> 别名</h1>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token operator">&lt;</span><span class="token operator">!</span>--别名,如果添加了别名,我们也可以使用别名获取到这个对象--<span class="token operator">></span></pre></td></tr><tr><td data-num="2"></td><td><pre><span class="token operator">&lt;</span>a1ias <span class="token assign-left variable">name</span><span class="token operator">=</span><span class="token string">"user"</span> <span class="token assign-left variable">alias</span><span class="token operator">=</span><span class="token string">"use rNew"</span>/<span class="token operator">></span></pre></td></tr></table></figure><h1 id="bean配置"><a class="anchor" href="#bean配置">#</a> Bean 配置</h1>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token operator">&lt;</span><span class="token operator">!</span>--</pre></td></tr><tr><td data-num="2"></td><td><pre><span class="token function">id</span> <span class="token builtin class-name">:</span> bean 的唯一 标识符,也就是相当于我们学的对象名</pre></td></tr><tr><td data-num="3"></td><td><pre>class <span class="token builtin class-name">:</span> bean 对象所对应的全限定名:包名+类型</pre></td></tr><tr><td data-num="4"></td><td><pre>name :也是别名,而且name可以同时取多个别名</pre></td></tr><tr><td data-num="5"></td><td><pre>可以通过空格,逗号,分号分隔</pre></td></tr><tr><td data-num="6"></td><td><pre>-- <span class="token operator">></span></pre></td></tr><tr><td data-num="7"></td><td><pre><span class="token operator">&lt;</span>bean <span class="token assign-left variable">id</span><span class="token operator">=</span><span class="token string">"userT"</span> <span class="token assign-left variable">class</span><span class="token operator">=</span><span class="token string">"com.kuang.pojo.userT"</span> <span class="token assign-left variable">name</span><span class="token operator">=</span><span class="token string">"user2 u2,u3;u4"</span><span class="token operator">></span></pre></td></tr><tr><td data-num="8"></td><td><pre> <span class="token operator">&lt;</span>property <span class="token assign-left variable">name</span><span class="token operator">=</span><span class="token string">"name"</span> <span class="token assign-left variable">value</span><span class="token operator">=</span><span class="token string">" 西部开源"</span>/<span class="token operator">></span></pre></td></tr><tr><td data-num="9"></td><td><pre><span class="token operator">&lt;</span>/bean<span class="token operator">></span></pre></td></tr></table></figure><h1 id="import"><a class="anchor" href="#import">#</a> import</h1>
<ul>
<li>这个 import, 一般用于团队开发使用,他可以将多个配置文件,导入合并为一个</li>
<li>假设,现在项目中有多个人开发,这三个人复制不同的类开发,不同的类需要注册在不同的 bean 中,我们可以利,用 import 将所有人的 beans.xmI 合并为一个总的!</li>
</ul>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>●张三</pre></td></tr><tr><td data-num="2"></td><td><pre>●李四</pre></td></tr><tr><td data-num="3"></td><td><pre>●王五</pre></td></tr><tr><td data-num="4"></td><td><pre>●applicationContext.xml</pre></td></tr><tr><td data-num="5"></td><td><pre></pre></td></tr><tr><td data-num="6"></td><td><pre><span class="token operator">&lt;</span>i mport <span class="token assign-left variable">resource</span><span class="token operator">=</span><span class="token string">"beans.xml"</span>/<span class="token operator">></span></pre></td></tr><tr><td data-num="7"></td><td><pre><span class="token operator">&lt;</span>i mport <span class="token assign-left variable">resource</span><span class="token operator">=</span><span class="token string">"beahs2.xml"</span>/<span class="token operator">></span></pre></td></tr><tr><td data-num="8"></td><td><pre><span class="token operator">&lt;</span>i mport <span class="token assign-left variable">resource</span><span class="token operator">=</span><span class="token string">"beans3.xml"</span>/<span class="token operator">></span></pre></td></tr><tr><td data-num="9"></td><td><pre></pre></td></tr><tr><td data-num="10"></td><td><pre>使用的时候,直接使用总的配置就可以了</pre></td></tr></table></figure> ]]></description>
</item>
<item>
<guid isPermalink="true">https://love.youhuamao.xyz/2022/11/20/Java/SSM/Spring/%E4%BE%9D%E8%B5%96%E6%B3%A8%E5%85%A5/</guid>
<title>依赖注入</title>
<link>https://love.youhuamao.xyz/2022/11/20/Java/SSM/Spring/%E4%BE%9D%E8%B5%96%E6%B3%A8%E5%85%A5/</link>
<category term="学习Java" scheme="https://love.youhuamao.xyz/categories/Java/" />
<category term="Java基础" scheme="https://love.youhuamao.xyz/categories/Java/Java%E5%9F%BA%E7%A1%80/" />
<category term="java" scheme="https://love.youhuamao.xyz/tags/java/" />
<pubDate>Sun, 20 Nov 2022 00:00:00 +0800</pubDate>
<description><![CDATA[ <h1 id="构造器注入"><a class="anchor" href="#构造器注入">#</a> 构造器注入</h1>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>public class Hello <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="2"></td><td><pre> private String str<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="3"></td><td><pre></pre></td></tr><tr><td data-num="4"></td><td><pre> public String <span class="token function-name function">getStr</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="5"></td><td><pre> <span class="token builtin class-name">return</span> str<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="6"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="7"></td><td><pre></pre></td></tr><tr><td data-num="8"></td><td><pre> public void setStr<span class="token punctuation">(</span>String str<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="9"></td><td><pre> this.str <span class="token operator">=</span> str<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="10"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="11"></td><td><pre></pre></td></tr><tr><td data-num="12"></td><td><pre> @Override</pre></td></tr><tr><td data-num="13"></td><td><pre> public String <span class="token function-name function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="14"></td><td><pre> <span class="token builtin class-name">return</span> <span class="token string">"Hello&#123;"</span> +</pre></td></tr><tr><td data-num="15"></td><td><pre> <span class="token string">"str='"</span> + str + <span class="token string">'\'</span>' +</pre></td></tr><tr><td data-num="16"></td><td><pre> <span class="token string">'&#125;'</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="17"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="18"></td><td><pre><span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="19"></td><td><pre></pre></td></tr><tr><td data-num="20"></td><td><pre></pre></td></tr><tr><td data-num="21"></td><td><pre></pre></td></tr><tr><td data-num="22"></td><td><pre> <span class="token operator">&lt;</span><span class="token operator">!</span>--使用Spring来创建对象,在Spring这 些都称为Bean</pre></td></tr><tr><td data-num="23"></td><td><pre> 类型 变量名<span class="token operator">=</span> new类型<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="24"></td><td><pre> Hello hello <span class="token operator">=</span> new HeLlo<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="25"></td><td><pre> <span class="token function">id</span> <span class="token operator">=</span> 变量名</pre></td></tr><tr><td data-num="26"></td><td><pre> class <span class="token operator">=</span> new 的对象<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="27"></td><td><pre> property 相当于给对象中的属性设置一个值<span class="token operator">!</span></pre></td></tr><tr><td data-num="28"></td><td><pre> <span class="token operator">!</span>--<span class="token operator">></span></pre></td></tr><tr><td data-num="29"></td><td><pre> <span class="token operator">&lt;</span>bean <span class="token assign-left variable">id</span><span class="token operator">=</span><span class="token string">"hello"</span> <span class="token assign-left variable">class</span><span class="token operator">=</span><span class="token string">"com.kuang.pojo.Hello"</span><span class="token operator">></span></pre></td></tr><tr><td data-num="30"></td><td><pre> <span class="token operator">&lt;</span>property <span class="token assign-left variable">name</span><span class="token operator">=</span><span class="token string">"str"</span> <span class="token assign-left variable">value</span><span class="token operator">=</span><span class="token string">"Spring"</span>/<span class="token operator">></span></pre></td></tr><tr><td data-num="31"></td><td><pre> <span class="token operator">&lt;</span>/bean<span class="token operator">></span></pre></td></tr></table></figure><h1 id="set方式注入"><a class="anchor" href="#set方式注入">#</a> Set 方式注入</h1>
<ul>
<li>依赖注入:set 注入</li>
<li>[环境搭建]</li>
</ul>
<ol>
<li>复杂类型</li>
</ol>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>package com.kuang.pojo<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="2"></td><td><pre></pre></td></tr><tr><td data-num="3"></td><td><pre>public class Address <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="4"></td><td><pre> public String address<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="5"></td><td><pre></pre></td></tr><tr><td data-num="6"></td><td><pre> public String <span class="token function-name function">getAddress</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="7"></td><td><pre> <span class="token builtin class-name">return</span> address<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="8"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="9"></td><td><pre></pre></td></tr><tr><td data-num="10"></td><td><pre> public void setAddress<span class="token punctuation">(</span>String address<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="11"></td><td><pre> this.address <span class="token operator">=</span> address<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="12"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="13"></td><td><pre><span class="token punctuation">&#125;</span></pre></td></tr></table></figure><ol start="2">
<li>真实测试对象</li>
</ol>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>package com.kuang.pojo<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="2"></td><td><pre></pre></td></tr><tr><td data-num="3"></td><td><pre><span class="token function">import</span> java.util.*<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="4"></td><td><pre></pre></td></tr><tr><td data-num="5"></td><td><pre>public class Student <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="6"></td><td><pre> private String name<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="7"></td><td><pre> private Address address<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="8"></td><td><pre> private String<span class="token punctuation">[</span><span class="token punctuation">]</span> books<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="9"></td><td><pre> private List<span class="token operator">&lt;</span>String<span class="token operator">></span> hobbys<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="10"></td><td><pre> private Map<span class="token operator">&lt;</span>String,String<span class="token operator">></span> card<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="11"></td><td><pre> private Set<span class="token operator">&lt;</span>String<span class="token operator">></span> games<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="12"></td><td><pre> private String wife<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="13"></td><td><pre> private Properties info<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="14"></td><td><pre></pre></td></tr><tr><td data-num="15"></td><td><pre> public String <span class="token function-name function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="16"></td><td><pre> <span class="token builtin class-name">return</span> name<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="17"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="18"></td><td><pre></pre></td></tr><tr><td data-num="19"></td><td><pre> public void setName<span class="token punctuation">(</span>String name<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="20"></td><td><pre> this.name <span class="token operator">=</span> name<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="21"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="22"></td><td><pre></pre></td></tr><tr><td data-num="23"></td><td><pre> public Address <span class="token function-name function">getAddress</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="24"></td><td><pre> <span class="token builtin class-name">return</span> address<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="25"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="26"></td><td><pre></pre></td></tr><tr><td data-num="27"></td><td><pre> public void setAddress<span class="token punctuation">(</span>Address address<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="28"></td><td><pre> this.address <span class="token operator">=</span> address<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="29"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="30"></td><td><pre></pre></td></tr><tr><td data-num="31"></td><td><pre> public String<span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token function-name function">getBooks</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="32"></td><td><pre> <span class="token builtin class-name">return</span> books<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="33"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="34"></td><td><pre></pre></td></tr><tr><td data-num="35"></td><td><pre> public void setBooks<span class="token punctuation">(</span>String<span class="token punctuation">[</span><span class="token punctuation">]</span> books<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="36"></td><td><pre> this.books <span class="token operator">=</span> books<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="37"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="38"></td><td><pre></pre></td></tr><tr><td data-num="39"></td><td><pre> public List<span class="token operator">&lt;</span>String<span class="token operator">></span> <span class="token function-name function">getHobbys</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="40"></td><td><pre> <span class="token builtin class-name">return</span> hobbys<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="41"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="42"></td><td><pre></pre></td></tr><tr><td data-num="43"></td><td><pre> public void setHobbys<span class="token punctuation">(</span>List<span class="token operator">&lt;</span>String<span class="token operator">></span> hobbys<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="44"></td><td><pre> this.hobbys <span class="token operator">=</span> hobbys<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="45"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="46"></td><td><pre></pre></td></tr><tr><td data-num="47"></td><td><pre> public Map<span class="token operator">&lt;</span>String, String<span class="token operator">></span> <span class="token function-name function">getCard</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="48"></td><td><pre> <span class="token builtin class-name">return</span> card<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="49"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="50"></td><td><pre></pre></td></tr><tr><td data-num="51"></td><td><pre> public void setCard<span class="token punctuation">(</span>Map<span class="token operator">&lt;</span>String, String<span class="token operator">></span> card<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="52"></td><td><pre> this.card <span class="token operator">=</span> card<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="53"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="54"></td><td><pre></pre></td></tr><tr><td data-num="55"></td><td><pre> public Set<span class="token operator">&lt;</span>String<span class="token operator">></span> <span class="token function-name function">getGames</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="56"></td><td><pre> <span class="token builtin class-name">return</span> games<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="57"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="58"></td><td><pre></pre></td></tr><tr><td data-num="59"></td><td><pre> public void setGames<span class="token punctuation">(</span>Set<span class="token operator">&lt;</span>String<span class="token operator">></span> games<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="60"></td><td><pre> this.games <span class="token operator">=</span> games<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="61"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="62"></td><td><pre></pre></td></tr><tr><td data-num="63"></td><td><pre> public String <span class="token function-name function">getWife</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="64"></td><td><pre> <span class="token builtin class-name">return</span> wife<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="65"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="66"></td><td><pre></pre></td></tr><tr><td data-num="67"></td><td><pre> public void setWife<span class="token punctuation">(</span>String wife<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="68"></td><td><pre> this.wife <span class="token operator">=</span> wife<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="69"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="70"></td><td><pre></pre></td></tr><tr><td data-num="71"></td><td><pre> public Properties <span class="token function-name function">getInfo</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="72"></td><td><pre> <span class="token builtin class-name">return</span> info<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="73"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="74"></td><td><pre></pre></td></tr><tr><td data-num="75"></td><td><pre> public void setInfo<span class="token punctuation">(</span>Properties info<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="76"></td><td><pre> this.info <span class="token operator">=</span> info<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="77"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="78"></td><td><pre></pre></td></tr><tr><td data-num="79"></td><td><pre> @Override</pre></td></tr><tr><td data-num="80"></td><td><pre> public String <span class="token function-name function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="81"></td><td><pre> <span class="token builtin class-name">return</span> <span class="token string">"Studen&#123;"</span> +</pre></td></tr><tr><td data-num="82"></td><td><pre> <span class="token string">"name='"</span> + name + <span class="token string">'\'</span>' +</pre></td></tr><tr><td data-num="83"></td><td><pre> <span class="token string">", address="</span> + address +</pre></td></tr><tr><td data-num="84"></td><td><pre> <span class="token string">", books="</span> + Arrays.toString<span class="token punctuation">(</span>books<span class="token punctuation">)</span> +</pre></td></tr><tr><td data-num="85"></td><td><pre> <span class="token string">", hobbys="</span> + hobbys +</pre></td></tr><tr><td data-num="86"></td><td><pre> <span class="token string">", card="</span> + card +</pre></td></tr><tr><td data-num="87"></td><td><pre> <span class="token string">", games="</span> + games +</pre></td></tr><tr><td data-num="88"></td><td><pre> <span class="token string">", wife='"</span> + wife + <span class="token string">'\'</span>' +</pre></td></tr><tr><td data-num="89"></td><td><pre> <span class="token string">", info="</span> + info +</pre></td></tr><tr><td data-num="90"></td><td><pre> <span class="token string">'&#125;'</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="91"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="92"></td><td><pre><span class="token punctuation">&#125;</span></pre></td></tr></table></figure><ol start="3">
<li>beans.xml</li>
</ol>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token operator">&lt;</span>?xml <span class="token assign-left variable">version</span><span class="token operator">=</span><span class="token string">"1.0"</span> <span class="token assign-left variable">encoding</span><span class="token operator">=</span> <span class="token string">"UTF-8"</span>?<span class="token operator">></span></pre></td></tr><tr><td data-num="2"></td><td><pre><span class="token operator">&lt;</span>beans <span class="token assign-left variable">xmlns</span><span class="token operator">=</span><span class="token string">"http://www.springframework.org/schema/beans"</span></pre></td></tr><tr><td data-num="3"></td><td><pre> xmlns:xsi<span class="token operator">=</span><span class="token string">"http://www.w3.org/2001/XMLSchema-instance"</span></pre></td></tr><tr><td data-num="4"></td><td><pre> xsi:schemaLocation<span class="token operator">=</span> <span class="token string">"http://www.springframework.org/schema/beans</pre></td></tr><tr><td data-num="5"></td><td><pre> https://www.springframework.org/schema/beans/spring-beans.xsd"</span><span class="token operator">></span></pre></td></tr><tr><td data-num="6"></td><td><pre></pre></td></tr><tr><td data-num="7"></td><td><pre> <span class="token operator">&lt;</span>bean <span class="token assign-left variable">id</span><span class="token operator">=</span><span class="token string">"student"</span> <span class="token assign-left variable">class</span><span class="token operator">=</span><span class="token string">"com.kuang.pojo.Student"</span><span class="token operator">></span></pre></td></tr><tr><td data-num="8"></td><td><pre> <span class="token operator">&lt;</span>property <span class="token assign-left variable">name</span><span class="token operator">=</span><span class="token string">"name"</span> <span class="token assign-left variable">value</span><span class="token operator">=</span><span class="token string">"幽化猫"</span>/<span class="token operator">></span></pre></td></tr><tr><td data-num="9"></td><td><pre> <span class="token operator">&lt;</span>/bean<span class="token operator">></span></pre></td></tr><tr><td data-num="10"></td><td><pre><span class="token operator">&lt;</span>/beans<span class="token operator">></span></pre></td></tr></table></figure><ol start="4">
<li>测试类</li>
</ol>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>public static void main<span class="token punctuation">(</span>String<span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="2"></td><td><pre> ApplicationContext context <span class="token operator">=</span> new ClassPathXmlApplicationContext<span class="token punctuation">(</span><span class="token string">"beans.xml"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="3"></td><td><pre> Student student <span class="token operator">=</span> <span class="token punctuation">(</span>Student<span class="token punctuation">)</span> context.getBean<span class="token punctuation">(</span><span class="token string">"student"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="4"></td><td><pre> System.out.println<span class="token punctuation">(</span>student.getName<span class="token punctuation">(</span><span class="token punctuation">))</span><span class="token punctuation">;</span></pre></td></tr></table></figure><ol start="5">
<li>完善注入信息</li>
</ol>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token operator">&lt;</span>bean <span class="token assign-left variable">id</span><span class="token operator">=</span><span class="token string">"address"</span> <span class="token assign-left variable">class</span><span class="token operator">=</span><span class="token string">"com.kuang.pojo.Address"</span><span class="token operator">></span></pre></td></tr><tr><td data-num="2"></td><td><pre> <span class="token operator">&lt;</span>property <span class="token assign-left variable">name</span><span class="token operator">=</span><span class="token string">"address"</span> <span class="token assign-left variable">value</span><span class="token operator">=</span><span class="token string">"河南"</span>/<span class="token operator">></span></pre></td></tr><tr><td data-num="3"></td><td><pre> <span class="token operator">&lt;</span>/bean<span class="token operator">></span></pre></td></tr><tr><td data-num="4"></td><td><pre></pre></td></tr><tr><td data-num="5"></td><td><pre></pre></td></tr><tr><td data-num="6"></td><td><pre> <span class="token operator">&lt;</span>bean <span class="token assign-left variable">id</span><span class="token operator">=</span><span class="token string">"student"</span> <span class="token assign-left variable">class</span><span class="token operator">=</span><span class="token string">"com.kuang.pojo.Student"</span><span class="token operator">></span></pre></td></tr><tr><td data-num="7"></td><td><pre> <span class="token operator">&lt;</span><span class="token operator">!</span>-- 第一种,普通值注入:value--<span class="token operator">></span></pre></td></tr><tr><td data-num="8"></td><td><pre> <span class="token operator">&lt;</span>property <span class="token assign-left variable">name</span><span class="token operator">=</span><span class="token string">"name"</span> <span class="token assign-left variable">value</span><span class="token operator">=</span><span class="token string">"幽化猫"</span>/<span class="token operator">></span></pre></td></tr><tr><td data-num="9"></td><td><pre></pre></td></tr><tr><td data-num="10"></td><td><pre> <span class="token operator">&lt;</span><span class="token operator">!</span>-- 第二种,Bean注入:ref--<span class="token operator">></span></pre></td></tr><tr><td data-num="11"></td><td><pre> <span class="token operator">&lt;</span>property <span class="token assign-left variable">name</span><span class="token operator">=</span><span class="token string">"address"</span> <span class="token assign-left variable">ref</span><span class="token operator">=</span><span class="token string">"address"</span>/<span class="token operator">></span></pre></td></tr><tr><td data-num="12"></td><td><pre></pre></td></tr><tr><td data-num="13"></td><td><pre> <span class="token operator">&lt;</span><span class="token operator">!</span>-- 数组--<span class="token operator">></span></pre></td></tr><tr><td data-num="14"></td><td><pre> <span class="token operator">&lt;</span>property <span class="token assign-left variable">name</span><span class="token operator">=</span><span class="token string">"books"</span><span class="token operator">></span></pre></td></tr><tr><td data-num="15"></td><td><pre> <span class="token operator">&lt;</span>array<span class="token operator">></span></pre></td></tr><tr><td data-num="16"></td><td><pre> <span class="token operator">&lt;</span>value<span class="token operator">></span>红楼梦<span class="token operator">&lt;</span>/value<span class="token operator">></span></pre></td></tr><tr><td data-num="17"></td><td><pre> <span class="token operator">&lt;</span>value<span class="token operator">></span>西游记<span class="token operator">&lt;</span>/value<span class="token operator">></span></pre></td></tr><tr><td data-num="18"></td><td><pre> <span class="token operator">&lt;</span>value<span class="token operator">></span>水浒传<span class="token operator">&lt;</span>/value<span class="token operator">></span></pre></td></tr><tr><td data-num="19"></td><td><pre> <span class="token operator">&lt;</span>value<span class="token operator">></span>三国演义<span class="token operator">&lt;</span>/value<span class="token operator">></span></pre></td></tr><tr><td data-num="20"></td><td><pre> <span class="token operator">&lt;</span>/array<span class="token operator">></span></pre></td></tr><tr><td data-num="21"></td><td><pre> <span class="token operator">&lt;</span>/property<span class="token operator">></span></pre></td></tr><tr><td data-num="22"></td><td><pre></pre></td></tr><tr><td data-num="23"></td><td><pre> <span class="token operator">&lt;</span><span class="token operator">!</span>--List--<span class="token operator">></span></pre></td></tr><tr><td data-num="24"></td><td><pre> <span class="token operator">&lt;</span>property <span class="token assign-left variable">name</span><span class="token operator">=</span> <span class="token string">"hobbys"</span><span class="token operator">></span></pre></td></tr><tr><td data-num="25"></td><td><pre> <span class="token operator">&lt;</span>list<span class="token operator">></span></pre></td></tr><tr><td data-num="26"></td><td><pre> <span class="token operator">&lt;</span>value<span class="token operator">></span>听歌<span class="token operator">&lt;</span>/value<span class="token operator">></span></pre></td></tr><tr><td data-num="27"></td><td><pre> <span class="token operator">&lt;</span>value<span class="token operator">></span>敲代码<span class="token operator">&lt;</span>/value<span class="token operator">></span></pre></td></tr><tr><td data-num="28"></td><td><pre> <span class="token operator">&lt;</span>value<span class="token operator">></span>看电影<span class="token operator">&lt;</span>/value<span class="token operator">></span></pre></td></tr><tr><td data-num="29"></td><td><pre> <span class="token operator">&lt;</span>/list<span class="token operator">></span></pre></td></tr><tr><td data-num="30"></td><td><pre> <span class="token operator">&lt;</span>/property<span class="token operator">></span></pre></td></tr><tr><td data-num="31"></td><td><pre></pre></td></tr><tr><td data-num="32"></td><td><pre> <span class="token operator">&lt;</span><span class="token operator">!</span>--Map--<span class="token operator">></span></pre></td></tr><tr><td data-num="33"></td><td><pre> <span class="token operator">&lt;</span>property <span class="token assign-left variable">name</span><span class="token operator">=</span> <span class="token string">"card"</span><span class="token operator">></span></pre></td></tr><tr><td data-num="34"></td><td><pre> <span class="token operator">&lt;</span>map<span class="token operator">></span></pre></td></tr><tr><td data-num="35"></td><td><pre> <span class="token operator">&lt;</span>entry <span class="token assign-left variable">key</span><span class="token operator">=</span><span class="token string">"身份证"</span> <span class="token assign-left variable">value</span><span class="token operator">=</span><span class="token string">"111111222222223333"</span>/<span class="token operator">></span></pre></td></tr><tr><td data-num="36"></td><td><pre> <span class="token operator">&lt;</span>entry <span class="token assign-left variable">key</span><span class="token operator">=</span><span class="token string">"银行卡"</span> <span class="token assign-left variable">value</span><span class="token operator">=</span><span class="token string">"1321231312312313123"</span>/<span class="token operator">></span></pre></td></tr><tr><td data-num="37"></td><td><pre> <span class="token operator">&lt;</span>/map<span class="token operator">></span></pre></td></tr><tr><td data-num="38"></td><td><pre> <span class="token operator">&lt;</span>/property<span class="token operator">></span></pre></td></tr><tr><td data-num="39"></td><td><pre></pre></td></tr><tr><td data-num="40"></td><td><pre> <span class="token operator">&lt;</span><span class="token operator">!</span>--Set--<span class="token operator">></span></pre></td></tr><tr><td data-num="41"></td><td><pre> <span class="token operator">&lt;</span>property <span class="token assign-left variable">name</span><span class="token operator">=</span><span class="token string">"games"</span><span class="token operator">></span></pre></td></tr><tr><td data-num="42"></td><td><pre> <span class="token operator">&lt;</span>set<span class="token operator">></span></pre></td></tr><tr><td data-num="43"></td><td><pre> <span class="token operator">&lt;</span>value<span class="token operator">></span>LOL<span class="token operator">&lt;</span>/value<span class="token operator">></span></pre></td></tr><tr><td data-num="44"></td><td><pre> <span class="token operator">&lt;</span>value<span class="token operator">></span>C0C<span class="token operator">&lt;</span>/value<span class="token operator">></span></pre></td></tr><tr><td data-num="45"></td><td><pre> <span class="token operator">&lt;</span>value<span class="token operator">></span>BOB<span class="token operator">&lt;</span>/value<span class="token operator">></span></pre></td></tr><tr><td data-num="46"></td><td><pre> <span class="token operator">&lt;</span>/set<span class="token operator">></span></pre></td></tr><tr><td data-num="47"></td><td><pre> <span class="token operator">&lt;</span>/property<span class="token operator">></span></pre></td></tr><tr><td data-num="48"></td><td><pre></pre></td></tr><tr><td data-num="49"></td><td><pre> <span class="token operator">&lt;</span><span class="token operator">!</span>--null--<span class="token operator">></span></pre></td></tr><tr><td data-num="50"></td><td><pre> <span class="token operator">&lt;</span>property <span class="token assign-left variable">name</span><span class="token operator">=</span><span class="token string">"wife"</span><span class="token operator">></span></pre></td></tr><tr><td data-num="51"></td><td><pre> <span class="token operator">&lt;</span>null/<span class="token operator">></span></pre></td></tr><tr><td data-num="52"></td><td><pre> <span class="token operator">&lt;</span>/property<span class="token operator">></span></pre></td></tr><tr><td data-num="53"></td><td><pre></pre></td></tr><tr><td data-num="54"></td><td><pre> <span class="token operator">&lt;</span><span class="token operator">!</span>-- properties--<span class="token operator">></span></pre></td></tr><tr><td data-num="55"></td><td><pre> <span class="token operator">&lt;</span>property <span class="token assign-left variable">name</span><span class="token operator">=</span><span class="token string">"info"</span><span class="token operator">></span></pre></td></tr><tr><td data-num="56"></td><td><pre> <span class="token operator">&lt;</span>props<span class="token operator">></span></pre></td></tr><tr><td data-num="57"></td><td><pre> <span class="token operator">&lt;</span>prop <span class="token assign-left variable">key</span><span class="token operator">=</span><span class="token string">"driver"</span><span class="token operator">></span><span class="token number">2019052</span><span class="token operator"><span class="token file-descriptor important">5</span>&lt;</span>/prop<span class="token operator">></span></pre></td></tr><tr><td data-num="58"></td><td><pre> <span class="token operator">&lt;</span>prop <span class="token assign-left variable">key</span><span class="token operator">=</span><span class="token string">"url"</span><span class="token operator">></span>男<span class="token operator">&lt;</span>/prop<span class="token operator">></span></pre></td></tr><tr><td data-num="59"></td><td><pre> <span class="token operator">&lt;</span>prop <span class="token assign-left variable">key</span><span class="token operator">=</span><span class="token string">"username"</span><span class="token operator">></span>root<span class="token operator">&lt;</span>/prop<span class="token operator">></span></pre></td></tr><tr><td data-num="60"></td><td><pre> <span class="token operator">&lt;</span>prop <span class="token assign-left variable">key</span><span class="token operator">=</span><span class="token string">"password"</span><span class="token operator">></span><span class="token number">12345</span><span class="token operator"><span class="token file-descriptor important">6</span>&lt;</span>/prop<span class="token operator">></span></pre></td></tr><tr><td data-num="61"></td><td><pre> <span class="token operator">&lt;</span>/props<span class="token operator">></span></pre></td></tr><tr><td data-num="62"></td><td><pre> <span class="token operator">&lt;</span>/property<span class="token operator">></span></pre></td></tr><tr><td data-num="63"></td><td><pre></pre></td></tr><tr><td data-num="64"></td><td><pre> <span class="token operator">&lt;</span>/bean<span class="token operator">></span></pre></td></tr></table></figure><h1 id="拓展方式注入"><a class="anchor" href="#拓展方式注入">#</a> 拓展方式注入</h1>
<ul>
<li>c 命名和 p 命名和</li>
</ul>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>使用</pre></td></tr><tr><td data-num="2"></td><td><pre><span class="token operator">&lt;</span>?xml <span class="token assign-left variable">version</span><span class="token operator">=</span><span class="token string">"1.0"</span> <span class="token assign-left variable">encoding</span><span class="token operator">=</span> <span class="token string">"UTF-8"</span>?<span class="token operator">></span></pre></td></tr><tr><td data-num="3"></td><td><pre><span class="token operator">&lt;</span>beans <span class="token assign-left variable">xmlns</span><span class="token operator">=</span><span class="token string">"http://www.springframework.org/schema/beans"</span></pre></td></tr><tr><td data-num="4"></td><td><pre> xmlns:xsi<span class="token operator">=</span><span class="token string">"http://www.w3.org/2001/XMLSchema-instance"</span></pre></td></tr><tr><td data-num="5"></td><td><pre> xmlns:p<span class="token operator">=</span><span class="token string">"http://www.springframework.org/schema/p"</span></pre></td></tr><tr><td data-num="6"></td><td><pre> xmlns:c<span class="token operator">=</span><span class="token string">"http://www.springframework.org/schema/c"</span></pre></td></tr><tr><td data-num="7"></td><td><pre> xsi:schemaLocation<span class="token operator">=</span> <span class="token string">"http://www.springframework.org/schema/beans</pre></td></tr><tr><td data-num="8"></td><td><pre> https://www.springframework.org/schema/beans/spring-beans.xsd"</span><span class="token operator">></span></pre></td></tr><tr><td data-num="9"></td><td><pre></pre></td></tr><tr><td data-num="10"></td><td><pre> <span class="token operator">&lt;</span><span class="token operator">!</span>--p命名空间注入,可以直接注入属性的值: property--<span class="token operator">></span></pre></td></tr><tr><td data-num="11"></td><td><pre> <span class="token operator">&lt;</span>bean <span class="token assign-left variable">id</span><span class="token operator">=</span><span class="token string">"user"</span> <span class="token assign-left variable">class</span><span class="token operator">=</span><span class="token string">"com.kuang.pojo.User"</span> p:age<span class="token operator">=</span><span class="token string">"18"</span> p:name<span class="token operator">=</span><span class="token string">"幽化猫"</span>/<span class="token operator">></span></pre></td></tr><tr><td data-num="12"></td><td><pre></pre></td></tr><tr><td data-num="13"></td><td><pre> <span class="token operator">&lt;</span><span class="token operator">!</span>--c命名空间注入,通过构造器注入: construct-args--<span class="token operator">></span></pre></td></tr><tr><td data-num="14"></td><td><pre> <span class="token operator">&lt;</span>bean <span class="token assign-left variable">id</span><span class="token operator">=</span><span class="token string">"user"</span> <span class="token assign-left variable">class</span><span class="token operator">=</span><span class="token string">"com.kuang.pojo.User"</span> c:age<span class="token operator">=</span><span class="token string">"18"</span> p:name<span class="token operator">=</span><span class="token string">"易知鱼"</span>/<span class="token operator">></span></pre></td></tr><tr><td data-num="15"></td><td><pre><span class="token operator">&lt;</span>/beans<span class="token operator">></span></pre></td></tr></table></figure><figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>测试</pre></td></tr><tr><td data-num="2"></td><td><pre> @Test</pre></td></tr><tr><td data-num="3"></td><td><pre> public void <span class="token function-name function">test2</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="4"></td><td><pre> ApplicationContext context <span class="token operator">=</span> new ClassPathXmlApplicationContext<span class="token punctuation">(</span><span class="token string">"userbeans.xml"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="5"></td><td><pre> User user <span class="token operator">=</span> context.getBean<span class="token punctuation">(</span><span class="token string">"user"</span>, User.class<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="6"></td><td><pre> System.out.println<span class="token punctuation">(</span>user<span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="7"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr></table></figure><ul>
<li>注意点</li>
</ul>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>注意点: p命名和c命名空间不能直接使用,需要导入xml约束<span class="token operator">!</span></pre></td></tr><tr><td data-num="2"></td><td><pre>xmlns:c<span class="token operator">=</span><span class="token string">"http://www.springframework.org/schema/c"</span></pre></td></tr><tr><td data-num="3"></td><td><pre>xm1ns:p<span class="token operator">=</span><span class="token string">"http://www.springframework.org/schema/p"</span></pre></td></tr></table></figure><h1 id="bean的作用域"><a class="anchor" href="#bean的作用域">#</a> bean 的作用域</h1>
<ul>
<li>单例模式 (Spring 默认机制)(getbean 获取的都是同一个对象)</li>
</ul>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token operator">&lt;</span>bean <span class="token assign-left variable">id</span><span class="token operator">=</span><span class="token string">"user2"</span> <span class="token assign-left variable">class</span><span class="token operator">=</span><span class="token string">"com. kuang. pojo.User"</span> c:age<span class="token operator">=</span><span class="token string">"18"</span> c:name<span class="token operator">=</span><span class="token string">"狂神"</span> <span class="token assign-left variable">scope</span><span class="token operator">=</span><span class="token string">"singleton"</span>/<span class="token operator">></span></pre></td></tr></table></figure><ul>
<li>原型模式:每次从容器中 get 的时候,都会产生一个新对象!</li>
</ul>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token operator">&lt;</span>bean i <span class="token assign-left variable">d</span><span class="token operator">=</span><span class="token string">"accountService"</span> <span class="token assign-left variable">class</span><span class="token operator">=</span><span class="token string">"com. something. DefaultAccountService"</span> <span class="token assign-left variable">scope</span><span class="token operator">=</span><span class="token string">"prototype"</span>/<span class="token operator">></span></pre></td></tr></table></figure><ul>
<li>其余的 request、session、 application、 这些个只能在 web 开发中使用到!</li>
</ul>
]]></description>
</item>
<item>
<guid isPermalink="true">https://love.youhuamao.xyz/2022/11/19/Java/SSM/Spring/HelloSpring/</guid>
<title>HelloSpring</title>
<link>https://love.youhuamao.xyz/2022/11/19/Java/SSM/Spring/HelloSpring/</link>
<category term="学习Java" scheme="https://love.youhuamao.xyz/categories/Java/" />
<category term="Java基础" scheme="https://love.youhuamao.xyz/categories/Java/Java%E5%9F%BA%E7%A1%80/" />
<category term="java" scheme="https://love.youhuamao.xyz/tags/java/" />
<pubDate>Sat, 19 Nov 2022 00:00:00 +0800</pubDate>
<description><![CDATA[ <h1 id="xml文件"><a class="anchor" href="#xml文件">#</a> xml 文件</h1>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token operator">&lt;</span>?xml <span class="token assign-left variable">version</span><span class="token operator">=</span><span class="token string">"1.0"</span> <span class="token assign-left variable">encoding</span><span class="token operator">=</span> <span class="token string">"UTF-8"</span>?<span class="token operator">></span></pre></td></tr><tr><td data-num="2"></td><td><pre><span class="token operator">&lt;</span>beans <span class="token assign-left variable">xmlns</span><span class="token operator">=</span><span class="token string">"http://www.springframework.org/schema/beans"</span></pre></td></tr><tr><td data-num="3"></td><td><pre> xmlns:xsi<span class="token operator">=</span><span class="token string">"http://www.w3.org/2001/XMLSchema-instance"</span></pre></td></tr><tr><td data-num="4"></td><td><pre> xsi:schemaLocation<span class="token operator">=</span> <span class="token string">"http://www.springframework.org/schema/beans</pre></td></tr><tr><td data-num="5"></td><td><pre> https://www.springframework.org/schema/beans/spring-beans.xsd"</span><span class="token operator">></span></pre></td></tr><tr><td data-num="6"></td><td><pre> <span class="token operator">&lt;</span><span class="token operator">!</span>--使用Spring来创建对象,在Spring这 些都称为Bean</pre></td></tr><tr><td data-num="7"></td><td><pre> 类型 变量名<span class="token operator">=</span> new类型<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="8"></td><td><pre> Hello hello <span class="token operator">=</span> new HeLlo<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="9"></td><td><pre> <span class="token function">id</span> <span class="token operator">=</span> 变量名</pre></td></tr><tr><td data-num="10"></td><td><pre> class <span class="token operator">=</span> new 的对象<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="11"></td><td><pre> property 相当于给对象中的属性设置一个值<span class="token operator">!</span></pre></td></tr><tr><td data-num="12"></td><td><pre> <span class="token operator">!</span>--<span class="token operator">></span></pre></td></tr><tr><td data-num="13"></td><td><pre> <span class="token operator">&lt;</span>bean <span class="token assign-left variable">id</span><span class="token operator">=</span><span class="token string">"hello"</span> <span class="token assign-left variable">class</span><span class="token operator">=</span><span class="token string">"com.kuang.pojo.Hello"</span><span class="token operator">></span></pre></td></tr><tr><td data-num="14"></td><td><pre> <span class="token operator">&lt;</span>property <span class="token assign-left variable">name</span><span class="token operator">=</span><span class="token string">"str"</span> <span class="token assign-left variable">value</span><span class="token operator">=</span><span class="token string">"Spring"</span>/<span class="token operator">></span></pre></td></tr><tr><td data-num="15"></td><td><pre> <span class="token operator">&lt;</span>/bean<span class="token operator">></span></pre></td></tr><tr><td data-num="16"></td><td><pre></pre></td></tr><tr><td data-num="17"></td><td><pre><span class="token operator">&lt;</span>/beans<span class="token operator">></span></pre></td></tr></table></figure><h1 id="测试"><a class="anchor" href="#测试">#</a> 测试</h1>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>//获取spring上下文内对象</pre></td></tr><tr><td data-num="2"></td><td><pre> ApplicationContext context <span class="token operator">=</span> new ClassPathXmlApplicationContext<span class="token punctuation">(</span><span class="token string">"beans.xml"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="3"></td><td><pre> //我没的对象都在Spring中的管理,如果要使用,直接拿出来就好了</pre></td></tr><tr><td data-num="4"></td><td><pre> Hello hello <span class="token operator">=</span> <span class="token punctuation">(</span>Hello<span class="token punctuation">)</span> context.getBean<span class="token punctuation">(</span><span class="token string">"hello"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="5"></td><td><pre></pre></td></tr><tr><td data-num="6"></td><td><pre> System.out.println<span class="token punctuation">(</span>hello.toString<span class="token punctuation">(</span><span class="token punctuation">))</span><span class="token punctuation">;</span></pre></td></tr></table></figure><h1 id="例一"><a class="anchor" href="#例一">#</a> 例一</h1>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token operator">&lt;</span>?xml <span class="token assign-left variable">version</span><span class="token operator">=</span><span class="token string">"1.0"</span> <span class="token assign-left variable">encoding</span><span class="token operator">=</span> <span class="token string">"UTF-8"</span>?<span class="token operator">></span></pre></td></tr><tr><td data-num="2"></td><td><pre><span class="token operator">&lt;</span>beans <span class="token assign-left variable">xmlns</span><span class="token operator">=</span><span class="token string">"http://www.springframework.org/schema/beans"</span></pre></td></tr><tr><td data-num="3"></td><td><pre> xmlns:xsi<span class="token operator">=</span><span class="token string">"http://www.w3.org/2001/XMLSchema-instance"</span></pre></td></tr><tr><td data-num="4"></td><td><pre> xsi:schemaLocation<span class="token operator">=</span> <span class="token string">"http://www.springframework.org/schema/beans</pre></td></tr><tr><td data-num="5"></td><td><pre> https://www.springframework.org/schema/beans/spring-beans.xsd"</span><span class="token operator">></span></pre></td></tr><tr><td data-num="6"></td><td><pre> <span class="token operator">&lt;</span><span class="token operator">!</span>--使用Spring来创建对象,在Spring这 些都称为Bean</pre></td></tr><tr><td data-num="7"></td><td><pre> 类型 变量名<span class="token operator">=</span> new类型<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="8"></td><td><pre> Hello hello <span class="token operator">=</span> new HeLlo<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="9"></td><td><pre> <span class="token function">id</span> <span class="token operator">=</span> 变量名</pre></td></tr><tr><td data-num="10"></td><td><pre> class <span class="token operator">=</span> new 的对象<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="11"></td><td><pre> property 相当于给对象中的属性设置一个值<span class="token operator">!</span></pre></td></tr><tr><td data-num="12"></td><td><pre> <span class="token operator">!</span>--<span class="token operator">></span></pre></td></tr><tr><td data-num="13"></td><td><pre> <span class="token operator">&lt;</span>bean <span class="token assign-left variable">id</span><span class="token operator">=</span><span class="token string">"hello"</span> <span class="token assign-left variable">class</span><span class="token operator">=</span><span class="token string">"com.kuang.pojo.Hello"</span><span class="token operator">></span></pre></td></tr><tr><td data-num="14"></td><td><pre> <span class="token operator">&lt;</span>property <span class="token assign-left variable">name</span><span class="token operator">=</span><span class="token string">"str"</span> <span class="token assign-left variable">value</span><span class="token operator">=</span><span class="token string">"Spring"</span>/<span class="token operator">></span></pre></td></tr><tr><td data-num="15"></td><td><pre> <span class="token operator">&lt;</span>/bean<span class="token operator">></span></pre></td></tr><tr><td data-num="16"></td><td><pre></pre></td></tr><tr><td data-num="17"></td><td><pre><span class="token operator">&lt;</span>/beans<span class="token operator">></span></pre></td></tr><tr><td data-num="18"></td><td><pre></pre></td></tr><tr><td data-num="19"></td><td><pre></pre></td></tr><tr><td data-num="20"></td><td><pre></pre></td></tr><tr><td data-num="21"></td><td><pre></pre></td></tr><tr><td data-num="22"></td><td><pre> //获取ApplicationContext,拿到Spring的容器</pre></td></tr><tr><td data-num="23"></td><td><pre> ApplicationContext context <span class="token operator">=</span> new ClassPathXmlApplicationContext<span class="token punctuation">(</span><span class="token string">"beans.xml"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="24"></td><td><pre></pre></td></tr><tr><td data-num="25"></td><td><pre> //拿到容器之后,需要什么就直接get什么</pre></td></tr><tr><td data-num="26"></td><td><pre> UserServiceImpl userServiceImpl <span class="token operator">=</span><span class="token punctuation">(</span>UserServiceImpl<span class="token punctuation">)</span> context.getBean<span class="token punctuation">(</span><span class="token string">"UserServiceImpl"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="27"></td><td><pre></pre></td></tr><tr><td data-num="28"></td><td><pre> userServiceImpl.getUser<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr></table></figure> ]]></description>
</item>
<item>
<guid isPermalink="true">https://love.youhuamao.xyz/2022/11/19/Java/SSM/Spring/IOC%E7%90%86%E8%AE%BA%E6%8E%A8%E5%AF%BC/</guid>
<title>IOC理论推导</title>
<link>https://love.youhuamao.xyz/2022/11/19/Java/SSM/Spring/IOC%E7%90%86%E8%AE%BA%E6%8E%A8%E5%AF%BC/</link>
<category term="学习Java" scheme="https://love.youhuamao.xyz/categories/Java/" />
<category term="Java基础" scheme="https://love.youhuamao.xyz/categories/Java/Java%E5%9F%BA%E7%A1%80/" />
<category term="java" scheme="https://love.youhuamao.xyz/tags/java/" />
<pubDate>Sat, 19 Nov 2022 00:00:00 +0800</pubDate>
<description><![CDATA[ <ul>
<li>我们使用一个 Set 接口实现。已经发生了革命性的变化!</li>
</ul>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>private UserDao userDao<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="2"></td><td><pre></pre></td></tr><tr><td data-num="3"></td><td><pre> //利用set进行动态实现值的注入</pre></td></tr><tr><td data-num="4"></td><td><pre> public void setUserDao<span class="token punctuation">(</span>UserDao userDao<span class="token punctuation">)</span><span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="5"></td><td><pre> this.userDao <span class="token operator">=</span> userDao<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="6"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr></table></figure><ul>
<li>之前,程序是主动创建对象!控制权在程序猿手。上!</li>
<li>使用了 set 注入后,程序不再具有主动性,而是变成了被动的接受对象!</li>
<li>这种思想,从本质上解决了问题,我们程序猿不用再去管理对象的创建了。系统的耦合性大大降低~,可以更加专注的在业务的实现上!</li>
</ul>
<h1 id="ioc本质"><a class="anchor" href="#ioc本质">#</a> IOC 本质</h1>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>控制反转IoC<span class="token punctuation">(</span>Inversion of Control<span class="token punctuation">)</span>,是一种设计思想,DI<span class="token punctuation">(</span>依赖注入<span class="token punctuation">)</span>是实现IoC的一 种方法,也有人认为DI只是IoC的另一种说法。 没有IoC的程序中,我们使用面向对象编程,对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,个人认为所谓控制反转就是:获得依赖对象的方式反转了。</pre></td></tr><tr><td data-num="2"></td><td><pre></pre></td></tr><tr><td data-num="3"></td><td><pre>采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为- -体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。</pre></td></tr><tr><td data-num="4"></td><td><pre></pre></td></tr><tr><td data-num="5"></td><td><pre>**控制反转是一种通过描述<span class="token punctuation">(</span>XML或注解<span class="token punctuation">)</span>并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是IoC容器,其实现方法是依赖注入<span class="token punctuation">(</span>Dependency Injection,DI<span class="token punctuation">)</span>。</pre></td></tr><tr><td data-num="6"></td><td><pre>**</pre></td></tr></table></figure> ]]></description>
</item>
<item>
<guid isPermalink="true">https://love.youhuamao.xyz/2022/11/12/ai/Andrew%20Ng%20Lesson/%E9%99%8D%E7%BB%B4/</guid>
<title>Dimensionality Reduction 降维</title>
<link>https://love.youhuamao.xyz/2022/11/12/ai/Andrew%20Ng%20Lesson/%E9%99%8D%E7%BB%B4/</link>
<category term="ai" scheme="https://love.youhuamao.xyz/categories/ai/" />
<category term="Andrew Ng Lesson" scheme="https://love.youhuamao.xyz/categories/ai/Andrew-Ng-Lesson/" />
<category term="ai lesson" scheme="https://love.youhuamao.xyz/tags/ai-lesson/" />
<pubDate>Sat, 12 Nov 2022 00:00:00 +0800</pubDate>
<description><![CDATA[ <h1 id="降维的动机一数据压缩-data-compression"><a class="anchor" href="#降维的动机一数据压缩-data-compression">#</a> 降维的动机一:数据压缩 Data Compression</h1>
<p>现在讨论第二种无监督学习问题:降维。 降维的一个作用是数据压缩,允许我们使用较少的内存或磁盘空间,也加快算法速度。</p>
<p>举例:<br />
假设用两个特征描述同一个物品的长度,x1 单位是厘米 cm,x2 单位是英寸 inches。这将导致高度冗余,所以需要减到一维。<br />
<img data-src="/pic/wuenda/jiangwei-01.png" alt="img.png" /></p>
<p>将数据从三维降至二维:将三维向量投射到一个二维的平面上,强迫使得所有的数据都在同一个平面上,降至二维的特征向量。<br />
<img data-src="/pic/wuenda/jiangwei-02.png" alt="img.png" /></p>
<p>这个过程可以用于把任何维度的数据降到任何想要的维度。事实工作中,不同的团队可能会给你几百或成千上万的特征,其中很容易出现冗余特征。</p>
<h1 id="降维的动机二数据可视化-visualization"><a class="anchor" href="#降维的动机二数据可视化-visualization">#</a> 降维的动机二:数据可视化 Visualization</h1>
<p>降维可以帮助我们将高维数据可视化。<br />
假使有关于许多不同国家的数据,每一个特征向量都有 50 个特征 (如 GDP,人均 GDP,平均寿命等)。如果要将这个 50 维的数据可视化是不可能的。将其降至 2 维,便可将其可视化了。<br />
<img data-src="/pic/wuenda/jiangwei-03.png" alt="img.png" /><br />
<img data-src="/pic/wuenda/jiangwei-04.png" alt="img.png" /><br />
<img data-src="/pic/wuenda/jiangwei-05.png" alt="img.png" /><br />
这样做的问题在于,降维算法只负责减少维数,新产生的特征的意义就必须由我们自己去发现了。</p>
<h1 id="pca问题的公式描述-principal-component-analysis-problem-formulation"><a class="anchor" href="#pca问题的公式描述-principal-component-analysis-problem-formulation">#</a> PCA 问题的公式描述 Principal Component Analysis Problem Formulation</h1>
<p>主成分分析 (PCA) 是最常见的降维算法。PCA 要做的是找到一个方向向量 (Vector direction),当把所有的数据都投射到该向量上时,投射平均均方误差尽可能小。方向向量是一个经过原点的向量,投射误差是从特征向量向该方向向量所作垂线的长度。如下图:<br />
<img data-src="/pic/wuenda/jiangwei-06.png" alt="img.png" /></p>
<p>主成分分析问题,要将 n 维数据降至 k 维,目标是找到向量 u (1) ,u (2) ,...,u (k) 使得总的投射误差 Projected Error 最小:<br />
<img data-src="/pic/wuenda/jiangwei-07.png" alt="img.png" /></p>
<p>主成分分析与线性回归的比较:<br />
<img data-src="/pic/wuenda/jiangwei-08.png" alt="img.png" /></p>
<p>主成分分析最小化的是投射误差,不作任何预测。</p>
<p>线性回归最小化的是预测误差,目的是预测结果。<br />
上图中,左边的是线性回归的误差 (垂直于横轴投影),右边则是主要成分分析的误差 (垂直于斜线投影)。</p>
<p>PCA 将 n 个特征降维到 k 个,可以用来进行数据压缩,如果 100 维的向量最后可以用 10 维来表示,那么压缩率为 90%。同样图像处理领域的 KL 变换使用 PCA 做图像压缩。但 PCA 要保证降维后数据的特性损失最小。</p>
<p>PCA 的一大好处是对数据进行降维处理。我们可以对新求出的 “主元” 向量的重要性进行排序,根据需要取前面最重要的部分,将后面的维数省去,可以达到降维从而简化模型或是对数据进行压缩的效果。同时最大程度保持原有数据的信息。</p>
<p>PCA 的一个很大的优点是,它是完全无参数限制的。在 PCA 的计算过程中完全不需要人为的设定参数或是根据任何经验模型对计算进行干预,最后的结果只与数据相关,与用户是独立的。 但这同时也是缺点,如果用户对观测对象有一定的先验知识,掌握了数据的一些特征,却无法通过参数化等方法对处理过程进行干预,可能会得不到预期的效果,效率也不高。</p>
<h1 id="pca算法-principal-component-analysis-algorithm"><a class="anchor" href="#pca算法-principal-component-analysis-algorithm">#</a> PCA 算法 Principal Component Analysis Algorithm</h1>
<p>使用 PCA 从 n 维减少到 k 维:<br />
1 均值归一化。计算出所有特征的均值,然后令 xj = xj − μj 。如果特征是在不同的数量级上,还需要将其除以标准差 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>σ</mi><mn>2</mn></msup></mrow><annotation encoding="application/x-tex">σ^{2}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141079999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">σ</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span></span> 。<br />
<img data-src="/pic/wuenda/jiangwei-09.png" alt="img.png" /></p>
<p>2 计算协方差矩阵 (covariance matrix) sigma Σ<br />
<img data-src="/pic/wuenda/jiangwei-10.png" alt="img.png" /><br />
<img data-src="/pic/wuenda/jiangwei-11.png" alt="img.png" /></p>
<p>3)计算协方差矩阵 Σ 的特征向量 (eigenvectors):<br />
在 Matlab 里我们可以利用奇异值分解 (singular value decomposition) 来得到特则向量矩阵 U,调用方式为 [U, S,V] = svd (sigma) 。(注:函数返回的矩阵 S 也有用,后续会讲到)<br />
<img data-src="/pic/wuenda/jiangwei-12.png" alt="img.png" /></p>
<p>对于一个 n × n 维度的矩阵,U 是一个由 “与数据之间最小投射误差的方向向量” 构成的矩阵。 如果希望将数据从 n 维降至 k 维,只需要从 U 中选取前 k 个向量,获得一个 n × k 维度的矩阵,用 Ureduce 表示,然后通过如下计算获得要求的新特征向量 z (i):<br />
<img data-src="/pic/wuenda/jiangwei-13.png" alt="img.png" /></p>
<p>其中 Ureduce 为 n x k 维,x 为 n × 1 维,因此结果 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>z</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup></mrow><annotation encoding="application/x-tex">z^{(i)}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8879999999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span></span> 为 k × 1 维。 注:我们不对方差特征进行处理。<br />
<img data-src="/pic/wuenda/jiangwei-14.png" alt="img.png" /></p>
<h1 id="重建原始特征-reconstruction-from-compressed-representation"><a class="anchor" href="#重建原始特征-reconstruction-from-compressed-representation">#</a> 重建原始特征 Reconstruction from Compressed Representation</h1>
<p>给定压缩后的低维数据 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>z</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup></mrow><annotation encoding="application/x-tex">z^{(i)}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8879999999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span></span> 怎么反向得到高维的 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup></mrow><annotation encoding="application/x-tex">x^{(i)}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8879999999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span></span> 数据? 即:如何根据压缩后的数据去重建原始数据?</p>
<p>当 x 为 2 维,z 为 1 维,z = UreduceT * x, 则相反的方程为: xappox = Ureduce ⋅ z, 这时有 xappox ≈ x。<br />
<img data-src="/pic/wuenda/jiangwei-15.png" alt="img.png" /></p>
<h1 id="选择主成分的数量k-choosing-the-number-of-principal-components"><a class="anchor" href="#选择主成分的数量k-choosing-the-number-of-principal-components">#</a> 选择主成分的数量 k Choosing The Number Of Principal Components</h1>
<p>主要成分分析最小化投射的平均均方误差,怎么选择适当降维目标 k 值(即主成分的数量)呢?</p>
<p>我们的目标是:在『平均均方误差与训练集方差的比例尽可能小』的情况下,选择尽可能小的 k 值。</p>
<p>如果希望比例小于 1%, 就意味着原本数据的偏差有 99% 都保留下来了。 另外,还可以使用 5%(对应 95% 的偏差), 10%(对应 90% 的偏差) 这些比例。</p>
<p>通常 95% 到 99% 是最常用的取值范围。(注:对于许多数据集,通常可以在保留大部分差异性的同时大幅降低数据的维度。这是因为大部分现实数据的许多特征变量都是高度相关的。)<br />
<img data-src="/pic/wuenda/jiangwei-16.png" alt="img.png" /></p>
<p>具体做法:<br />
<img data-src="/pic/wuenda/jiangwei-17.png" alt="img.png" /></p>
<p>a) 先令 k = 1,然后进行主要成分分析,获得 Ureduce 和 z,然后计算比例是否小于 1%。<br />
b) 如果不是的话,再令 k = 2,如此类推,直到找到可以使得比例小于 1% 的最小 k 值。</p>
<p>事实上还有一些更好的方式,在 Matlab 中有一个 “svd” 函数。 其中,SVD 代表为奇异值分解(singular value decomposition),函数调用 [U, S, V] = svd (sigma) 返回一个与 Σ(即 ppt 中的 Sigma) 同大小的对角矩阵 S(由 Σ 的特征值组成),两个酉矩阵 U 和 V ,且满足 Σ = U * S * V'。若 A 为 m×n 矩阵,则 U 为 m×m 矩阵,V 为 n×n 矩阵。奇异值在 S 的对角线上,非负且按降序排列,对角线之外的其它元素都是 0。</p>
<p>对于方阵 Σ,有<br />
<img data-src="/pic/wuenda/jiangwei-18.png" alt="img.png" /></p>
<p>因为我们的目的是从 n 维降到 k 维,也就是选出这 n 个特征中最重要的 k 个,也就是选出特征值最大的 k 个。所以得到矩阵 S 后,我们可以直接用它来计算平均均方误差与训练集方差的比例,而不用一遍遍重复计算误差和方差:<br />
<img data-src="/pic/wuenda/jiangwei-19.png" alt="img.png" /><br />
<img data-src="/pic/wuenda/jiangwei-20.png" alt="img.png" /></p>
<h1 id="pca的应用建议-advice-for-applying-pca"><a class="anchor" href="#pca的应用建议-advice-for-applying-pca">#</a> PCA 的应用建议 Advice for Applying PCA</h1>
<p>假使我们正在针对一张 100×100 像素的图片进行某个计算机视觉的机器学习,即总共有 10000 个特征。使用 PCA 算法的步骤如下:</p>
<ol>
<li>运用 PCA 将数据压缩至 1000 个特征</li>
<li>对训练集运行学习算法</li>
<li>在预测时,采用之前学习得到的 Ureduce 将输入的特征 x 转换成特征向量 z ,然后再进行预测<br />
<img data-src="/pic/wuenda/jiangwei-21.png" alt="img.png" /><br />
注:如果有交叉验证数据集,也采用对训练集学习而来的 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>U</mi><mrow><mi>r</mi><mi>e</mi><mi>d</mi><mi>u</mi><mi>c</mi><mi>e</mi></mrow></msub></mrow><annotation encoding="application/x-tex">U_{reduce}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10903em;">U</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:-0.10903em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.02778em;">r</span><span class="mord mathnormal mtight">e</span><span class="mord mathnormal mtight">d</span><span class="mord mathnormal mtight">u</span><span class="mord mathnormal mtight">c</span><span class="mord mathnormal mtight">e</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> 。</li>
</ol>
<ul>
<li>
<p>正确用法,压缩和可视化:<br />
<img data-src="/pic/wuenda/jiangwei-22.png" alt="img.png" /></p>
</li>
<li>
<p>错误的用法:</p>
</li>
</ul>
<ol>
<li>将其用于减少过拟合 (通过减少特征的数量)<br />
<img data-src="/pic/wuenda/jiangwei-23.png" alt="img.png" /></li>
</ol>
<p>这样做非常不好,不如使用正则化处理。原因在于 PCA 只是近似地丢弃掉一些特征,它并不考虑任何与结果变量有关的信息,因此可能会丢失非常重要的特征。而当进行正则化处理时,会考虑到结果变量,不会丢掉重要的数据。</p>
<ol start="2">
<li>在项目开始时便将 PCA 考虑进去</li>
<li><img data-src="/pic/wuenda/jiangwei-24.png" alt="img.png" /></li>
</ol>
]]></description>
</item>
<item>
<guid isPermalink="true">https://love.youhuamao.xyz/2022/11/11/ai/Andrew%20Ng%20Lesson/%E6%94%AF%E6%8C%81%E5%90%91%E9%87%8F%E6%9C%BA/</guid>
<title>支持向量机 Support Vector Machines</title>
<link>https://love.youhuamao.xyz/2022/11/11/ai/Andrew%20Ng%20Lesson/%E6%94%AF%E6%8C%81%E5%90%91%E9%87%8F%E6%9C%BA/</link>
<category term="ai" scheme="https://love.youhuamao.xyz/categories/ai/" />
<category term="Andrew Ng Lesson" scheme="https://love.youhuamao.xyz/categories/ai/Andrew-Ng-Lesson/" />
<category term="ai lesson" scheme="https://love.youhuamao.xyz/tags/ai-lesson/" />
<pubDate>Fri, 11 Nov 2022 00:00:00 +0800</pubDate>
<description><![CDATA[ <h1 id="优化目标-optimization-objective"><a class="anchor" href="#优化目标-optimization-objective">#</a> 优化目标 Optimization Objective</h1>
<p>支持向量机 (Support Vector Machine) 是一个更加强大的算法,广泛应用于工业界和学术界。与逻辑回归和神经网络相比, SVM 在学习复杂的非线性方程时提供了一种更为清晰,更加强大的方式。我们通过回顾逻辑回归,一步步将其修改为 SVM。<br />
首先回顾一下逻辑回归:<br />
<img data-src="/pic/wuenda/zhichixiangliangji-01.png" alt="img.png" /></p>
<p>其 cost function 公式如下(这里稍微有点变化,将负号移到了括号内):<br />
<img data-src="/pic/wuenda/zhichixiangliangji-02.png" alt="img.png" /></p>
<p>现在只考虑一个训练数据 x ,把 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>h</mi><mi>θ</mi></msub><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><mn>1</mn><mi mathvariant="normal">/</mi><mo stretchy="false">(</mo><mn>1</mn><mo>+</mo><msup><mi>e</mi><mrow><mo>−</mo><msup><mi>θ</mi><mi>T</mi></msup><mi>x</mi></mrow></msup><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">h_{θ}(x)=1/(1+e^{-θ^{T}x})</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.02778em;">θ</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">1</span><span class="mord">/</span><span class="mopen">(</span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.256365em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.006365em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.02778em;">θ</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.9190928571428572em;"><span style="top:-2.931em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span></span><span class="mord mathnormal mtight">x</span></span></span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span> 带入公式,得到下面的式子:<br />
<img data-src="/pic/wuenda/zhichixiangliangji-03.png" alt="img.png" /></p>
<p>下一步, 使用 z 标示其中的 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>θ</mi><mi>T</mi></msup><mi>x</mi></mrow><annotation encoding="application/x-tex">θ^{T}x</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8413309999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.02778em;">θ</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span></span><span class="mord mathnormal">x</span></span></span></span> , 则之前的目标变为:<br />
If y = 1, we want <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>h</mi><mi>θ</mi></msub><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">h_{θ}(x)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.02778em;">θ</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span></span></span></span> ≈ 1, z&gt;&gt;0;<br />
If y = 0, we want <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>h</mi><mi>θ</mi></msub><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">h_{θ}(x)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.02778em;">θ</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span></span></span></span> ≈ 0, z&lt;&lt;0;</p>
<p>当 y = 1 或 y = 0 时, 上面逻辑回归的 cost function 分别只剩下一项, 对应下面两张图中的灰色曲线:<br />
<img data-src="/pic/wuenda/zhichixiangliangji-04.png" alt="img.png" /></p>
<p>当 y=1 时,随着 z 增大,<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>h</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><mn>1</mn><mi mathvariant="normal">/</mi><mo stretchy="false">(</mo><mn>1</mn><mo>+</mo><msup><mi>e</mi><mrow><mo>−</mo><mi>z</mi></mrow></msup><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">h(x)=1/(1+e^{-z})</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">h</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">1</span><span class="mord">/</span><span class="mopen">(</span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.021331em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.771331em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mathnormal mtight" style="margin-right:0.04398em;">z</span></span></span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span> 逼近 1,cost 逐渐减小。 当 y=0 时,随着 z 减小,<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>h</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><mn>1</mn><mi mathvariant="normal">/</mi><mo stretchy="false">(</mo><mn>1</mn><mo>+</mo><msup><mi>e</mi><mrow><mo>−</mo><mi>z</mi></mrow></msup><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">h(x)=1/(1+e^{-z})</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">h</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">1</span><span class="mord">/</span><span class="mopen">(</span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.021331em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.771331em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mathnormal mtight" style="margin-right:0.04398em;">z</span></span></span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span> 逼近 0,cost 逐渐减小。<br />
现在我们用新的 cost function 来代替逻辑回归中的 cost function,即上图中玫瑰色的曲线,它分为直线和斜线两部分。左边的函数称为 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>c</mi><mi>o</mi><mi>s</mi><msub><mi>t</mi><mn>1</mn></msub><mo stretchy="false">(</mo><mi>z</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">cost_{1}(z)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">c</span><span class="mord mathnormal">o</span><span class="mord mathnormal">s</span><span class="mord"><span class="mord mathnormal">t</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="mclose">)</span></span></span></span>,右边函数称为 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>c</mi><mi>o</mi><mi>s</mi><msub><mi>t</mi><mn>0</mn></msub><mo stretchy="false">(</mo><mi>z</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">cost_{0}(z)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">c</span><span class="mord mathnormal">o</span><span class="mord mathnormal">s</span><span class="mord"><span class="mord mathnormal">t</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">0</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="mclose">)</span></span></span></span>。<br />
在之后的优化问题中,这种形式的 cost function 会为 SVM 带来计算上的优势。</p>
<p>现在开始构建 SVM<br />
<img data-src="/pic/wuenda/zhichixiangliangji-05.png" alt="img.png" /></p>
<p>逻辑回归的 cost function 分为 A、B 两个部分。 我们做下面的操作:<br />
(a) 使用之前定义的 cost1 () 和 cost0 () 替换公式中对应的项。<br />
(b) 根据 SVM 的习惯,除去 1/m 这个系数<br />
因为 1/m 仅是个常量,去掉它也会得出同样的 θ 最优值。<br />
(c)同样根据 SVM 的习惯,做一点变动<br />
对于逻辑回归, cost function 为 A + λ × B ,通过设置不同的 λ 达到优化目的。 对于 SVM, 我们删掉 λ,引入常数 C, 将 cost function 改为 C × A + B, 通过设置不同的 C 达到优化目的。 (在优化过程中,其意义和逻辑回归是一样的。可以理解为 C = 1 / λ)</p>
<p>最终得到 SVM 的代价函数:<br />
<img data-src="/pic/wuenda/zhichixiangliangji-06.png" alt="img.png" /></p>
<p>另外,逻辑回归中假设的输出是一个概率值。 而 SVM 直接预测 y = 1,还是 y = 0。<br />
<img data-src="/pic/wuenda/zhichixiangliangji-07.png" alt="img.png" /><br />
当 θTx ≥ 0 时,SVM 会预测结果为 1,其他情况下,预测结果为 0。</p>
<h1 id="大间距分类的直观理解-large-margin-intuition"><a class="anchor" href="#大间距分类的直观理解-large-margin-intuition">#</a> 大间距分类的直观理解 Large Margin Intuition</h1>
<p>SVM 经常被看作是一个 &quot;大间距分类器&quot;,也就是找到一条与正类、负类的距离最大的分隔线。 例如下图中的黑线:<br />
<img data-src="/pic/wuenda/zhichixiangliangji-08.png" alt="img.png" /></p>
<p>在这一节,我们将得出结论: 为了增加鲁棒性,得到更好的结果 (避免欠拟合、过拟合,应对线性不可分的情况),SVM 做的不仅仅是将间距最大化,而是做了一些优化:<br />
(1)之前的定义中,θTx ≥ 0 被分为正类,θTx &lt; 0 被分为负类。</p>
<p>事实上,SVM 的要求更严格: θTx ≥ 1 被分为正类;θTx ≤ -1 被分为负类<br />
<img data-src="/pic/wuenda/zhichixiangliangji-09.png" alt="img.png" /></p>
<p>这就相当于在支持向量机中嵌入了一个额外的安全因子,或者说安全的间距因子。<br />
(2)只有当 C 特别大的时候, SVM 才是一个最大间隔分类器<br />
<img data-src="/pic/wuenda/zhichixiangliangji-10.png" alt="img.png" /></p>
<p>当 C 特别大时,在优化过程中,第一项会接近于 0,目标变为最小化第二项:<br />
<img data-src="/pic/wuenda/zhichixiangliangji-11.png" alt="img.png" /></p>
<p>我们在训练集中加入一个异常点 outlier ,如下:<br />
<img data-src="/pic/wuenda/zhichixiangliangji-12.png" alt="img.png" /></p>
<p>(a)如果想将样本用最大间距分开,即将 C 设置的很大。那么仅因为一个异常点,决策边界会从黑线变成那条粉线,这实在是不明智的。<br />
(b)如果 C 设置的小一点,最终得到这条黑线。它可以忽略一些异常点的影响,而且当数据线性不可分的时候,也可以将它们恰当分开,得到更好地决策边界。</p>
<p>另外,因为 C = 1 / λ,因此:<br />
C 较小时,相当于 λ 较大。可能会导致欠拟合,高偏差 variance。<br />
C 较大时,相当于 λ 较小。可能会导致过拟合,高方差 bias。<br />
(注:这个性质在习题中考察多次)</p>
<h1 id="大间距分类背后的数学-mathematics-behind-large-margin-classification"><a class="anchor" href="#大间距分类背后的数学-mathematics-behind-large-margin-classification">#</a> 大间距分类背后的数学 Mathematics Behind Large Margin Classification</h1>
<h2 id="向量内积"><a class="anchor" href="#向量内积">#</a> 向量内积</h2>
<p>先看一下向量内积的知识: 假设有两个二维向量 u 和 v ,uTv 叫做向量 u 和 v 之间的内积。<br />
<img data-src="/pic/wuenda/zhichixiangliangji-13.png" alt="img.png" /><br />
∥u∥ 表示 u 的范数 norm,即向量 u 的欧几里得长度,是一个实数。根据毕达哥拉斯定理<br />
<img data-src="/pic/wuenda/zhichixiangliangji-14.png" alt="img.png" /></p>
<p>第一种内积计算方式:首先将 v 投影至 u 向量,记其长度为 p(有正负,与 u 同向为正,反向为负,标量),则两向量的内积<br />
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>u</mi><mi>T</mi></msub><mi>v</mi><mo>=</mo><mi mathvariant="normal">∣</mi><mi mathvariant="normal">∣</mi><mi>u</mi><mi mathvariant="normal">∣</mi><mi mathvariant="normal">∣</mi><mo separator="true">⋅</mo><mi mathvariant="normal">∣</mi><mi mathvariant="normal">∣</mi><mi>v</mi><mi mathvariant="normal">∣</mi><mi mathvariant="normal">∣</mi><mo separator="true">⋅</mo><mi>c</mi><mi>o</mi><mi>s</mi><mi>θ</mi><mo>=</mo><mi mathvariant="normal">∣</mi><mi mathvariant="normal">∣</mi><mi>u</mi><mi mathvariant="normal">∣</mi><mi mathvariant="normal">∣</mi><mo separator="true">⋅</mo><mi>p</mi></mrow><annotation encoding="application/x-tex">u_{T}v = ||u|| · ||v|| · cosθ = ||u|| · p</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">u</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.32833099999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">∣</span><span class="mord">∣</span><span class="mord mathnormal">u</span><span class="mord">∣</span><span class="mord">∣</span><span class="mpunct">⋅</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">∣</span><span class="mord">∣</span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="mord">∣</span><span class="mord">∣</span><span class="mpunct">⋅</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal">c</span><span class="mord mathnormal">o</span><span class="mord mathnormal">s</span><span class="mord mathnormal" style="margin-right:0.02778em;">θ</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">∣</span><span class="mord">∣</span><span class="mord mathnormal">u</span><span class="mord">∣</span><span class="mord">∣</span><span class="mpunct">⋅</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal">p</span></span></span></span><br />
(注:||u|| 是一个实数,p 也是一个实数,因此 uTv 就是两个实数正常相乘。)<br />
第二种内积计算公式:<br />
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>u</mi><mi>T</mi></msub><mi>v</mi><mo>=</mo><mi>u</mi><mn>1</mn><mo>×</mo><mi>v</mi><mn>1</mn><mo>+</mo><mi>u</mi><mn>2</mn><mo>×</mo><mi>v</mi><mn>2</mn><mo>=</mo><msub><mi>v</mi><mi>T</mi></msub><mi>u</mi></mrow><annotation encoding="application/x-tex">u_{T}v = u1 × v1 + u2 × v2 = v_{T}u</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">u</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.32833099999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">u</span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">u</span><span class="mord">2</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="mord">2</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.32833099999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord mathnormal">u</span></span></span></span></p>
<h2 id="svm-代价函数的另一种理解"><a class="anchor" href="#svm-代价函数的另一种理解">#</a> SVM 代价函数的另一种理解</h2>
<p>SVM 的 cost function 如下:<br />
<img data-src="/pic/wuenda/zhichixiangliangji-15.png" alt="img.png" /><br />
如果将 C 设的很大,cost function 只剩下后面的那项。 为简化设 θ0 = 0,只剩下 θ1 和 θ2,则 cost function 为:<br />
J(θ) = 1/2 × ||θ||^2<br />
<img data-src="/pic/wuenda/zhichixiangliangji-16.png" alt="img.png" /><br />
而根据上面内积的公式,我们知道有 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>θ</mi><mi>T</mi></msup><mi>x</mi><mo>=</mo><mi>p</mi><mo separator="true">⋅</mo><mi mathvariant="normal">∣</mi><mi mathvariant="normal">∣</mi><mi>θ</mi><mi mathvariant="normal">∣</mi><mi mathvariant="normal">∣</mi></mrow><annotation encoding="application/x-tex">θ^{T}x = p · ||θ||</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8413309999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.02778em;">θ</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span></span><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">p</span><span class="mpunct">⋅</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">∣</span><span class="mord">∣</span><span class="mord mathnormal" style="margin-right:0.02778em;">θ</span><span class="mord">∣</span><span class="mord">∣</span></span></span></span>,其中 p 是 x 在 θ 上的投影。 使用<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>p</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><mo>⋅</mo><mi mathvariant="normal">∣</mi><mi mathvariant="normal">∣</mi><mi>θ</mi><mi mathvariant="normal">∣</mi><mi mathvariant="normal">∣</mi></mrow><annotation encoding="application/x-tex">p^{(i)} ⋅ ||θ||</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.0824399999999998em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">∣</span><span class="mord">∣</span><span class="mord mathnormal" style="margin-right:0.02778em;">θ</span><span class="mord">∣</span><span class="mord">∣</span></span></span></span> 代替之前约束中的 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>θ</mi><mi>T</mi></msup><msup><mi>x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup></mrow><annotation encoding="application/x-tex">θ^{T}x^{(i)}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8879999999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.02778em;">θ</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span></span> ,得到:<br />
<img data-src="/pic/wuenda/zhichixiangliangji-17.png" alt="img.png" /></p>
<h2 id="svm-如何选择更优的决策边界"><a class="anchor" href="#svm-如何选择更优的决策边界">#</a> SVM 如何选择更优的决策边界</h2>
<p>考察优化目标函数时, 假设我们的到一条绿色的决策边界。样本在决策边界上的投影 p 是粉色的线:<br />
<img data-src="/pic/wuenda/zhichixiangliangji-18.png" alt="img.png" /><br />
对于正样本 x (1) 而言,想要 p (1) ⋅ ∥θ∥ &gt;= 1,现在 p (1) 长度非常短,就意味着 ||θ|| 需要非常大;<br />
对于负样本 x (2) 而言,想要 p (1) ⋅∥θ∥ &lt;= −1,现在 p (2) 长度非常短,就意味着 ||θ|| 需要非常大。</p>
<p>但我们的目标函数是希望最小化参数 θ 的范数,因此我们希望: 投影长度 p (i) 尽可能大。例如下面这条绿色的决策边界,就更好一些:<br />
<img data-src="/pic/wuenda/zhichixiangliangji-19.png" alt="img.png" /></p>
<p>θ0 = 0 的意思是我们让决策界通过原点。如果 θ0 ≠ 0,决策边界不过原点 ,SVM 产生大间距分类器的结论同样成立(在 C 特别大的情况下)</p>
<h1 id="核函数-kernels-i"><a class="anchor" href="#核函数-kernels-i">#</a> 核函数 Kernels I</h1>
<p>使用高级数的多项式模型,可以解决无法用直线进行分隔的分类:<br />
<img data-src="/pic/wuenda/zhichixiangliangji-20.png" alt="img.png" /></p>
<p>可以用一系列的新的特征 f 来替换模型中的每一项。例如令: f1 = x1 , f2 = x2 , f3 = x1 x2 , f4 = x12 , f5= x22... 得到 hθ(x) = f1 + f2 +. . . +fn 。有没有更好的方法来构造 f1 , f2 , f3 ? 我们可以利用核函数来计算出新的特征。</p>
<p>给定一个训练实例 x ,我们利用 x 的各个特征与我们预先选定的 landmarks l (1) , l (2) , l (3) 的近似程度来选取新的特征 f1 , f2 , f3 。<br />
<img data-src="/pic/wuenda/zhichixiangliangji-21.png" alt="img.png" /></p>
<p>其中: ||x − l (1) || 为实例 x 中所有特征与 landmark l (1) 距离的和。<br />
上例中的 similarity (x, l (1) ) 就是核函数,具体来说是一个高斯核函数 (Gaussian Kernel)。(注:这个函数与正态分布没什么实际上的关系,只是看上去像而已。)</p>
<p>如果一个训练实例 x 与 l 很近,则 f 近似于 e−0 = 1;如果一个训练实例 x 与 l 很远,则 f 近似于 e−(较大的数) = 0。 如下:<br />
<img data-src="/pic/wuenda/zhichixiangliangji-22.png" alt="img.png" /></p>
<p>假设 x 含有两个特征 [x1 x2], 不同的 σ 值会有不同效果。 图中水平面的坐标为 x1, x 2 而垂直坐标轴代表 f。只有当 x 与 l (1) 重合时, f 才具有最大值。随着 x 的改变 f 值的变化速率受到 σ2 的控制。 σ2 越小,曲线越瘦<br />
<img data-src="/pic/wuenda/zhichixiangliangji-23.png" alt="img.png" /></p>
<p>下图中,粉色点离 l (1) 更近,所以 f1 接近 1,而 f2 ,f3 接近 0。因此 h θ(x) ≥ 0,因此预测 y = 1;同理,绿色点离 l (2) 较近的,也预测 y = 1;但蓝绿色点离三个 landmark 都较远,预测 y = 0。<br />
<img data-src="/pic/wuenda/zhichixiangliangji-24.png" alt="img.png" /></p>
<p>图中红色封闭曲线便是决策边界。在预测时我们采用的特征不是训练实例本身的特征,而是通过核函数计算出的新特征 f1 , f2 , f3 。</p>
<h1 id="核函数-kernels-ii"><a class="anchor" href="#核函数-kernels-ii">#</a> 核函数 Kernels II</h1>
<h2 id="如何选择-landemark"><a class="anchor" href="#如何选择-landemark">#</a> 如何选择 landemark</h2>
<p>通常如果训练集有 m 个实例,则选取 m 个 landmark,并将 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>l</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup></mrow><annotation encoding="application/x-tex">l^{(i)}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8879999999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span></span> 初始化为 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup></mrow><annotation encoding="application/x-tex">x^{(i)}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8879999999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span></span> :<br />
<img data-src="/pic/wuenda/zhichixiangliangji-25.png" alt="img.png" /></p>
<p>好处:新特征建立在原有特征与训练集中所有其他特征之间距离的基础之上。<br />
<img data-src="/pic/wuenda/zhichixiangliangji-26.png" alt="img.png" /></p>
<p>对实例 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><msup><mi>x</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><mtext>,</mtext><msup><mi>y</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(x^{(i)},y^{(i)})</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.138em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mord cjk_fallback">,</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span>,有:<br />
<img data-src="/pic/wuenda/zhichixiangliangji-27.png" alt="img.png" /></p>
<h2 id="将-kernel-引入-svm"><a class="anchor" href="#将-kernel-引入-svm">#</a> 将 kernel 引入 SVM</h2>
<p>我们将 Gaussian Kernel 代入 SVM 的 cost function,如下图所示:<br />
<img data-src="/pic/wuenda/zhichixiangliangji-28.png" alt="img.png" /><br />
这里与之前的 cost function 的区别在于用核函数 f 代替了 x。<br />
预测一个实例 x 对应结果的方法: 给定 x,计算新特征 f,当 θTf &gt;= 0 时预测 y = 1; 否则反之。</p>
<h2 id="简化计算"><a class="anchor" href="#简化计算">#</a> 简化计算</h2>
<p>最后,为了简化计算, 在计算正则项 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>θ</mi><mi>T</mi></msup><mi>θ</mi></mrow><annotation encoding="application/x-tex">θ^{T}θ</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8413309999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.02778em;">θ</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span></span><span class="mord mathnormal" style="margin-right:0.02778em;">θ</span></span></span></span> 时,用 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>θ</mi><mi>T</mi></msup><mi>M</mi><mi>θ</mi></mrow><annotation encoding="application/x-tex">θ^{T}Mθ</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8413309999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.02778em;">θ</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span></span><span class="mord mathnormal" style="margin-right:0.10903em;">M</span><span class="mord mathnormal" style="margin-right:0.02778em;">θ</span></span></span></span> 代替 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>θ</mi><mi>T</mi></msup><mi>θ</mi></mrow><annotation encoding="application/x-tex">θ^{T}θ</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8413309999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.02778em;">θ</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span></span><span class="mord mathnormal" style="margin-right:0.02778em;">θ</span></span></span></span> ,其中 M 是一个矩阵,核函数不同则 M 不同。(注:理论上也可以在逻辑回归中使用核函数,但使用 M 简化计算的方法不适用于逻辑回归,计算将非常耗时。)</p>
<h2 id="线性核函数"><a class="anchor" href="#线性核函数">#</a> 线性核函数</h2>
<p>不使用核函数又称为线性核函数 (linear kernel)。线性核函数 SVM 适用于函数简单,或特征非常多而实例非常少的情况。</p>
<h2 id="svm-的参数"><a class="anchor" href="#svm-的参数">#</a> SVM 的参数</h2>
<p>带有 kernel 的 SVM 有两个参数 C 和 σ,对结果的影响如下:</p>
<ol>
<li>
<p>C<br />
当 C 较大,相当于 λ 小,可能会导致过拟合,高方差 variance;<br />
当 C 较小,相当于 λ 大,可能会导致欠拟合,高偏差 bias;</p>
</li>
<li>
<p>σ<br />
当 σ 较大时,图像扁平,可能会导致低方差,高偏差 bias;<br />
当 σ 较小时,图像窄尖,可能会导致低偏差,高方差 variance。<br />
<img data-src="/pic/wuenda/zhichixiangliangji-29.png" alt="img.png" /></p>
</li>
</ol>
<h1 id="使用支持向量机-using-an-svm"><a class="anchor" href="#使用支持向量机-using-an-svm">#</a> 使用支持向量机 Using An SVM</h1>
<p><img data-src="/pic/wuenda/zhichixiangliangji-30.png" alt="img.png" /></p>
<h2 id="使用现有软件包"><a class="anchor" href="#使用现有软件包">#</a> 使用现有软件包</h2>
<p>我们通常需要自己写核函数,然后使用现有的软件包 (如 liblinear,libsvm 等) 来最小化 SVM 代价函数。强烈建议使用高优化软件库中的一个,而不是尝试自己实现。</p>
<h2 id="对比一下两种-svm"><a class="anchor" href="#对比一下两种-svm">#</a> 对比一下两种 SVM</h2>
<p>一种是 No kernel(linear kernel),hθ(x)=g (θ0x0+θ1x1+…+θnxn),predict y=1 if θTx&gt;=0;<br />
另一种是使用 kernel f(比如 Gaussian Kernel),hθ(x)=g (θ0f0+θ1f1+…+θnfn),这里需要选择方差参数 σ2</p>
<h2 id="特征缩放"><a class="anchor" href="#特征缩放">#</a> 特征缩放</h2>
<p>特别地,如果使用高斯核函数,需要进行特征缩放。<br />
<img data-src="/pic/wuenda/zhichixiangliangji-31.png" alt="img.png" /></p>
<h2 id="其他-kernel"><a class="anchor" href="#其他-kernel">#</a> 其他 kernel</h2>
<p>在高斯核函数之外,还有其他一些选择,如:<br />
多项式核函数 (Polynomial Kernel), 字符串核函数 (String kernel), 卡方核函数 ( chi-square kernel) ,直方图交集核函数 (histogram intersection kernel) 等。<br />
它们的目标也都是根据训练集和地标之间的距离来构建新特征。一个核函数需要满足 Mercer's 定理,才能被 SVM 的优化软件正确处理。 但是 Andrew 表示他不用其他 kernel 函数。</p>
<p><img data-src="/pic/wuenda/zhichixiangliangji-32.png" alt="img.png" /></p>
<h2 id="多分类问题"><a class="anchor" href="#多分类问题">#</a> 多分类问题</h2>
<p>可以训练 k 个支持向量机来解决多类分类问题。 但是大多数支持向量机软件包都有内置的多类分类功能,我们只要直接使用即可。<br />
<img data-src="/pic/wuenda/zhichixiangliangji-33.png" alt="img.png" /></p>
<h2 id="参数设置"><a class="anchor" href="#参数设置">#</a> 参数设置</h2>
<p>下面是一些普遍使用的准则:<br />
n 为特征数,m 为训练样本数。<br />
(a) 如果 n » m,即训练集数据量不够支持我们训练一个复杂的非线性模型,选用逻辑回归模型或者不带核函数的 SVM。<br />
(b) 如果 n 较小,m 中等,例如 n 在 1-1000 之间,而 m 在 10-10000 之间,使用高斯核函数的 SVM。<br />
(c) 如果 n 较小,m 较大,例如 n 在 1-1000 之间,而 m 大于 50000,则使用 SVM 会非常慢。解决方案是创造、增加更多的特征,然后使用逻辑回归或不带核函数的 SVM。<br />
如果训练集非常大,高斯核函数的 SVM 会非常慢。 通常 Andrew 会尝试手动创建特征,然后用逻辑回归或者不带核函数的 SVM。</p>
<p>(注: 逻辑回归和不带核函数的 SVM 非常相似。但是根据实际情况,其中一个可能会更有效。随着 SVM 的复杂度增加、特征数量相当大时,不带核函数的 SVM 就会表现得相当突出。)<br />
<img data-src="/pic/wuenda/zhichixiangliangji-34.png" alt="img.png" /></p>
<p>一个设计得很好的神经网络也很有可能会非常有效。有一个缺点是,可能会特别慢。一个非常好的 SVM 实现包可能会运行得比较快比神经网络快很多,而且它的代价函数是凸函数,不存在局部最优解。 (黄海广注:当时 GPU 计算比较慢,神经网络还不流行。)</p>
]]></description>
</item>
<item>
<guid isPermalink="true">https://love.youhuamao.xyz/2022/11/11/ai/Andrew%20Ng%20Lesson/%E8%81%9A%E7%B1%BB/</guid>
<title>聚类 Clustering</title>
<link>https://love.youhuamao.xyz/2022/11/11/ai/Andrew%20Ng%20Lesson/%E8%81%9A%E7%B1%BB/</link>
<category term="ai" scheme="https://love.youhuamao.xyz/categories/ai/" />
<category term="Andrew Ng Lesson" scheme="https://love.youhuamao.xyz/categories/ai/Andrew-Ng-Lesson/" />
<category term="ai lesson" scheme="https://love.youhuamao.xyz/tags/ai-lesson/" />
<pubDate>Fri, 11 Nov 2022 00:00:00 +0800</pubDate>
<description><![CDATA[ <h1 id="无监督学习简介-unsupervised-learning-introduction"><a class="anchor" href="#无监督学习简介-unsupervised-learning-introduction">#</a> 无监督学习简介 Unsupervised Learning Introduction</h1>
<p>现在开始学习第一个无监督学习算法:聚类。我们的数据没有附带任何标签,拿到的数据就是这样的:<br />
<img data-src="/pic/wuenda/julei-01.png" alt="img.png" /></p>
<p>例子:<br />
<img data-src="/pic/wuenda/julei-02.png" alt="img.png" /></p>
<h1 id="k-means算法-k-means-algorithm"><a class="anchor" href="#k-means算法-k-means-algorithm">#</a> K-means 算法 K-Means Algorithm</h1>
<p>K-Means 是最普及的聚类算法,算法接受一个未标记的数据集,然后将数据聚类成不同的组。<br />
迭代过程为:<br />
1)选择 K 个随机的点,称为聚类中心 (cluster centroids);<br />
2)对于数据集中的每个数据,按照距离 K 个中心点的距离,将其与距离最近的中心点关联起来,与同一个中心点关联的所有点聚成一类。<br />
3)计算每一个组的平均值,将该组所关联的中心点移动到平均值的位置。<br />
4)重复步骤 2-3 直至中心点不再变化。</p>
<p><img data-src="/pic/wuenda/julei-03.png" alt="img.png" /></p>
<p>下面是一个聚类示例:<br />
初始化随机的中心点,计算距离后分类,然后移动中心点<br />
<img data-src="/pic/wuenda/julei-04.png" alt="img.png" /><br />
<img data-src="/pic/wuenda/julei-05.png" alt="img.png" /><br />
<img data-src="/pic/wuenda/julei-06.png" alt="img.png" /></p>
<p>迭代很多次之后,得到最终聚类结果:<br />
<img data-src="/pic/wuenda/julei-07.png" alt="img.png" /></p>
<p>在没有非常明显组群的情况下,也可以使用 K-means。例如下图中,使用 K-means 确定要生产的 T - 恤衫的三种尺寸:<br />
<img data-src="/pic/wuenda/julei-08.png" alt="img.png" /></p>
<h1 id="优化目标-optimization-objective"><a class="anchor" href="#优化目标-optimization-objective">#</a> 优化目标 Optimization Objective</h1>
<p>K-means 最小化问题,是要最小化所有数据点与其所关联的聚类中心点之间的距离之和,因此 K-means 的代价函数 (又称畸变函数 Distortion function) 为:<br />
<img data-src="/pic/wuenda/julei-09.png" alt="img.png" /></p>
<p>目标是使其最小<br />
<img data-src="/pic/wuenda/julei-10.png" alt="img.png" /></p>
<p>由于算法第一个循环用于减小 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>c</mi><mrow><mo stretchy="false">(</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></msup></mrow><annotation encoding="application/x-tex">c^{(i)}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8879999999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal">c</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8879999999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mopen mtight">(</span><span class="mord mathnormal mtight">i</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span></span></span></span> 引起的代价,而第二个循环则是用于减小 μi 引起的代价。会在每一次迭代都减小代价,不然便说明存在错误。<br />
<img data-src="/pic/wuenda/julei-11.png" alt="img.png" /></p>
<h1 id="随机初始化-random-initialization"><a class="anchor" href="#随机初始化-random-initialization">#</a> 随机初始化 Random Initialization</h1>
<p>随机初始化的聚类中心点的方法:<br />
a) 选择 K &lt; m,即聚类中心点的个数要小于所有训练集实例的数量<br />
b) 随机选择 K 个训练实例,然后令 K 个聚类中心分别与这 K 个训练实例相等</p>
<p><img data-src="/pic/wuenda/julei-12.png" alt="img.png" /><br />
<img data-src="/pic/wuenda/julei-13.png" alt="img.png" /></p>
<p>K-means 的一个问题在于,如果初始化不好,有可能会停留在一个局部最小值处。通常需要运行多次 K-means 算法,每一次都重新随机初始化,最后比较多次运行 K-means 的结果,选择代价函数最小的结果。这种方法在 K 较小的时候 (2-10) 可行,如果 K 较大可能不会有明显地改善。<br />
<img data-src="/pic/wuenda/julei-14.png" alt="img.png" /><br />
<img data-src="/pic/wuenda/julei-15.png" alt="img.png" /></p>
<h1 id="选择聚类数-choosing-the-number-of-clusters"><a class="anchor" href="#选择聚类数-choosing-the-number-of-clusters">#</a> 选择聚类数 Choosing the Number of Clusters</h1>
<p>没有最好的选择聚类数的方法,通常是需要根据不同的问题人工选择。需要思考运用 K-means 算法的动机,然后选择能最好服务于该目的的聚类数。<br />
这里存在一个 “肘部法则”:改变聚类数 K,运行聚类算法,然后计算成本函数 (畸变函数) J。 有可能会得到一条类似于肘部的曲线:<br />
<img data-src="/pic/wuenda/julei-16.png" alt="img.png" /></p>
<p>上图在 3 的时候达到一个肘点。在此之后,畸变值就下降的非常慢,那么我们就选 K = 3。<br />
但是大部分情况下图像会像右图一样没有肘点。就需要人工选择。 例如,根据客户需求选择 T - 恤的尺寸数:<br />
<img data-src="/pic/wuenda/julei-17.png" alt="img.png" /></p>
<p>附,参考黄海广笔记:<br />
<img data-src="/pic/wuenda/julei-18.png" alt="img.png" /><br />
<img data-src="/pic/wuenda/julei-19.png" alt="img.png" /><br />
<img data-src="/pic/wuenda/julei-20.png" alt="img.png" /></p>
]]></description>
</item>
<item>
<guid isPermalink="true">https://love.youhuamao.xyz/2022/11/10/ai/Andrew%20Ng%20Lesson/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0%E7%B3%BB%E7%BB%9F%E8%AE%BE%E8%AE%A1/</guid>
<title>机器学习系统设计 Machine Learning System Design</title>
<link>https://love.youhuamao.xyz/2022/11/10/ai/Andrew%20Ng%20Lesson/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0%E7%B3%BB%E7%BB%9F%E8%AE%BE%E8%AE%A1/</link>
<category term="ai" scheme="https://love.youhuamao.xyz/categories/ai/" />
<category term="Andrew Ng Lesson" scheme="https://love.youhuamao.xyz/categories/ai/Andrew-Ng-Lesson/" />
<category term="ai lesson" scheme="https://love.youhuamao.xyz/tags/ai-lesson/" />
<pubDate>Thu, 10 Nov 2022 00:00:00 +0800</pubDate>
<description><![CDATA[ <h1 id="垃圾邮件分类"><a class="anchor" href="#垃圾邮件分类">#</a> 垃圾邮件分类</h1>
<p>本章中用一个实际例子: 垃圾邮件 Spam 的分类 来描述机器学习系统设计方法。首先来看两封邮件,左边是一封垃圾邮件 Spam,右边是一封非垃圾邮件 Non-Spam:<br />
<img data-src="/pic/wuenda/xitongsheji-01.png" alt="img.png" /><br />
垃圾邮件有很多 features。如果我们想要建立一个 Spam 分类器,就要进行有监督学习,将 Spam 的 features 提取出来,而希望这些 features 能够很好的区分 Spam。<br />
<img data-src="/pic/wuenda/xitongsheji-02.png" alt="img.png" /></p>
<p>事实上,对于 spam 分类器,通常选取 spam 中词频最高的 100 个词来做 feature。<br />
为了构建分类器算法,可能有很多策略:</p>
<ol>
<li>收集更多的数据,让我们有更多的垃圾邮件和非垃圾邮件的样本</li>
<li>基于邮件的路由信息开发一系列复杂的特征</li>
<li>基于邮件的正文信息开发一系列复杂的特征,包括考虑截词的处理</li>
<li>为探测刻意的拼写错误 (把 watch 写成 w4tch) 开发复杂的算法</li>
</ol>
<h1 id="误差分析-error-analysis"><a class="anchor" href="#误差分析-error-analysis">#</a> 误差分析 Error Analysis</h1>
<p>构建一个学习算法的推荐方法为:</p>
<ol>
<li>从一个简单的能快速实现的算法开始,实现该算法并用交叉验证集数据测试这个算法</li>
<li>绘制学习曲线,决定是增加更多数据,或者添加更多特征,还是其他选择</li>
<li>进行误差分析:人工检查交叉验证集中我们算法中产生预测误差的实例,看看这些实例是否有某种系统化的趋势</li>
</ol>
<p>例如下图中,对 100 个分类错误的邮件进行人工分析,左边区分了它们的类型分布,右边分析没有被正确分类的原因。<br />
<img data-src="/pic/wuenda/xitongsheji-03.png" alt="img.png" /></p>
<p>在误差分析的时候,不能单纯依靠直觉 gut feeling ,而是用数字体现。<br />
例如,对于 discount/discounts/discounted/discounting 是否被视为都含有 discount 这个 feature。如果看作含有这个 feature,结果有 3% 的 error;如果不看做有这个 feature,则有 5% 的 error。以此进行比较。<br />
<img data-src="/pic/wuenda/xitongsheji-04.png" alt="img.png" /><br />
注:使用 Porter stemmer 这种软件可以合并类似的单词,但是也可能引发错误。</p>
<h1 id="类偏斜的误差度量-error-metrics-for-skewed-classes"><a class="anchor" href="#类偏斜的误差度量-error-metrics-for-skewed-classes">#</a> 类偏斜的误差度量 Error Metrics for Skewed Classes</h1>
<p>Skewed Classes:一个分类问题,结果仅有两类 y=0 和 y=1,其中一类样本非常多、另一类非常少。<br />
对于偏斜数据集,如果单纯考虑准确率 accuracy,会导致有时候模型预测的结果,还不如全部判断为 1 或者全部判断 0 的结果好。 所以需要引入另外一些辅助度量指标</p>
<p>考虑一个二分问题,即将实例分成正类(positive)或负类(negative)。对一个二分问题来说,会出现四种情况:</p>
<ol>
<li>正确肯定 (True Positive,TP):预测为真,实际为真</li>
<li>正确否定 (True Negative,TN):预测为假,实际为假</li>
<li>错误肯定 (False Positive,FP):预测为真,实际为假</li>
<li>错误否定 (False Negative,FN):预测为假,实际为真</li>
</ol>
<p>这样就可以建立一个 Error Metrics(下图左),并定义 precision 和 recall,如下图所示:<br />
<img data-src="/pic/wuenda/xitongsheji-05.png" alt="img.png" /><br />
<img data-src="/pic/wuenda/xitongsheji-06.png" alt="img.png" /></p>
<p>计算公式:<br />
<img data-src="/pic/wuenda/xitongsheji-07.png" alt="img.png" /></p>