所有文章分類的總目錄:http://www.cnblogs.com/asxinyu/p/4288836.html
微軟Infer.NET機器學習組件:http://www.cnblogs.com/asxinyu/p/4329742.html
關於本文檔的說明
本文檔基於Infer.NET 2.6對Infer.NET User Guide進行中文翻譯,但進行了若干簡化和提煉,按照原網站的思路進行,但不局限與其順序。
歡迎傳播分享,必須保持原作者的信息,但禁止將該文檔直接用於商業盈利。
本人正在研究基於Infer.NET組件,並計划將其應用於實際的預測之中,該組件功能強大,封裝很完善,但也有很多難以理解的地方,同時官方也給出了大量的例子,限於個人精力有限,更新時間較慢,也希望有興趣的朋友一起來完成該項工作。
Email:asxinyu@qq.com
本文章地址: http://www.cnblogs.com/asxinyu/p/InferNet_Demo_Learner_1.html
1.基本介紹
一個 "learner"是一個完整的機器學習應用解決方案,例如分類系統或者推薦系統。這些 Learners都能夠直接在命令行或者.NET程序中調用,而無須學習Infer.NET的 API接口. 每一個learner都包括訓練,預測以及評估能力。Learners的源代碼包括了一些綜合使用Infer.NET 的構建復雜穩定的機器學習功能程序的例子。本文是在前一篇文章基礎上進行介紹。本文英文原文地址:原文
2.標准數據格式的映射
我們一起回顧以下分類器映射接口IClassifierMapping ,它聲明了4個方法:
2.1 GetInstances
IEnumerable<TInstance> GetInstances(TInstanceSource instanceSource);
GetInstances方法手動給學習者提供了實例樣本集(培訓或測試集),可以在訓練和預測中使用。此外,這兩個泛型類型,TInstance TInstanceSource,可以自由選擇。例如,TInstance可能被綁定到一個類提供的特性和標簽;也可能引用或索引到這樣一個類的一個對象。為了配合緩存,貝葉斯機器分類器假設相同的實例源總是提供相同的實例。
2.2 GetFeatures
TFeatures GetFeatures( TInstance instance, TInstanceSource instanceSource = default(TInstanceSource));
GetFeatures 為指定的樣本實例提供所有特征值(指標)。這種方法也同樣用在訓練和預測中。注意,如果實例本身包含一個對應的特征值,則沒有必要指定源。貝葉斯機器分類器需要將TFeatures綁定到 MicrosoftResearch.Infer.Maths.Vector中。為了配合緩存,GetFeatures假設相同的實例源總是提供相同的實例。你可能想給所有實例添加一個恆定的特性,如添加1個特征值一直為1的特征。這將使分類器具有特性值轉移的不變性(通過為每個類添加一個預期值)。此外,特性之間的相關性存在越少越好(高度相關特性可能導致訓練算法的收斂速度慢)。
2.3 GetLabel
TLabel GetLabel(TInstance instance, TInstanceSource instanceSource = default(TInstanceSource), TLabelSource labelSource = default(TLabelSource));
GetLabel提供了實例需要的實際數據的標簽值(類別值),這個方法在訓練的過程中被調用。一個標簽的來源如果獨立與實例源,將會更靈活,因為在某些實際情況中,實際的數據源特性和標簽值可能是分開的。如果實例本身包括了標簽的數據,那么這里的就可以省略了。為了緩存標簽數據和避免轉換為本地數據格式的帶來的損失,貝葉斯機器分類器假設對於相同的實例調用GetLabel都獲取相同的標簽。
2.4 GetClassLabels
IEnumerable<TLabel> GetClassLabels( TInstanceSource instanceSource = default(TInstanceSource), TLabelSource labelSource = default(TLabelSource));
GetClassLabels方法可以獲取分類數據中所有標簽數據集。它不僅包括確定當前任務有多個標簽,還可以獲取對應標簽的類型標簽。在最簡單的情況下,當標簽是Bool類型時,GetClassLabels 將返回{true,false}。GetClassLabels可以在分類過程中保證每一個類型的標簽都是有效的。IClassifierMapping接口需要這種方法,是因為通常情況下,它有可能不能推出完整的樣本標簽集合,也就是說,訓練集或測試集可能並不包含所有標簽類型。
由於可以很靈活的選擇合適的數據類型TInstance,TInstanceSource,TLabelSource和TLabel(TFeatures需要Vector類型),一般直接提供一個簡單、高效的IClassifierMapping接口實現就可以了,所以提供標准的數據格式是一個使用分類器非常方便的方法。正如前面提到的,貝葉斯機器分類器最終需要將標准的數據格式的轉換為Infer.NET算法可以接受的本地數據格式。然而,在很多情況下,在程序中使用本地數據格式要比需要轉換的標准數據格式更加有用。IClassifierMapping的一個實現的例子就是本教程前面的性別預測的例子。
3.本地數據格式映射
IBayesPointMachineClassifierMapping接口提供可以由貝葉斯機器分類在訓練和預測過程中不需要轉換的數據格式,因此這個提供的格式也被稱為本地數據格式。
本機數據格式有兩個不同的表示方法:密集和稀疏。密集表示單個實例相關聯的所有特征值都存儲在一個double數組,而稀疏表示包含所有非零特征值和相應的索引。這2種表示方法產生的結果是相同的,只是計算的代價有差別。在訓練和預測數據包括很多0特征值的矩陣比對應的稀疏矩陣要快一些。
除了特征值的表示功能,本機數據格式還可以修復標簽的類型。在二分類問題中,標簽值必須是布爾類型,在多分類問題時,標簽必須從0開始的連續整數。通過原生格式提供數據需要實現下面8個方法:
1.IsSparse:IsSparse表示是否以稀疏矩陣存儲,注意該特征是不能修改的。
bool IsSparse(TInstanceSource instanceSource);
2.GetFeatureCount:GetFeatureCount獲取分類數據中多少個特征。當使用稀疏矩陣表示時,需要建立對應的推理算法。
int GetFeatureCount(TInstanceSource instanceSource);
3.GetClassCount:GetClassCount 返回實例中所有類別標簽總數。
int GetClassCount( TInstanceSource instanceSource = default(TInstanceSource), TLabelSource labelSource = default(TLabelSource));
上述三種方法都是用於設置貝葉斯機器分類器的特征和標簽的有效性。他們都在訓練和預測過程中被調用。IsSparse和GetFeatureCount方法可以從GetFeatureValues和GetFeatureIndexes中確定部分返回值。下面兩個方法在單個對象的預測中給單個實例傳遞特征值。他們的返回值不會被緩存。
4.GetFeatureValues (single-instance):GetFeatureValues返回給定實例的一個特征值數組。如果是以稀疏特性表示的(例如IsSparse返回true),這個方法只返回給定實例的所有相關非零特征值。如果表示是非稀疏表示,GetFeatureValues會返回所有的特征值,而不管他們是不是是否他們是零。
double[] GetFeatureValues( TInstance instance, TInstanceSource instanceSource = default(TInstanceSource));
5.GetFeatureIndexes (single-instance):GetFeatureIndexes方法如果實例是以非稀疏矩陣表示,則返回null,否則返回一個返回非零特征值對應的特征指數的數組。(??),因此,給訓練和測試算法有兩種提供特性值和其索引的方法。在訓練時,實例可能被進一步分成多個子集(稱為批次),可以不直接從內存出處理全部數據。不使用批次,也大部分使用以下兩個方法。
int[] GetFeatureIndexes(TInstance instance, TInstanceSource instanceSource = default(TInstanceSource));
6.GetFeatureValues (multi-instance):GetFeatureValues返回每個實例指定的批處理的實例的特性值(相對於是返回指定批次的特征值)。默認情況下,假定所有實例的特性和標簽都是在一個處理中進行。如果這是很困難,可能是因為需要太多內存,貝葉斯機器分類器允許將訓練數據映射為多個批次進行(設置BatchCount屬性)。實例將運行索引從0到BatchCount - 1的批處理。訓練的多個批次處理設置參考IterationCount。
double[][] GetFeatureValues( TInstanceSource instanceSource, int batchNumber = 0);
7.GetFeatureIndexes (multi-instance):如果以稀疏矩陣標准,GetFeatureIndexes返回null;否則返回指定實例上指定批次的特征索引。對同一批次的實例,這要與GetFeatureValues返回的特征值一致。IBayesPointMachineClassifierMapping最后一個方法是提供真實標簽值:
int[][] GetFeatureIndexes(TInstanceSource instanceSource, int batchNumber = 0);
8.GetLabels:getlabel提供給定實例或者標簽數據源的實際標簽類別值。注意,TLabel在二分類中是bool類型,在多份類中是int類型。在預測中不需要實用該方法。
TLabel[] GetLabels(TInstanceSource instanceSource, TLabelSource labelSource = default(TLabelSource), int batchNumber = 0);
MicrosoftResearch.Infer.Learners.BayesPointMachineClassifierInternal命名空間中的NativeClassifierMapping類及其子方法是實現IBayesPointMachineClassifierMapping接口的例子。這些IClassifierMapping類的封裝展示了如何從標准的數據格式轉換為本地數據的過程,以及如何在訓練中分批次的緩存數據。
4.評估數據格式映射
一個簡單的評估測試分類器性能的方法是使用evaluator。Evaluator通過一個實現IClassifierEvaluatorMapping映射接口的實例來讀取真是的標簽值,由於Evaluator獨立於特定分類器要求的具的數據格式,如貝葉斯分類器的IClassifierEvaluatorMapping本質上聲明了一個通用的標准數據格式映射IClassifierMapping接口,只是沒有GetFeatures方法。而預測輸入參數的評價方法,不要通過映射。
5.創建與序列化
5.1 創建貝葉斯分類器
一旦創建映射的實例,就可以根據分類問題的類型,調用下面2個工廠方法,很容易的創建一個貝葉斯機器分類器。
BayesPointMachineClassifier.CreateBinaryClassifier (二類問題) BayesPointMachineClassifier.CreateMulticlassClassifier (多類問題)
另外,這兩種方法都有兩個版本,一個是將輸入映射到本地數據格式,一個是將輸入映射到標准數據格式,分別實現IBayesPointMachineClassifierMapping和IClassifierMapping接口。工廠方法返回IBayesPointMachineClassifier類型的分類器,為訓練和預測提供一些適當設置。
例如,假設我們已經實現一個從SQL數據庫到貝葉斯機器分類所需的本地數據格式的映射SqlNativeMapping,可以很簡單的創建一個多分類器問題的分類器:
var mapping = new SqlNativeMapping(); var classifier = BayesPointMachineClassifier.CreateMulticlassClassifier(mapping);
創建貝葉斯機器分類器的操作是很簡單的,不需要數據輸入相關計算。
5.2 序列化
序列化是通過ILearner接口的Save擴展方法實現的。該方法有2個重載版本,1個是在文件,1個是在格式化的流。訓練和未訓練的分類器都可以被序列化和反序列化。序列化一個貝葉斯機器分類器到一個文件的調用程序如下:
classifier.Save("bpm.bin");
該程序序列化分類器的參數和用戶定義的映射。它不序列化任何訓練數據也沒有附加任何事件處理程序。
5.3 反序列化
通過調用BayesPointMachineClassifier的一個靜態方法可以加載一個之前被序列化的分類器。和保存方法類似,也可以從一個文件或者格式化流中反序列化一個分類器。
var classifier = BayesPointMachineClassifier.Load <SqlInstanceSource, Instance, SqlLabelSource, int, Discrete, BayesPointMachineClassifierTrainingSettings, MulticlassBayesPointMachineClassifierPredictionSettings<int>>("bpm.bin");
上述方法需要的泛型參數如下:
l TInstanceSource :源實例的類型
l TInstance :單個實例的類型
l TLabelSource :源標簽的類型
l TLabel :單個標簽的類型(貝葉斯分類器有2種,2類為bool,多類為Int)
l TLabelDistribution :標簽的分布類型
l TTrainingSettings:訓練設置類型
l TPredictionSettings :預測設置類型,分二類問題和多類問題,預測設置的類型是不一樣。(BinaryBayesPointMachineClassifierPredictionSettings
和 MulticlassBayesPointMachineClassifierPredictionSettings).
反序列化的泛型參數必須和分類器序列化時的參數精確匹配。同樣在反序列化時,將執行版本檢查程序,如果序列化的版本不匹配,將拋出一個異常。然而,很多情況下,為了方便,存在很多方法並不需要很多具體的泛型類型,如:
var classifier = BayesPointMachineClassifier.LoadMulticlassClassifier <SqlInstanceSource, Instance, SqlLabelSource, int, Discrete>("bpm.bin");
這和前面的從文件反序列化多類貝葉斯機器分類器是等價的。