これは、なにをしたくて書いたもの?
Qdrantのドキュメントを見ていて、Fakerというフェイクデータを生成するライブラリーがあることを知ったので簡単に試しておきます。
Faker
FakerのWebサイト、GitHubリポジトリーはこちら。
Welcome to Faker’s documentation! — Faker 24.4.0 documentation
GitHub - joke2k/faker: Faker is a Python package that generates fake data for you.
Fakerはフェイクデータを作成するライブラリーで、データベースのセットアップや性能テスト、匿名化したデータの作成といった用途で
利用することが想定されています。
今回はPythonのFakerを扱うのですが、複数の言語で存在するようです。
PHPのFakerのリポジトリーはアーカイブされていました。
GitHub - fzaninotto/Faker: Faker is a PHP library that generates fake data for you
ここからはPython版のFakerを見ていきます。
使い方はこんな感じで、Faker
のインスタンスを作成した後にフェイクデータに対応するメソッドを呼び出すようです。
from faker import Faker fake = Faker() fake.name() # 'Lucy Cechtelar' fake.address() # '426 Jordy Lodge # Cartwrightshire, SC 88120-6700' fake.text() # 'Sint velit eveniet. Rerum atque repellat voluptatem quia rerum. Numquam excepturi # beatae sint laudantium consequatur. Magni occaecati itaque sint et sit tempore. Nesciunt # amet quidem. Iusto deleniti cum autem ad quia aperiam. # A consectetur quos aliquam. In iste aliquid et aut similique suscipit. Consequatur qui # quaerat iste minus hic expedita. Consequuntur error magni et laboriosam. Aut aspernatur # voluptatem sit aliquam. Dolores voluptatum est. # Aut molestias et maxime. Fugit autem facilis quos vero. Eius quibusdam possimus est. # Ea quaerat et quisquam. Deleniti sunt quam. Adipisci consequatur id in occaecati. # Et sint et. Ut ducimus quod nemo ab voluptatum.'
これらのメソッド(上記例だとname
やaddress
、text
)のことは"fake"と呼ばれ、"fake"の多くはプロバイダーとしてパッケージされている
ようです。
プロバイダーのリストはこちら。
Standard Providers — Faker 24.4.0 documentation
コミュニティによるプロバイダーもあるようです。
Community Providers — Faker 24.4.0 documentation
また、自分でプロバイダーを作成したり、カスタマイズしたりすることもできるようです。
ローカライズにも対応しているようです。ja_JP
で、日本語のフェイクデータが生成できそうです。
from faker import Faker fake = Faker(['it_IT', 'en_US', 'ja_JP']) for _ in range(10): print(fake.name()) # 鈴木 陽一 # Leslie Moreno # Emma Williams # 渡辺 裕美子 # Marcantonio Galuppi # Martha Davis # Kristen Turner # 中津川 春香 # Ashley Castillo # 山田 桃子
コマンドラインツールとしても使えます。
紹介はこれくらいにして、使っていってみましょう。
環境
今回の環境はこちら。
$ python3 --version Python 3.10.12 $ pip3 --version pip 22.0.2 from /usr/lib/python3/dist-packages/pip (python 3.10)
Fakerを使ってみる
それでは、Fakerを使ってみましょう。
まずはインストール。
$ pip3 install Faker
現在のバージョンは24.4.0です。
$ pip3 list Package Version --------------- ----------- Faker 24.4.0 pip 22.0.2 python-dateutil 2.9.0.post0 setuptools 59.6.0 six 1.16.0
コマンドラインツールとして使ってみる
最初はコマンドラインツールとして使ってみましょう。
バージョン。
$ faker --version faker 24.4.0
ヘルプ。
$ faker --help usage: faker [-h] [--version] [-v] [-o output] [-l LOCALE] [-r REPEAT] [-s SEP] [--seed SEED] [-i [INCLUDE ...]] [fake] [fake argument ...] faker version 24.4.0 positional arguments: fake name of the fake to generate output for (e.g. profile) fake argument optional arguments to pass to the fake (e.g. the profile fake takes an optional list of comma separated field names as the first argument) options: -h, --help show this help message and exit --version show program's version number and exit -v, --verbose show INFO logging events instead of CRITICAL, which is the default. These logging events provide insight into localization of specific providers. -o output redirect output to a file -l LOCALE, --lang LOCALE specify the language for a localized provider (e.g. de_DE) -r REPEAT, --repeat REPEAT generate the specified number of outputs -s SEP, --sep SEP use the specified separator after each output --seed SEED specify a seed for the random generator so that results are repeatable. Also compatible with 'repeat' option -i [INCLUDE ...], --include [INCLUDE ...] list of additional custom providers to user, given as the import path of the module containing your Provider class (not the provider class itself) supported locales: ar_AA, ar_AE, ar_BH, ar_EG, ar_JO, ar_PS, ar_SA, az_AZ, bg_BG, bn_BD, bs_BA, cs_CZ, da_DK, de, de_AT, de_CH, de_DE, dk_DK, el_CY, el_GR, en, en_AU, en_BD, en_CA, en_GB, en_IE, en_IN, en_NZ, en_PH, en_TH, en_US, es, es_AR, es_CA, es_CL, es_CO, es_ES, es_MX, et_EE, fa_IR, fi_FI, fil_PH, fr_BE, fr_CA, fr_CH, fr_FR, fr_QC, ga_IE, he_IL, hi_IN, hr_HR, hu_HU, hy_AM, id_ID, it_CH, it_IT, ja_JP, ka_GE, ko_KR, la, lb_LU, lt_LT, lv_LV, mt_MT, ne_NP, nl_BE, nl_NL, no_NO, or_IN, pl_PL, pt_BR, pt_PT, ro_RO, ru_RU, sk_SK, sl_SI, sq_AL, sv_SE, ta_IN, th, th_TH, tl_PH, tr_TR, tw_GH, uk_UA, vi_VN, zh_CN, zh_TW, zu_ZA Faker can take a locale as an optional argument, to return localized data. If no locale argument is specified, the factory falls back to the user's OS locale as long as it is supported by at least one of the providers. - for this user, the default locale is ja_JP. If the optional argument locale and/or user's default locale is not available for the specified provider, the factory falls back to faker's default locale, which is en_US. examples: $ faker address 968 Bahringer Garden Apt. 722 Kristinaland, NJ 09890 $ faker -l de_DE address Samira-Niemeier-Allee 56 94812 Biedenkopf $ faker profile ssn,birthdate {'ssn': u'628-10-1085', 'birthdate': '2008-03-29'} $ faker -r=3 -s=";" name Willam Kertzmann; Josiah Maggio; Gayla Schmitt;
サポートされているLocaleも表示されるんですね。
supported locales: ar_AA, ar_AE, ar_BH, ar_EG, ar_JO, ar_PS, ar_SA, az_AZ, bg_BG, bn_BD, bs_BA, cs_CZ, da_DK, de, de_AT, de_CH, de_DE, dk_DK, el_CY, el_GR, en, en_AU, en_BD, en_CA, en_GB, en_IE, en_IN, en_NZ, en_PH, en_TH, en_US, es, es_AR, es_CA, es_CL, es_CO, es_ES, es_MX, et_EE, fa_IR, fi_FI, fil_PH, fr_BE, fr_CA, fr_CH, fr_FR, fr_QC, ga_IE, he_IL, hi_IN, hr_HR, hu_HU, hy_AM, id_ID, it_CH, it_IT, ja_JP, ka_GE, ko_KR, la, lb_LU, lt_LT, lv_LV, mt_MT, ne_NP, nl_BE, nl_NL, no_NO, or_IN, pl_PL, pt_BR, pt_PT, ro_RO, ru_RU, sk_SK, sl_SI, sq_AL, sv_SE, ta_IN, th, th_TH, tl_PH, tr_TR, tw_GH, uk_UA, vi_VN, zh_CN, zh_TW, zu_ZA
たとえば、name
で試してみましょう。
$ faker name 木村 陽一
いきなり日本語が出ました…。
よく見ると、Localeを未指定の場合はOSのLocaleを使うと書かれていますね。
Faker can take a locale as an optional argument, to return localized data. If no locale argument is specified, the factory falls back to the user's OS locale as long as it is supported by at least one of the providers. - for this user, the default locale is ja_JP.
明示的に指定する場合は-l
または--lang
で指定します。
$ faker -l ja_JP name 高橋 聡太郎 $ faker --lang en_US name Benjamin Shea
今回は明示的に指定することにしましょう。
-r
で、指定した回数出力できます。
$ faker -l ja_JP -r 3 address 大阪府大島町上高野10丁目8番13号 パレス湯本塩原922 長野県長生郡白子町四番町6丁目21番6号 佐賀県羽村市北上野36丁目12番3号
-s
でセパレーターを指定します。空行が気になるので、空文字にしました。
$ faker -l ja_JP -r 3 -s '' address 京都府我孫子市東神田25丁目13番17号 青森県大田区押上12丁目22番17号 島根県荒川区北上野25丁目25番4号 上吉羽パレス925
-o
でファイルに出力できます。
$ faker -l ja_JP -r 10 -s '' -o isbn13-10.txt isbn13
結果。
isbn13-10.txt
978-0-7743-8714-9 978-1-72817-220-0 978-1-61194-154-8 978-0-9625246-4-6 978-0-344-76991-7 978-0-252-38021-1 978-0-9788212-0-3 978-1-66603-286-4 978-1-9815-2440-2 978-1-103-64848-1
プロバイダーによっては、こういう出力になるものもあります。
$ faker -l ja_JP profile {'job': '公務員', 'company': '有限会社長谷川保険', 'ssn': '871-33-9808', 'residence': '新潟県八千代市六番町2丁目1番7号 柿木沢新田パーク717', 'current_location': (Decimal('-62.3285515'), Decimal('-22.976681')), 'blood_group': 'O-', 'website': ['https://www.nakamura.com/', 'https://ito.jp/', 'http://nakamura.com/'], 'username': 'fyamaguchi', 'name': '吉田 零', 'sex': 'M', 'address': '長野県青梅市高輪36丁目19番18号 パーク橋場885', 'mail': 'momokokondo@gmail.com', 'birthdate': datetime.date(2018, 6, 29)}
この場合、指定した要素に絞って出力もできます。
$ faker -l ja_JP profile job,company {'job': '司法書士', 'company': '合同会社松田保険'}
また、プロバイダーによってはプロバイダーをそのまま指定してもダメなものもあります。
## これはNG $ faker -l ja_JP person Traceback (most recent call last): File "/path/to/site-packages/faker/generator.py", line 92, in get_formatter return getattr(self, formatter) AttributeError: 'Generator' object has no attribute 'person' During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/path/to/site-packages/faker/cli.py", line 97, in print_doc print(fake.format(provider_or_field, *args), end="", file=output) File "/path/to/site-packages/faker/generator.py", line 88, in format return self.get_formatter(formatter)(*args, **kwargs) File "/path/to/site-packages/faker/generator.py", line 98, in get_formatter raise AttributeError(msg) AttributeError: Unknown formatter 'person' with locale 'ja_JP' During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/path/to/bin/faker", line 8, in <module> sys.exit(execute_from_command_line()) File "/path/to/site-packages/faker/cli.py", line 291, in execute_from_command_line command.execute() File "/path/to/site-packages/faker/cli.py", line 265, in execute print_doc( File "/path/to/site-packages/faker/cli.py", line 99, in print_doc raise ValueError(f'No faker found for "{provider_or_field}({args})"') ValueError: No faker found for "person([])" ## これはOK $ faker -l ja_JP name 佐藤 涼平
これは、あくまで指定するのはfakeだからです。
name
はperson
プロバイダーのfakeです。プロバイダーとfakeの名前が一致するとは限らないようなので、プロバイダーの一覧
というよりはその中にあるfakeを見た方がよさそうですね。
faker.providers.person — Faker 24.6.0 documentation
コマンドラインツールとしての使い方は、これくらいにしておきましょう。
プログラムで使う
続いて、プログラムで使ってみましょう。
こんな感じで作成。
app.py
from faker import Faker faker = Faker("ja_JP") header = ["name", "address", "phone-number", "job"] print(" | ".join(header)) for _ in range(10): print( " | ".join([faker.name(), faker.address(), faker.phone_number(), faker.job()]) )
実行結果。
$ python3 app.py name | address | phone-number | job 高橋 修平 | 島根県四街道市神明内1丁目7番9号 元浅草コーポ173 | 090-6292-3048 | 音楽家 小林 加奈 | 山口県八王子市上広谷14丁目23番3号 | 73-4556-0885 | 裁判官 山田 浩 | 栃木県稲城市羽折町22丁目19番6号 シャルム西浅草447 | 080-4384-5952 | コピーライター 斎藤 あすか | 大阪府武蔵村山市北上野16丁目1番20号 東浅草アーバン995 | 070-2098-5528 | 電気工事士 池田 篤司 | 宮城県山武郡芝山町箭坪24丁目5番5号 コート戸島217 | 080-9504-4444 | 医師 橋本 千代 | 群馬県山武郡横芝光町上高野35丁目26番8号 上高野コート456 | 65-8558-5395 | モデル 吉田 太一 | 熊本県香取市蟇沼24丁目16番5号 | 080-1606-0085 | 公務員 渡辺 千代 | 長崎県日野市中小来川8丁目3番17号 クレスト一ツ橋795 | 070-7744-8111 | 気象予報士 山田 和也 | 青森県武蔵村山市蔵前26丁目26番16号 | 66-1338-0212 | ゲームクリエイター 高橋 康弘 | 高知県横浜市鶴見区天神島2丁目27番19号 | 18-2240-9622 | 救急救命士
だいたい雰囲気はわかりましたね。
あとはプロバイダーのドキュメントを見ていけばよいかなと思います。
オマケ
ちょっと気になるので、実装を見てみましょう。
プロバイダーは、Localeごとのディレクトリにあるようです。
https://github.com/joke2k/faker/blob/v24.4.0/faker/providers/person/ja_JP/__init__.py
どんなデータが生成されそうなのかは、ソースコードを見ればわかりそうです。
first_name_female_pairs = ( ("明美", "アケミ", "Akemi"), ("あすか", "アスカ", "Asuka"), ("香織", "カオリ", "Kaori"), ("加奈", "カナ", "Kana"), ("くみ子", "クミコ", "Kumiko"), ("さゆり", "サユリ", "Sayuri"), ("知実", "サトミ", "Satomi"), ("千代", "チヨ", "Chiyo"), ("直子", "ナオコ", "Naoko"), ("七夏", "ナナミ", "Nanami"), ("花子", "ハナコ", "Hanako"), ("春香", "ハルカ", "Haruka"), ("真綾", "マアヤ", "Maaya"), ("舞", "マイ", "Mai"), ("美加子", "ミカコ", "Mikako"), ("幹", "ミキ", "Miki"), ("桃子", "モモコ", "Momoko"), ("結衣", "ユイ", "Yui"), ("裕美子", "ユミコ", "Yumiko"), ("陽子", "ヨウコ", "Yoko"), ("里佳", "リカ", "Rika"), ) # for backwards compatibility first_names_female = tuple(map(itemgetter(0), first_name_female_pairs)) first_kana_names_female = tuple(map(itemgetter(1), first_name_female_pairs)) first_romanized_names_female = tuple(map(itemgetter(2), first_name_female_pairs)) first_name_male_pairs = ( ("晃", "アキラ", "Akira"), ("篤司", "アツシ", "Atsushi"), ("治", "オサム", "Osamu"), ("和也", "カズヤ", "Kazuya"), ("京助", "キョウスケ", "Kyosuke"), ("健一", "ケンイチ", "Kenichi"), ("修平", "シュウヘイ", "Shohei"), ("翔太", "ショウタ", "Shota"), ("淳", "ジュン", "Jun"), ("聡太郎", "ソウタロウ", "Sotaro"), ("太一", "タイチ", "Taichi"), ("太郎", "タロウ", "Taro"), ("拓真", "タクマ", "Takuma"), ("翼", "ツバサ", "Tsubasa"), ("智也", "トモヤ", "Tomoya"), ("直樹", "ナオキ", "Naoki"), ("直人", "ナオト", "Naoto"), ("英樹", "ヒデキ", "Hideki"), ("浩", "ヒロシ", "Hiroshi"), ("学", "マナブ", "Manabu"), ("充", "ミツル", "Mituru"), ("稔", "ミノル", "Minoru"), ("裕樹", "ユウキ", "Yuki"), ("裕太", "ユウタ", "Yuta"), ("康弘", "ヤスヒロ", "Yasuhiro"), ("陽一", "ヨウイチ", "Yoichi"), ("洋介", "ヨウスケ", "Yosuke"), ("亮介", "リョウスケ", "Ryosuke"), ("涼平", "リョウヘイ", "Ryohei"), ("零", "レイ", "Rei"), ) # for backwards compatibility first_names_male = tuple(map(itemgetter(0), first_name_male_pairs)) first_kana_names_male = tuple(map(itemgetter(1), first_name_male_pairs)) first_romanized_names_male = tuple(map(itemgetter(2), first_name_male_pairs)) # for backwards compatibility first_names = first_names_male + first_names_female first_kana_names = first_kana_names_male + first_kana_names_female first_romanized_names = first_romanized_names_male + first_romanized_names_female first_name_pairs = first_name_male_pairs + first_name_female_pairs last_name_pairs = OrderedDict( ( (("佐藤", "サトウ", "Sato"), 366803.0), (("鈴木", "スズキ", "Suzuki"), 321135), (("高橋", "タカハシ", "Takahashi"), 266782), (("田中", "タナカ", "Tanaka"), 245821), (("伊藤", "イトウ", "Ito"), 203357), (("渡辺", "ワタナベ", "Watanabe"), 200504), (("山本", "ヤマモト", "Yamamoto"), 200134), (("中村", "ナカムラ", "Nakamura"), 195219), (("小林", "コバヤシ", "Kobayashi"), 191819), (("加藤", "カトウ", "Kato"), 160283), (("吉田", "ヨシダ", "Yoshida"), 154461), (("山田", "ヤマダ", "Yamada"), 151675), (("佐々木", "ササキ", "Sasaki"), 135927), (("山口", "ヤマグチ", "Yamaguchi"), 119501), (("松本", "マツモト", "Matsumoto"), 116490), (("井上", "イノウエ", "Inoue"), 111287), (("木村", "キムラ", "Kimura"), 107446), (("林", "ハヤシ", "Hayashi"), 101826), (("斎藤", "サイトウ", "Saito"), 101774), (("清水", "シミズ", "Shimizu"), 97826), (("山崎", "ヤマザキ", "Yamazaki"), 90781), (("阿部", "アベ", "Abe"), 86833), (("森", "モリ", "Mori"), 86507), (("池田", "イケダ", "Ikeda"), 84860), (("橋本", "ハシモト", "Hashimoto"), 82836), (("山下", "ヤマシタ", "Yamashita"), 80588), (("石川", "イシカワ", "Ishikawa"), 77471), (("中島", "ナカジマ", "Nakajima"), 74106), (("前田", "マエダ", "Maeda"), 72930), (("藤田", "フジタ", "Fujita"), 72375), (("後藤", "ゴトウ", "Goto"), 71629), (("小川", "オガワ", "Ogawa"), 71179), (("岡田", "オカダ", "Okada"), 70347), (("長谷川", "ハセガワ", "Hasegawa"), 69201), (("村上", "ムラカミ", "Murakami"), 68606), (("近藤", "コンドウ", "Kondo"), 68297), (("石井", "イシイ", "Ishii"), 67079), (("遠藤", "エンドウ", "Endo"), 62620), (("斉藤", "サイトウ", "Saito"), 62540), (("坂本", "サカモト", "Sakamoto"), 62308), (("青木", "アオキ", "Aoki"), 59516), (("藤井", "フジイ", "Fujii"), 59204), (("西村", "ニシムラ", "Nishimura"), 58821), (("福田", "フクダ", "Fukuda"), 58714), (("太田", "オオタ", "Ota"), 58439), (("三浦", "ミウラ", "Miura"), 58006), (("藤原", "フジワラ", "Fujiwara"), 57742), (("松田", "マツダ", "Matsuda"), 55883), (("岡本", "オカモト", "Okamoto"), 55539), (("中川", "ナカガワ", "Nakagawa"), 55221), ) )
https://github.com/joke2k/faker/blob/v24.4.0/faker/providers/person/ja_JP/__init__.py#L11-L138
プロバイダーによって、用意されているLocaleには差がありそうなので注意ですね。
たとえばperson
は多いですが
https://github.com/joke2k/faker/tree/v24.4.0/faker/providers/person
barcode
は5つだけです。
https://github.com/joke2k/faker/tree/v24.4.0/faker/providers/barcode
おわりに
フェイクデータを生成するFakerを試してみました。
こういうものがあるのを知らなかったです。複数の言語での実装もあるようですし、便利そうですね。少なくともPython版については
カスタマイズもできそうですし。
覚えておくとよさそうです。