■
pythonについてメモ
クラスの実体と、クラスの実体からインスタンス化されたオブジェクトは別モノ。
至極当然のことだけど。
a = 'hello world'
などとやると、内部では a という変数に hello world という値をもった「str型オブジェクトへの参照」が格納されることになる。
>>> 'hello world' 'hello world' >>> type('hello world') <type 'str'> >>> 'hello world'[:5] 'hello' >>> 'hello world'.split(' ') ['hello', 'world']
なので、上のように、文字列に対していきなりドットで繋いでstr型が持っている機能が使えるということが理解できる。
このstrというのは
http://docs.python.org/library/functions.html
ここで紹介されている、ビルトイン関数というもので、ここらへんをひと通り理解したら色々捗りそう。
>>> object <type 'object'> >>> str <type 'str'> >>> str.__bases__ (<type 'basestring'>,) >>> basestring <type 'basestring'> >>> basestring.__bases__ (<type 'object'>,)
strを遡っていくと、まぁ、結局はobject。
ちなみにobjectの__bases__はtupleだった。
>>> class A(object): ... test_val = 'hello world' ... pass ... >>> A <class '__main__.A'> # Aが定義された >>> A.test_val 'hello world' # Aの中身の値も当然、保持されている >>> type(A) <type 'type'> >>> A.__bases__ (<type 'object'>,) # 新スタイルクラスを使ってるよ >>> instance = A() >>> instance <__main__.A object at 0x2b171ccf4b90> # 実体が生成された >>> instance.test_val 'hello world' >>> type(instance) <class '__main__.A'> >>> A.test_val 'hello world' >>> instance.test_val 'hello world' >>> A.test_val = 'goodbye world' # Aのtest_valを直接アクセスして書き換えてみる >>> A.test_val 'goodbye world' >>> instance.test_val 'goodbye world' # インスタンスのtest_valも変わった! >>> instance2 = A() >>> instance2.test_val 'goodbye world' >>> instance.test_val = 'foobar' # instance側のtest_valを書き換えてみる >>> A.test_val 'goodbye world' # 変化無し >>> instance.test_val 'foobar' # ちゃんと書き換わってる >>> instance2.test_val 'goodbye world' # 変化無し
python面白い!
jubaconvの使い方
jubatusのconfigではフィルタールールなどを渡せますが、その辺りを使ってみようとすると、正規表現の動作結果を確認したくなりますよね。
jubaconv というコマンドがあるみたいなのですが、どうにも説明がさっぱりとしていて具体的な使い方がわからなかったのですが、勘で弄ったらなんとかなっちゃったので記載しておきます。
まず http://jubat.us/fv_convert.html ここの初めの方にある、最低限のコンフィグを元にしましょう。
{ "string_filter_types": {}, "string_filter_rules": [], "num_filter_types": {}, "num_filter_rules": [], "string_types": {}, "string_rules": [ { "key": "*", "type": "space", "sample_weight": "bin", "global_weight": "bin" } ], "num_types": {}, "num_rules": [ { "key": "*", "type": "num" } ] }
これをまるっとコピーして ./a.conf などの適当な名前を付けたファイルに記述して、保存。
[hiro@hiro test]$ jubaconv -i json -o fv -c ./a.conf
とすると、入力を待たれるはずなので、
{"message": "hello world"}
とか入力してエンターすると…
[hiro@hiro test]$ jubaconv -i json -o fv -c ./a.conf {"message": "hello world"} /message$world@space#bin/bin: 1 /message$hello@space#bin/bin: 1
うん。
動いたような気がする。
あとはconfigのとこをぐにぐにしてはこれを繰り返して、
どんな風にパースされたり、置換されたりするのかをチェックするべし。
jubatus実験中の出来事
jubatusを使ってとある物を作りたく目下試行錯誤中なのですが、その過程で起きているjubatus周りの問題(環境依存?)を記録しておきます。
client*2 -> jubakeeper*1 -> jubaclassifier*6 (3*2)
という、インスタンス2つ(testとuidというname)3個構成で一台のCentOS仮想マシン環境上に全て起動。
clientはphpで、mysqlのデータをばっこんばっこんtrainしていたのだけれど、どうも、ほっとくとjubakeeperが落ちた後、jubaclassifierも2つ程落ちた。
ずっと気にしないようにしていたが、classifierを起動し、zookeeperが認識すると、定期的かつ頻繁に、
E1109 10:38:18.679916 2682 map_fold_rpc.hpp:73] cannot recv rpc result: type error***.***.***.***:9180 E1109 10:38:18.680157 2682 map_fold_rpc.hpp:73] cannot recv rpc result: type error***.***.***.***:9181 E1109 10:38:18.680387 2682 map_fold_rpc.hpp:73] cannot recv rpc result: type error***.***.***.***:9182 E1109 10:38:18.680423 2682 classifier_serv.cpp:328] mix: failed to get diff from 3 servers.
こういうメッセージが出力される。なお、IPアドレスは念の為伏せさせて頂きます。(***.***.***.***)
で、落ちた時のログは下記。
2011-11-05 02:14:07,406:21942(0x40d87940):ZOO_WARN@zookeeper_interest@1461: Exceeded deadline by 11ms E1105 02:14:07.962105 21922 map_fold_rpc.hpp:73] cannot recv rpc result: type error***.***.***.***:9181 E1105 02:14:08.792454 21922 map_fold_rpc.hpp:73] cannot recv rpc result: type error***.***.***.***:9182 E1105 02:14:08.792552 21922 classifier_serv.cpp:328] mix: failed to get diff from 3 servers. E1105 02:14:11.806685 21928 map_fold_rpc.hpp:73] cannot recv rpc result: type error***.***.***.***:9180 E1105 02:14:12.669272 21928 map_fold_rpc.hpp:73] cannot recv rpc result: type error***.***.***.***:9181 2011-11-05 02:14:12,775:21942(0x40d87940):ZOO_WARN@zookeeper_interest@1461: Exceeded deadline by 17ms E1105 02:14:13.534540 21928 map_fold_rpc.hpp:73] cannot recv rpc result: type error***.***.***.***:9182 E1105 02:14:13.534633 21928 classifier_serv.cpp:328] mix: failed to get diff from 3 servers. 2011-11-05 02:14:15,454:21942(0x40d87940):ZOO_WARN@zookeeper_interest@1461: Exceeded deadline by 11ms E1105 02:14:20.201802 21934 map_fold_rpc.hpp:73] cannot recv rpc result: type error***.***.***.***:9180 E1105 02:14:21.054254 21934 map_fold_rpc.hpp:73] cannot recv rpc result: type error***.***.***.***:9181 E1105 02:14:21.955986 21934 map_fold_rpc.hpp:73] cannot recv rpc result: type error***.***.***.***:9182 E1105 02:14:21.956148 21934 classifier_serv.cpp:328] mix: failed to get diff from 3 servers. E1105 02:14:23.354889 21934 zk.cpp:101] /jubatus/actors/test/master_lock/lock_0000019376: removal failed - operation timeout 2011-11-05 02:14:23,481:21942(0x40d87940):ZOO_ERROR@handle_socket_error_msg@1528: Socket [127.0.0.1:2181] zk retcode=-7, errno=110(Connection timed out): connection timed out (exceeded timeout by 7ms) I1105 02:14:23.482103 21944 zk.cpp:211] zk connection expiration : type(-1) state(1) 2011-11-05 02:14:24,822:21942(0x40d87940):ZOO_WARN@zookeeper_interest@1461: Exceeded deadline by 1347ms 2011-11-05 02:14:24,822:21942(0x40d87940):ZOO_INFO@check_events@1585: initiated connection to server [127.0.0.1:2181] E1105 02:14:26.592995 21922 zk.cpp:91] /jubatus/actors/test/master_lock/lock_ failed in creation - operation timeout 2011-11-05 02:14:26,811:21942(0x40d87940):ZOO_INFO@check_events@1632: session establishment complete on server [127.0.0.1:2181], sessionId=0x1336c4924310023, negotiated timeout=4000 E1105 02:14:28.499533 21928 map_fold_rpc.hpp:73] cannot recv rpc result: type error***.***.***.***:9181 E1105 02:14:28.513236 21928 map_fold_rpc.hpp:73] cannot connect: Connection refused***.***.***.***:9182 E1105 02:14:28.513319 21928 classifier_serv.cpp:328] mix: failed to get diff from 2 servers. E1105 02:14:36.474046 21934 zk.cpp:91] /jubatus/actors/test/master_lock/lock_ failed in creation - invalid zhandle state E1105 02:14:36.474241 21934 zk.cpp:131] invalid zhandle state (/jubatus/actors/test/master_lock) E1105 02:14:45.517791 21928 map_fold_rpc.hpp:73] cannot recv rpc result: type error***.***.***.***:9181 E1105 02:14:45.517930 21928 classifier_serv.cpp:328] mix: failed to get diff from 1 servers. E1105 02:15:02.555667 21928 map_fold_rpc.hpp:73] cannot recv rpc result: type error***.***.***.***:9181 E1105 02:15:02.555769 21928 classifier_serv.cpp:328] mix: failed to get diff from 1 servers. E1105 02:15:19.535115 21928 map_fold_rpc.hpp:73] cannot recv rpc result: type error***.***.***.***:9181 E1105 02:15:19.535222 21928 classifier_serv.cpp:328] mix: failed to get diff from 1 servers.
以降、延々とラスト二行が繰り返し出力されていた。
ちなみにこの後、jubakeeperを起動させて、jubaclassifierも落ちた2個を再起動させたら、しばらくロックしてるよーってメッセージが出た後に、jubaclassifier全部お亡くなりになった…。
2011-11-09 10:18:18,569:2568(0x41f83940):ZOO_WARN@zookeeper_interest@1461: Exceeded deadline by 14ms 2011-11-09 10:18:27,983:2568(0x41f83940):ZOO_ERROR@handle_socket_error_msg@1528: Socket [127.0.0.1:2181] zk retcode=-7, errno=110(Connection timed out): connection timed out (exceeded timeout by 0ms) E1109 10:18:28.247558 2563 zk.cpp:91] /jubatus/actors/uid/master_lock/lock_ failed in creation - operation timeout E1109 10:18:28.312479 32062 zk.cpp:91] /jubatus/actors/test/master_lock/lock_ failed in creation - operation timeout E1109 10:18:28.313173 32187 zk.cpp:91] /jubatus/actors/uid/master_lock/lock_ failed in creation - operation timeout E1109 10:18:28.307246 32069 zk.cpp:91] /jubatus/actors/test/master_lock/lock_ failed in creation - operation timeout E1109 10:18:28.313670 32055 zk.cpp:91] /jubatus/actors/test/master_lock/lock_ failed in creation - operation timeout I1109 10:18:28.410428 2570 zk.cpp:211] zk connection expiration : type(-1) state(1) E1109 10:18:28.413918 2563 zk.cpp:101] : removal failed - bad arguments E1109 10:18:28.414378 32062 zk.cpp:101] : removal failed - bad arguments E1109 10:18:28.414834 32187 zk.cpp:101] : removal failed - bad arguments E1109 10:18:28.415371 32069 zk.cpp:101] : removal failed - bad arguments E1109 10:18:28.415837 32055 zk.cpp:101] : removal failed - bad arguments E1109 10:18:28.401837 2634 zk.cpp:101] /jubatus/actors/uid/master_lock/lock_0000440898: removal failed - operation timeout 2011-11-09 10:18:29,311:2568(0x41f83940):ZOO_WARN@zookeeper_interest@1461: Exceeded deadline by 1329ms 2011-11-09 10:18:29,311:2568(0x41f83940):ZOO_INFO@check_events@1585: initiated connection to server [127.0.0.1:2181] 2011-11-09 10:18:29,312:2568(0x41f83940):ZOO_INFO@check_events@1632: session establishment complete on server [127.0.0.1:2181], sessionId=0x13382aa7fc4002e, negotiated timeout=4000 E1109 10:19:37.884022 32069 zk.cpp:91] /jubatus/actors/test/master_lock/lock_ failed in creation - operation timeout E1109 10:19:37.884137 2563 zk.cpp:91] /jubatus/actors/uid/master_lock/lock_ failed in creation - operation timeout E1109 10:19:37.884224 32062 zk.cpp:91] /jubatus/actors/test/master_lock/lock_ failed in creation - operation timeout E1109 10:19:37.884371 32187 zk.cpp:91] /jubatus/actors/uid/master_lock/lock_ failed in creation - operation timeout E1109 10:19:37.884474 32055 zk.cpp:91] /jubatus/actors/test/master_lock/lock_ failed in creation - operation timeout E1109 10:19:38.795603 2634 zk.cpp:91] /jubatus/actors/uid/master_lock/lock_ failed in creation - operation timeout E1109 10:19:40.592905 32062 zk.cpp:131] operation timeout (/jubatus/actors/test/master_lock) E1109 10:19:40.593822 32069 zk.cpp:131] operation timeout (/jubatus/actors/test/master_lock) E1109 10:19:40.594594 2563 zk.cpp:131] operation timeout (/jubatus/actors/uid/master_lock) E1109 10:19:40.595274 32055 zk.cpp:131] operation timeout (/jubatus/actors/test/master_lock) E1109 10:19:40.595989 32187 zk.cpp:131] operation timeout (/jubatus/actors/uid/master_lock) E1109 10:19:41.491140 2634 zk.cpp:131] operation timeout (/jubatus/actors/uid/master_lock)
messageにもログが出ていた。
Nov 9 10:19:40 hiro kernel: jubaclassifier[32062]: segfault at 0000000000000000 rip 0000003e7fa9cf7b rsp 00000000428b8ea0 error 4 Nov 9 10:19:40 hiro kernel: jubaclassifier[32069]: segfault at 0000000000000000 rip 0000003e7fa9cf7b rsp 000000004266cea0 error 4 Nov 9 10:19:40 hiro kernel: jubaclassifier[2563]: segfault at 0000000000000000 rip 0000003e7fa9cf7b rsp 000000004359aea0 error 4 Nov 9 10:19:40 hiro kernel: jubaclassifier[32055]: segfault at 0000000000000000 rip 0000003e7fa9cf7b rsp 000000004340bea0 error 4 Nov 9 10:19:40 hiro kernel: jubaclassifier[32187]: segfault at 0000000000000000 rip 0000003e7fa9cf7b rsp 0000000042464ea0 error 4 Nov 9 10:19:41 hiro kernel: jubaclassifier[2634]: segfault at 0000000000000000 rip 0000003e7fa9cf7b rsp 00007fff185b4490 error 4
とりあえず、今日はこの原因を調査しながら全文検索環境を構築しよう…。
あ、あと、これは別問題かもしれないけれど、ZooKeeperを起動してから、jubakeeperを起動する流れで、jubakeeperが起動したりしなかったりする。
感覚的には、ZooKeeperとjubakeeperのコネクション確立にコケてjubakeeperが落ちてるような振る舞いを見せます。
zookeeper起動コマンドの後、sleep 1程度だと
./jubastart.sh: line 12: 2810 アボートしましたnohup jubakeeper --zookeeper=${ZOOKEEPER_HOST} --rpc-port=9198
となり、うまく起動してくれないが、sleepを15くらいにすると起動してくれる。
追記
hadoop-zookeeper.noarch 3.3.3+12.16-1 installed
zookeeper-c-client.x86_64 3.3.3-1 installed
JubatusをPHPから使うためのjubatus-php-clientを公開しました
先日、ビッグデータリアルタイム分析基盤 Jubatus(http://jubat.us/)というものが、株式会社プリファードインフラストラクチャーさんと、日本電信電話株式会社さんとの共同研究開発で生まれOSSとしてリリースされました。
これにより、大量の自然言語データを高精度で高速に学習・分類するシステムが誰にでも手軽に構築できるようになりました。
正に、現在開発中のものに利用したい!ということで、とりあえず、公式のチュートリアルをPythonのまま行ってみて挙動を確認した後、すぐにでも使いたかったので公式のjubatus-python-clientをベースにまるっとPHPクライアントライブラリを作成してみました。
現状、なかなか何とかの一つ覚え的な、ひどい写経なのですが、一応公開します。
https://github.com/oxalis-gps/jubatus-php-client
必須: php-msgpack (http://code.google.com/p/php-msgpack/)
現状あまり美味しくないポイントは多々あるのですが、大きな物からいくつか挙げておきます。
- MessagePack-RPCの型とPHPの型の問題
- 全体的なクラス設計
- Exceptionクラス一部未実装のまま(例外パターンの動作が一部Fatalで落ちます)
1.に関して
Jubatusは、クライアントとサーバーの通信にMessagePack-RPCというプロトコルが提供されています。
しかし、MessagePackというプロトコルでサポートされている型に、ArrayとMapsというものがあります。
サーバー側ではpythonの{}をMaps、[]と()をArrayとして区別していますが、PHPには、連想配列と配列の区別が無く、空のMapsを表現できませんでした。
フォーマットが適切でないデータ型でサーバーに送りつけると、サーバーがエラーを返してきてしまいます。
そのため、その部分の対応をphp-msgpackの作者様に伝えた所、パッチを送ってくださいました。
python上のデータ型で言うところの空の{}を、php上でnew stdClass()として与えてmsgpack_packすることで、適切にその部分を空のmap型としてシリアライズしてくれるようになりました。(php-msgpack 0.5.3から)
とりあえず、これで第一の関門は回避できました。
2.に関して
あまり頭を使わずに、ただ翻訳&写経のようにjubatus-python-clientを見ながら、PHP化しただけなのですが、
将来的にはZend Framework上での親和性を考慮したい為、若干アレンジが入っています。
そのため、中途半端な部分が多々あり、写経している間にどういう事をしたいのかが理解できたので、根本的にクラス設計
見直したほうがもうちょっとPHPらしくなるかなと思います。こちらは地道にやっていきます。
3.に関して
- Jubatus_BadRPC
- Jubatus_MethodNotFound
- Jubatus_TypeMismatch
上記三つの例外クラスを、MPCClientFuncクラス内でthrowしていますが、現状そんな名前のExceptionクラスは存在しません(えー
こちらはとりあえず、早急に実装致します。
データ分類とか学習器について、ぬるプログラマーによるぬるプログラマ向けまとめ
SVMという、使い方によってはすごいモノがあります(唐突)
誤解を恐れず、パッと簡単に説明すると
ラベル付けをしたデータを教師データとして、学習器に与えると、学習モデルを吐いてくれて、評価器にデータを与えると、学習モデルを使って
inputはaなのかbなのか?(二値分類)
という回答を返してくれる便利ツールです(SVM自体はアルゴリズムですが、その実装は一杯あるのでそれに頼れば、ということ)
ベイズ分類器とか使ったスパムフィルタとかを想像してもらえると、動作結果のイメージは間違ってないと思います。
で、SVMの仕組みを細かく説明するとそれだけで結構ボリューミーで、
マク○ナルドのクダブル○ーズクォーター▼ウンダー並に胃がもたれてしまうので、がっつり割愛させていただくとして…
とにかく、SVMの仕組みが仕組みなだけに、2次元上では分類が非常に難しいようなデータの分類にとても向いているモノです。
世の中には複雑な因果関係を持った問題ってたくさんありますよね。
…ありますよね、いっぱい。
…そういうのをなんかごねごねして、
「こんな感じが一番「っぽい」だろ! そぉぃ! 」(スパーン
ってな感じに分類してくれるものがSVMだとしたら、
それはすなわち、使いこなせたら割と幅広い分野で使えて、大きな力になる分類器ということになりませんか?
簡単に試してみたい場合は、まず以下のツールをlinux環境にインストールして、チュートリアルをやってみると、ピンとくるんじゃないかと思います。
http://code.google.com/p/broomie/wiki/broomie_turorial_ja
ちなみに、SVMは基本二値分類しかできません。
one vs oneか、one vs restという手法を用いれば、多値に分類しなければならない問題にも適用できるようですが、めんどくさそうなのでやだなー…。
でも、ご安心ください。
このbroomieならone vs restが組み込まれていますので、
安心して、このデータはaで、こっちはbで、そっちはcで…
と、複数のラベルを貼って気軽に実験できます。
適当にlinuxに形態素解析インストールして、
適当な文書データを分解させて、特徴が多く出るよう、ノイズが少なくなるよう、調整を加えて、出現回数や頻度などで、単語に重みを振って、一行にまとめて、頭にラベルを貼って…
ってな感じに、教師データを作ったら、brmtrainってコマンドに食わせて、modelファイルを出力させて、分類したいものを教師データを作った時と同じようにデータ加工して、それをbrmclassifyで評価。ってな感じです。(大雑把すぎる
ひとくちにSVMといっても、派生?が色々あるらしく、
最近、僕が使ってみたがっているのは、
Confidence Weighted(以下CW)ってアルゴリズムです。
学習時の「ごねごね」の仕方がだいぶ違うようです。(えー
ちなみにSVMにはバッチ学習ってのとオンライン学習ってタイプに分けられて、違いをぬるプログラマー的イメージに表すと、
ファイルをひらいて全てのデータをメモリに載せて処理するパターン(バッチ学習)
ファイルをひらいて一行づつ読み込んで処理して結果を書いてメモリから破棄するパターン(オンライン学習)
って感じです(わかりづれ
「オンライン?Web向きのがあるんだー!」とか思ってたら全然違ったので。
いやまぁ、確かにオンライン学習の方がウェブサービスに向いてる場合も多いですが、バッチ学習で十分なケース(一ヶ月に一回、まる一日かかっても、学習しなおせれば間に合うとか)もあるので オンライン学習=ウェブのオンライン で結び付けないでください。
CWはオンライン学習アルゴリズムの一つなのですが、
欠点としてラベル付けに間違ったデータ(ノイズ)に非常に脆弱で、教師データの精度が悪いと汎化能力が極端に落ちるみたいです。
そこで、CWにラベルノイズ対策を施したアルゴリズムとして、
AROW(Adaptive Regularization of Weights)
NAROW(Narrow Adaptive Regularization Of Weights)
というものがでてきたらしいのだけれど NAROW に関する文献が少なすぎる…。
http://webee.technion.ac.il/people/koby/publications/adaptive_nips10.pdf
ちなみにAROWの実装なら既存。
http://cl.naist.jp/~tetsuo-s/software/arowpp/
多値分類には未対応だけど、Planned Featuresの記述によると、対応予定らしい。wktk。
ちなみに、CWとAROWの違いとか関係性については以下のスライドが明快。
http://www.r.dl.itc.u-tokyo.ac.jp/~oiwa/upload/AROW.pdf
あ、あと、最初に言っておくべきでしたが、私は専門家でもなんでもなく、ただのぬるプログラマーです。
SVMを知ってから色々調べて、自分なりに解釈して、使ってみて手応えがあったので、もっとたくさんの人に使ってみてもらいたかったのです。(そして教えて欲しい)
要するに、この記事は、独学による曖昧な認識に基づいていますので、間違いやら勘違いやらひどい!ってのがあったら、是非ツッコんでください。
mieple.comに登録してみた
mieple.comというのがGoogle+ストリームに流れてきていて、
ちょっとトップの人物イメージ画像にビビッと来て、登録してみた。
まだサービスは使えないけど、とりあえず現時点でわかっている事をまとめ。
- まだサービス自体はリリースされていない(応募&招待URL発行だけしかできない)
- まずはクローズドベータでリリースされる
- クローズドベータに参加するためにはFacebookアカウントで認証して、発行されるURLから 3人 に登録してもらう必要がある
- 招待された「子」は「子」として3人集めなきゃならない
- より多くの「子」を獲得しているほど、ベータ公開時に招待メールが優先的に届く
mieple.comは人の紹介をオンラインで活性化させるサービス、とか、
新しい人との出会いを作るサービス、といった情報しか見当たらない。
一見、新手の出会い系か?って思いますが、
こんなロゴもあったので、もしかするとプロジェクトメンバーや、何かのグループに、求めている人材をマッチングしてくれるようなサービスなのかもしれません。
Google+ 入門
まず言いたいことは、ぐーたすは、とてもよきものです。
ぐーたすの中で外の人へのアピールしてても仕方ないと思ったので、
記事にしてみました。
全てのSNS系サービスに言える事だけど、
始めたばかりの頃は、みずからアクションを起こしまくる事
それが楽しむ為に必要な最初のスタート地点。
ぐーたすの良い所は、
その一つ一つのアクションに対する反応率が非常に高い事。
アクションに対してリアクションしたら、
リアクションに対してのリアクションが発生しやすい。
要するに、モチベーションが上がりやすくなって、中毒性が高まります。
というわけで、
とりあえず登録してみたけれど、
使い方が分からない&友達が居ないっていう、
俺のような人は、まず知らない人でも、ストリームをいっぱい開いてみて、
ビクビクせず、気軽かつ、てきとーに、
- 「+1」を押す
- 「コメント」を書く
- 「共有」
というアクションをとりまくってみよう!
ついでにその人のストリームが、全体的に興味深ければフォローしておくといい。
その時点で、
「自分の発言は、この人には合わないんじゃないかな…」
とかは一切気兼ねしなくていい。
なぜなら「サークル」というもので簡単に、
この発言はこの界隈の人たちにだけしたい。
という指定が出来るから。