为什么主成分分析会给我带来截然不同的结果?

时间:2017-03-23 11:34:30

标签: algorithm numpy pca data-analysis

我试图解决的问题是这样的:给定图像中的斑点,我想得到它的方向来指导我绘制线条来填充该区域。我希望线条跟随区域的长轴,使用尽可能少的线条。

我用谷歌搜索,并通过PCA算法为所有点坐标提供PCA(主成分分析)作为获得blob方向的好方法:

https://alyssaq.github.io/alyssaq.github.io/2015/computing-the-axes-or-orientation-of-a-blob/index.html

但是复制精确的算法,我得到了非常令人惊讶的结果。给定相似的形状区域,PCA算法返回完全不同的特征向量。它们似乎是垂直的:

Different directions

上面的线是按照PCA算法给出的斜率渲染的,具有轻微的随机变化。

我对数据处理知之甚少,这里发生了什么?我该如何解决这个问题?

代码:

import numpy as np

# I tried passing different set of points to pca:
# 1. Only points at the perimeter of the area
# 2. Random sample of points within the area
# 3. All points in the area

# points are like [(x1, y1), (x2, y2), ... ]
def pca(points):
    xs, ys = zip(*points)
    x = np.array(xs)
    y = np.array(ys)

    # Subtract mean from each dimension. We now have our 2xm matrix.
    x = x - np.mean(x)
    y = y - np.mean(y)
    coords = np.vstack([x, y])

    # Covariance matrix and its eigenvectors and eigenvalues
    cov = np.cov(coords)
    vals, evecs = np.linalg.eig(cov)

    # Sort eigenvalues in decreasing order (we only have 2 values)
    sort_indices = np.argsort(vals)[::-1]

    evec1, evec2 = evecs[:, sort_indices]  # Eigenvector with largest eigenvalue
    eval1, eval2 = vals[sort_indices[0]], vals[sort_indices[1]]
    print("PCA:", evec1, evec2, eval1, eval2)
    return evec1, evec2, eval1, eval2

我尝试将不同的点集传递给pca:

  1. 只在该区域的周边点
  2. 区域内随机抽样点
  3. 该地区的所有要点
  4. 但无所谓,每次点选择,我的算法都可以产生上述两种模式。虽然看起来右边的那个(不正确的一个)更频繁地产生。

1 个答案:

答案 0 :(得分:1)

错误在于这一行:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fitsSystemWindows="true"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar"
            android:layout_width="match_parent"
            android:layout_height="256dp"
            android:fitsSystemWindows="true"
            app:contentScrim="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            app:titleEnabled="false">

            <ImageView
                android:id="@+id/image_header"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:fitsSystemWindows="true"
                android:scaleType="centerCrop"
                app:layout_collapseMode="parallax" />

            <android.support.v7.widget.Toolbar
                android:id="@+id/anim_toolbar"
                android:layout_width="match_parent"
                android:layout_height="104dp"
                android:minHeight="?attr/actionBarSize"
                android:gravity="top"
                app:layout_collapseMode="pin"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                app:titleMarginTop="13dp" />


            <android.support.design.widget.TabLayout
                android:id="@+id/tabs"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="bottom"
                app:tabGravity="fill"
                app:tabMode="scrollable"
                style="@style/MyCustomTabLayout"/>
        </android.support.design.widget.CollapsingToolbarLayout>
    </android.support.design.widget.AppBarLayout>

    <android.support.v4.view.ViewPager
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />


    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab_map"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentBottom="true"
        android:layout_gravity="bottom|end"
        android:layout_margin="@dimen/fab_margin"
        app:backgroundTint="#f44336"
        android:src="@drawable/ic_maps_my_location" />

</android.support.design.widget.CoordinatorLayout>

特征向量位于列中,但该赋值将evec1, evec2 = evecs[:, sort_indices] 的第一个分配给evecs[:, sort_indices],将第二行分配给evec1。快速修复

evec2