pythonでカンマ入りの数値の修正

pythonのデータ解析をやっていた時

ValueError: Input contains NaN, infinity or a value too large for dtype('float64').

のエラーがでたので、

np.where( np.isnan(X) )

ひとまずNaNの場所を確認。値を参照したところ、数値データのハズなのにカンマ入りだったために文字列として認識されていたようです。もとのエクセルデータでそういった風に入力してしまったようで、さもありなん。

df['〇〇〇'] = np.array( [ float( i.replace(',','') ) if type(i) is str else i for i in df['〇〇〇'] ] )

リスト内包表記のifを使って修正。

参考にしました

qiita.com

Pythonで文字列を検索(〜を含むか判定、位置取得、カウント) | note.nkmk.me

Pythonリスト内包表記の使い方 | note.nkmk.me

VIFによる変数選択

重回帰分析をやっていると、多重共線性(マルチコ)ので変数選択が必要になりますが、評価指標として分散拡大係数:Variance Inflation Factorというものがあるそうで。

numpyで直接計算する。

corr_mat = np.array(df.corr())
inv_corr_mat = np.linalg.inv(corr_mat)
pd.Series(np.diag(inv_corr_mat), index=df.columns)

statsmodelsを使う。

import statsmodels.api as sm

xx = df.drop('目的変数',axis=1)
yy = df['目的変数']

x_add_const = sm.add_constant(xx)
model_sm = sm.OLS(yy, x_add_const).fit()
print(model_sm.summary())

from statsmodels.stats.outliers_influence import variance_inflation_factor as vif

num_cols = model.exog.shape[1]
vifs = [vif(model.exog, i) for i in range(0, num_cols)]

pd.DataFrame(vifs, index=model.exog_names, columns=['VIF'])

参考にしました

pythonのstatsmodelsを使った重回帰分析で溶解度予測:AICによるモデル選択 | 化学の新しいカタチ

Python(StatsModels) で重回帰分析を理解し、分析の精度を上げる方法 | たぬハック

VIF統計量をPythonで計算 | βshort Lab

VIFを利用した減少法による変数選択法in Python | βshort Lab

Pythonを使って変数選択! - 見習いデータサイエンティストの隠れ家

PythonのStatsModelsで重回帰分析 - Qiita

【python】マルチページtiffの読み込み

マルチページtiff画像を読み込んで、配列に画像データ(輝度値データ )を格納していきます。

from PIL import Image

im = Image.open('gazou.tif')
# imgはからの配列。追加していく。
img = np.arange(0)

for i in range(im.n_frames):
    # マルチページtiffでのページの進め方
    im.seek(i)
    # 配列imgへの画像データの追加
    img = np.append( img, im )
# 形状を変更
img = img.reshape( -1, np.shape( im )[0],np.shape( im )[1] )

参考にしました。

Python:マルチページTIFFを読み込んで1ページずつ処理する · GitHub

pythonで回帰分析(重回帰分析)

pythonで回帰分析(重回帰分析)をするときのまとめ。結果の出力まで。

scikitlearnを使う

後述のstatsmodelsが機能は充実しているが、サクッと使いたいor他のモデルを使っている場合はこちら。係数の比較などをしたいので、データは規格化しています。

from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression

scaler = StandardScaler()
clf = LinearRegression()

y = target #インプットデータ
X = x_data #インプットデータ 

scaler.fit(X)
clf.fit( scaler.transform(X), y )
y_pred = clf.predict(scaler.transform(X)) # yの予測
print( clf.coef_) # 重み(係数の確認)
print( clf.score(scaler.transform(X),y ) # スコアの確認

statsmodelsを使う

import statsmodels.api as sm
from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()

y = target #インプットデータ
X = x_data #インプットデータ 
#X = X.reshape(-1,1) #型の変換が必要な時
scaler.fit(X)
X = scaler.transform(X)
X = sm.add_constant(X)

model  = sm.OLS( y, X )
result = model.fit()
y_pred =  result.predict( X ) #yの予測
print( result.summary() ) # 重回帰のデータを出力

stasmodelを使ったあとのモデルの保存

result.save('foo') # statsmodelsの標準機能、pickleで保存

# summaryを適当なテキストデータで保存
file = open('summary.txt', 'w')
file.write(str(result.summary()))
file.close()

グラフを作成

回帰分析したので、予測値と実測値を比較する図を(ざっくり)作成します。下記は一例。

from decimal import Decimal, ROUND_HALF_UP

xy_min  = 0
xy_max = 4
plt.figure(figsize=(6,6)) # グラフは正方形
plt.plot( y_pred, y, 'o' )
plt.xlim([xy_min,xy_max])
plt.ylim([xy_min,xy_max])
plt.plot([xy_min,xy_max],[xy_min,xy_max],'k-')
plt.xlabel('Predicted')
plt.ylabel('Measured')
rs = str(Decimal(str(str( result.rsquared ))).quantize(Decimal('0.001'), rounding=ROUND_HALF_UP)) #スコアをstr形式に変換
plt.text(0.2,3.7,'R-squared: '+rs) # 適当な位置にスコアを表示
plt.savefig('result.png')