1,html
調用start方法方可啓動線程,而run方法只是thread的一個普通方法調用,仍是在主線程裏執行。node
2,python
HashMap和Hashtable都實現了Map接口,但決定用哪個以前先要弄清楚它們之間的分別。主要的區別有:線程安全性,同步(synchronization),以及速度算法
1) sychronized意味着在一次僅有一個線程可以更改Hashtable。就是說任何線程要更新Hashtable時要首先得到同步鎖,其它線程要等到同步鎖被釋放以後才能再次得到同步鎖更新Hashtable。編程
2) Fail-safe和iterator迭代器相關。若是某個集合對象建立了Iterator或者ListIterator,而後其它的線程試圖「結構上」更改集合對象,將會拋出ConcurrentModificationException異常。但其它線程能夠經過set()方法更改集合對象是容許的,由於這並無從「結構上」更改集合。可是假如已經從結構上進行了更改,再調用set()方法,將會拋出IllegalArgumentException異常。bootstrap
3) 結構上的更改指的是刪除或者插入一個元素,這樣會影響到map的結構。api
三、Python如何定義一個私有變量數組
經常看到一些 python 變量或者方法 以__開頭,其實這表示是私有方法和變量。
例如:安全
class Person:網絡
def __init__(self,name):
self.__name =name
__name就是私有方法。
四、介紹RNN
http://blog.csdn.net/aws3217150/article/details/50768453
在此以前,咱們已經學習了前饋網絡的兩種結構——多層感知器和卷積神經網絡,這兩種結構有一個特色,就是假設輸入是一個獨立的沒有上下文聯繫的單位,好比輸入是一張圖片,網絡識別是狗仍是貓。可是對於一些有明顯的上下文特徵的序列化輸入,好比預測視頻中下一幀的播放內容,那麼很明顯這樣的輸出必須依賴之前的輸入, 也就是說網絡必須擁有必定的」記憶能力」。爲了賦予網絡這樣的記憶力,一種特殊結構的神經網絡——遞歸神經網絡(Recurrent Neural Network)便應運而生了。網上對於RNN的介紹多不勝數,這篇《Recurrent Neural Networks Tutorial》對於RNN的介紹很是直觀,裏面手把手地帶領讀者利用python實現一個RNN語言模型,強烈推薦。爲了避免重複做者 Denny Britz的勞動,本篇將簡要介紹RNN,並強調RNN訓練的過程與多層感知器的訓練差別不大(至少比CNN簡單),但願能給讀者必定的信心——只要你理解了多層感知器,理解RNN便不是事兒:-)。
用途:
RNNs已經被在實踐中證實對NLP是很是成功的。如詞向量表達、語句合法性檢查、詞性標註等。在RNNs中,目前使用最普遍最成功的模型即是LSTMs(Long Short-Term Memory,長短時記憶模型)模型,該模型一般比vanilla RNNs可以更好地對長短時依賴進行表達,該模型相對於通常的RNNs,只是在隱藏層作了手腳。
和卷積神經網絡(convolutional Neural Networks, CNNs)同樣,RNNs已經在對無標圖像描述自動生成中獲得應用。將CNNs與RNNs結合進行圖像描述自動生成。
http://network.chinabyte.com/269/13936269.shtml
五、STL簡介
STL(Standard Template Library,標準模板庫)是惠普實驗室開發的一系列軟件的統稱,
STL的代碼從廣義上講分爲三類:algorithm(算法)、container(容器)和iterator(迭代器),幾乎全部的代碼都採用了模板類和模版函數的方式,這相比於傳統的由函數和類組成的庫來講提供了更好的代碼重用機會。在C++標準中,STL被組織爲下面的13個頭文件:<algorithm>、<deque>、<functional>、<iterator>、<vector>、<list>、<map>、<memory>、<numeric>、<queue>、<set>、<stack>和<utility>。
六、Trie樹
字典樹(Trie)能夠保存一些字符串->值的對應關係。基本上,它跟 Java 的 HashMap 功能相同,都是 key-value 映射,只不過 Trie 的 key 只能是字符串。
Trie 的強大之處就在於它的時間複雜度。它的插入和查詢時間複雜度都爲 O(k) ,其中 k 爲 key 的長度,與 Trie 中保存了多少個元素無關。Hash 表號稱是 O(1) 的,但在計算 hash 的時候就確定會是 O(k) ,並且還有碰撞之類的問題;Trie 的缺點是空間消耗很高。
至於Trie樹的實現,能夠用數組,也能夠用指針動態分配,我作題時爲了方便就用了數組,靜態分配空間。
Trie樹,又稱單詞查找樹或鍵樹,是一種樹形結構,是一種哈希樹的變種。典型應用是用於統計和排序大量的字符串(但不只限於字符串),因此常常被搜索引擎系統用於文本詞頻統計。它的優勢是:最大限度地減小無謂的字符串比較,查詢效率比哈希表高。
Trie的核心思想是空間換時間。利用字符串的公共前綴來下降查詢時間的開銷以達到提升效率的目的。
Trie樹的基本性質能夠概括爲:
(1)根節點不包含字符,除根節點意外每一個節點只包含一個字符。
(2)從根節點到某一個節點,路徑上通過的字符鏈接起來,爲該節點對應的字符串。
(3)每一個節點的全部子節點包含的字符串不相同。
Trie樹有一些特性:
1)根節點不包含字符,除根節點外每個節點都只包含一個字符。
2)從根節點到某一節點,路徑上通過的字符鏈接起來,爲該節點對應的字符串。
3)每一個節點的全部子節點包含的字符都不相同。
4)若是字符的種數爲n,則每一個結點的出度爲n,這也是空間換時間的體現,浪費了不少的空間。
5)插入查找的複雜度爲O(n),n爲字符串長度。
Trie樹的根結點不包含任何信息,第一個字符串爲"abc",第一個字母爲'a',所以根結點中數組next下標爲'a'-97的值不爲NULL,其餘同理,構建的Trie樹如圖所示,紅色結點表示在該處能夠構成一個單詞。
七、紅黑樹
R-B Tree,全稱是Red-Black Tree,又稱爲「紅黑樹」,它一種特殊的二叉查找樹。紅黑樹的每一個節點上都有存儲位表示節點的顏色,能夠是紅(Red)或黑(Black)。
紅黑樹的特性:
(1)每一個節點或者是黑色,或者是紅色。
(2)根節點是黑色。
(3)每一個葉子節點(NIL)是黑色。 [注意:這裏葉子節點,是指爲空(NIL或NULL)的葉子節點!]
(4)若是一個節點是紅色的,則它的子節點必須是黑色的。
(5)從一個節點到該節點的子孫節點的全部路徑上包含相同數目的黑節點。
注意:
(01) 特性(3)中的葉子節點,是隻爲空(NIL或null)的節點。
(02) 特性(5),確保沒有一條路徑會比其餘路徑長出倆倍。於是,紅黑樹是相對是接近平衡的二叉樹。
紅黑樹示意圖以下:
紅黑樹的應用比較普遍,主要是用它來存儲有序的數據,它的時間複雜度是O(lgn),效率很是之高。
例如,Java集合中的TreeSet和TreeMap,C++ STL中的set、map,以及Linux虛擬內存的管理,都是經過紅黑樹去實現的。
紅黑樹的時間複雜度爲: O(lgn)
八、快排的非遞歸實現
其實就是用棧保存每個待排序子串的首尾元素下標,下一次while循環時取出這個範圍,對這段子序列進行partition操做
/**使用棧的非遞歸快速排序**/
template
<
typename
Comparable>
void
quicksort2(vector<Comparable> &vec,
int
low,
int
high){
stack<
int
> st;
if
(low<high){
int
mid=partition(vec,low,high);
if
(low<mid-1){
st.push(low);
st.push(mid-1);
}
if
(mid+1<high){
st.push(mid+1);
st.push(high);
}
//其實就是用棧保存每個待排序子串的首尾元素下標,下一次while循環時取出這個範圍,對這段子序列進行partition操做
while
(!st.empty()){
int
q=st.top();
st.pop();
int
p=st.top();
st.pop();
mid=partition(vec,p,q);
if
(p<mid-1){
st.push(p);
st.push(mid-1);
}
if
(mid+1<q){
st.push(mid+1);
st.push(q);
}
}
}
}
舉例
無序數組[6 2 4 1 5 9]
先看一下每一個步驟下的狀態,完了再看合併細節
第一步 [6 2 4 1 5 9]原始狀態
第二步 [2 6] [1 4] [5 9]兩兩合併排序,排序細節後邊介紹
第三步 [1 2 4 6] [5 9]繼續兩組兩組合並
第四步 [1 2 4 5 6 9]合併完畢,排序完畢
輸出結果[1 2 4 5 6 9]
1 static void merge(int[] unsorted, int first, int mid, int last, int[] sorted) 2 { 3 int i = first, j = mid; 4 int k = 0; 5 while (i < mid && j < last) 6 if (unsorted[i] < unsorted[j]) 7 sorted[k++] = unsorted[i++]; 8 else 9 sorted[k++] = unsorted[j++]; 10 11 while (i < mid) 12 sorted[k++] = unsorted[i++]; 13 while (j < last) 14 sorted[k++] = unsorted[j++]; 15 16 for (int v = 0; v < k; v++) 17 unsorted[first + v] = sorted[v]; 18 } 19 20 static void merge_sort(int[] unsorted, int first, int last, int[] sorted) 21 { 22 if (first + 1 < last) 23 { 24 int mid = (first + last) / 2; 25 Console.WriteLine("{0}-{1}-{2}", first, mid, last); 26 merge_sort(unsorted, first, mid, sorted); 27 merge_sort(unsorted, mid, last, sorted); 28 merge(unsorted, first, mid, last, sorted); 29 } 30 } 31 32 static void Main(string[] args) 33 { 34 int[] x = { 6, 2, 4, 1, 5, 9 }; 35 int[] sorted = new int[x.Length]; 36 merge_sort(x, 0, x.Length, sorted); 37 for (int i = 0; i < sorted.Length; i++) 38 { 39 if (x[i] > 0) 40 Console.WriteLine(x[i]); 41 } 42 Console.ReadLine(); 43 }
十、隨機森林
http://www.cnblogs.com/maybe2030/p/4585705.html
隨機森林顧名思義,是用隨機的方式創建一個森林,森林裏面有不少的決策樹組成,隨機森林的每一棵決策樹之間是沒有關聯的。在獲得森林以後,當有一個新的輸入樣本進入的時候,就讓森林中的每一棵決策樹分別進行一下判斷,看看這個樣本應該屬於哪一類(對於分類算法),而後看看哪一類被選擇最多,就預測這個樣本爲那一類。
在創建每一棵決策樹的過程當中,有兩點須要注意 - 採樣與徹底分裂。首先是兩個隨機採樣的過程,random forest對輸入的數據要進行行、列的採樣。
隨機森林是一個最近比較火的算法,它有不少的優勢:
做爲新興起的、高度靈活的一種機器學習算法,隨機森林(Random Forest,簡稱RF)擁有普遍的應用前景,從市場營銷到醫療保健保險,既能夠用來作市場營銷模擬的建模,統計客戶來源,保留和流失,也可用來預測疾病的風險和病患者的易感性。最初,我是在參加校外競賽時接觸到隨機森林算法的。最近幾年的國內外大賽,包括2013年百度校園電影推薦系統大賽、2014年阿里巴巴天池大數據競賽以及Kaggle數據科學競賽,參賽者對隨機森林的使用佔有至關高的比例。此外,據個人我的瞭解來看,一大部分紅功進入答辯的隊伍也都選擇了Random Forest 或者 GBDT 算法。因此能夠看出,Random Forest在準確率方面仍是至關有優點的。
那說了這麼多,那隨機森林究竟是怎樣的一種算法呢?
若是讀者接觸過決策樹(Decision Tree)的話,那麼會很容易理解什麼是隨機森林。隨機森林就是經過集成學習的思想將多棵樹集成的一種算法,它的基本單元是決策樹,而它的本質屬於機器學習的一大分支——集成學習(Ensemble Learning)方法。隨機森林的名稱中有兩個關鍵詞,一個是「隨機」,一個就是「森林」。「森林」咱們很好理解,一棵叫作樹,那麼成百上千棵就能夠叫作森林了,這樣的比喻仍是很貼切的,其實這也是隨機森林的主要思想--集成思想的體現。「隨機」的含義咱們會在下邊部分講到。
其實從直觀角度來解釋,每棵決策樹都是一個分類器(假設如今針對的是分類問題),那麼對於一個輸入樣本,N棵樹會有N個分類結果。而隨機森林集成了全部的分類投票結果,將投票次數最多的類別指定爲最終的輸出,這就是一種最簡單的 Bagging 思想。
Bagging和Boosting都是將已有的分類或迴歸算法經過必定方式組合起來,造成一個性能更增強大的分類器,更準確的說這是一種分類算法的組裝方法。即將弱分類器組裝成強分類器的方法。
首先介紹Bootstraping,即自助法:它是一種有放回的抽樣方法(可能抽到重複的樣本)。
一、Bagging (bootstrap aggregating)(引導程序彙集)
Bagging即套袋法,其算法過程以下:
A)從原始樣本集中抽取訓練集。每輪從原始樣本集中使用Bootstraping的方法抽取n個訓練樣本(在訓練集中,有些樣本可能被屢次抽取到,而有些樣本可能一次都沒有被抽中)。共進行k輪抽取,獲得k個訓練集。(k個訓練集之間是相互獨立的)
B)每次使用一個訓練集獲得一個模型,k個訓練集共獲得k個模型。(注:這裏並無具體的分類算法或迴歸方法,咱們能夠根據具體問題採用不一樣的分類或迴歸方法,如決策樹、感知器等)
C)對分類問題:將上步獲得的k個模型採用投票的方式獲得分類結果;對迴歸問題,計算上述模型的均值做爲最後的結果。(全部模型的重要性相同)
二、Boosting(推動)
其主要思想是將弱分類器組裝成一個強分類器。在PAC(機率近似正確)學習框架下,則必定能夠將弱分類器組裝成一個強分類器。
關於Boosting的兩個核心問題:
1)在每一輪如何改變訓練數據的權值或機率分佈?
經過提升那些在前一輪被弱分類器分錯樣例的權值,減少前一輪分對樣例的權值,來使得分類器對誤分的數據有較好的效果。
2)經過什麼方式來組合弱分類器?
經過加法模型將弱分類器進行線性組合,好比AdaBoost經過加權多數表決的方式,即增大錯誤率小的分類器的權值,同時減少錯誤率較大的分類器的權值。
而提高樹經過擬合殘差的方式逐步減少殘差,將每一步生成的模型疊加獲得最終模型。
三、Bagging,Boosting兩者之間的區別
Bagging和Boosting的區別:
1)樣本選擇上:
Bagging:訓練集是在原始集中有放回選取的,從原始集中選出的各輪訓練集之間是獨立的。
Boosting:每一輪的訓練集不變,只是訓練集中每一個樣例在分類器中的權重發生變化。而權值是根據上一輪的分類結果進行調整。
2)樣例權重:
Bagging:使用均勻取樣,每一個樣例的權重相等
Boosting:根據錯誤率不斷調整樣例的權值,錯誤率越大則權重越大。
3)預測函數:
Bagging:全部預測函數的權重相等。
Boosting:每一個弱分類器都有相應的權重,對於分類偏差小的分類器會有更大的權重。
4)並行計算:
Bagging:各個預測函數能夠並行生成
Boosting:各個預測函數只能順序生成,由於後一個模型參數須要前一輪模型的結果。
四、總結
這兩種方法都是把若干個分類器整合爲一個分類器的方法,只是整合的方式不同,最終獲得不同的效果,將不一樣的分類算法套入到此類算法框架中必定程度上會提升了原單一分類器的分類效果,可是也增大了計算量。
下面是將決策樹與這些算法框架進行結合所獲得的新的算法:
1)Bagging + 決策樹 = 隨機森林
2)AdaBoost + 決策樹 = 提高樹
3)Gradient Boosting + 決策樹 = GBDT
十二、SVM
SVM(支持向量機)主要用於分類問題,主要的應用場景有字符識別、面部識別、行人檢測、文本分類等領域。
一般SVM用於二元分類問題,對於多元分類一般將其分解爲多個二元分類問題,再進行分類。下面咱們首先討論一下二元分類問題。
支持向量機三大理論要素:
最大化間距、核函數、對歐理論。
1三、word2vec
http://www.cnblogs.com/peghoty/p/3857839.html
word2vec 是 Google 於 2013 年開源推出的一個用於獲取 word vector 的工具包,它簡單、高效,所以引發了不少人的關注。因爲 word2vec 的做者 Tomas Mikolov 在兩篇相關的論文 [3,4] 中並無談及太多算法細節,於是在必定程度上增長了這個工具包的神祕感。一些按捺不住的人因而選擇了經過解剖源代碼的方式來一窺究竟
有word2vec訓練的詞向量庫,一個句子分詞後,把詞都換成對應的向量輸入
文本情感分類項目,文本向量用tf-idf這種有什麼問題沒有?
有,不能捕獲到上下文之間的聯繫。之後嘗試用doc2vec這種。
1四、BPTT
LSTM(Long Short-Term Memory)是長短時間記憶網絡,是一種時間遞歸神經網絡,適合於處理和預測時間序列中間隔和延遲相對較長的重要事件。
http://www.cnblogs.com/yymn/articles/4969851.html
循環神經網絡的反向傳播算法其實只是BP算法的一個簡單變體而已。
1五、問答系統倒排索引
問答系統,有200W個FAQ,如何用分類模型作分類(FAQ常見問題解答)
瞭解搜索引擎嗎?
用倒排索引,把FAQ的問題分詞,每一個詞對應多個FAQ。新來的query分詞,每一個詞對應的FAQ拉出來。再在這個裏面作分類。
1六、hadoop&spark
分佈式文件系統。數據在哪裏計算就在哪裏,移動數據變成了移動計算。更高效
map、reduce分別分配資源,能夠細粒度控制資源佔用狀況,有利於超大任務平穩正常運行。
http://www.cnblogs.com/tgzhu/p/5818374.html
與許多專有的大數據處理平臺不一樣,Spark創建在統一抽象的RDD之上,使得它能夠以基本一致的方式應對不一樣的大數據處理場景,包括MapReduce,Streaming,SQL,Machine Learning以及Graph等。這即Matei Zaharia所謂的「設計一個通用的編程抽象(Unified Programming Abstraction)。這正是Spark這朵小火花讓人着迷的地方。
要理解Spark,就需得理解RDD。
RDD,全稱爲Resilient Distributed Datasets,是一個容錯的、並行的數據結構,可讓用戶顯式地將數據存儲到磁盤和內存中,並能控制數據的分區。同時,RDD還提供了一組豐富的操做來操做這些數據。在這些操做中,諸如map、flatMap、filter等轉換操做實現了monad模式,很好地契合了Scala的集合操做。除此以外,RDD還提供了諸如join、groupBy、reduceByKey等更爲方便的操做(注意,reduceByKey是action,而非transformation),以支持常見的數據運算。
一般來說,針對數據處理有幾種常見模型,包括:Iterative Algorithms,Relational Queries,MapReduce,Stream Processing。例如Hadoop MapReduce採用了MapReduces模型,Storm則採用了Stream Processing模型。RDD混合了這四種模型,使得Spark能夠應用於各類大數據處理場景。
RDD做爲數據結構,本質上是一個只讀的分區記錄集合。一個RDD能夠包含多個分區,每一個分區就是一個dataset片斷。RDD能夠相互依賴。若是RDD的每一個分區最多隻能被一個Child RDD的一個分區使用,則稱之爲narrow dependency;若多個Child RDD分區均可以依賴,則稱之爲wide dependency。不一樣的操做依據其特性,可能會產生不一樣的依賴。例如map操做會產生narrow dependency,而join操做則產生wide dependency。
Spark之因此將依賴分爲narrow與wide,基於兩點緣由。
首先,narrow dependencies能夠支持在同一個cluster node上以管道形式執行多條命令,例如在執行了map後,緊接着執行filter。相反,wide dependencies須要全部的父分區都是可用的,可能還須要調用相似MapReduce之類的操做進行跨節點傳遞。
其次,則是從失敗恢復的角度考慮。narrow dependencies的失敗恢復更有效,由於它只須要從新計算丟失的parent partition便可,並且能夠並行地在不一樣節點進行重計算。而wide dependencies牽涉到RDD各級的多個Parent Partitions。下圖說明了narrow dependencies與wide dependencies之間的區別:
本圖來自Matei Zaharia撰寫的論文An Architecture for Fast and General Data Processing on Large Clusters。圖中,一個box表明一個RDD,一個帶陰影的矩形框表明一個partition。
RDD提供了兩方面的特性persistence和patitioning,用戶能夠經過persist與patitionBy函數來控制RDD的這兩個方面。RDD的分區特性與並行計算能力(RDD定義了parallerize函數),使得Spark能夠更好地利用可伸縮的硬件資源。若將分區與持久化兩者結合起來,就能更加高效地處理海量數據。例如:
input.map(parseArticle _).partitionBy(partitioner).cache()
partitionBy函數須要接受一個Partitioner對象,如:
val partitioner = new HashPartitioner(sc.defaultParallelism)
RDD本質上是一個內存數據集,在訪問RDD時,指針只會指向與操做相關的部分。例如存在一個面向列的數據結構,其中一個實現爲Int的數組,另外一個實現爲Float的數組。若是隻須要訪問Int字段,RDD的指針能夠只訪問Int數組,避免了對整個數據結構的掃描。
RDD將操做分爲兩類:transformation與action。不管執行了多少次transformation操做,RDD都不會真正執行運算,只有當action操做被執行時,運算纔會觸發。而在RDD的內部實現機制中,底層接口則是基於迭代器的,從而使得數據訪問變得更高效,也避免了大量中間結果對內存的消耗。
在實現時,RDD針對transformation操做,都提供了對應的繼承自RDD的類型,例如map操做會返回MappedRDD,而flatMap則返回FlatMappedRDD。當咱們執行map或flatMap操做時,不過是將當前RDD對象傳遞給對應的RDD對象而已。例如:
def map[U: ClassTag](f: T => U): RDD[U] = new MappedRDD(this, sc.clean(f))
這些繼承自RDD的類都定義了compute函數。該函數會在action操做被調用時觸發,在函數內部是經過迭代器進行對應的轉換操做:
private[spark] class MappedRDD[U: ClassTag, T: ClassTag](prev: RDD[T], f: T => U) extends RDD[U](prev) { override def getPartitions: Array[Partition] = firstParent[T].partitions override def compute(split: Partition, context: TaskContext) = firstParent[T].iterator(split, context).map(f) }
支持容錯一般採用兩種方式:數據複製或日誌記錄。對於以數據爲中心的系統而言,這兩種方式都很是昂貴,由於它須要跨集羣網絡拷貝大量數據,畢竟帶寬的數據遠遠低於內存。
RDD天生是支持容錯的。首先,它自身是一個不變的(immutable)數據集,其次,它可以記住構建它的操做圖(Graph of Operation),所以當執行任務的Worker失敗時,徹底能夠經過操做圖得到以前執行的操做,進行從新計算。因爲無需採用replication方式支持容錯,很好地下降了跨網絡的數據傳輸成本。
不過,在某些場景下,Spark也須要利用記錄日誌的方式來支持容錯。例如,在Spark Streaming中,針對數據進行update操做,或者調用Streaming提供的window操做時,就須要恢復執行過程的中間狀態。此時,須要經過Spark提供的checkpoint機制,以支持操做可以從checkpoint獲得恢復。
針對RDD的wide dependency,最有效的容錯方式一樣仍是採用checkpoint機制。不過,彷佛Spark的最新版本仍然沒有引入auto checkpointing機制。
RDD是Spark的核心,也是整個Spark的架構基礎。它的特性能夠總結以下:
1七、Kmeans優缺點
Kmeans:
優勢:
簡單易實現
缺點:
可能收斂於局部最小值(對初始k個聚類中心的選擇敏感),在大規模數據集上收斂較慢
適用數據類型:數值型數據
度量聚類效果的指標:
SSE(sum of squared error, 偏差平方和),SSE值越小表示數據點越接近於他們的質心,聚類效果也越好
改進方法:簇劃分
二分k均值算法:請參考博客:http://blog.csdn.net/u013593585/article/details/51263980
1八、kd-tree
k-d樹[1] (k-dimensional樹的簡稱),是一種分割k維數據空間的數據結構。主要應用於多維空間關鍵數據的搜索(如:範圍搜索和最近鄰搜索)。K-D樹是二進制空間分割樹的特殊的狀況。