新着記事一覧

転職エージェント

キャリア形成・転職 仕事・キャリア

2026/10/20

【40代の転職】転職エージェントの選び方

転職活動を始めるとき、利用する人も多い「転職サイト」。 転職サイトに登録していると、様々な転職エージェントからスカウトや連絡があります。 私も今回の転職活動では、複数の転職サイトに登録し、その中でスカウトを送ってくれたいくつかの転職エージェントの担当者と実際に話をしました。 そこで感じたのが、「転職エージェントなら、どこでも同じというわけではない」ということです。 求人の紹介方法も違えば、書類添削や面接対策などのサポート内容も違います。 そして何より、担当者によって熱量や相性がかなり違うと感じました。 今 ...

続きを読む

ポケモン 遊び・趣味

2026/10/20

【ポケモン】ポケモンGo リアルイベントの醍醐味

ポケモンGOのリアルイベントに参加してみて、改めて感じたことがあります。 それは、「ポケモンGOって、こんなに人とつながれるゲームだったんだ!」ということ。 普段もポケモンGOをプレイしていますが、家の近所や通勤途中で遊んでいるときは、一人(もしくは子供と)で黙々とポケモンを捕まえています。 知らない人に話しかけることも、ほとんどありません。 ところが、リアルイベントになると、それがちょっと変わります。 そこには、同じようにポケモンが好きな人が全国、そして世界中から集まっている。 「ポケモンが好き」という ...

続きを読む

キャリア形成・転職 仕事・キャリア

2026/10/20

【40代の転職】転職活動のスケジュールと進め方

海外営業からデジタルマーケティングへキャリアチェンジし、やりたい仕事に手応えを感じていたものの、組織変更によってデジタルマーケティングの仕事そのものがなくなってしまったことが、転職を考える大きなきっかけでした。 今回は、その後の転職活動のスケジュールと、実際にどのように転職活動を進めたのかを書いてみたいと思います。 結果的には、3月に本格的に転職活動を始め、4月に転職先を決定、4月22日を最終出社日として、5月は少しゆっくり過ごし、6月から新しい会社で働き始めました。 これから転職を考えている方の参考にな ...

続きを読む

ポケモン 遊び・趣味

2026/10/18

【ポケモン】Pokémon GO Fest 2026:東京!5月のリアルイベントの服装と持ち物まとめ

5月に開催されたPokémon GO Fest 東京に、小学2年生の息子と一緒に参加してきました!リアルイベントは初参加です! 今回が初めてのリアルイベント参加。 参加する前は、 「5月ならそこまで暑くないかな?」 「飲み物はどれくらい持っていけばいい?」 「スマホの充電は足りる?」 など、いろいろと気になることがありました。 実際に参加してみると、ポケモンGOのリアルイベントならではの準備がかなり重要! 特に、たくさんの人が集まるイベントなので、飲み物やモバイルバッテリーなどは「ちょっと多いかな?」くら ...

続きを読む

キャリア形成・転職 仕事・キャリア

2026/10/20

【40代の転職】転職のきっかけ

Haruは41歳で転職をしました。この記事では、40代の転職のきっかけをお伝えしようと思います。 なぜ転職を決めたのか 「なぜ転職したの?」 転職すると、よく聞かれる質問です。 私の場合、突然「今の会社が嫌になったから」というわけではありません。むしろ、これまでの会社で自分なりにやりたいことを見つけ、勉強して、部署異動まで実現させて、少しずつキャリアを変えてきました。 それでも最終的に転職を決めたのは、「この会社にいても、これ以上自分がやりたい方向には進めない」と思う出来事があったからです。 今回は、私が ...

続きを読む

ポケモン 遊び・趣味

2026/10/11

【ポケモン】豊橋ポケモン天文台に行ってきた話

三連休の土曜日、子どもたちと一緒にポケモン天文台へ行ってきました!ポケモンと宇宙が組み合わさった施設ということで、子どもたちは行く前から楽しみにしていました。今回は、実際に訪れてみて感じたことを中心に、アクセスや駐車場、混雑状況、館内の見どころ、グッズ購入までまとめてみます。(ネタばれしない範囲で) ポケモン天文台ってどんなところ? ポケモン天文台は、宇宙や星について楽しく学べる、ポケモン好きの子どもにはたまらないスポット。単に展示を見るだけではなく、ポケモンと一緒に太陽系や星、隕石などについて学べるので ...

続きを読む

Python 仕事・キャリア

2026/10/10

【Python】Pythonでの自然言語処理(日本語)

こちらの記事では、自然言語処理についてまとめています。 自然言語処理とは? 自然言語とは、日本語や英語のような自然発生的に生まれた言語です。日常的に使用している自然言語について、言葉が持つ意味を解析し処理します。活用事例としては、チャットボット、音声認識AI、文字認識(手書き文字をカメラが認識し文字データへと変換する技術)、検索エンジン、翻訳、感情分析、文章要約などがあります。 文章の意味を機械に理解させるには、単語分割を行う必要があります。手法は主に2つあります。 1.形態素解析形態素とは意味を持つ最小 ...

続きを読む

Python 仕事・キャリア

【Python】機械学習(教師あり学習 分類)ランダムフォレストの実装

機械学習(教師あり学習 分類)のランダムフォレストを実装してみたいと思います。

※学習初学者の勉強のアウトプットですので、もしコードや解釈に間違い等あればご指摘頂けますと幸いです。
メモも兼ねて、各コードなるべく詳しく説明をつけるようにしています。

前提:教師あり学習 分類とは?

カテゴリ別に分けてあるデータを学習し、未知のデータのカテゴリを予測する手法です。
新商品をメールで案内する時に、顧客の過去の購買履歴を使用し購買見込みが高い人を予測、その人のみに特別なメールを送る、などの活用例があります。

分類は大まかに2項分類、多項分類に分けられます。

2項分類:YES/ NOのように、予測するカテゴリが2つの分類を指します。さらに線形分類・非線形分類に分けられます。

多項分類:分類するカテゴリが3つ以上の分類を指します。

分類の主な手法について

・ロジスティック回帰:
線形分離可能なデータの境界線を見つけ、データの分類を行う手法。境界が直線になるので、2項分類等カテゴリの少ないデータの分類に使用される。「回帰」とあるが分類の手法であることに注意。

・線形SVM(サポートベクターマシン):
データの境界線を見つけ、線形分類を行う手法。SVMはサポートベクトルというベクトルを用いて境界線を引きます。SVMは境界線が2カテゴリの最も離れた場所に引かれるので、ロジスティック回帰よりも一般化されやすく精度が高い傾向があります。

・非線形SVM(サポートベクターマシン):
線形SVMの”線形分離可能なデータ"しか分類できない、という欠点を補うために開発されたモデルです。

・決定木:
データの説明変数(要素)に注目し、説明変数内のある値を堺にデータを分割し、データの属するカテゴリを決定する手法。
それぞれの説明変数が目的変数にどの程度の影響を与えているのかを見ることができます。分割を繰り返して枝分かれしていくが、先に分割される条件に用いられる変数ほど、影響力が高いと言えます。線形分離できないデータは分類が難しい点が欠点。

・ランダムフォレスト:
決定木を複数作り、分類の結果を多数決で決める手法。アンサンブル学習の手法の一つ。
決定木では、全ての説明変数を使用していたが、ランダムフォレストでは少数の説明変数を用いてデータのカテゴリを決定します。
線形分離できない複雑なデータでも分類可能。欠点として、決定木と同様、説明変数の数に対してデータが少ないと決定木の分割ができず、予測精度が下がってしまう点が挙げられる。

・k-NN:
k近似法とも呼ばれる。予測するデータと類似したデータを見つけ、多数決により分離結果を決める手法。
教師データから学習するのではなく、教師データを直接参照してラベルを予測するのが他の分類手法との違い。k-NNの特徴としては、学習コストが0である点、アルゴリズムが単純だが比較的精度が高い点、複雑な形の境界線も表現可能な点が挙げられます。

ランダムフォレストの実装

今回はskleranのirisデータセットを使用して、ランダムフォレストを実装していきます。
4つの特徴量(sepal length(cm): がく片の長さ/sepal width(cm): がく片の幅/petal length(cm): 花びらの長さ/petal width(cm): 花びらの幅)とラベル(0: setosa/1:versicolor/2:virginica)で構成されているデータセット(150件)です。
本コード内で、決定木とランダムフォレストの比較も行ってみます。

from sklearn.model_selection import train_test_split 
from sklearn import datasets
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn import metrics

#アヤメのデータセットを取得し、中身を確認する
iris = datasets.load_iris()

#irisデータセットの全行と0列目、2列目をXに格納する
X = iris.data[0:, [0,2]]

#yにtargetを格納する
y = iris.target

#train_data ,testデータに分割し、分割できているか確認
train_X, test_X, train_y, test_y = train_test_split(X, y, test_size = 0.3, random_state=42)
print(f"train_X:{train_X.shape}")
print(f"test_X:{test_X.shape}")
print(f"train_y:{train_y.shape}")
print(f"test_y:{test_y.shape}")

#モデルを構築する
model1 = RandomForestClassifier()
model2 = DecisionTreeClassifier()

#モデルに学習させる
model1.fit(train_X, train_y)
model2.fit(train_X, train_y)

#test_xとtest_yを用いた場合の正答率を出す
print(f"RandomForestClassifier: {model1.score(test_X, test_y)}")
print(f"DecisionTreeClassifier: {model2.score(test_X, test_y)}")

#matplotlibで可視化を行う
fig, (axL, axR) = plt.subplots(ncols=2, figsize=(10,4))

#ランダムフォレストモデルを可視化する
axL.scatter(X[:, 0], X[:, 1], c=y ,marker=".", cmap=matplotlib.cm.get_cmap("cool"), alpha=1.0)

#モデルが学習した決定境界をプロットしていく
#特徴空間の範囲を指定する、0列目の特徴量、1列目の特徴量の最小値-1と最大値+1を指定し、特徴空間の範囲を広げておく
x1_min, x1_max = X[:, 0].min() - 1, X[:, 0].max() + 1
x2_min, x2_max = X[:, 1].min() - 1, X[:, 1].max() + 1

#徴空間をメッシュグリッドで表現する、meshgridで格子点を作る
#x1_min,x1_maxまでの範囲を0.02刻みで配列を作成する
xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, 0.02), np.arange(x2_min, x2_max, 0.02) )

#学習済モデル(model)を使用し、各座標のラベルを予測する
Z1 = model1.predict(np.array([xx1.ravel(), xx2.ravel()]).T).reshape(xx1.shape)

#contourfで等高線を作成し、alphaで透明度、cmapでカラーマップを指定する
axL.contourf(xx1, xx2, Z1, cmap=matplotlib.cm.get_cmap(name="Wistia"), alpha=0.4)
axL.set_xlim(xx1.min(), xx1.max())
axL.set_ylim(xx2.min(), xx2.max())
axL.set_title("Classification data using RandomForestClassifier")
axL.set_xlabel("Sepal length")
axL.set_ylabel("Petal length")
axL.grid(True)


#決定木を可視化する
axR.scatter(X[:, 0], X[:, 1], c=y , marker=".", cmap=matplotlib.cm.get_cmap(name="cool"), alpha=1.0)
x1_min, x1_max = X[:, 0].min() - 1 , X[:, 0].max() + 1
x2_min, x2_max = X[:, 1].min() - 1 , X[:, 1].max() + 1
xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, 0.02),np.arange(x2_min, x2_max, 0.02))
Z2 = model2.predict(np.array([xx1.ravel(), xx2.ravel()]).T).reshape(xx1.shape)
axR.contourf(xx1, xx2, Z2, cmap=matplotlib.cm.get_cmap(name="Wistia"), alpha=0.4)
axR.set_xlim(xx1.min(), xx1.max())
axR.set_ylim(xx2.min(), xx2.max())
axR.set_title("Classification data using DecisionTreeClassifier")
axR.set_xlabel("Sepal length")
axR.set_ylabel("Petal length")
axR.grid(True)
plt.show()

解説

#irisデータセットを取得し、中身を確認する
iris = datasets.load_iris()
iris.keys()

必要なライブラリをインポートした後、irisのデータセットを読み込みます。
iris.keys()で、key値が取得できます。

たとえば、iris.feature_namesとすると、特徴量の名称が確認できます。

#irisデータセットの全行と0列目(sepal length)、2列目(petal length)をXに格納する
X = iris.data[0:, [0,2]]

元々のirisのデータの中身をiris.dataで確認してみると、以下のようになります。


そこから黄色で色をつけた0列目、2列目をXに格納します。
iris.data[0:, [0,2]]で、0:全行、[0,2]で0列目と2列目を指定しています。中身を確認すると、以下のように格納できていることがわかりました。

#yにtargetを格納する
y = iris.target

yにtarget(ラベル)を格納していきます。ラベルが格納されていることも確認できました。

#train_data ,testデータに分割し、分割できているか確認
train_X, test_X, train_y, test_y = train_test_split(X, y, test_size = 0.3, random_state=42)
print(f"train_X:{train_X.shape}")
print(f"test_X:{test_X.shape}")
print(f"train_y:{train_y.shape}")
print(f"test_y:{test_y.shape}")

trainデータ(0.7)とtestデータ(0.3)に分割し、分割できているかを念のため確認しておきます。
元々データセットは150件だったので、train_X: 105行×2列、test_X: 45行×2列、train_y: 105行×1列、test_y: 45行×1列となっていれば大丈夫です。念のため.shapeで確認しておきます。

#モデルを構築する
model1 = RandomForestClassifier()
model2 = DecisionTreeClassifier()

#モデルに学習させる
model1.fit(train_X, train_y)
model2.fit(train_X, train_y)

#test_xとtest_yを用いた場合の正答率を出す
print(f"RandomForestClassifier: {model1.score(test_X, test_y)}")
print(f"DecisionTreeClassifier: {model2.score(test_X, test_y)}")

model1をランダムフォレスト、model2を決定木とします。
それぞれ、train_X、train_yを入れて学習させ、.score()でtest_X、text_yを入れて正答率を出します。

#matplotlibで可視化を行う、図を作成する
fig, (axL, axR) = plt.subplots(ncols=2, figsize=(10,4))

figは図全体を表すオブジェクトです。(axL, axR)はサブプロットを表すオブジェクトのタプルです。
ncols=2により2列をもつサブプロットが作成されます。左のサブプロットはaxL、右のサブプロットはaxRと定義されます。
figsizeで図のサイズを指定、この場合は幅が10インチ、高さが4インチとなります。

#ランダムフォレストモデルを可視化する
axL.scatter(X[:, 0], X[:, 1], c=y ,marker=".", cmap=matplotlib.cm.get_cmap("cool"), alpha=1.0)

まず、axLにランダムフォレストの散布図を描画していきます。X軸とY軸の値を指定し、他のパラメーターも調整します。

#モデルが学習した決定境界をプロットしていく
#特徴空間の範囲を指定する、0列目の特徴量、1列目の特徴量の最小値-1と最大値+1を指定し、特徴空間の範囲を広げておく
x1_min, x1_max = X[:, 0].min() -1, X[:, 0].max() +1
x2_min, x2_max = X[:, 1].min() -1, X[:, 1].max() +1

特徴空間の範囲をまず指定します。例えば、X[:, 0].min()-1の意味は、Xに格納した全行、0列目の中で一番小さい値を抽出。特徴空間の範囲を広げるため、-1をしておきます。

#特徴空間をメッシュグリッドで表現する
#x1_min,x1_max/x2_min,x2_maxまでの範囲を0.02刻みで配列を作成する
xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, 0.02),
                       np.arange(x2_min, x2_max, 0.02))

meshgridは格子点を作る関数です。基本的な考え方はこちらのサイトを参考にさせて頂きました。とてもわかりやすいです。
x1_min,x1_max/x2_min,x2_maxまでの範囲を0.02刻みで配列を作成し、それぞれxx1, xx2に格納していきます。
print()で表示してみると、以下のようになります。
赤線より上がxx1(X軸の値), 下がxx2(Y軸の値)の値になります。(3.3, 0), (3.32, 0), (3.34, 0), ・・・(8.84, 0), (8.86, 0), (8.88, 0),と言った格子点です。
shape()で確認すると、xx1/xx2ともに(395, 280)の配列であることがわかります。

#学習済モデル(model1)を使用し、各座標のラベルを予測する
Z1 = model1.predict(np.array([xx1.ravel(), xx2.ravel()]).T).reshape(xx1.shape)

学習済モデルを使用し、各格子点のラベルを予測していきます。

予測する際にはデータを一次元に戻す必要がありますので、ravel()でxx1, xx2をそれぞれ1次元配列に戻します。1次元配列に戻すと、(110600, )となります。元の配列が395×280 =110600なので、正しく一次元配列に戻りましたが、今は列方向に配列が並んでいるので.Tで転置して行方向に配列が並ぶようにします。転置をしないと"X has 110600 features, but LogisticRegression is expecting 2 features as input."というエラーがでます。

一次元に戻したものを学習済モデルに入れ、各格子点のラベルを予測します。
その後、予測したラベルを元々のxx1の配列(395, 280)の形にreshape()で戻します。

#contourfで等高線を作成し、alphaで透明度、cmapでカラーマップを指定する
axL.contourf(xx1, xx2, Z1, cmap=matplotlib.cm.get_cmap(name="Wistia"), alpha=0.4)
axL.set_xlim(xx1.min(), xx1.max())
axL.set_ylim(xx2.min(), xx2.max())
axL.set_title("Classification data using RandomForestClassifier")
axL.set_xlabel("Sepal length")
axL.set_ylabel("Petal length")
axL.grid(True)

contourfは等高線を引く時に使います。contourf(格子点のX座標の配列、格子点のY座標の配列、値の配列)として値を渡します。
今回は、xx1、xx2、そしてxx1/xx2から予測したラベルの値をそれぞれ渡します。
cmapでカラーマップの色を指定します。Matplotlibのサイトで確認できます。Alphaは透明度を調整します。

最後に、描画する際の表示範囲を指定、グラフにタイトルをつけます。ランダムフォレストの描画完了です。

同様に以下コードで決定木を描画していきます。

#決定木を可視化する
axR.scatter(X[:, 0], X[:, 1], c=y , marker=".", cmap=matplotlib.cm.get_cmap(name="cool"), alpha=1.0)
x1_min, x1_max = X[:, 0].min() - 1 , X[:, 0].max() + 1
x2_min, x2_max = X[:, 1].min() - 1 , X[:, 1].max() + 1
xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, 0.02),np.arange(x2_min, x2_max, 0.02))
Z2 = model2.predict(np.array([xx1.ravel(), xx2.ravel()]).T).reshape(xx1.shape)
axR.contourf(xx1, xx2, Z2, cmap=matplotlib.cm.get_cmap(name="Wistia"), alpha=0.4)
axR.set_xlim(xx1.min(), xx1.max())
axR.set_ylim(xx2.min(), xx2.max())
axR.set_title("Classification data using DecisionTreeClassifier")
axR.set_xlabel("Sepal length")
axR.set_ylabel("Petal length")
axR.grid(True)
plt.show()

以下のように描画できました。

https://haruhaya-channel.com/python13
  • この記事を書いた人

Haru

会社員。育休2回取得、40代で転職。
職種はデジタルマーケティング。
ポケモン、スノボ、IT系の学び、キャリア、育児について発信していきます。

-Python, 仕事・キャリア
-, , ,