<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Toru Furukawa</title>
    <description>The latest articles on DEV Community by Toru Furukawa (@torufurukawa).</description>
    <link>https://dev.to/torufurukawa</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F44078%2F7e877c56-a56c-491a-8d53-65f6fbb18904.jpeg</url>
      <title>DEV Community: Toru Furukawa</title>
      <link>https://dev.to/torufurukawa</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/torufurukawa"/>
    <language>en</language>
    <item>
      <title>Publications</title>
      <dc:creator>Toru Furukawa</dc:creator>
      <pubDate>Wed, 12 Jan 2022 00:50:01 +0000</pubDate>
      <link>https://dev.to/torufurukawa/publications-237l</link>
      <guid>https://dev.to/torufurukawa/publications-237l</guid>
      <description>&lt;ul&gt;
&lt;li&gt;Toru Furukawa (2021). &lt;em&gt;Stripe Connect Data Models and Fund Flows.&lt;/em&gt; &lt;a href="https://zenn.dev/toruf/books/stripe-connect-2021"&gt;https://zenn.dev/toruf/books/stripe-connect-2021&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Toru Furukawa (2020). &lt;em&gt;Stripe データのコンセプト.&lt;/em&gt; &lt;a href="https://dev.to/torufurukawa/stripe-17n9"&gt;https://dev.to/torufurukawa/stripe-17n9&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Toru Furukawa (2018). &lt;em&gt;Twitter 広告と API を組み合わせたインタラクティブなキャンペーン.&lt;/em&gt; &lt;a href="https://www.slideshare.net/torufurukawa/twitter-api-121399949"&gt;https://www.slideshare.net/torufurukawa/twitter-api-121399949&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Toru Furukawa (2013). &lt;em&gt;Tast failed, then...&lt;/em&gt;, PyCon APAC 2013, &lt;a href="https://pyvideo.org/pycon-apac-2013-in-japan/test-failed-then-by-torufurukawa.html"&gt;https://pyvideo.org/pycon-apac-2013-in-japan/test-failed-then-by-torufurukawa.html&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Stripe データのコンセプト</title>
      <dc:creator>Toru Furukawa</dc:creator>
      <pubDate>Tue, 08 Dec 2020 23:20:58 +0000</pubDate>
      <link>https://dev.to/torufurukawa/stripe-17n9</link>
      <guid>https://dev.to/torufurukawa/stripe-17n9</guid>
      <description>&lt;p&gt;Stripe という決済 SaaS の存在を、最近知りました。いろんな API を組み合わせて、いろんな決済処理を実装できます。個々の API エンドポイントのパラメータや挙動はドキュメントがあり、テストモードで簡単に試せます。&lt;/p&gt;

&lt;p&gt;一方、外側からみて、Stripe におけるデータオブジェクトのコンセプトが分かると、個々の API をやみくもに調べるよりは、設計の役に立つような気がします。決済というのが、そもそも比較的抽象度の高い概念です。サービス上のユーザー体験が API と 1対1 で対応しないことがあります。そんなときは、少しレイヤーを上げた視点 &lt;strong&gt;も&lt;/strong&gt; あるといいんじゃないかなー、と思います。&lt;/p&gt;

&lt;p&gt;そこで &lt;a href="https://adventar.org/calendars/5626"&gt;JP_Stripes Advent Calendar 2020&lt;/a&gt; にぶらさがって、自分なりの解釈をまとめました。&lt;/p&gt;

&lt;p&gt;以下、クレジットカードでの支払いを想定します。&lt;/p&gt;

&lt;h1&gt;
  
  
  Payment Intent
&lt;/h1&gt;

&lt;p&gt;Payment Intent は 1回の「支払い」の設定、状態、処理を管理するオブジェクトです。設定というのは「1000円」みたいな情報です。&lt;/p&gt;

&lt;p&gt;状態というは、カード番号が必要だとか、認証が必要だとか、処理中だとか、キャンセルされたとかです。&lt;/p&gt;

&lt;p&gt;状態遷移をするときに、裏側では必要に応じて、クレジットカードのシステムと通信が走ります。&lt;/p&gt;

&lt;p&gt;とりあえず、どんなのか試したいときは、&lt;a href="https://stripe.com/docs/payments/integration-builder"&gt;Integration Builder&lt;/a&gt;&lt;br&gt;
が、手っ取り早いです。&lt;a href="https://stripe.com/docs/payments/payment-intents"&gt;もう少し細かい説明&lt;/a&gt; もあります。&lt;/p&gt;

&lt;p&gt;大雑把な状態遷移はこんな感じ。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pHJBP8OT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/a53etbox9urbi5fkzj8w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pHJBP8OT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/a53etbox9urbi5fkzj8w.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;requires_payment_method: Payment Method （クレジットカード番号など）が必要。&lt;/li&gt;
&lt;li&gt;requires_confirmation: アプリケーションによる確認（これでOKっす、って指定する API コール）が必要。&lt;/li&gt;
&lt;li&gt;requires_action: 何かアクションが必要。&lt;a href="https://ja.wikipedia.org/wiki/3D%E3%82%BB%E3%82%AD%E3%83%A5%E3%82%A2"&gt;3Dセキュア&lt;/a&gt; のパスワード入力とか。&lt;/li&gt;
&lt;li&gt;processing: 処理中。大抵、数秒で、次の状態に遷移する。&lt;/li&gt;
&lt;li&gt;succeeded: 支払い完了。クレジットカードの引き落とし日を楽しみにしてください&lt;/li&gt;
&lt;li&gt;canceled: アプリケーションがキャンセルした。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;決済に失敗したら、requires_payment_method に遷移します。&lt;/p&gt;

&lt;p&gt;破線枠の状態は、スキップする場合がある状態を表します。正確に分岐を明示すると、ごちゃごちゃするので省略しました。&lt;/p&gt;

&lt;p&gt;Payment Intent は支払いの行動を追跡・処理するオブジェクトです。カード番号なんかを直接管理しません。&lt;/p&gt;

&lt;h1&gt;
  
  
  Payment Method
&lt;/h1&gt;

&lt;p&gt;Payment Method は支払い方法・手段を表すオブジェクトです。クレジットカードによる支払いの場合、クレジットカード番号、有効期限、CVC などを保持します。&lt;/p&gt;

&lt;p&gt;Payment Intent を作ってから、フロントエンドで Payment Method を作成して Payment Intent と関連づけることができます。&lt;br&gt;
&lt;br&gt;
反対に、先に Payment Method を作成して（＝クレジットカード番号を入力させて）から、Payment Intent を作成して関連づけてもよいです。クレジットカードのブランドによって、挙動を変えたいような場合に有効な順序です。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KfUDJ_Pt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/1k90hl6nkjxnn9p1ip5i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KfUDJ_Pt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/1k90hl6nkjxnn9p1ip5i.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Customer
&lt;/h1&gt;

&lt;p&gt;会員的な概念があって、繰り返し利用するクレジットカード番号を保存したい、というケースがあると思います。その場合は、Payment Method を Customer オブジェクトに attach します。&lt;/p&gt;

&lt;p&gt;Customer オブジェクトは、顧客、より正確には支払いをする主体を表します。B2C だったらおそらくは会員とかユーザーという概念に対応します。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--il4jyXRl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/im3k1oqpp41uqrup6hnb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--il4jyXRl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/im3k1oqpp41uqrup6hnb.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ひとつの Customer は、0個以上の Payment Method と関連づけられます。ひとつの Payment Method は、0〜1個の Customer と関連づけられます。&lt;/p&gt;

&lt;p&gt;Payment Method を一度 Customer と関連づけると、他の Customer と関連づけることはできません。&lt;/p&gt;

&lt;h1&gt;
  
  
  サブスクリプション・ビジネス
&lt;/h1&gt;

&lt;p&gt;Customer と Payment Method の関連づけができれば、毎月バッチを走らせると月額課金ができます。「毎月3,000円支払ってくれたら、うちで飼っている猫が、毎朝、朝食をとっている動画を見せてあげる」みたいなサービスを作れるわけです。やったね。&lt;/p&gt;

&lt;p&gt;さて Billing と呼ばれるサービス・API群を使うと、このへんの処理を自動化できます。月に一度決済をするだけならいいんですが、バッチを回すだけより、もうちょい複雑なコンセプトが絡みます。&lt;/p&gt;

&lt;p&gt;世の中には3つの嘘があります。嘘、ひどい嘘、定期的に決済するだけ、です。&lt;/p&gt;

&lt;p&gt;まずは、定期的に決済するだけに必要なデータオブジェクトを、順番に見ていきましょう。&lt;/p&gt;

&lt;h1&gt;
  
  
  Product と Price
&lt;/h1&gt;

&lt;p&gt;まず商品と料金体系を定義します。&lt;/p&gt;

&lt;p&gt;Product は商品やサービスを表す抽象的な概念です。たとえば「猫の朝食動画ストリーミング」というサービスを表します。&lt;/p&gt;

&lt;p&gt;Price は、Product と関連づいた価格体系を表します。ひとつの Product に対して、複数の Price を関連づけられます。&lt;/p&gt;

&lt;p&gt;複数の Price の用途は大きくふたつあります。複数通貨の場合です。月額3,000円と、月額30ドルを用意するとかですね。&lt;/p&gt;

&lt;p&gt;もうひとつは期間が違う場合です。月額3,000円と、年額30,000円を用意するような場合です。&lt;/p&gt;

&lt;p&gt;これで商品と価格体系の定義ができました。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UhAdJoKY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/m4rt2ybp154vehdhgpxm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UhAdJoKY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/m4rt2ybp154vehdhgpxm.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;「猫の&lt;strong&gt;夕&lt;/strong&gt;食動画ストリーミング」というサービスを追加する場合や、「朝夕バンドル」を追加する場合には、Product 側を変更するとすっきりするでしょう。&lt;/p&gt;

&lt;p&gt;3ヶ月ごと、半年ごとの価格体系を追加するときは、Price を操作するのがよいでしょう。&lt;br&gt;
&lt;br&gt;
ただ Price 側でいろいろ定義したり、後述する Coupon を使ったりして、いろんなバリエーションを作れます。このあたりこそが、設計者の腕の見せ所だと思います。&lt;/p&gt;

&lt;h1&gt;
  
  
  Subscription
&lt;/h1&gt;

&lt;p&gt;Subscription オブジェクトは、定期課金の契約の定義と状態の保持、それから関連する自動化処理のトリガーの役割があります。&lt;/p&gt;

&lt;p&gt;「ある Customer が、ある Price にサブスクライブする」という契約を定義するのがSubscription です。Price で定義したとおり、Customer に関連づいた Payment Method から資金を回収したいよ、という契約です。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XHvP4QiR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/jxkkj9kq6tmpus532oz4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XHvP4QiR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/jxkkj9kq6tmpus532oz4.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;注意すべきは Customer は支払いの主体だ、ということです。たとえば「3ユーザーまで視聴可」みたいな契約のとき、Customer はおそらく「ユーザー」には関連づかず、支払いをする代表ユーザーのみを表すことになるでしょう。&lt;/p&gt;

&lt;p&gt;先払いの契約を想定しているため、契約開始時に最初の請求が発生します。&lt;/p&gt;

&lt;p&gt;しかし Subscription は契約を保持するだけで、直接決済をしません。じゃあ、どうするかっていうと、支払いが必要になったとき、自動的に Invoice オブジェクトをつくります。&lt;/p&gt;

&lt;h1&gt;
  
  
  Invoice
&lt;/h1&gt;

&lt;p&gt;Invoice オブジェクトは1回の請求行為を表します。猫ストリームの例では「今月ぶんの3,000円を請求するのだ」という活動です。&lt;/p&gt;

&lt;p&gt;未払いだとか、支払い済みだとか、期限切れだとか、もういらねぇよ（void）などの状態を持ちます。&lt;/p&gt;

&lt;p&gt;請求の状態を持ちますが、支払いを直接管理しません。じゃあどうするのかというと、ここで最初に出てきた Payment Intent が登場します。Invoice が資金の回収ができる条件がそろうと、自動的に Payment Intent を作り、実行しようとします。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1kJI-2CT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/etkcl4htfntug703f1vf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1kJI-2CT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/etkcl4htfntug703f1vf.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Payment Intent は、Customer -&amp;gt; Subscription -&amp;gt; Invoice と伝搬・継承してきた Payment Method から、支払いを回収しようとします。その結果は、今度は逆向きに Invoice -&amp;gt; Subscription のほうに伝搬していきます。&lt;/p&gt;

&lt;p&gt;Invoice が回収に失敗したとき、スマートリトライなる自動化処理があり、なんとなくいいタイミングでリトライします。それでも失敗し続けると、諦めます。その場合に、未回収だけど subscription を生かしておく、subscription をキャンセルするなどの挙動定義は、ダッシュボードで設定できます。&lt;/p&gt;

&lt;h1&gt;
  
  
  trial
&lt;/h1&gt;

&lt;p&gt;さて、めでたくサブスクリプション・ビジネスのサービスが開発できました。やったね！　すると、マーケティング担当とか、グロース担当とかが、こういうことを言い出すわけです。&lt;/p&gt;

&lt;p&gt;「今月サブスクしたら、一ヶ月無料キャンペーンをしよう！」&lt;/p&gt;

&lt;p&gt;だるいですね。&lt;/p&gt;

&lt;p&gt;初月無料キャンペーンのだるいところは、契約開始日と資金回収開始日がずれてしまうことです。そんなデータ構造持ってねぇよ、って言いたくなりますよね。&lt;/p&gt;

&lt;p&gt;そこで trial です。Subscription オブジェクトを作るときに、使用期間を指定できます。これは subscription が始まってからしばらく無料が続き、そのあとで最初の支払いを発生させるためのパラメータです。&lt;/p&gt;

&lt;p&gt;Subscription を作った時点では、0円の invoice が作られます。支払いは発生しないので Payment Intent は作られず、Invoice はすぐに paid 状態になります。そのため subscription は生きたままです。&lt;/p&gt;

&lt;p&gt;trial 期間が終わると、そこから支払いサイクルが始まり、Invoice -&amp;gt; Payment Intent の連鎖が始まります。&lt;/p&gt;

&lt;h1&gt;
  
  
  Coupon
&lt;/h1&gt;

&lt;p&gt;やりました。開発者のみなさんは、trial をも乗り越えました。すると、グロース担当（）が言うわけです。&lt;/p&gt;

&lt;p&gt;「競合が似たサービスを作ってきた！　継続してもらうために、既存顧客を2ヶ月間 50% オフにしよう！」&lt;/p&gt;

&lt;p&gt;はー。だるいですね。&lt;/p&gt;

&lt;p&gt;「難しかったら、1ヶ月でもいいよ」&lt;/p&gt;

&lt;p&gt;そういう問題じゃねーよ、お前のギャラを120%オフにすんぞ。&lt;/p&gt;

&lt;p&gt;それはそれとして、Coupon オブジェクトが使えるかもしれません。Subscription に Coupon を関連づけると、その Subscription の今後の請求に割引が適用されます。定義できる割引の挙動には、以下のようなパラメータがあります。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;何%オフにするか、◯◯円引きにするか&lt;/li&gt;
&lt;li&gt;1度だけか、指定した回数か、ずーっとか&lt;/li&gt;
&lt;li&gt;クーポン適用できる期限&lt;/li&gt;
&lt;li&gt;クーポンを適用できる最大数&lt;/li&gt;
&lt;li&gt;など&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;物理的に配るクーポン、デジタルクーポンを管理するものではありません。「Subscription に適用する割引」を表す、抽象的な概念です。&lt;/p&gt;

&lt;p&gt;Coupon が適用された結果、支払いサイクルで請求額が0円になる場合もあます。そのときは、0円 の Invoice が作られます。&lt;/p&gt;

&lt;h1&gt;
  
  
  おわりに
&lt;/h1&gt;

&lt;p&gt;バッチでできなくもないんですが、ワークフロー的な挙動をある程度 SaaS に任せられると、だるさから開放されることも多いと思います。ここでは、基本的なコンセプトを、自分なりにまとめてみました。&lt;/p&gt;

&lt;p&gt;よいお年を。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Disclaimer&lt;/strong&gt;: この記事は、公開されている情報を、個人が解釈して書き記したものです。所属する組織と関係ありそうに見えるかもしれませんが、関係ありません。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Disclaimer 2&lt;/strong&gt;: 所属する組織の人々へ。この文書は、勤務時間外に、個人の機材を使って、個人の解釈をまとめたものです。仕事ではないので、仕事として何か言ってこないでください。もちろん問題があったら修正・削除します。よろ。&lt;/p&gt;

</description>
      <category>stripe</category>
    </item>
    <item>
      <title>入門自然言語処理 pp.225-241</title>
      <dc:creator>Toru Furukawa</dc:creator>
      <pubDate>Sat, 17 Feb 2018 02:56:30 +0000</pubDate>
      <link>https://dev.to/torufurukawa/-pp225-xxx--5d6</link>
      <guid>https://dev.to/torufurukawa/-pp225-xxx--5d6</guid>
      <description>&lt;p&gt;5.6 変換を利用したタグ付け。一旦大雑把にタグ付けしたあと、教師あり学習したルールでさらに修正を加えていく。&lt;/p&gt;

&lt;p&gt;6章は、テキスト分類の学習。&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;「a」、[e]、「i」で終わる名前は女性の名前であることが多く、「k」、「o」、「r」、「s」、「t」で終わる名前は男性であることが多い。&lt;/p&gt;

&lt;p&gt;訳注: [...]日本語の場合は「男」や「夫」は男性、「子」は女性といった考え方をすることができる。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;へー。なるほどね。&lt;/p&gt;

</description>
      <category>nlp</category>
      <category>python</category>
      <category>reading</category>
    </item>
    <item>
      <title>入門自然言語処理 pp.215-225</title>
      <dc:creator>Toru Furukawa</dc:creator>
      <pubDate>Wed, 07 Feb 2018 22:56:21 +0000</pubDate>
      <link>https://dev.to/torufurukawa/-pp215-225--1b2n</link>
      <guid>https://dev.to/torufurukawa/-pp215-225--1b2n</guid>
      <description>&lt;p&gt;5.4 自動タグ付けの続き。「's」で終わる単語は所有格名詞、のような正規表現にタグ付けをする。タグ付けされたコーパスの頻出単語からルックアップテーブルを作る、残りはとりあえずよくあるタグである名詞としてタグ付けする。と、そこそこの精度でタグ付けができるようだ。もちろんルックアップテーブルや正規表現パターンを増やせば精度はあがるけど、ある程度からは向上しない。&lt;/p&gt;

&lt;p&gt;たぶん、時事ニュース記事なのか、ある特定の分野の学術論文なのか、はあちゅうのブログなのか、とかがあらかじめ分かっていれば、より適切なタグ付けモデルを作ることがきるんだろう。&lt;/p&gt;

&lt;p&gt;5.5 Nグラムタグ付け。直前の単語も考慮することで、文脈によるタグ付けが可能になる。未知語にもある程度対応できる。&lt;/p&gt;

</description>
      <category>nlp</category>
      <category>python</category>
      <category>reading</category>
    </item>
    <item>
      <title>入門自然言語処理 pp.204-215</title>
      <dc:creator>Toru Furukawa</dc:creator>
      <pubDate>Wed, 07 Feb 2018 00:08:25 +0000</pubDate>
      <link>https://dev.to/torufurukawa/-pp204-215--26mf</link>
      <guid>https://dev.to/torufurukawa/-pp204-215--26mf</guid>
      <description>&lt;p&gt;5.3 は、Python の辞書に関する説明。nltk.defaultdict と collections.defaultdict は同じものらしい。たぶん標準ライブラリに defaultdict が追加される前に、nltk に defaultdict が入ってたのであろうと想像する。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; import collections
&amp;gt;&amp;gt;&amp;gt; collections.defaultdict
&amp;lt;class 'collections.defaultdict'&amp;gt;
&amp;gt;&amp;gt;&amp;gt; import nltk
&amp;gt;&amp;gt;&amp;gt; nltk.defaultdict
&amp;lt;class 'collections.defaultdict'&amp;gt;
&amp;gt;&amp;gt;&amp;gt; collections.defaultdict == nltk.defaultdict
True
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;5.4 は自動タグ付け。&lt;/p&gt;

</description>
      <category>nlp</category>
      <category>python</category>
      <category>reading</category>
    </item>
    <item>
      <title>入門自然言語処理 pp.199-203</title>
      <dc:creator>Toru Furukawa</dc:creator>
      <pubDate>Tue, 30 Jan 2018 23:53:31 +0000</pubDate>
      <link>https://dev.to/torufurukawa/-pp199-203-fab</link>
      <guid>https://dev.to/torufurukawa/-pp199-203-fab</guid>
      <description>&lt;p&gt;5.2 はタグ付きコーパスの続き。&lt;/p&gt;

&lt;p&gt;タグの &lt;code&gt;NN$&lt;/code&gt; のように、$がついているとプロットするときのラベルとしてパースでいないので、雑に削除するコードを昨日書いた。んだけど、これはよくないことに気づく。&lt;/p&gt;

&lt;p&gt;読み進めていくと、&lt;code&gt;NN&lt;/code&gt; タグは spam のような一般的な名詞、 &lt;code&gt;NN$&lt;/code&gt; タグは spam's のような所有格名詞を表す。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import nltk
tagged_words = nltk.corpus.brown.tagged_words(categories="news")
dist = nltk.FreqDist(tag.replace("$", r"\$") for (word, tag) in tagged_words)
dist.plot()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>nlp</category>
      <category>python</category>
      <category>reading</category>
    </item>
    <item>
      <title>入門自然言語処理 pp.195-198</title>
      <dc:creator>Toru Furukawa</dc:creator>
      <pubDate>Mon, 29 Jan 2018 22:19:44 +0000</pubDate>
      <link>https://dev.to/torufurukawa/-pp195-198-47im</link>
      <guid>https://dev.to/torufurukawa/-pp195-198-47im</guid>
      <description>&lt;p&gt;5.2 タグ付きコーパスの導入。単語とタグのタプルとして、コーパスが格納されている。tagged_words() メソッドでイテレートできる。&lt;/p&gt;

&lt;p&gt;tagged_sents() なら、 &lt;code&gt;[[(word, tag), (word, tag), ...], [...], ...]&lt;/code&gt; として文ごとにイテレートできる。&lt;/p&gt;

&lt;p&gt;Python 3.6 + matplotlib==2.1.1 では、p.198 のプロットするサンプルでエラーが出る。FreqDict のキーに「PP$」のように $ が入っていて、この $をパースできないようだ。ここで根本原因を解決するのは本来の目的ではないので、適当に済ませる。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import nltk
tagged_words = nltk.corpus.brown.tagged_words(categories="news")
dist = nltk.FreqDist(tag.replace("$", "") for (word, tag) in tagged_words)
dist.plot()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>nlp</category>
      <category>python</category>
      <category>reading</category>
    </item>
    <item>
      <title>入門自然言語処理 pp.118-195</title>
      <dc:creator>Toru Furukawa</dc:creator>
      <pubDate>Sun, 28 Jan 2018 23:17:24 +0000</pubDate>
      <link>https://dev.to/torufurukawa/-pp118-195-38ai</link>
      <guid>https://dev.to/torufurukawa/-pp118-195-38ai</guid>
      <description>&lt;p&gt;4章はほとんどPythonの基礎なので、読み飛ばし。&lt;/p&gt;

&lt;p&gt;5章はタグ付きコーパス。5.1 でタグ付けの方法を紹介。&lt;/p&gt;

</description>
      <category>nlp</category>
      <category>python</category>
      <category>reading</category>
    </item>
    <item>
      <title>入門自然言語処理 pp.86-117</title>
      <dc:creator>Toru Furukawa</dc:creator>
      <pubDate>Thu, 25 Jan 2018 23:16:33 +0000</pubDate>
      <link>https://dev.to/torufurukawa/-pp86-117-1j64</link>
      <guid>https://dev.to/torufurukawa/-pp86-117-1j64</guid>
      <description>&lt;p&gt;3.2章は、Python の基本的な文字列処理。3.3 は Unicode とエンコーディングの考え方。Python 2 を前提にしているので、 u"..." とか。3.4、3.5 は正規表現と nltk の検索関数。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import nltk
from nltk.corpus import gutenberg, nps_chat

moby = nltk.Text(gutenberg.words("melville-moby_dick.txt"))
moby.findall(r"&amp;lt;a&amp;gt; (&amp;lt;.*&amp;gt;) &amp;lt;man&amp;gt;")

chat = nltk.Text(nps_chat.words())
chat.findall(r"&amp;lt;.*&amp;gt; &amp;lt;.*&amp;gt; &amp;lt;bro&amp;gt;")
chat.findall(r"&amp;lt;l.*&amp;gt;{3,}")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3.6 は正規化、ステミング。&lt;/p&gt;

</description>
      <category>nlp</category>
      <category>python</category>
      <category>reading</category>
    </item>
    <item>
      <title>東京公共交通オープンデータチャレンジ</title>
      <dc:creator>Toru Furukawa</dc:creator>
      <pubDate>Wed, 24 Jan 2018 22:45:36 +0000</pubDate>
      <link>https://dev.to/torufurukawa/-2a46</link>
      <guid>https://dev.to/torufurukawa/-2a46</guid>
      <description>&lt;p&gt;&lt;a href="http://tokyochallenge.odpt.org/"&gt;東京公共交通オープンデータチャレンジ&lt;/a&gt; という、アプリコンテスト＋アイデアコンテストがある。東京の交通機関のAPIやデータを活用しましょうってことらしい。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://qiita.com/teracy/items/962d9feb3349824090e2"&gt;ここがつらいよ東京公共交通オープンデータチャレンジAPI&lt;/a&gt; というまとめがあるくらい、なかなか大変そうではある。でも、いままで全然こんなデータはなかったんだから、こういうことでちょっとずつ進んでいくとよいのかも知れない。NAVITIME や Google はすごいな、と改めて思う。&lt;/p&gt;

</description>
      <category>odpt</category>
    </item>
    <item>
      <title>入門自然言語処理 pp.83-86</title>
      <dc:creator>Toru Furukawa</dc:creator>
      <pubDate>Tue, 23 Jan 2018 22:22:47 +0000</pubDate>
      <link>https://dev.to/torufurukawa/-pp83-86-3co4</link>
      <guid>https://dev.to/torufurukawa/-pp83-86-3co4</guid>
      <description>&lt;p&gt;ウェブのテキストを取得する方法。nltk 3.2.5 では、サンプルがそのまま動かない。3.1.2章のHTML処理をするには、以下のようにする。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ pip install beautifulsoup4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ python
Python 3.6.3 (default, Dec 14 2017, 14:27:23)
...
&amp;gt;&amp;gt;&amp;gt; import nltk
&amp;gt;&amp;gt;&amp;gt; from bs4 import BeautifulSoup
&amp;gt;&amp;gt;&amp;gt; url = "http://news.bbc.co.uk/2/hi/health/2284783.stm"
&amp;gt;&amp;gt;&amp;gt; html = urlopen(url).read()
&amp;gt;&amp;gt;&amp;gt; html = html.decode()
&amp;gt;&amp;gt;&amp;gt; soup = BeautifulSoup(html, "html.parser")
&amp;gt;&amp;gt;&amp;gt; raw = soup.get_text()
&amp;gt;&amp;gt;&amp;gt; tokens = nltk.word_tokenize(raw)
&amp;gt;&amp;gt;&amp;gt; text = nltk.Text(tokens)
&amp;gt;&amp;gt;&amp;gt; text.concordance("gene")
Displaying 7 of 7 matches:
hey say too few people now carry the gene for blondes to last beyond the next
blonde hair is caused by a recessive gene . In order for a child to have blond
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>nlp</category>
      <category>python</category>
      <category>reading</category>
    </item>
    <item>
      <title>入門自然言語処理 p.79</title>
      <dc:creator>Toru Furukawa</dc:creator>
      <pubDate>Mon, 08 Jan 2018 02:32:43 +0000</pubDate>
      <link>https://dev.to/torufurukawa/-p79-i31</link>
      <guid>https://dev.to/torufurukawa/-p79-i31</guid>
      <description>&lt;p&gt;あまりに頭に入っていない気がするので、練習問題をいくつかやってみることにする。私は手を動かして、何かを作って、理解する必要がある傾向がある。効率は悪いけれど、そういうパターンらしいのでしょうがない。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/torufurukawa/learn-nlp"&gt;https://github.com/torufurukawa/learn-nlp&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;リポジトリを作ったんだけど、initial commit のプッシュがうまくいかなくて時間を使った。SourceTree を使って clone するときに https を使ったらしく、push のときに SSH の認証情報を渡してもだめだった、というオチである。何をやっているんだか。&lt;/p&gt;

&lt;p&gt;とりあえず数行で解決する問題を、1問解いてプッシュしておいた。&lt;/p&gt;

</description>
      <category>nlp</category>
      <category>python</category>
      <category>reading</category>
    </item>
  </channel>
</rss>
