大數據分析平台
商業模式與大數據分析競賽專用平台如下
各服務連結如下
- Hadoop叢集
- GPU伺服器(使用GPU環境必須要透過中山大學的ip位置才可以連線)
大數據分析平台的服務有兩項,分別是由18台主機共有136個核心數和1.5TB記憶體組成的Hadoop的叢集(Hadoop cluster) 以及 備載GPU運算能力的伺服器。 而本院提供的開發環境為RStudio和Jupyter,使用者可以透過R和Python兩種語言來撰寫程式。
在這個頁面我們提供幾項簡易的教學,分別是
- Hadoop連線設定
- Spark連線設定
- Spark實作巨量資料範例
- GreenPlum實作範例
- GPU伺服器的環境變數設定
Hadoop
Hadoop是什麼呢?
簡單來講,想像如果有個檔案大小超過你的個人電腦可以儲存的容量,那絕對無法被放進你的電腦對吧?這時候我們就需要Hadoop了!
Hadoop是一個能儲存並管理大量資料的雲端平台,除了能儲存超過一個伺服器所能容納的檔案外,還能夠同時儲存、處理、分析幾千萬份這種超大的檔案,所以每當講到大數據,便會提到Hadoop這套技術。
這段影音及文字教學,目的是要讓使用者可以連線上管院伺服器上的Hadoop,並對HDFS(Hadoop File System)上的檔案做些簡單的操作。
影音教學

-
連線設定
-
載入packages
-
rmr2, plyrmr, rhdfs 這些packages提供許多R的函式,讓使用者可以直接對HDFS系統上的任何檔案執行些指令,像是存取或是做資料分析。
-
hdfs.init() 這句的意思是連線HDFS系統。
library(rmr2)
library(plyrmr)
library(rhdfs)
hdfs.init()
-
與HDFS系統互動
-
to.dfs( ): 寫入檔案至HDFS。
-
from.dfs( ):讀取HDFS上的檔案。
to.dfs(mtcars, "/home/yourAccountName/mtcars.csv", format = "csv")
from.dfs("/home/yourAccountName/mtcars.csv", format = "csv")
-
hdfs.ls():列出HDFS上的所有檔案。
-
hdfs.del():刪除HDFS上的所有檔案。
hdfs.ls("/home/yourAccountName")
hdfs.del("/home/yourAccountName/mtcars.csv")
-
上述語法的 /yourAccountName/ 部分,請使用者自行將其改成自己的目錄名稱。
以上就是對於如何連線上Hadoop以及與HDFS互動的介紹。
當然,使用者可以透過"MapRudeuce"的方法去對Hadoop上的資料做更多操作。
Spark
既然處理大數據我們有了Hadoop這個強大的工具了,那為何還有Spark的出現呢?而Spark與Hadoop又有什麼不同呢?
Hadoop在執行MapReduce的運算時,會將中間產生的數據,存儲在硬碟中,也就說任何的資料存取都是在執行I/O,而I/O往往是效能的瓶頸,因此會有讀寫資料延遲的問題。但Spark比Hadoop晚4年問世,卻能以100倍快的速度執行MapReduce是為什麼呢?
Spark是基於記憶體內的運算框架,在運算時,會將中間產生的數據暫存在記憶體中,因此可以大大地加快運算速度,尤其是反覆執行越多次時,所需讀取的資料量就越大,越能看出Spark的效能。而Spark同時也與Hadoop相容,所以同樣可以透過HDFS存儲檔案。
影音教學

-
載入所需的package並連線上HDFS
-
設定Spark的連線資訊
- 由於Spark是基於記憶體的運算,所以在連線前必須了解連線的伺服器提供多大的資源,並設定合理的資源消耗,例如使用多少的記憶體、核心數等等。
library(dplyr)
library(sparklyr)
Sys.setenv(SPARK_HOME="/usr/local/spark/spark-2.1.0-bin-hadoop2.7/")
config <- spark_config()
config$spark.executor.memory = "32G"
config$spark.cores.max = "50"
config$spark.driver.memory = "16G"
config$spark.yarn.executor.memoryOverhead = "4096"
sc <- spark_connect(master = "spark://hnamenode:7077", config = config)
執行完以上的程式後就可以連線上Spark了。
如果連線成功的話,會在RStudio的畫面右上角看到一個新的頁籤叫做"connection"。如果連線失敗則會在console的頁面跳出錯誤訊息。
-
在HDFS上存取檔案
- 先前提到過,Spark跟HDFS是相容的,所以連線上Spark時也可以對HDFS上的檔案做存取。
- 底下程式碼示範如何從HDFS上讀出檔案和把R的物件儲存至HDFS。
hdfs.ls("/home/yourAccountName/")
mySDF = spark_read_csv(sc, name = "mtcars", path = "hdfs:/home/yourAccountName/mtcars.csv", header = T)
movies_sdf = copy_to(sc, df = ggplot2movies::movies, name = "movies",overwrite = T)
-
中斷連線
- 若使用者在執行完畢Spark的操作卻沒有中斷連線的話,會導致集群上環的運算資源被特定使用者佔用住,導致其他使用者無法使用群集上資源,所以,當使用完Spark時務必要養成斷線的好習慣。
spark_disconnect(sc)
範例:如何在Spark上操作巨量資料
接下來的範例會示範如何在Spark上操作巨量資料。
範例中我們會用到 babynames 資料集,資料集紀錄一百八十多萬的新生兒姓名資料。選用這個資料集的目的是要讓使用者感受在操作巨量資料時,Spark的運算能力有多強大。
影音教學

-
設定連線資訊&讀取資料
-
Spark 連線
Sys.setenv("HADOOP_CMD" = "/home/hadoop/hadoop/bin/hadoop")
Sys.setenv("HADOOP_STREAMING"="/home/hadoop/hadoop/share/hadoop/tools/lib/hadoop-streaming-2.8.1.jar")
library("rhdfs")
hdfs.init()
library(dplyr)
library(sparklyr)
Sys.setenv(SPARK_HOME="/usr/local/spark/spark-2.1.0-bin-hadoop2.7/")
config <- spark_config()
config$spark.executor.memory = "32G"
config$spark.cores.max = "50"
config$spark.driver.memory = "16G"
config$spark.yarn.executor.memoryOverhead = "4096"
sc <- spark_connect(master = "spark://hnamenode:7077", config = config)
-
資料集讀取
- 上述的資料集已經放在叫做 sample 資料夾裡面了,透過底下的程式碼就可以將資料讀出來了。
- babynames是美國新生兒的姓名資料,資料筆數大約有 一百八十多萬 多筆。
data_file_1 = "hdfs:/home/sample/babynames.csv"
baby = spark_read_csv(sc, "babynames", data_file_2)
baby %>% summarise(n = n())
-
簡單查詢句:以 babynames 資料為例
使用者可以想像當資料筆數超級多的時候,一句查詢句至少要搜尋過全部資料一次,那會需要花多少時間去執行這個查詢句,況且實務上我們不會只做單一條件的查詢句,也就是說我們的條件可能會很複雜包含不只一個變數,那表示一定會搜尋全部的資料不少次,可想而知,這必定是很耗資源的一段程式。但透過Spark,執行底下的程式最多只要花5~7秒的時間就可以完成查詢,這就是Spark強大的地方。
- 以babynames資料為例,底下查詢句用來查詢各欄位中 不重複的資料 有幾筆。
- 執行結果可以看出prop欄位的不重複資料有16萬多筆,卻能夠很快就完成查詢句。
start_time <- proc.time()
baby %>%
summarise(n_year = n_distinct(year),
n_sex = n_distinct(sex),
n_name = n_distinct(name),
n_n = n_distinct(n),
n_prop = n_distinct(prop)) %>%
data.frame
proc.time() - start_time
- 如果是直接在執行相同的查詢句,而不是透過spark做運算的話,其執行速度沒有辦法來得像spark這麼快。
start_time <- proc.time()
babynames::babynames %>%
summarise(n_year = n_distinct(year),
n_sex = n_distinct(sex),
n_name = n_distinct(name),
n_n = n_distinct(n),
n_prop = n_distinct(prop)) %>%
data.frame
proc.time() - start_time
-
資料視覺化:以 babynames 這個資料集為範例
babynames這個資料集紀錄從1880年開始,在美國每年出生的新生兒取哪些名字,每個名字總共被用了幾次等資訊,在資料集裡面共有5個columns,分別是年份、性別、姓名、總數、佔總出生人數的比重。
在範例中,寫了一個函式用來查詢特定一年中,哪些名字最常被使用來命名。
另外我們也附上官方教學文件供使用者參考。
-
載入會用到的packages
library(ggplot2)
library(dygraphs)
library(rbokeh)
library(RColorBrewer)
library(plotly)
-
先找出1986以後且被用來命名過超過一千次的資料,列出姓名跟性別這個兩個變數,並以topNames這個變數儲存起來。
topNames = baby
filter(year > 1986)
group_by(name, sex)
summarize(count = sum(n))
filter(count > 1000)
select(name, sex)
-
接著用原始資料對topNames做inner_join,並且group_by年份這個變數,表示出來的結果會是各年中最代表的姓名
yearlyName = baby
filter(year > 1986)
inner_join(topNames)
group_by(year, name, sex)
summarize(count = sum(n))
sdf_copy_to(sc, ., "yearlyname", T, overwrite=T)
-
再來我們將上面做過的事情,寫成一個函式,以便未來想要做查詢的時候,不需要重複打這麼多程式碼,只要傳入年份變數就可以得到我們想要的結果,還可以把結果以圖形化的方式呈現出來。
MostPopularNames <- function(year) {
topNames <- baby
filter(year >= 1986)
group_by(name, sex)
summarize(count = sum(n))
filter(count > 1000)
select(name, sex)
yearlyName <- baby
filter(year >= 1986)
inner_join(topNames)
group_by(year, name, sex)
summarize(count = sum(n))
sdf_copy_to(sc, ., "yearlyname", T, overwrite=T)
TopNm <- yearlyName
filter(year == year)
group_by(name,sex)
summarize(count=sum(count))
group_by(sex)
mutate(rank = min_rank(desc(count)))
filter(rank < 5)
arrange(sex, rank)
select(name,sex,rank)
sdf_copy_to(sc,.,"topNames",T,overwrite=TRUE)
topNamesYearly <- yearlyName
inner_join(select(TopNm, sex, name))
collect
#兩種畫法可以選一種畫就好
#第一種圖
ggplot(topNamesYearly,
aes(year, count, color = name)) +
facet_grid(~sex) +
geom_line() +
ggtitle(paste0("Most Popular Names of ", year))
#第二種圖
# 拿出名字欄位之後要做factor化
names <- TopNm
select(name)
collect
as.data.frame
names <- names[, 1, T]
topNamesYearly$name <- factor(topNamesYearly$name, levels = names, labels = names)
p = ggplot(df, aes(year, count, color=name)) +
theme_light() +
facet_wrap(~sex, nrow=2) +
geom_vline(xintercept = year, col='yellow', lwd=1.2) +
geom_line() +
ggtitle(sprintf('Most Popular Names of %d',year)) +
scale_colour_brewer(palette = "Paired")
plotly_build(p)
}
-
透過函式給定特定年份,就可以得到該年中最常被使用的姓名是哪個。
MostPopularNames(2015)
MostPopularNames(2000)

- 將男生姓名及女生姓名在資料中的分佈狀況畫出來。
sharedName = baby
mutate(male=ifelse(sex == "M", n, 0),
female=ifelse(sex == "F", n, 0))
group_by(name)
summarize(Male = sum(male),
Female = sum(female),
count = sum(n),
AvgYear = round(sum(year * n) / sum(n),0))
filter(Male > 10000 & Female > 10000)
figure(width = NULL, height = NULL,
xlab = "Log10 Number of Males",
ylab = "Log10 Number of Females",
title = "Top shared names (1880 - 2014)")
ly_points(log10(Male), log10(Female), data = sharedName,
color = AvgYear, size = scale(sqrt(count)),
hover = list(name, Male, Female, AvgYear), legend = FALSE

-
使用完Spark後,如果暫時沒有要再使用,務必要將其中斷連線
spark_disconnect(sc)
Greenplum 實作範例
影音教學

Greenplum database是一種開源的分散式資料庫,它提供PB級別數據量的快速分析能力及對超大資料表做快速查詢的能力。
過去,當使用者要分析儲存在資料庫上的結構化資料的時候,必須先將資料表讀入分析工具中,例如將一個table讀進RStudio中,再進行資料分析、建立模型等等,但如果資料表很大的話,會造成在讀取資料的階段就耗盡了大量的運算資源。而現在有了Greenplum這個擁有資料分析能力的資料庫,使用者可以直接在資料庫中對資料表做資料分析、做查詢句甚至是訓練模型,並將結果直接輸出至我們的分析工具中,如此一來,就可以避免在讀取資料時大量消耗運算資源的問題,使用者可以直接對資料庫中的資料表做更快速、更彈性的操作。
底下的範例會教使用者如何用RStudio連線上資料庫(本院提供的資料庫為Greenplum)以及對資料表做些簡單的查詢句。
- 載入packages
- 設定資料庫的連線資訊
- 為了方便起見,在申請帳號時本院會將dbname設定成使用者的帳號名稱。而user和password則是大數據分析平台的帳號和密碼。
- host為192.168.1.100。
pgConn = dbConnect("PostgreSQL",
dbname = "帳號名稱",
user="帳號名稱",
password="密碼",
host = "192.168.1.100")
- 常用基本語法
- dbListTables():列出所有資料表
- dbWriteTable():建立資料表
- dbReadTable():讀取資料表
- dbListFields():讀取資料表欄位
#
dbListTables(pgConn)
diamonds = as.data.frame(diamonds)
#
dbWriteTable(pgConn, "diamonds", diamonds)
#
dbReadTable(pgConn, "diamonds")
#
dbListFields(pgConn, "diamonds")
- 執行查詢句
- 第一種方式為dbSendQuery(),使用者下SQL去執行,執行完畢後產生一個resultset用來儲存結果,再透過fetch() function讀取resultset裡面儲存的資訊。
- 第二種方式為dbGetQuery(),直接取得使用者所下的SQL地執行結果。
rs = dbSendQuery(pgConn, statement = "SELECT count(*) FROM diamonds");
fetch(rs);
dbClearResult(rs); rm(rs)
df = dbGetQuery(pgConn, "SELECT color, avg(price) as AvgPrice FROM diamonds group by color")
df$color = factor(df$color,
order = T,
levels = c("J","I","H","G","F","E","D"))
df[order(df$color), ]
以上是連線上資料庫與簡易的資料庫操作範例,使用可以依照自己的需求去使用一開始提到的幾個package內的功能,在這邊只簡單示範了幾個基本語法而已
GPU環境變數設定
GPU的環境變數設定是很重要的步驟,因為在管院商業大數據平台上,運算資源是由中山大學管理學院的學生共同享有的,若沒有適當地設定GPU環境變數的話,可能會造成系統資源被特定使用者佔用,導致其他使用者無法共享平台上的資源。以下我們會分別教學在Python和R中要如何設定GPU的環境變數。
Python
-
GPU 指定
-
GPU指定的意思就是告訴電腦你要使用第幾張GPU。
-
GPU的索引位置是從0開始並透過逗號分隔,也就是說如果要使用第一張和第三張GPU,則可以透過底下這段程式碼完成設定。
import os
os.environ["CUDA_VISIBLE_DEVICES"] = "0,2"
-
限制GPU用量
-
限制GPU的記憶體使用量
R
- GPU 指定
-
GPU指定的意思就是告訴電腦你要使用第幾張GPU。
-
GPU的索引位置是從0開始並透過逗號分隔,也就是說如果要使用第一張和第二張GPU,則可以透過底下這段程式碼完成設定。
Sys.setenv(CUDA_HOME="/usr/local/cuda")
Sys.setenv(PATH=paste(Sys.getenv("PATH"), "/usr/local/cuda/bin", sep = ":"))
# Use both card #0 and #1
Sys.setenv(CUDA_VISIBLE_DEVICES="0,1")
- 限制GPU用量
- 限制GPU的記憶體使用量
大數據分析平台
商業模式與大數據分析競賽專用平台如下
各服務連結如下
大數據分析平台的服務有兩項,分別是由18台主機共有136個核心數和1.5TB記憶體組成的Hadoop的叢集(Hadoop cluster) 以及 備載GPU運算能力的伺服器。 而本院提供的開發環境為RStudio和Jupyter,使用者可以透過R和Python兩種語言來撰寫程式。
在這個頁面我們提供幾項簡易的教學,分別是
Hadoop
Hadoop是什麼呢?
簡單來講,想像如果有個檔案大小超過你的個人電腦可以儲存的容量,那絕對無法被放進你的電腦對吧?這時候我們就需要Hadoop了!
Hadoop是一個能儲存並管理大量資料的雲端平台,除了能儲存超過一個伺服器所能容納的檔案外,還能夠同時儲存、處理、分析幾千萬份這種超大的檔案,所以每當講到大數據,便會提到Hadoop這套技術。
這段影音及文字教學,目的是要讓使用者可以連線上管院伺服器上的Hadoop,並對HDFS(Hadoop File System)上的檔案做些簡單的操作。
影音教學
連線設定
Sys.setenv("HADOOP_CMD" = "/home/hadoop/hadoop/bin/hadoop") Sys.setenv("HADOOP_STREAMING"="/home/hadoop/hadoop/share/hadoop/tools/lib/hadoop-streaming-2.8.1.jar")
載入packages
rmr2, plyrmr, rhdfs 這些packages提供許多R的函式,讓使用者可以直接對HDFS系統上的任何檔案執行些指令,像是存取或是做資料分析。
hdfs.init() 這句的意思是連線HDFS系統。
library(rmr2) library(plyrmr) library(rhdfs) hdfs.init()
與HDFS系統互動
to.dfs( ): 寫入檔案至HDFS。
from.dfs( ):讀取HDFS上的檔案。
# 將mtcars這個dataframe上傳至hdfs檔案處理系統 to.dfs(mtcars, "/home/yourAccountName/mtcars.csv", format = "csv") # 從hdfs檔案處理系統上讀取檔案 from.dfs("/home/yourAccountName/mtcars.csv", format = "csv")
hdfs.ls():列出HDFS上的所有檔案。
hdfs.del():刪除HDFS上的所有檔案。
hdfs.ls("/home/yourAccountName") hdfs.del("/home/yourAccountName/mtcars.csv")
上述語法的 /yourAccountName/ 部分,請使用者自行將其改成自己的目錄名稱。
以上就是對於如何連線上Hadoop以及與HDFS互動的介紹。
當然,使用者可以透過"MapRudeuce"的方法去對Hadoop上的資料做更多操作。
Spark
既然處理大數據我們有了Hadoop這個強大的工具了,那為何還有Spark的出現呢?而Spark與Hadoop又有什麼不同呢?
Hadoop在執行MapReduce的運算時,會將中間產生的數據,存儲在硬碟中,也就說任何的資料存取都是在執行I/O,而I/O往往是效能的瓶頸,因此會有讀寫資料延遲的問題。但Spark比Hadoop晚4年問世,卻能以100倍快的速度執行MapReduce是為什麼呢?
Spark是基於記憶體內的運算框架,在運算時,會將中間產生的數據暫存在記憶體中,因此可以大大地加快運算速度,尤其是反覆執行越多次時,所需讀取的資料量就越大,越能看出Spark的效能。而Spark同時也與Hadoop相容,所以同樣可以透過HDFS存儲檔案。
影音教學
載入所需的package並連線上HDFS
Sys.setenv("HADOOP_CMD" = "/home/hadoop/hadoop/bin/hadoop") Sys.setenv("HADOOP_STREAMING"="/home/hadoop/hadoop/share/hadoop/tools/lib/hadoop-streaming-2.8.1.jar") library("rhdfs") hdfs.init()
設定Spark的連線資訊
# the following code are fixed setting library(dplyr) library(sparklyr) Sys.setenv(SPARK_HOME="/usr/local/spark/spark-2.1.0-bin-hadoop2.7/") config <- spark_config() config$spark.executor.memory = "32G" config$spark.cores.max = "50" config$spark.driver.memory = "16G" config$spark.yarn.executor.memoryOverhead = "4096" # create a connection to Spark sc <- spark_connect(master = "spark://hnamenode:7077", config = config)
執行完以上的程式後就可以連線上Spark了。
如果連線成功的話,會在RStudio的畫面右上角看到一個新的頁籤叫做"connection"。如果連線失敗則會在console的頁面跳出錯誤訊息。
在HDFS上存取檔案
hdfs.ls("/home/yourAccountName/") mySDF = spark_read_csv(sc, name = "mtcars", path = "hdfs:/home/yourAccountName/mtcars.csv", header = T) # you can also move R dataframe to Spark. movies_sdf = copy_to(sc, df = ggplot2movies::movies, name = "movies",overwrite = T)
中斷連線
範例:如何在Spark上操作巨量資料
接下來的範例會示範如何在Spark上操作巨量資料。
範例中我們會用到 babynames 資料集,資料集紀錄一百八十多萬的新生兒姓名資料。選用這個資料集的目的是要讓使用者感受在操作巨量資料時,Spark的運算能力有多強大。
影音教學
設定連線資訊&讀取資料
Spark 連線
# the following code are fixed setting Sys.setenv("HADOOP_CMD" = "/home/hadoop/hadoop/bin/hadoop") Sys.setenv("HADOOP_STREAMING"="/home/hadoop/hadoop/share/hadoop/tools/lib/hadoop-streaming-2.8.1.jar") library("rhdfs") hdfs.init() library(dplyr) library(sparklyr) Sys.setenv(SPARK_HOME="/usr/local/spark/spark-2.1.0-bin-hadoop2.7/") config <- spark_config() config$spark.executor.memory = "32G" config$spark.cores.max = "50" config$spark.driver.memory = "16G" config$spark.yarn.executor.memoryOverhead = "4096" # create a connection to Spark sc <- spark_connect(master = "spark://hnamenode:7077", config = config)
資料集讀取
data_file_1 = "hdfs:/home/sample/babynames.csv" # 透過spark_read_csv 至 hdfs上 讀取babynames 資料集 baby = spark_read_csv(sc, "babynames", data_file_2) # babynames 資料集總共有一百八十多萬筆 baby %>% summarise(n = n())
簡單查詢句:以 babynames 資料為例
使用者可以想像當資料筆數超級多的時候,一句查詢句至少要搜尋過全部資料一次,那會需要花多少時間去執行這個查詢句,況且實務上我們不會只做單一條件的查詢句,也就是說我們的條件可能會很複雜包含不只一個變數,那表示一定會搜尋全部的資料不少次,可想而知,這必定是很耗資源的一段程式。但透過Spark,執行底下的程式最多只要花5~7秒的時間就可以完成查詢,這就是Spark強大的地方。
# 設定起始時間 start_time <- proc.time() baby %>% summarise(n_year = n_distinct(year), n_sex = n_distinct(sex), n_name = n_distinct(name), n_n = n_distinct(n), n_prop = n_distinct(prop)) %>% data.frame # n_year n_sex n_name n_n n_prop # 136 2 95025 13604 162480 # 用程式執行完的時間減去起始時間 proc.time() - start_time # user system elapsed # 0.059 0.025 0.769
# 設定起始時間 start_time <- proc.time() babynames::babynames %>% summarise(n_year = n_distinct(year), n_sex = n_distinct(sex), n_name = n_distinct(name), n_n = n_distinct(n), n_prop = n_distinct(prop)) %>% data.frame # n_year n_sex n_name n_n n_prop # 136 2 95025 13604 162480 proc.time() - start_time # user system elapsed # 0.578 0.013 0.658
資料視覺化:以 babynames 這個資料集為範例
babynames這個資料集紀錄從1880年開始,在美國每年出生的新生兒取哪些名字,每個名字總共被用了幾次等資訊,在資料集裡面共有5個columns,分別是年份、性別、姓名、總數、佔總出生人數的比重。
在範例中,寫了一個函式用來查詢特定一年中,哪些名字最常被使用來命名。
另外我們也附上官方教學文件供使用者參考。
載入會用到的packages
library(ggplot2) #The following are the tools for graphing library(dygraphs) library(rbokeh) library(RColorBrewer) library(plotly)
先找出1986以後且被用來命名過超過一千次的資料,列出姓名跟性別這個兩個變數,並以topNames這個變數儲存起來。
topNames = baby %>% filter(year > 1986) %>% group_by(name, sex) %>% summarize(count = sum(n)) %>% filter(count > 1000) %>% select(name, sex)
接著用原始資料對topNames做inner_join,並且group_by年份這個變數,表示出來的結果會是各年中最代表的姓名
yearlyName = baby %>% filter(year > 1986) %>% inner_join(topNames) %>% group_by(year, name, sex) %>% summarize(count = sum(n)) %>% sdf_copy_to(sc, ., "yearlyname", T, overwrite=T)
再來我們將上面做過的事情,寫成一個函式,以便未來想要做查詢的時候,不需要重複打這麼多程式碼,只要傳入年份變數就可以得到我們想要的結果,還可以把結果以圖形化的方式呈現出來。
MostPopularNames <- function(year) { topNames <- baby %>% filter(year >= 1986) %>% group_by(name, sex) %>% summarize(count = sum(n)) %>% filter(count > 1000) %>% select(name, sex) yearlyName <- baby %>% filter(year >= 1986) %>% inner_join(topNames) %>% group_by(year, name, sex) %>% summarize(count = sum(n)) %>% sdf_copy_to(sc, ., "yearlyname", T, overwrite=T) TopNm <- yearlyName %>% filter(year == year) %>% group_by(name,sex) %>% summarize(count=sum(count)) %>% group_by(sex) %>% mutate(rank = min_rank(desc(count))) %>% filter(rank < 5) %>% arrange(sex, rank) %>% select(name,sex,rank) %>% sdf_copy_to(sc,.,"topNames",T,overwrite=TRUE) topNamesYearly <- yearlyName %>% inner_join(select(TopNm, sex, name)) %>% collect #兩種畫法可以選一種畫就好 #第一種圖 ggplot(topNamesYearly, aes(year, count, color = name)) + facet_grid(~sex) + geom_line() + ggtitle(paste0("Most Popular Names of ", year)) #第二種圖 # 拿出名字欄位之後要做factor化 names <- TopNm %>% select(name) %>% collect %>% as.data.frame names <- names[, 1, T] topNamesYearly$name <- factor(topNamesYearly$name, levels = names, labels = names) p = ggplot(df, aes(year, count, color=name)) + theme_light() + facet_wrap(~sex, nrow=2) + geom_vline(xintercept = year, col='yellow', lwd=1.2) + geom_line() + ggtitle(sprintf('Most Popular Names of %d',year)) + scale_colour_brewer(palette = "Paired") plotly_build(p) }
透過函式給定特定年份,就可以得到該年中最常被使用的姓名是哪個。
sharedName = baby %>% mutate(male=ifelse(sex == "M", n, 0), female=ifelse(sex == "F", n, 0)) %>% group_by(name) %>% summarize(Male = sum(male), Female = sum(female), count = sum(n), AvgYear = round(sum(year * n) / sum(n),0)) %>% filter(Male > 10000 & Female > 10000) %>% collect figure(width = NULL, height = NULL, xlab = "Log10 Number of Males", ylab = "Log10 Number of Females", title = "Top shared names (1880 - 2014)") %>% ly_points(log10(Male), log10(Female), data = sharedName, color = AvgYear, size = scale(sqrt(count)), hover = list(name, Male, Female, AvgYear), legend = FALSE
使用完Spark後,如果暫時沒有要再使用,務必要將其中斷連線
Greenplum 實作範例
影音教學
Greenplum database是一種開源的分散式資料庫,它提供PB級別數據量的快速分析能力及對超大資料表做快速查詢的能力。
過去,當使用者要分析儲存在資料庫上的結構化資料的時候,必須先將資料表讀入分析工具中,例如將一個table讀進RStudio中,再進行資料分析、建立模型等等,但如果資料表很大的話,會造成在讀取資料的階段就耗盡了大量的運算資源。而現在有了Greenplum這個擁有資料分析能力的資料庫,使用者可以直接在資料庫中對資料表做資料分析、做查詢句甚至是訓練模型,並將結果直接輸出至我們的分析工具中,如此一來,就可以避免在讀取資料時大量消耗運算資源的問題,使用者可以直接對資料庫中的資料表做更快速、更彈性的操作。
底下的範例會教使用者如何用RStudio連線上資料庫(本院提供的資料庫為Greenplum)以及對資料表做些簡單的查詢句。
pgConn = dbConnect("PostgreSQL", dbname = "帳號名稱", user="帳號名稱", password="密碼", host = "192.168.1.100")
##List tables in database dbListTables(pgConn) diamonds = as.data.frame(diamonds) ##create table dbWriteTable(pgConn, "diamonds", diamonds) ##Read data in table dbReadTable(pgConn, "diamonds") ##List column name of table dbListFields(pgConn, "diamonds")
## send query to database and create resultset object ## use fetch() function to read the resultset rs = dbSendQuery(pgConn, statement = "SELECT count(*) FROM diamonds"); fetch(rs); dbClearResult(rs); rm(rs) df = dbGetQuery(pgConn, "SELECT color, avg(price) as AvgPrice FROM diamonds group by color") # color variable of diamonds dataset says that from "J" to "D" represents worst to best df$color = factor(df$color, order = T, levels = c("J","I","H","G","F","E","D")) df[order(df$color), ]
以上是連線上資料庫與簡易的資料庫操作範例,使用可以依照自己的需求去使用一開始提到的幾個package內的功能,在這邊只簡單示範了幾個基本語法而已
GPU環境變數設定
GPU的環境變數設定是很重要的步驟,因為在管院商業大數據平台上,運算資源是由中山大學管理學院的學生共同享有的,若沒有適當地設定GPU環境變數的話,可能會造成系統資源被特定使用者佔用,導致其他使用者無法共享平台上的資源。以下我們會分別教學在Python和R中要如何設定GPU的環境變數。
Python
GPU 指定
GPU指定的意思就是告訴電腦你要使用第幾張GPU。
GPU的索引位置是從0開始並透過逗號分隔,也就是說如果要使用第一張和第三張GPU,則可以透過底下這段程式碼完成設定。
import os # use first and third GPU os.environ["CUDA_VISIBLE_DEVICES"] = "0,2"
限制GPU用量
一次只使用一張。
# use any one GPU import tensorflow as tf config = tf.ConfigProto(device_count={'GPU': 1}) sess = tf.Session(config=config)
限制GPU的記憶體使用量
# use 20% memory of GPU gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=0.2) sess = tf.Session(config=tf.ConfigProto(gpu_options=gpu_options)) # if using Keras import tensorflow as tf from keras.backend.tensorflow_backend import set_session config = tf.ConfigProto() config.gpu_options.per_process_gpu_memory_fraction = 0.2 set_session(tf.Session(config=config))
R
GPU指定的意思就是告訴電腦你要使用第幾張GPU。
GPU的索引位置是從0開始並透過逗號分隔,也就是說如果要使用第一張和第二張GPU,則可以透過底下這段程式碼完成設定。
Sys.setenv(CUDA_HOME="/usr/local/cuda") Sys.setenv(PATH=paste(Sys.getenv("PATH"), "/usr/local/cuda/bin", sep = ":")) # Use both card #0 and #1 Sys.setenv(CUDA_VISIBLE_DEVICES="0,1")
一次只使用一張。
library(keras); library(tensorflow) config = tf$ConfigProto(device_count={'GPU': 1}) sess = tf$Session(config=config) # if using keras please add the following k_set_session(sess)
限制使用者只能使用20%的記憶體
gpu_options=tf$GPUOptions(per_process_gpu_memory_fraction=0.2) sess = tf$Session(config=tf$ConfigProto(gpu_options=gpu_options)) # if using keras please add the following k_set_session(sess)