CLOVER🍀

That was when it all began.

Fakerでフェむクデヌタを䜜成する

これは、なにをしたくお曞いたもの

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
# 山田 桃子

Localization

コマンドラむンツヌルずしおも䜿えたす。

Command line usage

玹介はこれくらいにしお、䜿っおいっおみたしょう。

環境

今回の環境はこちら。

$ 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版に぀いおは
カスタマむズもできそうですし。

芚えおおくずよさそうです。