在我們這個數(shù)據(jù)驅(qū)動的世界中,機器學習正在迅速改變著各行各業(yè)。無論是推薦你喜歡的電影,還是幫助醫(yī)生診斷疾病,機器學習的應用無處不在。當談到機器學習時,大多數(shù)人首先想到的是訓練機器進行預測或分類的“監(jiān)督學習”。但是,有一種同樣強大但更神秘的學習方式,叫做“無監(jiān)督學習”。今天,我們將揭開無監(jiān)督學習的面紗,探索它的工作原理、應用場景以及幾種經(jīng)典的算法。
什么是無監(jiān)督學習?
在解釋無監(jiān)督學習之前,先來簡單回顧一下有監(jiān)督學習。在監(jiān)督學習中,我們有一個標注良好的數(shù)據(jù)集,每個數(shù)據(jù)樣本都有一個明確的標簽,比如“貓”或“狗”。機器學習模型通過學習這些已知的輸入(特征)與輸出(標簽)之間的關(guān)系,來對新數(shù)據(jù)進行預測。
然而,在許多現(xiàn)實場景中,標注數(shù)據(jù)是稀缺的。標注數(shù)據(jù)集往往昂貴且耗時,因為每個數(shù)據(jù)樣本都需要人工干預進行標簽標注。這時候,無監(jiān)督學習就派上用場了。無監(jiān)督學習處理的是未標注的數(shù)據(jù),也就是說,模型在訓練過程中并不知道每個數(shù)據(jù)樣本對應的類別或標簽。它的任務是從數(shù)據(jù)中發(fā)現(xiàn)隱藏的模式、結(jié)構(gòu)或關(guān)系。
簡單來說,無監(jiān)督學習就像是在一個陌生的環(huán)境中探險,沒有地圖,但它仍然可以通過觀察地形、尋找規(guī)律來理解這個環(huán)境。
無監(jiān)督學習 vs. 監(jiān)督學習:有點像放羊
我們常說的監(jiān)督學習就像你給羊群安排了一名牧羊人,告訴它們?nèi)ツ睦锍圆荩ㄓ脴撕灨嬖V機器哪些是正確的答案)。無監(jiān)督學習則不一樣,它更像是把羊群放在一大片草原上,讓它們自己去找最好吃的草,自己摸索出哪里才是最佳的草地(沒有標簽,機器自己摸索數(shù)據(jù)中的模式)。
無監(jiān)督學習的應用場景
雖然無監(jiān)督學習看似復雜且缺少明確的目標,但它在許多領(lǐng)域中都有著廣泛的應用。以下是幾個常見的場景:
聚類分析:這是無監(jiān)督學習的一個經(jīng)典應用。通過聚類,模型可以將相似的數(shù)據(jù)點歸為一組。比如,在市場營銷中,企業(yè)可以使用聚類算法將客戶分成不同的群體,從而進行更有針對性的營銷策略。
異常檢測:無監(jiān)督學習也被廣泛用于檢測異常行為。例如,在金融領(lǐng)域,它可以幫助檢測欺詐交易,或者在制造業(yè)中發(fā)現(xiàn)生產(chǎn)線上的異常情況。
降維與特征提?。寒敂?shù)據(jù)集維度非常高時,降維技術(shù)可以將高維數(shù)據(jù)映射到低維空間,以便于可視化和分析。主成分分析(PCA)就是一種常見的無監(jiān)督降維方法。
生成模型:無監(jiān)督學習還可以用于生成新數(shù)據(jù),例如通過生成對抗網(wǎng)絡(GANs)生成逼真的圖像,或者通過變分自編碼器(VAE)生成合成數(shù)據(jù)。
無監(jiān)督學習的主要算法
讓我們深入了解幾種常見的無監(jiān)督學習算法,看看它們是如何工作的。
1. 聚類算法
聚類算法是機器學習中一種非常有趣的技術(shù),簡單來說,它就是在一堆雜亂無章的數(shù)據(jù)中,把相似的東西放在一起,分成幾組。這就像是把各種水果分成不同的籃子,蘋果放一籃,橘子放一籃,香蕉放一籃。
舉個例子
假如你是超市的管理員,在超市收銀處,你能看到很多顧客在買單前決定不需要購買的物品,比如水果、蔬菜、零食、飲料等等。你的任務是把這些東西歸類放好:蘋果、香蕉、西瓜是水果區(qū)的物品,薯片、餅干是零食區(qū)的物品,牛奶、可樂是飲料區(qū)的物品。你沒必要知道它們的名字,只要根據(jù)它們的外形、顏色、大小等特征來分類就行了。
常見的聚類算法
有幾種常見的聚類算法,每一種都有自己獨特的“分組”方式:
K-Means聚類:這是最常見的聚類算法之一。K-Means會先隨便選幾個點作為“組長”(我們叫它“質(zhì)心”),然后看看哪些數(shù)據(jù)點(比如商品)離哪個“組長”最近,就把這些數(shù)據(jù)分到這個“組長”管轄的組里。接著,組長會調(diào)整位置,讓自己盡量站在組員們的中間,這樣來回幾次,直到組員們不再更換組長位置為止。這個算法簡單高效,但有時候你得提前知道要分多少組(比如K值)。
層次聚類:這個算法有點像搭積木。它可以從小到大把相似的點先湊成小團體,然后這些小團體再合并成更大的團體,最后形成一個“家族樹”。當然,你也可以反過來,從一個大團體開始,逐步拆分出更小的團體。這個算法能讓你看到數(shù)據(jù)的層次結(jié)構(gòu),比如從“水果”到“蘋果”再到“紅蘋果”。
DBSCAN:這是一個基于密度的算法。想象一下,你在一個派對上觀察人群,那些站得很近、聚在一起的人就是一組,而那些站得遠遠的、獨自一人的人就被當作“獨行俠”或“噪聲”處理。DBSCAN特別擅長發(fā)現(xiàn)形狀不規(guī)則的群體,而不只是像K-Means那樣找圓形或球形的群體。
聚類的應用
聚類算法可以用在很多地方,比如:
客戶分群:在市場營銷中,公司可以用聚類算法把客戶分成不同的群體,比如“喜歡買奢侈品的客戶”和“喜歡打折商品的客戶”,然后針對每個群體設(shè)計不同的營銷策略。
圖像壓縮:你可以用聚類算法來減少圖像中的顏色種類,比如把相近的顏色歸為一類,這樣能減少圖像文件的大小,同時保留主要的視覺效果。
異常檢測:在網(wǎng)絡安全領(lǐng)域,聚類算法可以用來發(fā)現(xiàn)異常的行為模式,比如一臺電腦突然開始發(fā)送大量數(shù)據(jù),可能就是被黑客入侵了。
2. 降維算法
降維算法是機器學習中一個非常實用的工具,它的作用就像是整理房間里的雜物,把那些看起來很亂的東西重新歸類擺放,讓整個房間看起來更整潔,更容易找到東西。
什么是降維?
想象一下,你有一個巨大的衣柜,里面堆滿了各種各樣的東西:衣服、鞋子、帽子,還有一些看似無關(guān)的小物件。這個衣柜亂得不得了,每件東西都占據(jù)了一個“維度”,你感覺整個衣柜就是一團亂麻,找東西的時候總是毫無頭緒。
現(xiàn)在,降維算法就像一個聰明的整理專家,它走進你的衣柜,開始認真觀察。首先,它發(fā)現(xiàn)有些物品本質(zhì)上是相似的,比如你有好幾件不同顏色的T恤,這些T恤雖然在顏色上有區(qū)別,但它們都是同一類衣物。因此,它決定把顏色的差異稍微淡化一點,只保留“T恤”這個大類。然后,它發(fā)現(xiàn)你那些五顏六色的圍巾雖然各不相同,但它們都屬于“配飾”這一類,所以也把它們歸到一起。
經(jīng)過一番整理,降維算法把那些看似復雜、冗余的信息簡化了——它把不太重要的差異“折疊”起來,只保留了那些真正讓你衣柜有條理的信息。最后,整理專家讓你的衣柜變得井井有條,你不再被無數(shù)的細節(jié)淹沒,而是能夠快速找到你需要的東西,因為它已經(jīng)把你衣柜的“維度”降到了一個更容易管理的水平,同時還保留了所有重要的類別和關(guān)鍵信息。
為什么要降維?
在實際應用中,我們經(jīng)常會遇到“高維數(shù)據(jù)”,也就是包含非常多特征的數(shù)據(jù)。這些特征可能包含了大量冗余信息,甚至會增加分析的復雜性,導致“維度詛咒”(也就是數(shù)據(jù)太多了,反而難以分析)。降維的目的是簡化數(shù)據(jù)結(jié)構(gòu),把高維數(shù)據(jù)轉(zhuǎn)換成低維數(shù)據(jù),讓我們更容易理解和分析,同時保留原始數(shù)據(jù)中的主要信息。
常見的降維算法
降維算法有很多種,但這里介紹幾種最常見的:
主成分分析(PCA):
主成分分析是一種非常經(jīng)典的降維算法。PCA的工作原理是找到數(shù)據(jù)中方差最大的一些方向,這些方向代表了數(shù)據(jù)中最重要的信息。簡單來說,它就是試圖找到數(shù)據(jù)最“廣”的幾條線,把數(shù)據(jù)投影到這些線上,丟掉那些不重要的“窄”方向。結(jié)果是,你得到了一個維度更少但信息密度更高的數(shù)據(jù)集。
打個比方,假如你在一個足球場上看一堆人跑步,從某個角度看過去,他們可能看起來都擠在一條線上,完全看不出誰跑得快誰跑得慢。但如果你換個角度,從更廣的方向看,你就能更清楚地看到每個人的位置和速度。PCA就是在找這個最佳視角。
t-SNE(t-分布隨機鄰居嵌入):
t-SNE是一種非線性的降維算法,主要用于數(shù)據(jù)可視化。它擅長把高維數(shù)據(jù)映射到二維或三維空間里,同時保留數(shù)據(jù)點之間的局部結(jié)構(gòu)關(guān)系。換句話說,t-SNE更在意的是近鄰數(shù)據(jù)點之間的關(guān)系,而不是全局結(jié)構(gòu)。
想象一下,你有一大堆不同顏色的珠子,你希望把它們擺放在一張紙上,顏色相近的珠子放在一起。t-SNE就像一個精細的排列師,幫你把這些珠子按照顏色、亮度、飽和度等特征排成一個美觀的圖案。
線性判別分析(LDA):
雖然LDA常被用于分類任務,但它也有降維的效果。LDA試圖找到能最好地分離不同類別的數(shù)據(jù)的方向。它不是像PCA那樣找“最廣”的方向,而是找那些能把不同類別數(shù)據(jù)分開的方向。
舉個例子,假設(shè)你有一組學生考試成績的數(shù)據(jù),你想通過降維來看看這些學生是否可以按成績分成“優(yōu)秀”、“中等”和“差”三個等級。LDA會找到一個方向,讓不同等級的學生盡量分開,以便你能更清晰地看到他們的分布。
降維的應用
降維算法被廣泛應用于各種領(lǐng)域,比如:
數(shù)據(jù)可視化:通過降維,把高維數(shù)據(jù)投影到二維或三維空間,方便我們用圖表來觀察數(shù)據(jù)的結(jié)構(gòu)和模式。
特征提?。涸谔幚?a class="article-link" target="_blank" href="/tag/%E5%A4%A7%E6%95%B0%E6%8D%AE/">大數(shù)據(jù)集時,降維可以幫助我們提取出最重要的特征,從而減少計算量,提高算法的性能。
噪聲去除:有時候,數(shù)據(jù)中的一些維度可能是噪聲,通過降維我們可以減少這些噪聲的影響,使數(shù)據(jù)更純凈。
降維算法就像是一種數(shù)據(jù)的“精簡術(shù)”,幫助我們從復雜的、高維的原始數(shù)據(jù)中提取出最有用的信息,讓數(shù)據(jù)變得更簡單、更容易理解。
3. 關(guān)聯(lián)規(guī)則學習
關(guān)聯(lián)規(guī)則學習是一種很有趣的機器學習方法,它的主要任務是從大量數(shù)據(jù)中發(fā)現(xiàn)隱藏的模式和關(guān)系。你可以把它想象成是超市里的“購物籃分析”——通過分析大家買東西的習慣,找出哪些商品經(jīng)常一起出現(xiàn)在購物車里。
什么是關(guān)聯(lián)規(guī)則學習?
關(guān)聯(lián)規(guī)則學習的核心就是尋找數(shù)據(jù)中的“如果……那么……”的規(guī)則。比如,你可能會發(fā)現(xiàn)“如果有人買了牛奶,那么他很可能也會買面包”。這些發(fā)現(xiàn)可以用來制定促銷策略、優(yōu)化商品擺放,甚至是設(shè)計更好的推薦系統(tǒng)。
關(guān)聯(lián)規(guī)則學習的基本概念
要理解關(guān)聯(lián)規(guī)則學習,我們先來看看幾個基本概念:
支持度(Support):支持度就是一種模式出現(xiàn)的頻率。比如,如果10%的購物籃里同時有牛奶和面包,那么我們就說“牛奶 -> 面包”這個規(guī)則的支持度是10%。支持度高的規(guī)則意味著它們在數(shù)據(jù)中出現(xiàn)得比較頻繁。
置信度(Confidence):置信度表示的是在購買了牛奶的情況下,購買面包的概率有多大。如果80%的買牛奶的人也買了面包,那么“牛奶 -> 面包”這個規(guī)則的置信度就是80%。置信度高的規(guī)則表明兩者的關(guān)聯(lián)性比較強。
提升度(Lift):提升度是用來衡量兩個事件之間是否真的存在關(guān)聯(lián)。如果提升度大于1,說明買牛奶的人比一般情況下更有可能買面包,這表明兩者之間確實存在某種關(guān)聯(lián)。如果提升度等于1,說明買面包的概率跟買不買牛奶沒有關(guān)系。
關(guān)聯(lián)規(guī)則學習的應用場景
關(guān)聯(lián)規(guī)則學習可以應用在很多領(lǐng)域,以下是幾個常見的例子:
超市購物籃分析:這是關(guān)聯(lián)規(guī)則學習的經(jīng)典應用。超市可以通過分析顧客的購買習慣,發(fā)現(xiàn)哪些商品經(jīng)常一起購買,比如“啤酒和薯片”、“牙刷和牙膏”。通過這些發(fā)現(xiàn),超市可以將相關(guān)商品擺在一起,或者設(shè)計捆綁銷售的促銷活動。
推薦系統(tǒng):在電商平臺,關(guān)聯(lián)規(guī)則學習可以用來推薦商品。如果一個顧客購買了某件商品,系統(tǒng)可以根據(jù)關(guān)聯(lián)規(guī)則推薦其他相關(guān)的商品,比如“買了手機,推薦手機殼”和“買了書,推薦其他同類書籍”。
醫(yī)療診斷:在醫(yī)療領(lǐng)域,關(guān)聯(lián)規(guī)則學習可以用來發(fā)現(xiàn)某些癥狀和疾病之間的關(guān)系,幫助醫(yī)生更好地診斷病人。比如,通過分析大量病人的數(shù)據(jù),可以發(fā)現(xiàn)“長期咳嗽 -> 高血壓”的關(guān)聯(lián),從而提醒醫(yī)生注意患者可能存在的其他健康問題。
網(wǎng)絡安全:在網(wǎng)絡安全中,關(guān)聯(lián)規(guī)則學習可以幫助發(fā)現(xiàn)異常的訪問模式,識別潛在的安全威脅。比如,通過分析服務器日志,可以發(fā)現(xiàn)“多次失敗登錄嘗試 -> 惡意攻擊”的規(guī)則,從而提前預警。
關(guān)聯(lián)規(guī)則學習的常用算法
有幾種經(jīng)典的算法可以用來進行關(guān)聯(lián)規(guī)則學習:
Apriori算法:這是最早的關(guān)聯(lián)規(guī)則學習算法之一。Apriori算法通過逐步擴大頻繁項集來發(fā)現(xiàn)規(guī)則,但它的計算量很大,因此更適合中小規(guī)模的數(shù)據(jù)集。
FP-Growth算法:FP-Growth是一種比Apriori更高效的算法,它通過構(gòu)建一種叫做“頻繁模式樹”的結(jié)構(gòu)來發(fā)現(xiàn)頻繁項集。這個算法可以在大規(guī)模數(shù)據(jù)中更快地找到關(guān)聯(lián)規(guī)則。
關(guān)聯(lián)規(guī)則學習就是幫我們從海量數(shù)據(jù)中找出“如果發(fā)生了A,那么很可能會發(fā)生B”這種有用的規(guī)律。它的應用非常廣泛,從超市的商品擺放到電商的推薦系統(tǒng),再到醫(yī)療診斷和網(wǎng)絡安全,都可以看到它的身影。通過這些規(guī)則,我們可以更好地理解數(shù)據(jù)背后的模式和趨勢,從而做出更明智的決策。總的來說,關(guān)聯(lián)規(guī)則學習是一種非常實用且強大的工具,幫助我們在復雜的數(shù)據(jù)世界中找到有價值的信息。
4. 生成模型
生成模型是機器學習中的一類算法,它們的任務是“創(chuàng)造”新數(shù)據(jù),聽起來有點像是機器學習界的“藝術(shù)家”。生成模型可以根據(jù)已經(jīng)學到的知識,生成看起來很真實的新樣本。比如,通過學習大量的貓咪圖片,一個生成模型就能“畫”出一張從未見過的貓咪圖片,看起來和真的一樣。
什么是生成模型?
生成模型的核心目標是學會數(shù)據(jù)背后的分布規(guī)律,然后根據(jù)這個規(guī)律來生成新的數(shù)據(jù)樣本。通俗點說,假如你給模型看了很多風景畫,它會慢慢學會畫出類似風格的畫作,即使這些畫從未存在過。
生成模型的應用
生成模型在很多領(lǐng)域有著廣泛的應用,以下是幾個例子:
圖像生成:生成模型可以用來生成逼真的圖像,比如人臉、風景甚至藝術(shù)作品。你可能見過一些AI生成的虛擬人物,他們看起來和真實的人幾乎沒有區(qū)別,這就是生成模型的功勞。
文本生成:在自然語言處理領(lǐng)域,生成模型可以用來創(chuàng)作文章、寫詩或者生成對話。像我們現(xiàn)在聊天的AI助手,背后就有生成模型的支持,它能根據(jù)上下文來生成合理的回答。
數(shù)據(jù)增強:在某些情況下,訓練數(shù)據(jù)可能比較稀缺。生成模型可以用來合成新的數(shù)據(jù)樣本,幫助增強訓練集的多樣性,提高模型的性能。比如,生成更多的虛擬手寫數(shù)字來訓練一個數(shù)字識別系統(tǒng)。
風格遷移:生成模型還能做“風格遷移”的工作,比如把一張普通的照片變成梵高風格的畫,或者把白天的風景圖像轉(zhuǎn)換成夜晚的樣子。
常見的生成模型
生成模型有幾種常見的類型,每一種都有它獨特的生成方式:
生成對抗網(wǎng)絡(GANs):
生成對抗網(wǎng)絡是近年來非常流行的一種生成模型。它由兩個部分組成:一個生成器和一個判別器。生成器負責生成假的數(shù)據(jù),判別器則負責判斷這些數(shù)據(jù)是真是假。生成器和判別器不斷對抗,生成器努力生成越來越真實的數(shù)據(jù),以至于判別器無法分辨真假。最終,生成器能生成出非常逼真的數(shù)據(jù)。
比如,GANs可以用來生成虛擬人臉圖片,甚至是編造從未存在的街景。這種對抗的方式讓生成模型不斷改進,最終生成的數(shù)據(jù)非常接近真實數(shù)據(jù)。
變分自編碼器(VAE):
變分自編碼器是一種基于概率的生成模型。VAE通過學習數(shù)據(jù)的“潛在表示”來生成新樣本。你可以把VAE想象成一個壓縮器,它把數(shù)據(jù)壓縮到一個簡化的版本,然后再解壓還原成原始數(shù)據(jù)的樣子。在這個過程中,它學會了如何生成看起來合理的新數(shù)據(jù)。
VAE在生成連續(xù)的數(shù)據(jù)(比如圖像、音頻)方面表現(xiàn)得很好,并且相比于GANs更容易訓練和解釋。
樸素貝葉斯生成模型:
這是一種比較簡單的生成模型,基于貝葉斯定理。它假設(shè)所有特征是獨立的(雖然這個假設(shè)有時不太準確),然后根據(jù)這些特征生成新數(shù)據(jù)。樸素貝葉斯生成模型通常用于分類任務,但也可以用來生成數(shù)據(jù)。
生成模型就像是數(shù)據(jù)的“創(chuàng)造者”,它們通過學習已有的數(shù)據(jù),生成出新的數(shù)據(jù)樣本。這些模型在圖像生成、文本生成、數(shù)據(jù)增強等方面有著廣泛的應用。通過不斷改進和發(fā)展,生成模型正在逐漸突破極限,生成越來越逼真的數(shù)據(jù),不論是在虛擬世界中創(chuàng)造圖像,還是在現(xiàn)實應用中增強數(shù)據(jù),它們都展現(xiàn)出了巨大的潛力。
生成模型讓機器學習不僅能“理解”數(shù)據(jù),還能“創(chuàng)造”數(shù)據(jù),為我們打開了通往無限可能的大門。
無監(jiān)督學習的挑戰(zhàn)
盡管無監(jiān)督學習有著廣泛的應用和強大的功能,但它也面臨著許多挑戰(zhàn)。
缺乏標簽指導:無監(jiān)督學習的最大挑戰(zhàn)之一是缺乏標簽的指導,這使得模型的性能評估變得更加困難。由于沒有明確的“正確答案”,很難量化模型的準確性。
結(jié)果解釋性差:由于無監(jiān)督學習模型的結(jié)果通常是數(shù)據(jù)的潛在結(jié)構(gòu)或模式,這些結(jié)構(gòu)或模式可能并不直觀或容易解釋。因此,在實際應用中,需要結(jié)合領(lǐng)域知識來解釋模型的結(jié)果。
對初始條件敏感:許多無監(jiān)督學習算法,如K-Means,強烈依賴于初始條件的選擇。這意味著不同的初始值可能導致截然不同的結(jié)果,增加了結(jié)果的不確定性。
隨著數(shù)據(jù)量的不斷增加和計算能力的提升,無監(jiān)督學習的應用前景越來越廣闊。未來的研究可能集中在以下幾個方面:
更強的模型解釋性:研究人員正在開發(fā)能夠提供更好解釋性的無監(jiān)督學習算法,以便在保持高效性能的同時,提高結(jié)果的可理解性。
融合有監(jiān)督與無監(jiān)督學習:半監(jiān)督學習和自監(jiān)督學習是將有監(jiān)督學習與無監(jiān)督學習相結(jié)合的兩種方法。這些方法通過利用部分標注數(shù)據(jù)來提高模型的學習能力,并且在某些任務上已經(jīng)展示出優(yōu)異的性能。
無監(jiān)督學習在新領(lǐng)域的應用:隨著新技術(shù)的發(fā)展,無監(jiān)督學習正在被應用到越來越多的領(lǐng)域,如自動駕駛、自然語言處理和生物醫(yī)學等。在這些新領(lǐng)域中,無監(jiān)督學習可以幫助發(fā)現(xiàn)數(shù)據(jù)中的潛在模式,從而推動技術(shù)的進步。
無監(jiān)督學習就像是給機器一副眼鏡,讓它能從一堆混亂的數(shù)據(jù)中看出其中的奧秘。它并不是要讓機器得出一個明確的答案,而是幫助它在探索中找到隱藏的模式和關(guān)聯(lián)。就像我們在人生的旅途中,有時候也需要停下來,自己思考和發(fā)現(xiàn)問題的答案。
這就是無監(jiān)督學習,一個機器學習中的“自我發(fā)現(xiàn)”過程。如果說監(jiān)督學習是機器“按圖索驥”,那么無監(jiān)督學習就是它“摸著石頭過河”——雖然沒那么直截了當,但也許會發(fā)現(xiàn)一些出乎意料的驚喜。
實踐環(huán)節(jié):
下面我們隨機介紹幾個算法:
a.?K-Means聚類算法的代碼示例
我們需要生成兩個簇的二維數(shù)據(jù),每個簇包含100個點,分別圍繞著 [2, 2] 和 [-2, -2] 這兩個中心點。我們使用KMeans類來創(chuàng)建K-Means模型,并指定簇的數(shù)量為2(即 n_clusters=2)。然后,我們用生成的數(shù)據(jù) X 來訓練模型,即執(zhí)行聚類操作。我們打印出每個簇的中心點 kmeans.cluster_centers_,以及每個數(shù)據(jù)點所屬的簇標簽 kmeans.labels_。使用matplotlib庫將聚類結(jié)果進行可視化。數(shù)據(jù)點根據(jù)聚類的結(jié)果使用不同的顏色標識,簇的中心用紅色的叉號表示。
import numpy as np
import os
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
# 設(shè)置matplotlib的中文字體
plt.rcParams['font.sans-serif'] = ['SimHei'] # 指定默認字體為SimHei,如果使用微軟雅黑,則替換為'Microsoft YaHei'
plt.rcParams['axes.unicode_minus'] = False # 解決保存圖像是負號'-'顯示為方塊的問題
# 解決KMeans在Windows系統(tǒng)上使用MKL時的內(nèi)存泄漏問題
os.environ["OMP_NUM_THREADS"] = "1"
# 1.?生成模擬數(shù)據(jù)
# 創(chuàng)建兩個簇的樣本數(shù)據(jù)
np.random.seed(0)
X = np.vstack((
np.random.normal(loc=[2, 2], scale=0.5, size=(100, 2)),
np.random.normal(loc=[-2, -2], scale=0.5, size=(100, 2)),
))
# 2. 使用K-Means進行聚類
# 我們假設(shè)有兩個簇
kmeans = KMeans(n_clusters=2, random_state=0, n_init=10)
kmeans.fit(X)
# 3.?輸出聚類結(jié)果
# kmeans.labels_?包含了每個數(shù)據(jù)點的簇標簽
print("簇中心: n", kmeans.cluster_centers_)
print("每個點的簇標簽: n", kmeans.labels_)
# 4.?可視化結(jié)果
plt.figure(figsize=(8, 6))
# 繪制原始數(shù)據(jù)點
plt.scatter(X[:, 0], X[:, 1], c=kmeans.labels_, cmap='viridis', marker='o', s=50, edgecolor='k')
# 繪制簇中心
plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1], c='red', marker='x', s=200, label='Centroids')
plt.title("K-Means 聚類")
plt.xlabel("X1")
plt.ylabel("X2")
plt.legend()
plt.show()
# 輸出
簇中心:
[[-2.07153917 -2.05647532]
[ 1.99952116 2.07138933]]
每個點的簇標簽:
[1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
b.?層次聚類(Hierarchical Clustering)聚類算法的代碼示例
我們生成了四個簇的二維數(shù)據(jù),每個簇包含50個點,分別圍繞著 [2, 2], [-2, -2], [2, -2] 和 [-2, 2] 這四個中心點。使用 AgglomerativeClustering 類進行凝聚層次聚類(自下而上)。我們設(shè)置 n_clusters=4,意味著希望最終得到4個簇。fit_predict 方法將數(shù)據(jù)點聚類,并返回每個數(shù)據(jù)點的簇標簽。使用 matplotlib 來繪制聚類后的數(shù)據(jù)點,不同簇使用不同的顏色表示。linkage 函數(shù)使用 ward 方法計算層次聚類的鏈接矩陣(樹狀圖中的節(jié)點關(guān)系),這是創(chuàng)建樹狀圖的基礎(chǔ)。使用 dendrogram 函數(shù)將層次聚類的樹狀結(jié)構(gòu)可視化。樹狀圖顯示了數(shù)據(jù)點之間的層次關(guān)系和合并順序,越低的分支代表越早被合并的數(shù)據(jù)點。
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import AgglomerativeClustering
from scipy.cluster.hierarchy import dendrogram, linkage
# 設(shè)置matplotlib的中文字體
plt.rcParams['font.sans-serif'] = ['SimHei'] # 指定默認字體為SimHei,如果使用微軟雅黑,則替換為'Microsoft YaHei'
plt.rcParams['axes.unicode_minus'] = False # 解決保存圖像是負號'-'顯示為方塊的問題
# 1. 生成模擬數(shù)據(jù)
np.random.seed(0)
X = np.vstack((
np.random.normal(loc=[2, 2], scale=0.5, size=(50, 2)),
np.random.normal(loc=[-2, -2], scale=0.5, size=(50, 2)),
np.random.normal(loc=[2, -2], scale=0.5, size=(50, 2)),
np.random.normal(loc=[-2, 2], scale=0.5, size=(50, 2)),
))
# 2. 使用層次聚類(凝聚層次聚類)
clustering = AgglomerativeClustering(n_clusters=4)
labels = clustering.fit_predict(X)
# 3. 可視化結(jié)果(聚類結(jié)果)
plt.figure(figsize=(8, 6))
plt.scatter(X[:, 0], X[:, 1], c=labels, cmap='viridis', marker='o', s=50, edgecolor='k')
plt.title("層次聚類結(jié)果")
plt.xlabel("X1")
plt.ylabel("X2")
plt.show()
# 4. 計算層次聚類的鏈接矩陣
Z = linkage(X, 'ward')
# 5. 可視化層次結(jié)構(gòu)(樹狀圖)
plt.figure(figsize=(10, 7))
dendrogram(Z)
plt.title("層次聚類的樹狀圖")
plt.xlabel("數(shù)據(jù)點編號")
plt.ylabel("距離")
plt.show()
#?輸出
c.?支持度(Support)關(guān)聯(lián)學習算法的代碼示例
我們創(chuàng)建了一個模擬的超市購物數(shù)據(jù),每個交易都是一組購買的商品,例如['雞蛋', '西紅柿', '豆腐']表示一次購買了這三樣商品。使用TransactionEncoder將原始交易數(shù)據(jù)轉(zhuǎn)換為適合算法處理的布爾型數(shù)據(jù)框(DataFrame),每列代表一個商品,每行代表一次交易。如果某個商品出現(xiàn)在某次交易中,則該位置為True,否則為False。
使用apriori函數(shù)來計算所有可能的頻繁項集及其對應的支持度。min_support參數(shù)設(shè)置為0.3,意味著我們只關(guān)心那些至少在30%的交易中出現(xiàn)的項集。打印出所有頻繁項集以及它們的支持度。結(jié)果中會列出每個頻繁項集(如{'土豆', '西紅柿'})及其對應的支持度(如0.375)。
import pandas as pd
from mlxtend.preprocessing import TransactionEncoder
from mlxtend.frequent_patterns import apriori
# 1. 準備交易數(shù)據(jù)集
# 模擬超市購物籃數(shù)據(jù)
transactions = [
['西紅柿', '土豆', '茄子', '蓮藕'],
['西紅柿', '土豆'],
['土豆', '茄子', '豆腐'],
['西紅柿', '茄子', '土豆'],
['土豆', '茄子', '雞蛋'],
['西紅柿', '雞蛋', '紅蘿卜'],
['雞蛋', '茄子'],
['西紅柿', '土豆', '雞蛋'],
]
# 2. 使用TransactionEncoder進行數(shù)據(jù)編碼
te = TransactionEncoder()
te_ary = te.fit(transactions).transform(transactions)
df = pd.DataFrame(te_ary, columns=te.columns_)
# 3. 使用Apriori算法計算頻繁項集的支持度
# 最小支持度設(shè)置為0.3(即至少在30%的交易中出現(xiàn))
frequent_itemsets = apriori(df, min_support=0.3, use_colnames=True)
# 4. 輸出頻繁項集及其支持度
print("頻繁項集及其支持度:")
print(frequent_itemsets)
#?輸出
頻繁項集及其支持度:
support itemsets
0 0.750 (土豆)
1 0.625 (茄子)
2 0.625 (西紅柿)
3 0.500 (雞蛋)
4 0.500 (土豆, 茄子)
5 0.500 (土豆, 西紅柿)
d.?生成對抗網(wǎng)絡(GANs)生成模型算法的代碼示例
使用PyTorch實現(xiàn)生成對抗網(wǎng)絡(GANs)的一個簡單示例。我們將使用PyTorch來訓練一個GAN模型,通過生成手寫數(shù)字圖像(使用MNIST數(shù)據(jù)集)來演示該算法的工作原理。
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt
# 1. 設(shè)置超參數(shù)
batch_size = 100
learning_rate = 0.0002
#?為了快速演示?我這里設(shè)置了訓練為10個epoch?數(shù)字越高生成的字越清晰,建議設(shè)置為 50
epochs?=?10
latent_dim = 100
# 檢查CUDA是否可用
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# 2. 加載MNIST數(shù)據(jù)集
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize([0.5], [0.5])])
train_dataset = datasets.MNIST(root='./data', train=True, transform=transform, download=True)
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
# 3. 定義生成器模型
class Generator(nn.Module):
def __init__(self):
super(Generator, self).__init__()
self.model = nn.Sequential(
nn.Linear(latent_dim, 256),
nn.ReLU(True),
nn.Linear(256, 512),
nn.ReLU(True),
nn.Linear(512, 1024),
nn.ReLU(True),
nn.Linear(1024, 28 * 28),
nn.Tanh()
)
def forward(self, x):
return self.model(x).view(-1, 1, 28, 28)
# 4. 定義判別器模型
class Discriminator(nn.Module):
def __init__(self):
super(Discriminator, self).__init__()
self.model = nn.Sequential(
nn.Linear(28 * 28, 1024),
nn.LeakyReLU(0.2, inplace=True),
nn.Dropout(0.3),
nn.Linear(1024, 512),
nn.LeakyReLU(0.2, inplace=True),
nn.Dropout(0.3),
nn.Linear(512, 256),
nn.LeakyReLU(0.2, inplace=True),
nn.Dropout(0.3),
nn.Linear(256, 1),
nn.Sigmoid()
)
def forward(self, x):
x = x.view(-1, 28 * 28)
return self.model(x)
# 5. 初始化模型和優(yōu)化器
generator = Generator().to(device)
discriminator = Discriminator().to(device)
criterion = nn.BCELoss().to(device)
optimizer_g = optim.Adam(generator.parameters(), lr=learning_rate)
optimizer_d = optim.Adam(discriminator.parameters(), lr=learning_rate)
# 6. 訓練模型
def train():
for epoch in range(epochs):
for i, (images, _) in enumerate(train_loader):
images = images.to(device)
real_labels = torch.ones(batch_size, 1).to(device)
fake_labels = torch.zeros(batch_size, 1).to(device)
# 訓練判別器
outputs = discriminator(images)
d_loss_real = criterion(outputs, real_labels)
real_score = outputs
z = torch.randn(batch_size, latent_dim).to(device)
fake_images = generator(z)
outputs = discriminator(fake_images.detach())
d_loss_fake = criterion(outputs, fake_labels)
fake_score = outputs
d_loss = d_loss_real + d_loss_fake
optimizer_d.zero_grad()
d_loss.backward()
optimizer_d.step()
# 訓練生成器
z = torch.randn(batch_size, latent_dim).to(device)
fake_images = generator(z)
outputs = discriminator(fake_images)
g_loss = criterion(outputs, real_labels)
optimizer_g.zero_grad()
g_loss.backward()
optimizer_g.step()
# 輸出訓練信息
print(f'Epoch [{epoch+1}/{epochs}], d_loss: {d_loss.item():.4f}, g_loss: {g_loss.item():.4f}, '
f'D(x): {real_score.mean().item():.2f}, D(G(z)): {fake_score.mean().item():.2f}')
# 每10個epoch生成并保存圖片
if (epoch + 1) % 10 == 0:
save_fake_images(fake_images, epoch + 1)
# 7. 保存生成的圖片
def save_fake_images(fake_images, epoch):
fake_images = fake_images.reshape(fake_images.size(0), 1, 28, 28)
fake_images = fake_images.detach().cpu()
plt.figure(figsize=(10, 10))
for i in range(25):
plt.subplot(5, 5, i+1)
plt.imshow(fake_images[i][0], cmap='gray')
plt.axis('off')
plt.tight_layout()
plt.savefig(f'fake_images_epoch_{epoch}.png')
plt.show()
# 8. 開始訓練
train()
# 輸出
Epoch [1/10], d_loss: 0.0100, g_loss: 16.2670, D(x): 0.99, D(G(z)): 0.00
Epoch [2/10], d_loss: 0.9867, g_loss: 1.0011, D(x): 0.62, D(G(z)): 0.37
Epoch [3/10], d_loss: 0.6031, g_loss: 2.1963, D(x): 0.83, D(G(z)): 0.17
Epoch [4/10], d_loss: 0.4026, g_loss: 4.2384, D(x): 0.89, D(G(z)): 0.14
Epoch [5/10], d_loss: 0.2319, g_loss: 3.6145, D(x): 0.96, D(G(z)): 0.08
Epoch [6/10], d_loss: 0.2127, g_loss: 4.0321, D(x): 0.97, D(G(z)): 0.12
Epoch [7/10], d_loss: 0.0496, g_loss: 4.4559, D(x): 0.98, D(G(z)): 0.02
Epoch [8/10], d_loss: 0.2561, g_loss: 4.0185, D(x): 0.91, D(G(z)): 0.08
Epoch [9/10], d_loss: 0.0920, g_loss: 3.8384, D(x): 0.97, D(G(z)): 0.04
Epoch [10/10], d_loss: 0.7587, g_loss: 2.5974, D(x): 0.80, D(G(z)): 0.19