『壹』 大數據專業主要學習什麼語言
大數據是近五年興起的行業,發展迅速,很多技術經過這些年的迭代也變得比較成熟了,同時新的東西也不斷涌現,想要保持自己競爭力的唯一辦法就是不斷學習。但是,大數據需要學習什麼?1 思維導圖下面的是我之前整理的一張思維導圖,內容分成幾大塊,包括了分布式計算與查詢,分布式調度與管理,持久化存儲,大數據常用的編程語言等等內容,每個大類下有很多的開源工具。2大數據需要的語言javajava可以說是大數據最基礎的編程語言,據我這些年的經驗,我接觸的很大一部分的大數據開發都是從Jave Web開發轉崗過來的(當然也不是絕對我甚至見過產品轉崗大數據開發的,逆了個天)。一是因為大數據的本質無非就是海量數據的計算,查詢與存儲,後台開發很容易接觸到大數據量存取的應用場景二就是java語言本事了,天然的優勢,因為大數據的組件很多都是用java開發的像HDFS,Yarn,Hbase,MR,Zookeeper等等,想要深入學習,填上生產環境中踩到的各種坑,必須得先學會java然後去啃源碼。說到啃源碼順便說一句,開始的時候肯定是會很難,需要對組件本身和開發語言都有比較深入的理解,熟能生巧慢慢來,等你過了這個階段,習慣了看源碼解決問題的時候你會發現源碼真香。Scalascala和java很相似都是在jvm運行的語言,在開發過程中是可以無縫互相調用的。Scala在大數據領域的影響力大部分都是來自社區中的明星Spark和kafka,這兩個東西大家應該都知道(後面我會有文章多維度介紹它們),它們的強勢發展直接帶動了Scala在這個領域的流行。Python和Shellshell應該不用過多的介紹非常的常用,屬於程序猿必備的通用技能。python更多的是用在數據挖掘領域以及寫一些復雜的且shell難以實現的日常腳本。3分布式計算什麼是分布式計算?分布式計算研究的是如何把一個需要非常巨大的計算能力才能解決的問題分成許多小的部分,然後把這些部分分配給許多伺服器進行處理,最後把這些計算結果綜合起來得到最終的結果。舉個栗子,就像是組長把一個大項目拆分,讓組員每個人開發一部分,最後將所有人代碼merge,大項目完成。聽起來好像很簡單,但是真正參與過大項目開發的人一定知道中間涉及的內容可不少。分布式計算目前流行的工具有:離線工具Spark,MapRece等實時工具Spark Streaming,Storm,Flink等這幾個東西的區別和各自的應用場景我們之後再聊。4分布式存儲傳統的網路存儲系統採用的是集中的存儲伺服器存放所有數據,單台存儲伺服器的io能力是有限的,這成為了系統性能的瓶頸,同時伺服器的可靠性和安全性也不能滿足需求,尤其是大規模的存儲應用。分布式存儲系統,是將數據分散存儲在多台獨立的設備上。採用的是可擴展的系統結構,利用多台存儲伺服器分擔存儲負荷,利用位置伺服器定位存儲信息,它不但提高了系統的可靠性、可用性和存取效率,還易於擴展。上圖是hdfs的存儲架構圖,hdfs作為分布式文件系統,兼備了可靠性和擴展性,數據存儲3份在不同機器上(兩份存在同一機架,一份存在其他機架)保證數據不丟失。由NameNode統一管理元數據,可以任意擴展集群。主流的分布式資料庫有很多hbase,mongoDB,GreenPlum,redis等等等等,沒有孰好孰壞之分,只有合不合適,每個資料庫的應用場景都不同,其實直接比較是沒有意義的,後續我也會有文章一個個講解它們的應用場景原理架構等。5分布式調度與管理現在人們好像都很熱衷於談"去中心化",也許是區塊鏈帶起的這個潮流。但是"中心化"在大數據領域還是很重要的,至少目前來說是的。分布式的集群管理需要有個組件去分配調度資源給各個節點,這個東西叫yarn;需要有個組件來解決在分布式環境下"鎖"的問題,這個東西叫zookeeper;需要有個組件來記錄任務的依賴關系並定時調度任務,這個東西叫azkaban。當然這些「東西」並不是唯一的,其實都是有很多替代品的,本文只舉了幾個比較常用的例子。
『貳』 大數據需要學習什麼樣的知識
看從事大數抄據的哪個部分。
大數據分三個部分,數據分析、大數據平台的中台和大數據底層處理。
數據分析:統計專業+一門實際業務+計算機數據分析工具。可以參考研究生BA專業。
數據中台:CS專業+大數據方向的演算法 (並行計算、機器學習一類的)。研究生起步。
數據底層處理:一定的軟體基礎+資料庫應用。本科即可。
本科不要學大數據專業,四年學不出來,幹啥啥不行。
『叄』 為什麼說Lucene不好
在Lingway公司,我們使用了Lucene至進今已有好幾年時間。對那些剛接觸Lucene的人來說,這里是使用它的關鍵:Apache Lucene是一個由java編寫的高性能,全方位的單詞搜索引擎庫。
在批評它之前,我必須承認Lucene是一個高性能的劃詞搜索引擎。幾年來,Lucene已經被看作是用java編寫的嵌入式搜索引擎中的一等公民。它的聲譽每日劇增,並且仍然是開源java搜索引擎中的最佳。每個人都在說:「Doug Cutting做了一項偉大的工作」。然而,最近的幾個月內,開發的進程變得緩慢,我認為Lucene將不會滿足現代的文檔處理需求。不要把東西搞糟:我不是搜索引擎開發者,我只是個開發者,使用搜索引擎,來提供合適信息的檢索科技。
Lucene不是最好選擇,至少對我們而言如此,並且情況並沒有得到改變。我們列出Lucene的局限性:Lingway公司基於語意來生成復雜的查詢。例如當你正在查找關於「中東地區沖突」的文章,你也許還需要找關於「伊拉克戰爭」文章。在上面這個用例中,「戰爭」和「伊拉克」分別是「沖突」和「中東」的擴展。我們使用一種技術能分析你的查詢,產生相應的最合適的擴展,為它們生成查詢。然而,為了得到相關的結果,這些還是不夠的:通過Lucene實現的類似Google的等級或是經常變化積分的並不能滿足語意級別積分。例如,一個包含「中」和「東」短語,但是被超過一個以上的單詞隔開,這種情況並不是我們想要查找的。更重要的是,相對常規的單詞,我們應該給擴展更低的分數。比如,我們應該給「中東地區沖突」這個短語更高的分數,而不是「伊拉克戰爭」。
在Lingway公司,我們認為這種文章相關性技術是一種未來的搜索引擎。Google在文章搜索上做的很出色。但我們想要的卻是最相關的文章。但是,大部分的當代搜索引擎都沒有對這樣復雜查詢做相關的設計…Lucene被wikipedia使用,如果你注意到當你查詢查過一個單詞時,大多數的查詢結果並不是由關聯的…
為了演示需求,這里有一個Lingway公司即將上線的KM3.7產品的界面截圖。這里我們用法語寫一個查詢,用來查找那些同樣主題,而用英語寫的文章。注意,這可不僅僅是簡簡單單的翻譯,我們稱之為語言交叉模式:
注意到那些綠色的匹配:chanteur變成了singer,但是我們也發現singing被匹配了。同樣情況流行樂成為藍調的擴展。
6大理由不選用Lucene
6. 沒有對集群的內置支持。
如果你創建集群,你可以寫出自己對Directory的實現,或是使用Solr或者使用Nutch+Hadoop。Solr和Nutch都支持Lucene,但不是直接的替代。Lucene是可嵌入的,而你必須支持Solr和Nutch..我認為Hadoop從Lucene團隊中產生並不驚訝:Lucene並不是通用的。它的內在性決定了對大多數場合來說它是非常快速的,但是對大型文檔集合時,你不得不排除Lucene。因為它在內核級別上並沒有實現集群,你必須把Lucene轉換到別的搜索引擎,這樣做並不直接。轉換到Solr或者Nutch上的問題會讓你遇到許多不必要的麻煩:Nutch中的集成crawling和Solr中的檢索服務。
5.跨度查詢太慢
這對Lingway公司來說可能是個特殊的問題。我們對跨度查詢有很強要求,Lucene檢索結構已經開始添加這一細節,但它們當初可沒這么想。最基礎的實現導致了復雜的演算法並且運行緩慢,尤其是當某些短語在一份文檔中重復了許多次出現。這是為什麼我傾向說Lucene是一個高性能的劃詞檢索引擎當你僅僅使用基本的布爾查詢時。
4.積分不能被插件化
Lucene有自己對積分演算法的實現,當條件增加時使用Similarity類。但很快它顯示出局限性當你想要表示復雜的積分,例如基於實際匹配和元數據的查詢。如果你這樣做,你不得不繼承Lucene的查詢類。因為Lucene使用類似tf/idf的積分演算法,然而在我們遇到的場合,在語意上的積分上Lucene的積分機制並不合適。我們被迫重寫每一個Lucene的查詢類使得它支持我們自定義的積分。這是一個問題。
3.Lucene並非良好設計
作為一個系統架構師,我傾向認為(1)Lucene有一個非常糟糕的OO設計。雖然有包,有類的設計,但是它幾乎沒有任何設計模式。這讓我想起一個由C(++)開發者的行為,並且他把壞習慣帶到了java中。這造成了,當你需要自定義Lucene來滿足你的需求(你將來必定會遇到這樣的需求),你必須面對這樣的問題。例如:
<!--[if !supportLists]--> <!--[endif]-->幾乎沒有使用介面。查詢類(例如BooleanQuery,SpanQuery,TermQuery…)都是一個抽象類的子類。如果你要添加其中的一個細節,你會首先想到寫一個介面來描述你擴展的契約,但是抽象的Query類並沒有實現介面,你必須經常的變化自己的查詢對象到Query中並在本地Lucene中調用。成堆的例子如(HitCollecor,…)這對使用AOP和自動代理來說也是一個問題.
<!--[if !supportLists]--> <!--[endif]-->別扭的迭代實現.沒有hasNext()方法,next()方法返回布爾類型並刷新對象內容.這對你想要保持對迭代的元素跟蹤來說非常的痛苦.我假定這是故意用來節省內存但是它又一次導致了演算法上的雜亂和復雜.
2.一個關閉的API使得繼承Lucene成為痛苦
在Lucene的世界中,它被稱之為特性。當某些用戶需要得到某些細節,方針是開放類。這導致了大多數的類都是包保護級別的,這意味著你不能夠繼承他們(除非在你創建的類似在同一個包下,這樣做會污染客戶代碼)或者你不得不復制和重寫代碼。更重要的是,如同上面一點提到的,這個嚴重缺乏OO設計的結構,一些類應該被設為內部類卻沒有,匿名類被用作復雜的計算當你需要重寫他們的行為。關閉API的理由是讓代碼在發布前變得整潔並且穩定。雖然想法很光榮,但它再一次讓人感到痛苦。因為如果你有一些代碼和Lucene的主要思路並不吻合,你不得不經常回歸Lucene的改進到你自己的版本直到你的補丁被接受。
然而當開發者開始越來越長的限制API的更改,你的補丁很少有機會被接受。在一些類和方法上加上final修飾符會讓你遇到問題。我認為如果Spring框架有這樣的限制,是覺不會流行起來。
<!--[if !supportLists]-->1. Lucene搜索演算法不適合網格計算<!--[endif]-->
Lucene被寫出來的時候硬體還沒有很大的內存,多處理器也不存在。因此,索引結構是被設計成使用線性的內存開銷很小的方式。我花了很長的時間來重寫跨度查詢演算法,並使用多線程內容(使用雙核處理器),但是基於迭代器的目錄讀取演算法幾乎不能實現。在一些罕見的場合你能做一些優化並能迭代一個索引通過並行方式,但是大多數場合這是不可能的。我們遇到的情況是,當我們有一個復雜的,超過50+的內嵌跨度查詢,CPU還在空閑但I/O卻一直忙�擔踔獵謔褂昧薘AMDirectory.
有沒有替代品?
我認為最後一個觀點充滿疑問:Lucene到達了它的極限當它在現在硬體基礎的條件下,檢索大型數據集合時。那就是我為什麼尋找下一個可以替代Lucene的出現。在閱讀了博客目錄和 Wikia的討論後,我發現並沒有很多的替代品。然而我最後推薦一個有希望的方案:MG4J。它有一個良好的面向對象設計,性能良好的檢索(索引比Lucene慢),內存開銷上也很小,達到10倍於Lucene速度的跨度查詢,在我的跨度查詢基準上,並且是原生上支持集群。同樣它也內置了負載平衡,而Lucene最近才加入這項功能並且還是實驗性質的。然而MG4J仍然缺少一些特性例如簡單的索引指數,文檔移除和更簡單的使用索引處理。讓我感到高興的是我可以自定義Lucene上的功能在MG4J上只需花幾個小時,而在Lucene上卻需要數天。
我認為對開源的搜索引擎來說仍然有發展空間,它不是通過單台電腦用有限的內存來索引批量文檔,而是通過透明的分布式索引來提供對大型數據集合檢索更為快捷的答案。你不必利用應用來獲得集群特性。Lucene對第一類搜索引擎有了很好的實現,單我認為它並不符合我們的需求:在一個合理的時間內找到最佳的答案。基於tf/idf的搜索演算法和google的等級並不是未來搜索引擎的趨勢。實現對原數據和語義的復雜查詢並找出相關的信息,這是Lingway公司(通過Lucene和其他搜索引擎技術)所作的,不過它要求有更多支持新硬體的新技術。
使用Lucene的一個好理由
無論我如何指責Lucene,它仍然是java開源解決方案中的最佳實現。
『肆』 elasticsearch映射的數據類型有哪些
es支持大多數java裡面的數據類型:
(一)核心數據類型:
(1)string: 默認會被分詞,一個完整示例如下
"status": {
"type": "string", //字元串類型
"index": "analyzed"//分詞,不分詞是:not_analyzed ,設置成no,欄位將不會被索引
"analyzer":"ik"//指定分詞器
"boost":1.23//欄位級別的分數加權
"doc_values":false//對not_analyzed欄位,默認都是開啟,分詞欄位不能使用,對排序和聚合能提升較大性能,節約內存
"fielddata":{"format":"disabled"}//針對分詞欄位,參與排序或聚合時能提高性能,不分詞欄位統一建議使用doc_value
"fields":{"raw":{"type":"string","index":"not_analyzed"}} //可以對一個欄位提供多種索引模式,同一個欄位的值,一個分詞,一個不分詞
"ignore_above":100 //超過100個字元的文本,將會被忽略,不被索引
"include_in_all":ture//設置是否此欄位包含在_all欄位中,默認是true,除非index設置成no選項
"index_options":"docs"//4個可選參數docs(索引文檔號) ,freqs(文檔號+詞頻),positions(文檔號+詞頻+位置,通常用來距離查詢),offsets(文檔號+詞頻+位置+偏移量,通常被使用在高亮欄位)分詞欄位默認是position,其他的默認是docs
"norms":{"enable":true,"loading":"lazy"}//分詞欄位默認配置,不分詞欄位:默認{"enable":false},存儲長度因子和索引時boost,建議對需要參與評分欄位使用 ,會額外增加內存消耗量
"null_value":"NULL"//設置一些缺失欄位的初始化值,只有string可以使用,分詞欄位的null值也會被分詞
"position_increament_gap":0//影響距離查詢或近似查詢,可以設置在多值欄位的數據上火分詞欄位上,查詢時可指定slop間隔,默認值是100
"store":false//是否單獨設置此欄位的是否存儲而從_source欄位中分離,默認是false,只能搜索,不能獲取值
"search_analyzer":"ik"//設置搜索時的分詞器,默認跟ananlyzer是一致的,比如index時用standard+ngram,搜索時用standard用來完成自動提示功能
"similarity":"BM25"//默認是TF/IDF演算法,指定一個欄位評分策略,僅僅對字元串型和分詞類型有效
"term_vector":"no"//默認不存儲向量信息,支持參數yes(term存儲),with_positions(term+位置),with_offsets(term+偏移量),with_positions_offsets(term+位置+偏移量) 對快速高亮fast vector highlighter能提升性能,但開啟又會加大索引體積,不適合大數據量用
}
(2)數字類型主要如下幾種:
long:64位存儲
integer:32位存儲
short:16位存儲
byte:8位存儲
double:64位雙精度存儲
float:32位單精度存儲
支持參數:
coerce:true/false 如果數據不是干凈的,將自動會將字元串轉成合適的數字類型,字元串會被強轉成數字,浮點型會被轉成整形,經緯度會被轉換為標准類型
boost:索引時加權因子
doc_value:是否開啟doc_value
ignore_malformed:false(錯誤的數字類型會報異常)true(將會忽略)
include_in_all:是否包含在_all欄位中
index:not_analyzed默認不分詞
null_value:默認替代的數字值
precision_step:16 額外存儲對應的term,用來加快數值類型在執行范圍查詢時的性能,索引體積相對變大
store:是否存儲具體的值
(3)復合類型
數組類型:沒有明顯的欄位類型設置,任何一個欄位的值,都可以被添加0個到多個,要求,他們的類型必須一致:
對象類型:存儲類似json具有層級的數據
嵌套類型:支持數組類型的對象Aarray[Object],可層層嵌套
(4)地理類型
geo-point類型: 支持經緯度存儲和距離范圍檢索
geo-shape類型:支持任意圖形范圍的檢索,例如矩形和平面多邊形
(5)專用類型
ipv4類型:用來存儲IP地址,es內部會轉換成long存儲
completion類型:使用fst有限狀態機來提供suggest前綴查詢功能
token_count類型:提供token級別的計數功能
mapper-murmur3類型:安裝sudo bin/plugin install mapper-size插件,可支持_size統計_source數據的大小
附件類型:需要 https://github.com/elastic/elasticsearch-mapper-attachments開源es插件支持,可存儲office,html等類型
(6)多值欄位:
一個欄位的值,可以通過多種分詞器存儲,使用fields參數,支持大多數es數據類型
『伍』 如何用Python玩轉TF-IDF之尋找相似文章並生成摘要
應用1:關鍵詞自動生成
核心思想是對於某個文檔中的某個詞,計算其在這個文檔中的標准化TF值,然後計算這個詞在整個語料庫中的標准化IDF值。在這里,標准化是說對原始的計算公式進行了一些變換以取得更好的衡量效果,並避免某些極端情況的出現。這個詞的TF-IDF值便等於TF*IDF。對於這個文檔中的所有詞計算它們的TF-IDF值,並按照由高到低的順序進行排序,由此我們便可以提取我們想要的數量的關鍵詞。
TF-IDF的優點是快捷迅速,結果相對來說比較符合實際情況。缺點是當一篇文檔中的兩個詞的IDF值相同的時候,出現次數少的那個詞有可能更為重要。再者,TF-IDF演算法無法體現我詞的位置信息,出現位置靠前的詞與出現位置靠後的詞,都被視為重要性相同,這是不正確的。存在的解決辦法是對文章的第一段和每段的第一句話給予比較大的權重。
應用2:計算文本相似度
明白了對於每個詞,如何計算它的TF-IDF值。那麼計算文本相似度也輕而易舉。我們已經計算了文章中每個詞的TF-IDF值,那麼我們便可以將文章表徵為詞的TF-IDF數值向量。要計算兩個文本的相似度,只需要計算餘弦即可,餘弦值越大,兩個文本便越相似。
應用3:自動摘要
2007年,美國學者的論文<A Survey on Automatic Text Summarization>總結了目前的自動摘要演算法,其中很重要的一種就是詞頻統計。這種方法最早出自1958年IBM公司一位科學家的論文<The Automatic Creation of Literature Abstracts>。這位科學家認為,文章的信息都包含在句子中,有的句子包含的信息多,有的句子包含的信息少。自動摘要就是找出那些包含信息最多的句子。那麼句子的信息量怎麼衡量呢?論文中採用了關鍵詞來衡量。如果包含的關鍵詞越多,就說明這個句子越重要,這位科學家提出用Cluster的來表示關鍵詞的聚集。所謂簇,就是包含多個關鍵詞的句子片段。
以第一個圖為例,其中的cluster一共有7個詞,其中4個是關鍵詞。因此它的重要性分值就等於(4*4)/7=2.3。然後,找出包含cluster重要性分值最高的句子(比如5句),把它們合在一起,就構成了這篇文章的自動摘要。具體實現可以參見<Mining the Social Web: Analyzing Data from Facebook, Twitter, LinkedIn, and Other Social Media Sites>(O'Reilly, 2011)一書的第8章,Python代碼見github。這種演算法後來被簡化,不再區分cluster,只考慮句子包含的關鍵詞。偽代碼如下。
Summarizer(originalText,maxSummarySize):
//計算文本的詞頻,生成一個列表,比如[(10,'the'),(3,'language'),(8,'code')...]
wordFrequences=getWordCounts(originalText)
//過濾掉停用詞,列表變成[(3,'language'),(8,'code')...]
contentWordFrequences=filtStopWords(wordFrequences)
//按照詞頻的大小進行排序,形成的列表為['code','language'...]
contentWordsSortbyFreq=sortByFreqThenDropFreq(contentWordFrequences)
//將文章分成句子
sentences=getSentences(originalText)
//選擇關鍵詞首先出現的句子
setSummarySentences={}
:
firstMatchingSentence=search(sentences,word)
setSummarySentences.add(firstMatchingSentence)
ifsetSummarySentences.size()=maxSummarySize:
break
//將選中的句子按照出現順序,組成摘要
summary=""
foreachsentenceinsentences:
:
summary=summary+""+sentence
returnsummary
類似的演算法已經被寫成了工具,比如基於Java的Classifier4J庫的SimpleSummariser模塊、基於C語言的OTS庫、以及基於classifier4J的C#實現和python實現。