F# Data


F# Data: WorldBank プロバイダー

世界銀行 (World Bank)は世界中の発展途上国に対して、 経済的かつ技術的な支援を行っている国際組織です。 また、世界銀行は活動の一環として世界中の各国における発展指標や その他のデータを収集しています。 data catalog のページではプログラムからも アクセスできる8000以上の指標が公開されています。

WorldBank 型プロバイダーを使うと、F#プログラムやスクリプトから型安全かつ 簡単な方法でWorldBankのデータにアクセスできるようになります。 このドキュメントはこの型プロバイダーの基本的な部分のみ説明しています。 WorldBank 型プロバイダーは Try F# の Webサイトにある"Data Science" のチュートリアルでも使われているため、 そちらも参考にするとよいでしょう。

型プロバイダーの基本

以下の例では(F# Interactive上で) FSharp.Data.dll ライブラリを読み込んだ後、 GetDataContext メソッドを使ってWorldBankへの接続を初期化し、 イギリスで大学に進学した人口の割合を受信しています;

1: 
2: 
3: 
4: 
5: 
6: 
7: 
8: 
9: 
#r "../../../../bin/lib/net45/FSharp.Data.dll"
open FSharp.Data

let data = WorldBankData.GetDataContext()

data
  .Countries.``United Kingdom``
  .Indicators.``Gross capital formation (% of GDP)``
|> Seq.maxBy fst

データコンテキストが生成されると、WorldBank 型プロバイダーは 世界銀行で把握されているすべての国のリスト、および 利用可能なすべての指針のリストを受信します。 それぞれはプロパティとして参照できるようになっているため、 自動コンプリートの候補から様々なデータソースが利用できることが確認できるでしょう。 多くの指標には長い名前がつけられているため、 名前を \`` で囲む必要があります。

Gross capital formation (% of GDP) プロパティの結果は 異なる年毎の値のシーケンスです。 Seq.maxBy fst とすることで直近で利用可能な最新のデータを取得できます。

世界銀行のデータをチャート表示する

FSharp.Charting ライブラリを使うと 大学進学率の変遷を簡単に図表にできます:

1: 
2: 
#load "../../../../packages/test/FSharp.Charting/lib/net45/FSharp.Charting.fsx"
open FSharp.Charting
1: 
2: 
3: 
data.Countries.``United Kingdom``
    .Indicators.``Gross capital formation (% of GDP)``
|> Chart.Line

Chart.Line 関数はXとYの値ペアのシーケンスを受け取ります。 そのため、世界銀行から受信したデータセットをそのまま渡せば Xが年、Yがその年の値になったチャートが作成できます。

Chart

世界銀行のデータを非同期的に使う

非常に大量のデータをダウンロードする必要がある場合、 あるいは呼び出し元をブロックせずに処理を実行した場合には、 F#の非同期ワークフローを使って操作ができればいいなと思うのではないでしょうか。 F# Dataライブラリには様々なstatic引数を受け取るような WorldBankDataProvider 型があります。 引数 Asyncronoustrue にすると、 すべての操作を非同期的に実行するような型が 型プロバイダーによって生成されます:

1: 
2: 
type WorldBank = WorldBankDataProvider<"World Development Indicators", Asynchronous=true>
WorldBank.GetDataContext()

上のコードではデータソース(一般的に利用可能な指標のコレクション)の名前として "World Development Indicators" を指定して、オプション引数 Asynchronoustrue を設定しています。 そうするとたとえば Gross capital formation (% of GDP) などのプロパティが Async<(int * int)[]> になります。 これはつまり非同期的に処理を始めることができ、最終的にデータを生成するような 操作であることを示しています。

データを並列にダウンロードする

非同期バージョンの型プロバイダーのデモとして、 多数の国における大学進学率を並列にダウンロートしてみます。 まずデータコンテキストを作成した後に、 対象とする国を配列として定義します:

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
let wb = WorldBank.GetDataContext()

// 対象とする国のリストを作成
let countries = 
 [| wb.Countries.``Arab World``
    wb.Countries.``European Union``
    wb.Countries.Australia
    wb.Countries.Brazil
    wb.Countries.Canada
    wb.Countries.Chile
    wb.Countries.``Czech Republic``
    wb.Countries.Denmark
    wb.Countries.France
    wb.Countries.Greece
    wb.Countries.``Low income``
    wb.Countries.``High income``
    wb.Countries.``United Kingdom``
    wb.Countries.``United States`` |]

データを並列にダウンロードするには、非同期計算のリストを作成した後、 それらを Async.Parallel で組み合わせ、 (1つになった)計算を実行してすべてのダウンロード処理を行います:

1: 
2: 
3: 
4: 
5: 
6: 
[ for c in countries ->
    c.Indicators.``Gross capital formation (% of GDP)`` ]
|> Async.Parallel
|> Async.RunSynchronously
|> Array.map Chart.Line
|> Chart.Combine

上のコードは単に Async.RunSynchronously を使ってダウンロードするだけではなく、 それぞれのデータセットから1つの折れ線チャートを出力して、 各チャートを Chart.Combine で1つの総合チャートにしています。

Chart

関連する記事

Multiple items
namespace FSharp

--------------------
namespace Microsoft.FSharp
Multiple items
namespace FSharp.Data

--------------------
namespace Microsoft.FSharp.Data
val data : WorldBankData.ServiceTypes.WorldBankDataService
type WorldBankData =
  static member GetDataContext : unit -> WorldBankDataService
  nested type ServiceTypes


<summary>Typed representation of WorldBank data. See http://www.worldbank.org for terms and conditions.</summary>
WorldBankData.GetDataContext() : WorldBankData.ServiceTypes.WorldBankDataService
module Seq

from Microsoft.FSharp.Collections
val maxBy : projection:('T -> 'U) -> source:seq<'T> -> 'T (requires comparison)
val fst : tuple:('T1 * 'T2) -> 'T1
namespace FSharp.Charting
property WorldBankData.ServiceTypes.WorldBankDataService.Countries: WorldBankData.ServiceTypes.Countries
property WorldBankData.ServiceTypes.Countries.( United Kingdom ): WorldBankData.ServiceTypes.Country


The data for country 'United Kingdom'
type Chart =
  static member Area : data:seq<#value> * ?Name:string * ?Title:string * ?Labels:#seq<string> * ?Color:Color * ?XTitle:string * ?YTitle:string -> GenericChart
  static member Area : data:seq<#key * #value> * ?Name:string * ?Title:string * ?Labels:#seq<string> * ?Color:Color * ?XTitle:string * ?YTitle:string -> GenericChart
  static member Bar : data:seq<#value> * ?Name:string * ?Title:string * ?Labels:#seq<string> * ?Color:Color * ?XTitle:string * ?YTitle:string -> GenericChart
  static member Bar : data:seq<#key * #value> * ?Name:string * ?Title:string * ?Labels:#seq<string> * ?Color:Color * ?XTitle:string * ?YTitle:string -> GenericChart
  static member BoxPlotFromData : data:seq<#key * #seq<'a2>> * ?Name:string * ?Title:string * ?Color:Color * ?XTitle:string * ?YTitle:string * ?Percentile:int * ?ShowAverage:bool * ?ShowMedian:bool * ?ShowUnusualValues:bool * ?WhiskerPercentile:int -> GenericChart (requires 'a2 :> value)
  static member BoxPlotFromStatistics : data:seq<#key * #value * #value * #value * #value * #value * #value> * ?Name:string * ?Title:string * ?Labels:#seq<string> * ?Color:Color * ?XTitle:string * ?YTitle:string * ?Percentile:int * ?ShowAverage:bool * ?ShowMedian:bool * ?ShowUnusualValues:bool * ?WhiskerPercentile:int -> GenericChart
  static member Bubble : data:seq<#value * #value> * ?Name:string * ?Title:string * ?Labels:#seq<string> * ?Color:Color * ?XTitle:string * ?YTitle:string * ?BubbleMaxSize:int * ?BubbleMinSize:int * ?BubbleScaleMax:float * ?BubbleScaleMin:float * ?UseSizeForLabel:bool -> GenericChart
  static member Bubble : data:seq<#key * #value * #value> * ?Name:string * ?Title:string * ?Labels:#seq<string> * ?Color:Color * ?XTitle:string * ?YTitle:string * ?BubbleMaxSize:int * ?BubbleMinSize:int * ?BubbleScaleMax:float * ?BubbleScaleMin:float * ?UseSizeForLabel:bool -> GenericChart
  static member Candlestick : data:seq<#value * #value * #value * #value> * ?Name:string * ?Title:string * ?Labels:#seq<string> * ?Color:Color * ?XTitle:string * ?YTitle:string -> CandlestickChart
  static member Candlestick : data:seq<#key * #value * #value * #value * #value> * ?Name:string * ?Title:string * ?Labels:#seq<string> * ?Color:Color * ?XTitle:string * ?YTitle:string -> CandlestickChart
  ...
static member Chart.Line : data:seq<#value> * ?Name:string * ?Title:string * ?Labels:#seq<string> * ?Color:System.Drawing.Color * ?XTitle:string * ?YTitle:string -> ChartTypes.GenericChart
static member Chart.Line : data:seq<#key * #value> * ?Name:string * ?Title:string * ?Labels:#seq<string> * ?Color:System.Drawing.Color * ?XTitle:string * ?YTitle:string -> ChartTypes.GenericChart
Multiple items
module WorldBank

--------------------
type WorldBank = WorldBankDataProvider<...>
type WorldBankDataProvider


<summary>Typed representation of WorldBank data with additional configuration parameters. See http://www.worldbank.org for terms and conditions.</summary>
                        <param name='Sources'>The World Bank data sources to include, separated by semicolons. Defaults to `World Development Indicators;Global Financial Development`.
                        If an empty string is specified, includes all data sources.</param>
                        <param name='Asynchronous'>Generate asynchronous calls. Defaults to false.</param>
WorldBankDataProvider<...>.GetDataContext() : WorldBankDataProvider<...>.ServiceTypes.WorldBankDataService
val wb : WorldBankDataProvider<...>.ServiceTypes.WorldBankDataService
val countries : WorldBankDataProvider<...>.ServiceTypes.Country []
property WorldBankDataProvider<...>.ServiceTypes.WorldBankDataService.Countries: WorldBankDataProvider<...>.ServiceTypes.Countries
property WorldBankDataProvider<...>.ServiceTypes.Countries.( Arab World ): WorldBankDataProvider<...>.ServiceTypes.Country


The data for country 'Arab World'
property WorldBankDataProvider<...>.ServiceTypes.Countries.( European Union ): WorldBankDataProvider<...>.ServiceTypes.Country


The data for country 'European Union'
property WorldBankDataProvider<...>.ServiceTypes.Countries.Australia: WorldBankDataProvider<...>.ServiceTypes.Country


The data for country 'Australia'
property WorldBankDataProvider<...>.ServiceTypes.Countries.Brazil: WorldBankDataProvider<...>.ServiceTypes.Country


The data for country 'Brazil'
property WorldBankDataProvider<...>.ServiceTypes.Countries.Canada: WorldBankDataProvider<...>.ServiceTypes.Country


The data for country 'Canada'
property WorldBankDataProvider<...>.ServiceTypes.Countries.Chile: WorldBankDataProvider<...>.ServiceTypes.Country


The data for country 'Chile'
property WorldBankDataProvider<...>.ServiceTypes.Countries.( Czech Republic ): WorldBankDataProvider<...>.ServiceTypes.Country


The data for country 'Czech Republic'
property WorldBankDataProvider<...>.ServiceTypes.Countries.Denmark: WorldBankDataProvider<...>.ServiceTypes.Country


The data for country 'Denmark'
property WorldBankDataProvider<...>.ServiceTypes.Countries.France: WorldBankDataProvider<...>.ServiceTypes.Country


The data for country 'France'
property WorldBankDataProvider<...>.ServiceTypes.Countries.Greece: WorldBankDataProvider<...>.ServiceTypes.Country


The data for country 'Greece'
property WorldBankDataProvider<...>.ServiceTypes.Countries.( Low income ): WorldBankDataProvider<...>.ServiceTypes.Country


The data for country 'Low income'
property WorldBankDataProvider<...>.ServiceTypes.Countries.( High income ): WorldBankDataProvider<...>.ServiceTypes.Country


The data for country 'High income'
property WorldBankDataProvider<...>.ServiceTypes.Countries.( United Kingdom ): WorldBankDataProvider<...>.ServiceTypes.Country


The data for country 'United Kingdom'
property WorldBankDataProvider<...>.ServiceTypes.Countries.( United States ): WorldBankDataProvider<...>.ServiceTypes.Country


The data for country 'United States'
val c : WorldBankDataProvider<...>.ServiceTypes.Country
property WorldBankDataProvider<...>.ServiceTypes.Country.Indicators: WorldBankDataProvider<...>.ServiceTypes.Indicators


<summary>The indicators for the country</summary>
property WorldBankDataProvider<...>.ServiceTypes.Indicators.( Gross capital formation (% of GDP) ): Async<Runtime.WorldBank.Indicator>


Gross capital formation (formerly gross domestic investment) consists of outlays on additions to the fixed assets of the economy plus net changes in the level of inventories. Fixed assets include land improvements (fences, ditches, drains, and so on); plant, machinery, and equipment purchases; and the construction of roads, railways, and the like, including schools, offices, hospitals, private residential dwellings, and commercial and industrial buildings. Inventories are stocks of goods held by firms to meet temporary or unexpected fluctuations in production or sales, and "work in progress." According to the 1993 SNA, net acquisitions of valuables are also considered capital formation.
Multiple items
type Async =
  static member AsBeginEnd : computation:('Arg -> Async<'T>) -> ('Arg * AsyncCallback * obj -> IAsyncResult) * (IAsyncResult -> 'T) * (IAsyncResult -> unit)
  static member AwaitEvent : event:IEvent<'Del,'T> * ?cancelAction:(unit -> unit) -> Async<'T> (requires delegate and 'Del :> Delegate)
  static member AwaitIAsyncResult : iar:IAsyncResult * ?millisecondsTimeout:int -> Async<bool>
  static member AwaitTask : task:Task -> Async<unit>
  static member AwaitTask : task:Task<'T> -> Async<'T>
  static member AwaitWaitHandle : waitHandle:WaitHandle * ?millisecondsTimeout:int -> Async<bool>
  static member CancelDefaultToken : unit -> unit
  static member Catch : computation:Async<'T> -> Async<Choice<'T,exn>>
  static member Choice : computations:seq<Async<'T option>> -> Async<'T option>
  static member FromBeginEnd : beginAction:(AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
  ...

--------------------
type Async<'T> =
static member Async.Parallel : computations:seq<Async<'T>> -> Async<'T []>
static member Async.RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:System.Threading.CancellationToken -> 'T
module Array

from Microsoft.FSharp.Collections
val map : mapping:('T -> 'U) -> array:'T [] -> 'U []
static member Chart.Combine : charts:seq<ChartTypes.GenericChart> -> ChartTypes.GenericChart
Fork me on GitHub